diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-05-15 19:04:11 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-05-15 19:04:11 +0200 |
commit | 1d5db1f18f4d6f61433f4b91961378df24e5949b (patch) | |
tree | 0cb3ccfd9d0ef8540a92044835c5a3a929180f37 /src | |
parent | 51bab442d6ef8af394e5a5c33d63b2fe6b89af37 (diff) | |
download | ghdl-1d5db1f18f4d6f61433f4b91961378df24e5949b.tar.gz ghdl-1d5db1f18f4d6f61433f4b91961378df24e5949b.tar.bz2 ghdl-1d5db1f18f4d6f61433f4b91961378df24e5949b.zip |
synth: handle initialized inout port. For #1312
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/ghdlsynth_gates.h | 22 | ||||
-rw-r--r-- | src/synth/netlists-builders.adb | 21 | ||||
-rw-r--r-- | src/synth/netlists-builders.ads | 2 | ||||
-rw-r--r-- | src/synth/netlists-gates.ads | 24 | ||||
-rw-r--r-- | src/synth/synth-insts.adb | 42 |
5 files changed, 72 insertions, 39 deletions
diff --git a/src/synth/ghdlsynth_gates.h b/src/synth/ghdlsynth_gates.h index 901df76ab..5b6fdad49 100644 --- a/src/synth/ghdlsynth_gates.h +++ b/src/synth/ghdlsynth_gates.h @@ -53,14 +53,15 @@ enum Module_Id { Id_Mux2 = 46, Id_Mux4 = 47, Id_Pmux = 48, - Id_Signal = 56, - Id_Isignal = 57, - Id_Output = 58, - Id_Ioutput = 59, - Id_Port = 60, - Id_Inout = 61, - Id_Enable = 62, - Id_Nop = 63, + Id_Signal = 52, + Id_Isignal = 53, + Id_Output = 54, + Id_Ioutput = 55, + Id_Port = 56, + Id_Inout = 57, + Id_Iinout = 58, + Id_Enable = 59, + Id_Nop = 60, Id_Dff = 64, Id_Adff = 65, Id_Idff = 66, @@ -105,8 +106,9 @@ enum Module_Id { Id_Const_X = 117, Id_Const_Z = 118, Id_Const_0 = 119, - Id_Const_Bit = 120, - Id_Const_Log = 121, + Id_Const_1 = 120, + Id_Const_Bit = 121, + Id_Const_Log = 122, }; enum Param_Type { diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index 85b2eece9..626debfa7 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -493,6 +493,12 @@ package body Netlists.Builders is Outputs2 := (0 => Outputs (0), 1 => Create_Output ("oport")); Set_Ports_Desc (Ctxt.M_Inout, Inputs2 (0 .. 0), Outputs2); + + Ctxt.M_Iinout := New_User_Module + (Ctxt.Design, + New_Sname_Artificial (Get_Identifier("iinout"), No_Sname), + Id_Iinout, 2, 2, 0); + Set_Ports_Desc (Ctxt.M_Iinout, Inputs2 (0 .. 1), Outputs2); end Create_Objects_Module; procedure Create_Dff_Modules (Ctxt : Context_Acc) @@ -1355,19 +1361,30 @@ package body Netlists.Builders is return Build_Object (Ctxt, Ctxt.M_Output, W); end Build_Output; - function Build_Inout (Ctxt : Context_Acc; W : Width) return Instance + function Build_Inout_Object (Ctxt : Context_Acc; M : Module; W : Width) + return Instance is Inst : Instance; O : Net; begin - Inst := New_Internal_Instance (Ctxt, Ctxt.M_Inout); + Inst := New_Internal_Instance (Ctxt, M); O := Get_Output (Inst, 0); Set_Width (O, W); O := Get_Output (Inst, 1); Set_Width (O, W); return Inst; + end Build_Inout_Object; + + function Build_Inout (Ctxt : Context_Acc; W : Width) return Instance is + begin + return Build_Inout_Object (Ctxt, Ctxt.M_Inout, W); end Build_Inout; + function Build_Iinout (Ctxt : Context_Acc; W : Width) return Instance is + begin + return Build_Inout_Object (Ctxt, Ctxt.M_Iinout, W); + end Build_Iinout; + function Build_Ioutput (Ctxt : Context_Acc; Init : Net) return Net is Wd : constant Width := Get_Width (Init); diff --git a/src/synth/netlists-builders.ads b/src/synth/netlists-builders.ads index 6a1c0fb82..4883c1e85 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -162,6 +162,7 @@ package Netlists.Builders is function Build_Output (Ctxt : Context_Acc; W : Width) return Net; function Build_Ioutput (Ctxt : Context_Acc; Init : Net) return Net; function Build_Inout (Ctxt : Context_Acc; W : Width) return Instance; + function Build_Iinout (Ctxt : Context_Acc; W : Width) return Instance; function Build_Signal (Ctxt : Context_Acc; Name : Sname; W : Width) return Net; function Build_Isignal (Ctxt : Context_Acc; Name : Sname; Init : Net) @@ -246,6 +247,7 @@ private M_Isignal : Module; M_Port : Module; M_Inout : Module; + M_Iinout : Module; M_Enable : Module; M_Dff : Module; M_Idff : Module; diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index 96d498d57..bef8c3245 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -120,11 +120,11 @@ package Netlists.Gates is -- 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 := 56; - Id_Isignal : constant Module_Id := 57; - Id_Output : constant Module_Id := 58; - Id_Ioutput : constant Module_Id := 59; - Id_Port : constant Module_Id := 60; + Id_Signal : constant Module_Id := 52; + Id_Isignal : constant Module_Id := 53; + Id_Output : constant Module_Id := 54; + Id_Ioutput : constant Module_Id := 55; + Id_Port : constant Module_Id := 56; -- Id_Inout is a virtual gate used to fit inout direction into the netlist -- model which has only inputs and outputs. @@ -137,13 +137,16 @@ package Netlists.Gates is -- Inputs: 0: value to be assigned to the port -- Outputs: 0: value of the port -- 1: direct and only connection to the port - Id_Inout : constant Module_Id := 61; + Id_Inout : constant Module_Id := 57; + + -- Like Id_Inout but with an initial value. + Id_Iinout : constant Module_Id := 58; -- Behaves like Id_Signal but for enable wires. - Id_Enable : constant Module_Id := 62; + Id_Enable : constant Module_Id := 59; -- Temporary gate, O = I - Id_Nop : constant Module_Id := 63; + Id_Nop : constant Module_Id := 60; -- Note: initial values must be constant nets. -- @@ -340,6 +343,7 @@ package Netlists.Gates is Id_Const_X : constant Module_Id := 117; Id_Const_Z : constant Module_Id := 118; Id_Const_0 : constant Module_Id := 119; + Id_Const_1 : constant Module_Id := 120; -- Should we keep them ? pragma Unreferenced (Id_Const_UB64, Id_Const_UL64); @@ -348,8 +352,8 @@ package Netlists.Gates is -- For Const_Bit: param N is for bits 32*N .. 32*N+31 -- For Const_Log: param 2*N is for 0/1 of bits 32*N .. 32*N+31 -- param 2*N+1 is for Z/X of bits 32*N .. 32*N+31 - Id_Const_Bit : constant Module_Id := 120; - Id_Const_Log : constant Module_Id := 121; + Id_Const_Bit : constant Module_Id := 121; + Id_Const_Log : constant Module_Id := 122; subtype Constant_Module_Id is Module_Id range Id_Const_UB32 .. Id_Const_Log; diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb index 72df81993..e0d4b62a7 100644 --- a/src/synth/synth-insts.adb +++ b/src/synth/synth-insts.adb @@ -1361,14 +1361,15 @@ package body Synth.Insts is Idx : Port_Idx; Val : Valtyp) is - Ctxt : constant Context_Acc := Get_Build (Syn_Inst); - Default : constant Node := Get_Default_Value (Inter); - Desc : constant Port_Desc := + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); + Default : constant Node := Get_Default_Value (Inter); + Desc : constant Port_Desc := Get_Output_Desc (Get_Module (Self_Inst), Idx); Inter_Typ : Type_Acc; - Value : Net; - Init : Valtyp; - Inp : Input; + Value : Net; + Init : Valtyp; + Init_Net : Net; + Inp : Input; begin pragma Assert (Val.Val.Kind = Value_Wire); @@ -1378,27 +1379,34 @@ package body Synth.Insts is Inp := Get_Input (Self_Inst, Idx); + if Default /= Null_Node then + Inter_Typ := Get_Subtype_Object (Syn_Inst, Get_Type (Inter)); + Init := Synth_Expression_With_Type (Syn_Inst, Default, Inter_Typ); + Init := Synth_Subtype_Conversion + (Ctxt, Init, Inter_Typ, False, Inter); + Init_Net := Get_Net (Ctxt, Init); + else + Init_Net := No_Net; + end if; + if Desc.Is_Inout then - if Default /= Null_Node then - -- TODO: initialized inout. - raise Internal_Error; - end if; declare Io_Inst : Instance; begin - Io_Inst := Builders.Build_Inout (Ctxt, Desc.W); + if Init_Net /= No_Net then + Io_Inst := Builders.Build_Iinout (Ctxt, Desc.W); + Connect (Get_Input (Io_Inst, 1), Init_Net); + else + Io_Inst := Builders.Build_Inout (Ctxt, Desc.W); + end if; -- Connect port1 of gate inout to the pin. Connect (Inp, Get_Output (Io_Inst, 1)); -- And port0 of the gate will be use to read from the pin. Value := Get_Output (Io_Inst, 0); end; else - if Default /= Null_Node then - Inter_Typ := Get_Subtype_Object (Syn_Inst, Get_Type (Inter)); - Init := Synth_Expression_With_Type (Syn_Inst, Default, Inter_Typ); - Init := Synth_Subtype_Conversion - (Ctxt, Init, Inter_Typ, False, Inter); - Value := Builders.Build_Ioutput (Ctxt, Get_Net (Ctxt, Init)); + if Init_Net /= No_Net then + Value := Builders.Build_Ioutput (Ctxt, Init_Net); else Value := Builders.Build_Output (Ctxt, Desc.W); end if; |