aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-07 10:44:17 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-07 10:44:17 +0100
commit87907d6da96eb4bab35e8eb7aabc481e9b32e04c (patch)
tree0c147dad9e4c57e25c2bfff06a6be31eb2b9db65 /src/synth
parent8795c9031088fa5c9e5514bbce804bffd9ed6d6b (diff)
downloadghdl-87907d6da96eb4bab35e8eb7aabc481e9b32e04c.tar.gz
ghdl-87907d6da96eb4bab35e8eb7aabc481e9b32e04c.tar.bz2
ghdl-87907d6da96eb4bab35e8eb7aabc481e9b32e04c.zip
synthesis: handle initialized output ports.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/ghdlsynth_gates.h15
-rw-r--r--src/synth/netlists-builders.adb23
-rw-r--r--src/synth/netlists-builders.ads2
-rw-r--r--src/synth/netlists-cleanup.adb7
-rw-r--r--src/synth/netlists-gates.ads16
-rw-r--r--src/synth/netlists-inference.adb14
-rw-r--r--src/synth/synth-insts.adb20
7 files changed, 72 insertions, 25 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h
index e7594295b..1611a81e1 100644
--- a/src/synth/ghdlsynth_gates.h
+++ b/src/synth/ghdlsynth_gates.h
@@ -50,13 +50,14 @@ enum Module_Id {
Id_Signal = 46,
Id_Isignal = 47,
Id_Output = 48,
- Id_Port = 49,
- Id_Dff = 50,
- Id_Adff = 51,
- Id_Idff = 52,
- Id_Iadff = 53,
- Id_Mdff = 54,
- Id_Midff = 55,
+ Id_Ioutput = 49,
+ Id_Port = 50,
+ Id_Dff = 52,
+ Id_Adff = 53,
+ Id_Idff = 54,
+ Id_Iadff = 55,
+ Id_Mdff = 56,
+ Id_Midff = 57,
Id_Utrunc = 64,
Id_Strunc = 65,
Id_Uextend = 66,
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb
index 385a73d8b..3110855e9 100644
--- a/src/synth/netlists-builders.adb
+++ b/src/synth/netlists-builders.adb
@@ -421,6 +421,8 @@ package body Netlists.Builders is
Inputs2 : Port_Desc_Array (0 .. 1);
begin
Inputs := (0 => Create_Input ("i"));
+ Inputs2 := (0 => Create_Input ("i"),
+ 1 => Create_Input ("init"));
Outputs := (0 => Create_Output ("o"));
Ctxt.M_Output := New_User_Module
@@ -428,13 +430,17 @@ package body Netlists.Builders is
Id_Output, 1, 1, 0);
Set_Ports_Desc (Ctxt.M_Output, Inputs, Outputs);
+ Ctxt.M_Ioutput := New_User_Module
+ (Ctxt.Design,
+ New_Sname_Artificial (Get_Identifier ("ioutput"), No_Sname),
+ Id_Ioutput, 2, 1, 0);
+ Set_Ports_Desc (Ctxt.M_Ioutput, Inputs2, Outputs);
+
Ctxt.M_Signal := New_User_Module
(Ctxt.Design, New_Sname_Artificial (Name_Signal, No_Sname),
Id_Signal, 1, 1, 0);
Set_Ports_Desc (Ctxt.M_Signal, Inputs, Outputs);
- Inputs2 := (0 => Create_Input ("i"),
- 1 => Create_Input ("init"));
Ctxt.M_Isignal := New_User_Module
(Ctxt.Design,
New_Sname_Artificial (Get_Identifier ("isignal"), No_Sname),
@@ -1237,6 +1243,19 @@ package body Netlists.Builders is
return Build_Object (Ctxt, Ctxt.M_Output, W);
end Build_Output;
+ function Build_Ioutput (Ctxt : Context_Acc; Init : Net) return Net
+ is
+ Wd : constant Width := Get_Width (Init);
+ Inst : Instance;
+ O : Net;
+ begin
+ Inst := New_Internal_Instance (Ctxt, Ctxt.M_Ioutput);
+ O := Get_Output (Inst, 0);
+ Set_Width (O, Wd);
+ Connect (Get_Input (Inst, 1), Init);
+ return O;
+ end Build_Ioutput;
+
function Build_Signal (Ctxt : Context_Acc; Name : Sname; W : Width)
return Net
is
diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads
index d28c8c332..b9aa7757c 100644
--- a/src/synth/netlists-builders.ads
+++ b/src/synth/netlists-builders.ads
@@ -151,6 +151,7 @@ package Netlists.Builders is
Data : Net) return Instance;
function Build_Output (Ctxt : Context_Acc; W : Width) return Net;
+ function Build_Ioutput (Ctxt : Context_Acc; Init : Net) return Net;
function Build_Signal (Ctxt : Context_Acc; Name : Sname; W : Width)
return Net;
function Build_Isignal (Ctxt : Context_Acc; Name : Sname; Init : Net)
@@ -220,6 +221,7 @@ private
M_Mux2 : Module;
M_Mux4 : Module;
M_Output : Module;
+ M_Ioutput : Module;
M_Signal : Module;
M_Isignal : Module;
M_Port : Module;
diff --git a/src/synth/netlists-cleanup.adb b/src/synth/netlists-cleanup.adb
index d95267c88..991ca3ad7 100644
--- a/src/synth/netlists-cleanup.adb
+++ b/src/synth/netlists-cleanup.adb
@@ -126,6 +126,7 @@ package body Netlists.Cleanup is
case Get_Id (Inst) is
when Id_Output
+ | Id_Ioutput
| Id_Port =>
declare
Inp : Input;
@@ -142,6 +143,12 @@ package body Netlists.Cleanup is
else
Disconnect (Get_First_Sink (O));
end if;
+
+ if Get_Id (Inst) = Id_Ioutput then
+ -- Disconnect the initial value.
+ Disconnect (Get_Input (Inst, 1));
+ end if;
+
Remove_Instance (Inst);
end;
when others =>
diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads
index 1816bc8eb..c6c1c4815 100644
--- a/src/synth/netlists-gates.ads
+++ b/src/synth/netlists-gates.ads
@@ -109,10 +109,12 @@ package Netlists.Gates is
-- be read. At the end, this is not an issue because an output is driven
-- by a gate (and thus the value of the output could be read), but that
-- driving value may not be available early enough.
+ -- Id_Ioutput is an output with an initial value.
Id_Signal : constant Module_Id := 46;
Id_Isignal : constant Module_Id := 47;
Id_Output : constant Module_Id := 48;
- Id_Port : constant Module_Id := 49;
+ Id_Ioutput : constant Module_Id := 49;
+ Id_Port : constant Module_Id := 50;
-- Note: initial values must be constant nets.
--
@@ -122,7 +124,7 @@ package Netlists.Gates is
-- Inputs: 0: CLK
-- 1: D
-- Output: 0: Q
- Id_Dff : constant Module_Id := 50;
+ Id_Dff : constant Module_Id := 52;
-- A DFF with an asynchronous reset. Note that the asynchronous reset
-- has priority over the clock. When RST is asserted, the value is
@@ -132,7 +134,7 @@ package Netlists.Gates is
-- 2: RST
-- 3: RST_VAL
-- Output: 0: Q
- Id_Adff : constant Module_Id := 51;
+ Id_Adff : constant Module_Id := 53;
-- A simple DFF with an initial value (must be constant). This is
-- for FPGAs.
@@ -140,7 +142,7 @@ package Netlists.Gates is
-- 1: D
-- 2: INIT (initial value)
-- Output: 0: Q
- Id_Idff : constant Module_Id := 52;
+ Id_Idff : constant Module_Id := 54;
-- A DFF with an asynchronous reset and an initial value.
-- Inputs: 0: CLK
@@ -149,14 +151,14 @@ package Netlists.Gates is
-- 3: RST_VAL
-- 4: INIT (initial value)
-- Output: 0: Q
- Id_Iadff : constant Module_Id := 53;
+ Id_Iadff : constant Module_Id := 55;
-- Multi clock dff. ELSE is the output of the next DFF.
-- Inputs: 0: CLK
-- 1: D
-- 2: ELSE
-- Output: 0: Q
- Id_Mdff : constant Module_Id := 54;
+ Id_Mdff : constant Module_Id := 56;
-- Multi clock dff with initial value. ELSE is the output of the next DFF.
-- Inputs: 0: CLK
@@ -164,7 +166,7 @@ package Netlists.Gates is
-- 2: ELSE
-- 3: Init
-- Output: 0: Q
- Id_Midff : constant Module_Id := 55;
+ Id_Midff : constant Module_Id := 57;
-- Width change: truncate or extend. Sign is know in order to possibly
-- detect loss of value.
diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb
index 44a419eff..177e10020 100644
--- a/src/synth/netlists-inference.adb
+++ b/src/synth/netlists-inference.adb
@@ -496,12 +496,14 @@ package body Netlists.Inference is
-- If the signal declaration has an initial value, get it.
Sig := Get_Net_Parent (Prev_Val);
- if Get_Id (Get_Module (Sig)) = Id_Isignal then
- Init := Get_Input_Net (Sig, 1);
- Init := Build2_Extract (Ctxt, Init, Off, Get_Width (O));
- else
- Init := No_Net;
- end if;
+ case Get_Id (Get_Module (Sig)) is
+ when Id_Isignal
+ | Id_Ioutput =>
+ Init := Get_Input_Net (Sig, 1);
+ Init := Build2_Extract (Ctxt, Init, Off, Get_Width (O));
+ when others =>
+ Init := No_Net;
+ end case;
Enable := Clk_Enable;
diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb
index e2320aa9f..decee8c72 100644
--- a/src/synth/synth-insts.adb
+++ b/src/synth/synth-insts.adb
@@ -1293,12 +1293,16 @@ package body Synth.Insts is
Val.N := Get_Output (Self_Inst, Idx);
end Create_Input_Wire;
- procedure Create_Output_Wire (Self_Inst : Instance;
+ procedure Create_Output_Wire (Syn_Inst : Synth_Instance_Acc;
+ Self_Inst : Instance;
Inter : Node;
Idx : Port_Idx;
Val : Value_Acc)
is
+ Default : constant Node := Get_Default_Value (Inter);
+ Inter_Typ : Type_Acc;
Value : Net;
+ Init : Value_Acc;
Inp : Input;
W : Width;
begin
@@ -1308,7 +1312,16 @@ package body Synth.Insts is
Val.W := Alloc_Wire (Wire_Output, Inter);
W := Get_Output_Desc (Get_Module (Self_Inst), Idx).W;
pragma Assert (W = Get_Type_Width (Val.Typ));
- Value := Builders.Build_Output (Build_Context, W);
+ if Default /= Null_Node then
+ Inter_Typ := Get_Value_Type (Syn_Inst, Get_Type (Inter));
+ Init := Synth_Expression_With_Type
+ (Syn_Inst, Default, Inter_Typ);
+ Init := Synth_Subtype_Conversion
+ (Init, Inter_Typ, False, Inter);
+ Value := Builders.Build_Ioutput (Build_Context, Get_Net (Init));
+ else
+ Value := Builders.Build_Output (Build_Context, W);
+ end if;
Set_Location (Value, Inter);
Inp := Get_Input (Self_Inst, Idx);
Connect (Inp, Value);
@@ -1416,7 +1429,8 @@ package body Synth.Insts is
Create_Input_Wire (Self_Inst, Nbr_Inputs, Val);
Nbr_Inputs := Nbr_Inputs + 1;
when Port_Out =>
- Create_Output_Wire (Self_Inst, Inter, Nbr_Outputs, Val);
+ Create_Output_Wire
+ (Syn_Inst, Self_Inst, Inter, Nbr_Outputs, Val);
Nbr_Outputs := Nbr_Outputs + 1;
end case;
Inter := Get_Chain (Inter);