From e84f35edb1c36d07a15f8f15873b4990b55d9aaf Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 1 Jan 2021 18:05:00 +0100 Subject: netlists-inference: handle multiple dff with the same clock. Fix #1563 --- src/synth/netlists-gates.ads | 2 ++ src/synth/netlists-inference.adb | 25 ++++++++++++++++++++----- src/synth/netlists-utils.adb | 13 +++++++++++++ src/synth/netlists-utils.ads | 4 ++++ 4 files changed, 39 insertions(+), 5 deletions(-) (limited to 'src/synth') diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads index 4acf9f6b4..c20cddf74 100644 --- a/src/synth/netlists-gates.ads +++ b/src/synth/netlists-gates.ads @@ -186,6 +186,8 @@ package Netlists.Gates is -- Output: 0: Q Id_Iadff : constant Module_Id := 67; + subtype Dff_Module_Id is Module_Id range Id_Dff .. Id_Iadff; + -- Multi clock dff. ELSE is the output of the next DFF. -- Inputs: 0: CLK -- 1: D diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb index 58df1b556..fe136008a 100644 --- a/src/synth/netlists-inference.adb +++ b/src/synth/netlists-inference.adb @@ -334,14 +334,19 @@ package body Netlists.Inference is is Ndata : Net; Res : Net; + Els_Net : Net; + Els_Inst : Instance; begin + Els_Net := Els; + pragma Unreferenced (Els); + if Off = 0 and then Rst = No_Net and then not Synth.Flags.Flag_Debug_Nomemory1 and then Can_Infere_RAM (Data, Prev_Val) then -- Maybe it is a RAM. - Res := Infere_RAM (Ctxt, Data, Els, Clk, Clk_Enable); + Res := Infere_RAM (Ctxt, Data, Els_Net, Clk, Clk_Enable); else if Clk_Enable /= No_Net then -- If there is a condition with the clock, that's an enable which @@ -363,7 +368,17 @@ package body Netlists.Inference is if Rst = No_Net then -- No async reset pragma Assert (Rst_Val = No_Net); - if Els = No_Net then + + if Els_Net /= No_Net then + Els_Inst := Get_Net_Parent (Els_Net); + if Get_Id (Els_Inst) in Dff_Module_Id + and then Same_Clock (Clk, Get_Input_Net (Els_Inst, 0)) + then + Els_Net := No_Net; + end if; + end if; + + if Els_Net = No_Net then if Init /= No_Net then Res := Build_Idff (Ctxt, Clk, D => Ndata, Init => Init); else @@ -372,13 +387,13 @@ package body Netlists.Inference is else if Init /= No_Net then Res := Build_Midff (Ctxt, Clk, D => Ndata, - Els => Els, Init => Init); + Els => Els_Net, Init => Init); else - Res := Build_Mdff (Ctxt, Clk, D => Ndata, Els => Els); + Res := Build_Mdff (Ctxt, Clk, D => Ndata, Els => Els_Net); end if; end if; else - if Els /= No_Net then + if Els_Net /= No_Net then Error_Msg_Synth (Loc, "synchronous code does not expect else part"); end if; diff --git a/src/synth/netlists-utils.adb b/src/synth/netlists-utils.adb index 74df5908c..8463da355 100644 --- a/src/synth/netlists-utils.adb +++ b/src/synth/netlists-utils.adb @@ -289,6 +289,19 @@ package body Netlists.Utils is end; end Same_Net; + function Same_Clock (L, R : Net) return Boolean + is + Linst : constant Instance := Get_Net_Parent (L); + Rinst : constant Instance := Get_Net_Parent (R); + begin + if Get_Id (Linst) /= Get_Id (Rinst) then + return False; + end if; + pragma Assert (Get_Id (Linst) in Edge_Module_Id); + return Same_Net (Get_Input_Net (Linst, 0), + Get_Input_Net (Rinst, 0)); + end Same_Clock; + procedure Copy_Attributes (Dest : Instance; Src : Instance) is Attr : Attribute; diff --git a/src/synth/netlists-utils.ads b/src/synth/netlists-utils.ads index 111c6f9f3..c7a76a502 100644 --- a/src/synth/netlists-utils.ads +++ b/src/synth/netlists-utils.ads @@ -90,6 +90,10 @@ package Netlists.Utils is -- selection of the same net. function Same_Net (L, R : Net) return Boolean; + -- Like Same_Net but for a clock. L and R must be both the output of + -- an edge detector. + function Same_Clock (L, R : Net) return Boolean; + -- If N is the output of a signal or isignal, return the driver of the -- input. function Skip_Signal (N : Net) return Net; -- cgit v1.2.3