aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-04-22 08:13:41 +0200
committerTristan Gingold <tgingold@free.fr>2020-04-22 08:13:41 +0200
commit8691914c9c40dbfde5d757b563520c42691cfc6b (patch)
treef50f76235d37ca871ca84c9988c9399f8c3d2331
parent5841b245ee5f3d31b1c1856a443d6aed26fcf582 (diff)
downloadghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.tar.gz
ghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.tar.bz2
ghdl-8691914c9c40dbfde5d757b563520c42691cfc6b.zip
synth: add tri gate.
-rw-r--r--src/synth/ghdlsynth_gates.h5
-rw-r--r--src/synth/netlists-builders.adb33
-rw-r--r--src/synth/netlists-builders.ads3
-rw-r--r--src/synth/netlists-disp_vhdl.adb4
-rw-r--r--src/synth/netlists-gates.ads21
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.