diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-04-22 08:13:41 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-04-22 08:13:41 +0200 |
commit | 8691914c9c40dbfde5d757b563520c42691cfc6b (patch) | |
tree | f50f76235d37ca871ca84c9988c9399f8c3d2331 | |
parent | 5841b245ee5f3d31b1c1856a443d6aed26fcf582 (diff) | |
download | ghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.tar.gz ghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.tar.bz2 ghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.zip |
synth: add tri gate.
-rw-r--r-- | src/synth/ghdlsynth_gates.h | 5 | ||||
-rw-r--r-- | src/synth/netlists-builders.adb | 33 | ||||
-rw-r--r-- | src/synth/netlists-builders.ads | 3 | ||||
-rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 4 | ||||
-rw-r--r-- | src/synth/netlists-gates.ads | 21 |
5 files changed, 64 insertions, 2 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h index 03bd87499..71b29221b 100644 --- a/src/synth/ghdlsynth_gates.h +++ b/src/synth/ghdlsynth_gates.h @@ -64,7 +64,8 @@ enum Module_Id { Id_Iadff = 59, Id_Mdff = 60, Id_Midff = 61, - Id_Nop = 60, + Id_Nop = 62, + Id_Tri = 63, Id_Utrunc = 64, Id_Strunc = 65, Id_Uextend = 66, @@ -75,6 +76,7 @@ enum Module_Id { Id_Dyn_Insert_En = 71, Id_Memidx = 72, Id_Addidx = 73, + Id_Memory = 74, Id_Memory_Init = 75, Id_Mem_Rd = 76, @@ -91,6 +93,7 @@ enum Module_Id { Id_Anyconst = 91, Id_Allseq = 92, Id_Anyseq = 93, + Id_Resolver = 94, Id_Const_UB32 = 112, Id_Const_SB32 = 113, Id_Const_UL32 = 114, diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index 15d570a70..cf7a4ff71 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -584,6 +584,22 @@ package body Netlists.Builders is Set_Ports_Desc (Res, Port_Desc_Array'(1 .. 0 => <>), Outputs); end Create_Formal_Input; + procedure Create_Tri_Module (Ctxt : Context_Acc) + is + Outputs : Port_Desc_Array (0 .. 0); + Inputs : Port_Desc_Array (0 .. 1); + Res : Module; + begin + Res := New_User_Module (Ctxt.Design, + New_Sname_Artificial (Name_Tri, No_Sname), + Id_Tri, 2, 1, 0); + Ctxt.M_Tri := Res; + Outputs := (0 => Create_Output ("o")); + Inputs := (0 => Create_Input ("en"), + 1 => Create_Input ("i")); + Set_Ports_Desc (Res, Inputs, Outputs); + end Create_Tri_Module; + function Build_Builders (Design : Module) return Context_Acc is Res : Context_Acc; @@ -723,6 +739,8 @@ package body Netlists.Builders is Create_Formal_Input (Res, Id_Allseq, Name_Allseq); Create_Formal_Input (Res, Id_Anyseq, Name_Anyseq); + Create_Tri_Module (Res); + return Res; end Build_Builders; @@ -1501,6 +1519,21 @@ package body Netlists.Builders is return O; end Build_Midff; + function Build_Tri (Ctxt : Context_Acc; En : Net; D : Net) return Net + is + Wd : constant Width := Get_Width (D); + pragma Assert (Get_Width (En) = 1); + Inst : Instance; + O : Net; + begin + Inst := New_Internal_Instance (Ctxt, Ctxt.M_Tri); + O := Get_Output (Inst, 0); + Set_Width (O, Wd); + Connect (Get_Input (Inst, 0), En); + Connect (Get_Input (Inst, 1), D); + return O; + end Build_Tri; + function Build_Extract (Ctxt : Context_Acc; I : Net; Off, W : Width) return Net is diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads index a58f1bba9..09b5c4854 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -202,6 +202,8 @@ package Netlists.Builders is Els : Net; Init : Net) return Net; + function Build_Tri (Ctxt : Context_Acc; En : Net; D : Net) return Net; + function Build_Nop (Ctxt : Context_Acc; I : Net) return Net; private type Module_Arr is array (Module_Id range <>) of Module; @@ -240,6 +242,7 @@ private M_Iadff : Module; M_Mdff : Module; M_Midff : Module; + M_Tri : Module; M_Truncate : Module_Arr (Truncate_Module_Id); M_Extend : Module_Arr (Extend_Module_Id); M_Reduce : Module_Arr (Reduce_Module_Id); diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb index c772be71b..23e1cb782 100644 --- a/src/synth/netlists-disp_vhdl.adb +++ b/src/synth/netlists-disp_vhdl.adb @@ -1242,6 +1242,10 @@ package body Netlists.Disp_Vhdl is when Id_Negedge => Disp_Template (" \o0 <= '1' when falling_edge (\i0) else '0';" & NL, Inst); + when Id_Tri => + Disp_Template (" \o0 <= \i1 when (\i0 = '1') else ", Inst); + Disp_X_Lit (Get_Width (Get_Output (Inst, 0)), 'Z'); + Put_Line (";"); when Id_Assert => Disp_Template (" \l0: assert \i0 = '1' severity error;" & NL, Inst); diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index 8dcb65cce..8c50e76c6 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -186,7 +186,14 @@ package Netlists.Gates is Id_Midff : constant Module_Id := 61; -- Temporary gate, O = I - Id_Nop : constant Module_Id := 60; + Id_Nop : constant Module_Id := 62; + + -- Tri state buffer. + -- Inputs: 0: D + -- 1: EN + -- Outputs: 0: O + -- O <= EN ? O : 'Z' + Id_Tri : constant Module_Id := 63; -- Width change: truncate or extend. Sign is know in order to possibly -- detect loss of value. @@ -234,6 +241,9 @@ package Netlists.Gates is -- OUT := IN0 + IN1, size extension (max of inputs width). Id_Addidx : constant Module_Id := 73; + -- TODO: + -- Id_Addidx_Cst : constant Module_Id := XX; + -- Represent a memory with a fixed size. -- This is not a regular gate as it has only one output, PORTS. -- The width of the output is the size (in bits) of the memory. @@ -298,6 +308,15 @@ package Netlists.Gates is subtype Formal_Module_Id is Module_Id range Id_Allconst .. Id_Anyseq; + -- A resolver for tri-state. The two inputs (tri or resolver gates) are + -- connected together and to the output. + -- I0 I1 O + -- Z Z Z + -- Z v1 v1 + -- v0 Z v0 + -- v0 v1 vo Ok if v0 = v1, error if v0 /= v1. + Id_Resolver : constant Module_Id := 94; + -- Constants are gates with only one constant output. There are multiple -- kind of constant gates: for small width, the value is stored as a -- parameter, possibly signed or unsigned extended. |