diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-02-17 18:37:09 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-02-17 18:37:09 +0100 |
commit | 5b9ccf680b139a94bd164bd0fba57b1e4a5535d3 (patch) | |
tree | 8acf2ea3071bbd873c358f5a51752d6d229de358 /src | |
parent | 4284956d63b11db7e6b003f9c5ca81ea6eb234ff (diff) | |
download | ghdl-5b9ccf680b139a94bd164bd0fba57b1e4a5535d3.tar.gz ghdl-5b9ccf680b139a94bd164bd0fba57b1e4a5535d3.tar.bz2 ghdl-5b9ccf680b139a94bd164bd0fba57b1e4a5535d3.zip |
synth: add mdff.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/netlists-builders.adb | 30 | ||||
-rw-r--r-- | src/synth/netlists-builders.ads | 8 | ||||
-rw-r--r-- | src/synth/netlists-gates.ads | 8 | ||||
-rw-r--r-- | src/synth/netlists-inference.adb | 54 |
4 files changed, 88 insertions, 12 deletions
diff --git a/src/synth/netlists-builders.adb b/src/synth/netlists-builders.adb index c591c38a8..99080d9ae 100644 --- a/src/synth/netlists-builders.adb +++ b/src/synth/netlists-builders.adb @@ -487,7 +487,15 @@ package body Netlists.Builders is 2 => Create_Input ("rst"), 3 => Create_Input ("rst_val"), 4 => Create_Input ("init")), - Outputs); + Outputs); + + Ctxt.M_Mdff := New_User_Module + (Ctxt.Design, New_Sname_Artificial (Get_Identifier ("mdff"), No_Sname), + Id_Mdff, 3, 1, 0); + Set_Ports_Desc (Ctxt.M_Mdff, (0 => Create_Input ("clk", 1), + 1 => Create_Input ("d"), + 2 => Create_Input ("els")), + Outputs); end Create_Dff_Modules; procedure Create_Assert_Assume_Cover (Ctxt : Context_Acc) @@ -1338,6 +1346,26 @@ package body Netlists.Builders is return O; end Build_Iadff; + function Build_Mdff (Ctxt : Context_Acc; + Clk : Net; + D : Net; + Els : Net) return Net + is + Wd : constant Width := Get_Width (D); + pragma Assert (Get_Width (Clk) = 1); + pragma Assert (Get_Width (Els) = Wd); + Inst : Instance; + O : Net; + begin + Inst := New_Internal_Instance (Ctxt, Ctxt.M_Mdff); + O := Get_Output (Inst, 0); + Set_Width (O, Wd); + Connect (Get_Input (Inst, 0), Clk); + Connect (Get_Input (Inst, 1), D); + Connect (Get_Input (Inst, 2), Els); + return O; + end Build_Mdff; + 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 36554acad..de2a9da3c 100644 --- a/src/synth/netlists-builders.ads +++ b/src/synth/netlists-builders.ads @@ -185,7 +185,12 @@ package Netlists.Builders is function Build_Iadff (Ctxt : Context_Acc; Clk : Net; D : Net; Rst : Net; Rst_Val : Net; - Init : Net) return Net; + Init : Net) return Net; + + function Build_Mdff (Ctxt : Context_Acc; + Clk : Net; + D : Net; + Els : Net) return Net; private type Module_Arr is array (Module_Id range <>) of Module; @@ -217,6 +222,7 @@ private M_Idff : Module; M_Adff : Module; M_Iadff : Module; + M_Mdff : 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-gates.ads b/src/synth/netlists-gates.ads index bb5e64204..848c7a10f 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -141,6 +141,7 @@ package Netlists.Gates is -- 2: INIT (initial value) -- Output: 0: Q Id_Idff : constant Module_Id := 52; + -- A DFF with an asynchronous reset and an initial value. -- Inputs: 0: CLK -- 1: D @@ -150,6 +151,13 @@ package Netlists.Gates is -- Output: 0: Q Id_Iadff : constant Module_Id := 53; + -- 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; + -- Width change: truncate or extend. Sign is know in order to possibly -- detect loss of value. Id_Utrunc : constant Module_Id := 64; diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb index 9f82e7207..8786d42eb 100644 --- a/src/synth/netlists-inference.adb +++ b/src/synth/netlists-inference.adb @@ -328,6 +328,7 @@ package body Netlists.Inference is Stmt : Synth.Source.Syn_Src) return Net is O : constant Net := Get_Output (Last_Mux, 0); + Mux_Loc : constant Location_Type := Get_Location (Last_Mux); Data : Net; Res : Net; Sig : Instance; @@ -335,6 +336,7 @@ package body Netlists.Inference is Rst : Net; Rst_Val : Net; Enable : Net; + Els : Net; begin -- Create and return the DFF. @@ -344,12 +346,31 @@ package body Netlists.Inference is Sel : constant Input := Get_Mux2_Sel (Last_Mux); I0 : constant Input := Get_Mux2_I0 (Last_Mux); I1 : constant Input := Get_Mux2_I1 (Last_Mux); + Els_Inst : Instance; + Els_Clk : Net; + Els_En : Net; begin -- There must be no 'else' part for clock expression. - if not Is_Prev_FF_Value (Get_Driver (I0), Prev_Val, Off) then - Error_Msg_Synth - (+Stmt, "synchronous code does not expect else part"); - return Prev_Val; + Els := Get_Driver (I0); + if Is_Prev_FF_Value (Els, Prev_Val, Off) then + -- The loop. + Els := No_Net; + else + Els_Inst := Get_Net_Parent (Els); + if Get_Id (Els_Inst) = Id_Mux2 then + Extract_Clock (Ctxt, Get_Driver (Get_Mux2_Sel (Els_Inst)), + Els_Clk, Els_En); + else + Els_Clk := No_Net; + end if; + if Els_Clk = No_Net then + Error_Msg_Synth + (+Stmt, "clocked logic requires clocked logic on else part"); + Els := No_Net; + else + Els := Infere_FF (Ctxt, Prev_Val, Off, Els_Inst, + Els_Clk, Els_En, Stmt); + end if; end if; Disconnect (Sel); @@ -471,6 +492,8 @@ package body Netlists.Inference is end loop; end; + Free_Instance (Last_Mux); + if Off = 0 and then Can_Infere_RAM (Data, Prev_Val) then @@ -493,12 +516,25 @@ package body Netlists.Inference is -- Create the FF. if Rst = No_Net then pragma Assert (Rst_Val = No_Net); - if Init /= No_Net then - Res := Build_Idff (Ctxt, Clk, D => Data, Init => Init); + if Els = No_Net then + if Init /= No_Net then + Res := Build_Idff (Ctxt, Clk, D => Data, Init => Init); + else + Res := Build_Dff (Ctxt, Clk, D => Data); + end if; else - Res := Build_Dff (Ctxt, Clk, D => Data); + if Init /= No_Net then + raise Internal_Error; + else + Res := Build_Mdff (Ctxt, Clk, D => Data, Els => Els); + end if; end if; else + if Els /= No_Net then + Error_Msg_Synth + (+Stmt, "synchronous code does not expect else part"); + end if; + if Init /= No_Net then Res := Build_Iadff (Ctxt, Clk, D => Data, Rst => Rst, Rst_Val => Rst_Val, @@ -508,9 +544,7 @@ package body Netlists.Inference is Rst => Rst, Rst_Val => Rst_Val); end if; end if; - Copy_Location (Res, Last_Mux); - - Free_Instance (Last_Mux); + Set_Location (Res, Mux_Loc); return Res; end Infere_FF; |