diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-05-31 07:38:50 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-05-31 07:38:50 +0200 |
commit | eed73a6969ebdcac2aca1c03b6fc16b09af12fbd (patch) | |
tree | bc298c9bf9825ea8c4fc8b757729f76c54480a27 /src | |
parent | 3d8cc349b675ddfcd41008ba8f7b17a49da9e184 (diff) | |
download | ghdl-eed73a6969ebdcac2aca1c03b6fc16b09af12fbd.tar.gz ghdl-eed73a6969ebdcac2aca1c03b6fc16b09af12fbd.tar.bz2 ghdl-eed73a6969ebdcac2aca1c03b6fc16b09af12fbd.zip |
netlists-inference: add comments, reorder subprograms.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/netlists-inference.adb | 133 |
1 files changed, 63 insertions, 70 deletions
diff --git a/src/synth/netlists-inference.adb b/src/synth/netlists-inference.adb index a57b50bbb..ed84f6127 100644 --- a/src/synth/netlists-inference.adb +++ b/src/synth/netlists-inference.adb @@ -318,76 +318,7 @@ package body Netlists.Inference is and then Get_Input_Net (Inst, 0) = Prev_Val; end Is_Prev_FF_Value; - function Infere_FF_Else (Ctxt : Context_Acc; - Prev_Val : Net; - Off : Uns32; - Last_Mux : Instance; - Init : Net; - Rst : Net; - Rst_Val : Net; - Data : Net; - Els : Net; - Clk : Net; - Clk_Enable : Net; - Loc : Location_Type) return Net; - - procedure Infere_FF_Mux (Ctxt : Context_Acc; - Prev_Val : Net; - Off : Uns32; - Last_Mux : Instance; - Els : out Net; - Data : out Net) - is - Mux_Loc : constant Location_Type := Get_Location (Last_Mux); - 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; - Data2 : Net; - Els2 : Net; - begin - -- There must be no 'else' part for clock expression. - 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 - (Mux_Loc, "clocked logic requires clocked logic on else part"); - Els := No_Net; - else - -- Create and return the DFF. - - -- 1. Remove the mux that creates the loop (will be replaced by - -- the dff). - Infere_FF_Mux (Ctxt, Prev_Val, Off, Last_Mux, Els2, Data2); - - Els := Infere_FF_Else (Ctxt, Prev_Val, Off, Last_Mux, No_Net, - No_Net, No_Net, Data2, Els2, - Els_Clk, Els_En, Get_Location (Last_Mux)); - Remove_Instance (Last_Mux); - end if; - end if; - - Disconnect (Sel); - -- Don't try to free driver of I0 as this is Prev_Val or a selection - -- of it. - Disconnect (I0); - Data := Get_Driver (I1); - -- Don't try to free driver of I1 as it is reconnected. - Disconnect (I1); - end Infere_FF_Mux; - + -- Build the FF, according to the inputs. function Infere_FF_Create (Ctxt : Context_Acc; Rst : Net; Rst_Val : Net; @@ -486,6 +417,67 @@ package body Netlists.Inference is return Res; end Infere_FF_Else; + procedure Infere_FF_Mux (Ctxt : Context_Acc; + Prev_Val : Net; + Off : Uns32; + Last_Mux : Instance; + Els : out Net; + Data : out Net) + is + Mux_Loc : constant Location_Type := Get_Location (Last_Mux); + 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; + Data2 : Net; + Els2 : Net; + begin + -- There must be no 'else' part for clock expression. + 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 + (Mux_Loc, "clocked logic requires clocked logic on else part"); + Els := No_Net; + else + -- Create and return the DFF. + + -- 1. Remove the mux that creates the loop (will be replaced by + -- the dff). + Infere_FF_Mux (Ctxt, Prev_Val, Off, Els_Inst, Els2, Data2); + + Els := Infere_FF_Else (Ctxt, Prev_Val, Off, Els_Inst, No_Net, + No_Net, No_Net, Data2, Els2, + Els_Clk, Els_En, Get_Location (Els_Inst)); + Remove_Instance (Els_Inst); + end if; + end if; + + Disconnect (Sel); + -- Don't try to free driver of I0 as this is Prev_Val or a selection + -- of it. + Disconnect (I0); + Data := Get_Driver (I1); + -- Don't try to free driver of I1 as it is reconnected. + Disconnect (I1); + end Infere_FF_Mux; + + -- A Mux2 with a logical loop and a clock has been found. + -- Determine the kind of FF and extract the asynchronous reset. + -- Build the FF (or the RAM). + -- -- CLOCK_MUX is the mux whose input 0 is the loop and clock for selector. function Infere_FF (Ctxt : Context_Acc; Val : Net; @@ -794,6 +786,7 @@ package body Netlists.Inference is return Val; end Infere_Latch; + -- VAL is the value to be assigned to a wire at offset OFF. -- Note: PREV_VAL is the wire gate, so with full width and no offset. function Infere (Ctxt : Context_Acc; Val : Net; |