diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-08-23 06:19:17 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-08-23 06:19:17 +0200 |
commit | 9d41b070c29508d5c941566b5687673a2e182578 (patch) | |
tree | 04f0902bce6031e5a3970d5692669ce9b0f8de2c | |
parent | 68765b386b7fece1b0fc709846d3f8bc29b45ecb (diff) | |
download | ghdl-9d41b070c29508d5c941566b5687673a2e182578.tar.gz ghdl-9d41b070c29508d5c941566b5687673a2e182578.tar.bz2 ghdl-9d41b070c29508d5c941566b5687673a2e182578.zip |
simul: add extra drivers for ports without sources
-rw-r--r-- | src/simul/simul-vhdl_elab.adb | 86 | ||||
-rw-r--r-- | src/simul/simul-vhdl_elab.ads | 11 | ||||
-rw-r--r-- | src/simul/simul-vhdl_simul.adb | 69 |
3 files changed, 152 insertions, 14 deletions
diff --git a/src/simul/simul-vhdl_elab.adb b/src/simul/simul-vhdl_elab.adb index 33501a536..61737af24 100644 --- a/src/simul/simul-vhdl_elab.adb +++ b/src/simul/simul-vhdl_elab.adb @@ -66,10 +66,16 @@ package body Simul.Vhdl_Elab is begin E := Proto_E; E.Typ := Val.Typ; + + -- Be sure the width is correct for a signal. Convert_Type_Width (E.Typ); + + -- Allocate the value in global pool. Current_Pool := Global_Pool'Access; E.Val := Alloc_Memory (E.Typ); Current_Pool := Expr_Pool'Access; + + -- Set it to the default value. if Val.Val.Init /= null then Copy_Memory (E.Val, Val.Val.Init.Mem, E.Typ.Sz); else @@ -77,6 +83,14 @@ package body Simul.Vhdl_Elab is end if; E.Sig := null; + if E.Typ.W > 0 then + E.Nbr_Sources := + new Nbr_Sources_Array'(0 .. E.Typ.W - 1 => + (Nbr_Drivers => 0, + Nbr_Conns => 0, + Last_Proc => No_Process_Index)); + end if; + pragma Assert (E.Kind /= Mode_End); pragma Assert (Signals_Table.Table (Val.Val.S).Kind = Mode_End); Signals_Table.Table (Val.Val.S) := E; @@ -118,28 +132,28 @@ package body Simul.Vhdl_Elab is when Iir_Linkage_Mode => Gather_Signal ((Mode_Linkage, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); when Iir_Buffer_Mode => Gather_Signal ((Mode_Buffer, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); when Iir_Out_Mode => Gather_Signal ((Mode_Out, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); when Iir_Inout_Mode => Gather_Signal ((Mode_Inout, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); when Iir_In_Mode => Gather_Signal ((Mode_In, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); end case; when Iir_Kind_Signal_Declaration => Gather_Signal ((Mode_Signal, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index, - No_Driver_Index, No_Connect_Index)); + No_Driver_Index, No_Connect_Index, null)); when Iir_Kind_Configuration_Specification => null; when Iir_Kind_Free_Quantity_Declaration @@ -172,9 +186,16 @@ package body Simul.Vhdl_Elab is when Iir_Kind_Above_Attribute => Gather_Signal ((Mode_Above, Decl, Inst, null, null, null, No_Sensitivity_Index, No_Signal_Index)); + when Iir_Kind_Object_Alias_Declaration => + -- In case it aliases a signal. + declare + V : Valtyp; + begin + V := Get_Value (Inst, Decl); + Convert_Type_Width (V.Typ); + end; when Iir_Kind_Constant_Declaration | Iir_Kind_Variable_Declaration - | Iir_Kind_Object_Alias_Declaration | Iir_Kind_Non_Object_Alias_Declaration | Iir_Kind_Attribute_Declaration | Iir_Kind_Attribute_Specification @@ -205,24 +226,51 @@ package body Simul.Vhdl_Elab is end loop; end Gather_Processes_Decls; + -- Add a driver for process PROC_IDX on signal SIG at OFF/TYP. procedure Add_Process_Driver (Proc_Idx : Process_Index_Type; Sig : Signal_Index_Type; Off : Value_Offsets; - Typ : Type_Acc) is + Typ : Type_Acc) + is + S : Signal_Entry renames Signals_Table.Table (Sig); + Need_It : Boolean; begin + pragma Assert (Typ.Wkind = Wkind_Sim); + + if Typ.W = 0 then + -- Be safe: no signal, then no driver. + return; + end if; + + -- Increment the number of driver for each scalar element. + Need_It := False; + for I in Off.Net_Off .. Off.Net_Off + Typ.W - 1 loop + if S.Nbr_Sources (I).Last_Proc /= Proc_Idx then + S.Nbr_Sources (I).Nbr_Drivers := S.Nbr_Sources (I).Nbr_Drivers + 1; + S.Nbr_Sources (I).Last_Proc := Proc_Idx; + Need_It := True; + end if; + end loop; + + if not Need_It then + -- The driver has already been added. + return; + end if; + Drivers_Table.Append ((Sig => Sig, Off => Off, Typ => Typ, - Prev_Sig => Signals_Table.Table (Sig).Drivers, + Prev_Sig => S.Drivers, Proc => Proc_Idx, Prev_Proc => Processes_Table.Table (Proc_Idx).Drivers)); - Signals_Table.Table (Sig).Drivers := Drivers_Table.Last; + S.Drivers := Drivers_Table.Last; Processes_Table.Table (Proc_Idx).Drivers := Drivers_Table.Last; end Add_Process_Driver; + -- Add drivers for process PROC. procedure Gather_Process_Drivers (Inst : Synth_Instance_Acc; Proc : Node; Proc_Idx : Process_Index_Type) is @@ -349,6 +397,22 @@ package body Simul.Vhdl_Elab is Destroy_Iir_List (List); end Gather_Process_Sensitivity; + -- Increment the number of sources for EP. + procedure Increment_Nbr_Sources (Ep : Connect_Endpoint) is + begin + if Ep.Typ.W = 0 then + return; + end if; + for I in Ep.Offs.Net_Off .. Ep.Offs.Net_Off + Ep.Typ.W - 1 loop + declare + N : Uns32 renames + Signals_Table.Table (Ep.Base).Nbr_Sources (I).Nbr_Conns; + begin + N := N + 1; + end; + end loop; + end Increment_Nbr_Sources; + procedure Gather_Connections (Port_Inst : Synth_Instance_Acc; Ports : Node; Assoc_Inst : Synth_Instance_Acc; @@ -414,10 +478,12 @@ package body Simul.Vhdl_Elab is | Iir_Buffer_Mode => Conn.Drive_Formal := False; Conn.Drive_Actual := True; + Increment_Nbr_Sources (Actual_Ep); when Iir_Inout_Mode | Iir_Linkage_Mode => Conn.Drive_Formal := True; Conn.Drive_Actual := True; + Increment_Nbr_Sources (Actual_Ep); when Iir_Unknown_Mode => raise Internal_Error; end case; diff --git a/src/simul/simul-vhdl_elab.ads b/src/simul/simul-vhdl_elab.ads index c17555920..0fb790475 100644 --- a/src/simul/simul-vhdl_elab.ads +++ b/src/simul/simul-vhdl_elab.ads @@ -122,6 +122,16 @@ package Simul.Vhdl_Elab is -- Signals. + -- Number of drivers and out connections for each scalar element. + type Nbr_Sources_Type is record + Nbr_Drivers : Uns32; + Nbr_Conns : Uns32; + Last_Proc : Process_Index_Type; + end record; + + type Nbr_Sources_Array is array (Uns32 range <>) of Nbr_Sources_Type; + type Nbr_Sources_Arr_Acc is access Nbr_Sources_Array; + type Signal_Entry (Kind : Mode_Signal_Type := Mode_Signal) is record Decl : Iir; Inst : Synth_Instance_Acc; @@ -139,6 +149,7 @@ package Simul.Vhdl_Elab is when Mode_Signal_User => Drivers : Driver_Index_Type; Connect : Connect_Index_Type; + Nbr_Sources : Nbr_Sources_Arr_Acc; when Mode_Quiet | Mode_Stable | Mode_Delayed | Mode_Transaction => Time : Std_Time; diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb index fb0efee72..58efc7101 100644 --- a/src/simul/simul-vhdl_simul.adb +++ b/src/simul/simul-vhdl_simul.adb @@ -1995,7 +1995,6 @@ package body Simul.Vhdl_Simul is procedure Create_Signal (Val : Memory_Ptr; Sig_Off : Uns32; --- Sig : Memory_Ptr; Sig_Type: Iir; Typ : Type_Acc; Vec : Nbr_Sources_Vector; @@ -2181,8 +2180,7 @@ package body Simul.Vhdl_Simul is pragma Assert (E.Sig = null); if E.Collapsed_By /= No_Signal_Index then E.Sig := Signals_Table.Table (E.Collapsed_By).Sig; - -- TODO: keep val ? - E.Val := Signals_Table.Table (E.Collapsed_By).Val; + -- E.Val will be assigned in Collapse_Signals. else Create_Signal (I); end if; @@ -2190,6 +2188,69 @@ package body Simul.Vhdl_Simul is end loop; end Create_Signals; + procedure Add_Extra_Driver_To_Signal (Sig : Memory_Ptr; + Typ : Type_Acc; + Init : Memory_Ptr; + Off : Uns32; + Vec : Nbr_Sources_Array) is + begin + case Typ.Kind is + when Type_Logic + | Type_Bit + | Type_Discrete + | Type_Float => + if Vec (Off).Nbr_Drivers = 0 + and then Vec (Off).Nbr_Conns = 0 + then + Grt.Signals.Ghdl_Signal_Add_Extra_Driver + (Read_Sig (Sig), To_Ghdl_Value ((Typ, Init))); + end if; + when Type_Vector + | Type_Array => + declare + Len : constant Uns32 := Typ.Abound.Len; + El : constant Type_Acc := Typ.Arr_El; + begin + for I in 1 .. Len loop + Add_Extra_Driver_To_Signal + (Sig_Index (Sig, (Len - I) * El.W), El, + Init + Size_Type (I - 1) * El.Sz, Off + (Len - I), Vec); + end loop; + end; + when Type_Record => + for I in Typ.Rec.E'Range loop + declare + E : Rec_El_Type renames Typ.Rec.E (I); + begin + Add_Extra_Driver_To_Signal + (Sig_Index (Sig, E.Offs.Net_Off), E.Typ, + Init + E.Offs.Mem_Off, Off + E.Offs.Net_Off, Vec); + end; + end loop; + when others => + raise Internal_Error; + end case; + end Add_Extra_Driver_To_Signal; + + procedure Collapse_Signals is + begin + for I in Signals_Table.First .. Signals_Table.Last loop + declare + E : Signal_Entry renames Signals_Table.Table (I); + begin + if E.Collapsed_By /= No_Signal_Index then + if Get_Mode (E.Decl) in Iir_Out_Modes then + Add_Extra_Driver_To_Signal + (E.Sig, E.Typ, E.Val, 0, E.Nbr_Sources.all); + end if; + -- The signal value is the value of the collapsed signal. + -- TODO: keep the default value ? + E.Val := Signals_Table.Table (E.Collapsed_By).Val; + end if; + end; + end loop; + end Collapse_Signals; + type Connect_Mode is (Connect_Source, Connect_Effective); -- Add a driving value PORT to signal SIG, ie: PORT is a source for SIG. @@ -2635,9 +2696,9 @@ package body Simul.Vhdl_Simul is Create_Connects; -- Create_Disconnections; Create_Processes; - -- Create_PSL; Create_Terminals; Create_Quantities; + Collapse_Signals; -- Allow Synth_Expression to handle signals. Synth.Vhdl_Expr.Hook_Signal_Expr := Hook_Signal_Expr'Access; |