aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-08-23 06:19:17 +0200
committerTristan Gingold <tgingold@free.fr>2022-08-23 06:19:17 +0200
commit9d41b070c29508d5c941566b5687673a2e182578 (patch)
tree04f0902bce6031e5a3970d5692669ce9b0f8de2c
parent68765b386b7fece1b0fc709846d3f8bc29b45ecb (diff)
downloadghdl-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.adb86
-rw-r--r--src/simul/simul-vhdl_elab.ads11
-rw-r--r--src/simul/simul-vhdl_simul.adb69
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;