diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-04-16 19:03:15 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-04-16 19:03:15 +0200 |
commit | e1f9a72eb52af14a55d884b6f33971ddfb8839c4 (patch) | |
tree | 17b91a8a9a0647372e0ad8e05b6b17022df3aa58 /src/synth/synth-inference.adb | |
parent | f549640aa2a4dbf8e4d386092112de07239a9343 (diff) | |
download | ghdl-e1f9a72eb52af14a55d884b6f33971ddfb8839c4.tar.gz ghdl-e1f9a72eb52af14a55d884b6f33971ddfb8839c4.tar.bz2 ghdl-e1f9a72eb52af14a55d884b6f33971ddfb8839c4.zip |
synth: handle synchronous enable in inference.
Diffstat (limited to 'src/synth/synth-inference.adb')
-rw-r--r-- | src/synth/synth-inference.adb | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/src/synth/synth-inference.adb b/src/synth/synth-inference.adb index 726d67ec5..bdf5d3dd7 100644 --- a/src/synth/synth-inference.adb +++ b/src/synth/synth-inference.adb @@ -71,6 +71,23 @@ package body Synth.Inference is -- This is a memorizing element as there is a loop. It is an asynchronous -- reset as Q is forced to '0' when RST is asserted. + function Has_Clock (N : Net) return Boolean + is + Inst : constant Instance := Get_Net_Parent (N); + begin + case Get_Id (Inst) is + when Edge_Module_Id => + return True; + when Id_And => + -- Assume the condition is canonicalized, ie of the form: + -- CLK and EXPR. + -- FIXME: do it! + return Has_Clock (Get_Driver (Get_Input (Inst, 0))); + when others => + return False; + end case; + end Has_Clock; + -- Find the longest chain of mux starting from VAL with a final input -- of PREV_VAL. Such a chain means this is a memorising element. -- RES is the last mux in the chain, DIST the number of mux in the chain. @@ -84,31 +101,36 @@ package body Synth.Inference is Res0, Res1 : Instance; Dist0, Dist1 : Integer; begin - Find_Longest_Loop - (Get_Driver (Get_Mux2_I0 (Inst)), Prev_Val, Res0, Dist0); - Find_Longest_Loop - (Get_Driver (Get_Mux2_I1 (Inst)), Prev_Val, Res1, Dist1); - -- Input1 has an higher priority than input0 in case the selector - -- is a clock. - -- FIXME: improve algorithm. - if Dist1 > Dist0 then - Dist := Dist1 + 1; - if Dist1 > 0 then - Res := Res1; - else - Res := Inst; - end if; - elsif Dist0 >= 0 then - Dist := Dist0 + 1; - if Dist0 > 0 then - Res := Res0; + if Has_Clock (Get_Driver (Get_Mux2_Sel (Inst))) then + Res := Inst; + Dist := 1; + else + Find_Longest_Loop + (Get_Driver (Get_Mux2_I0 (Inst)), Prev_Val, Res0, Dist0); + Find_Longest_Loop + (Get_Driver (Get_Mux2_I1 (Inst)), Prev_Val, Res1, Dist1); + -- Input1 has an higher priority than input0 in case + -- the selector is a clock. + -- FIXME: improve algorithm. + if Dist1 > Dist0 then + Dist := Dist1 + 1; + if Dist1 > 0 then + Res := Res1; + else + Res := Inst; + end if; + elsif Dist0 >= 0 then + Dist := Dist0 + 1; + if Dist0 > 0 then + Res := Res0; + else + Res := Inst; + end if; else - Res := Inst; + pragma Assert (Dist1 < 0 and Dist0 < 0); + Res := No_Instance; + Dist := -1; end if; - else - pragma Assert (Dist1 < 0 and Dist0 < 0); - Res := No_Instance; - Dist := -1; end if; end; elsif Val = Prev_Val then |