aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-inference.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-04-16 19:03:15 +0200
committerTristan Gingold <tgingold@free.fr>2019-04-16 19:03:15 +0200
commite1f9a72eb52af14a55d884b6f33971ddfb8839c4 (patch)
tree17b91a8a9a0647372e0ad8e05b6b17022df3aa58 /src/synth/synth-inference.adb
parentf549640aa2a4dbf8e4d386092112de07239a9343 (diff)
downloadghdl-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.adb68
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