diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-08-17 03:19:30 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-08-17 03:19:30 +0200 |
commit | a546ecfe5c8643c72435318de3973cbf83993fa4 (patch) | |
tree | 76c82ce2422c8e110efa496a8d13dc9f591a447d /src/simul | |
parent | e57ba3e335d1f3692805f46d7d9cba49ffea4219 (diff) | |
download | ghdl-a546ecfe5c8643c72435318de3973cbf83993fa4.tar.gz ghdl-a546ecfe5c8643c72435318de3973cbf83993fa4.tar.bz2 ghdl-a546ecfe5c8643c72435318de3973cbf83993fa4.zip |
simul: add create_connects
Diffstat (limited to 'src/simul')
-rw-r--r-- | src/simul/simul-vhdl_debug.adb | 4 | ||||
-rw-r--r-- | src/simul/simul-vhdl_elab.adb | 75 | ||||
-rw-r--r-- | src/simul/simul-vhdl_elab.ads | 18 | ||||
-rw-r--r-- | src/simul/simul-vhdl_simul.adb | 93 |
4 files changed, 144 insertions, 46 deletions
diff --git a/src/simul/simul-vhdl_debug.adb b/src/simul/simul-vhdl_debug.adb index 067e06186..0c8a707f1 100644 --- a/src/simul/simul-vhdl_debug.adb +++ b/src/simul/simul-vhdl_debug.adb @@ -376,13 +376,13 @@ package body Simul.Vhdl_Debug is declare C : Connect_Entry renames Connect_Table.Table (Conn); begin - if C.Formal_Base = Idx then + if C.Formal.Base = Idx then if C.Drive_Formal then Nbr_Conn_Drv := Nbr_Conn_Drv + 1; end if; Conn := C.Formal_Link; else - pragma Assert (C.Actual_Base = Idx); + pragma Assert (C.Actual.Base = Idx); if C.Drive_Actual then Nbr_Conn_Drv := Nbr_Conn_Drv + 1; end if; diff --git a/src/simul/simul-vhdl_elab.adb b/src/simul/simul-vhdl_elab.adb index 884d83c28..9539645e3 100644 --- a/src/simul/simul-vhdl_elab.adb +++ b/src/simul/simul-vhdl_elab.adb @@ -185,7 +185,8 @@ package body Simul.Vhdl_Elab is | Iir_Kind_Procedure_Declaration | Iir_Kind_Function_Body | Iir_Kind_Procedure_Body - | Iir_Kind_Component_Declaration => + | Iir_Kind_Component_Declaration + | Iir_Kind_File_Declaration => null; when others => Error_Kind ("gather_processes_decl", Decl); @@ -366,6 +367,7 @@ package body Simul.Vhdl_Elab is Dyn : Dyn_Name; Conn : Connect_Entry; List : Iir_List; + Formal_Ep, Actual_Ep : Connect_Endpoint; begin Assoc := Assocs; Assoc_Inter := Ports; @@ -377,22 +379,23 @@ package body Simul.Vhdl_Elab is (Port_Inst, Inter, Formal_Base, Typ, Off, Dyn); pragma Assert (Dyn = No_Dyn_Name); Formal_Sig := Formal_Base.Val.S; - Conn.Formal_Base := Formal_Sig; - Conn.Formal_Offs := Off; - Conn.Formal_Type := Typ; - Conn.Formal_Link := Signals_Table.Table (Formal_Sig).Connect; - + Formal_Ep := (Formal_Sig, Off, Typ); Synth_Assignment_Prefix (Assoc_Inst, Get_Actual (Assoc), Actual_Base, Typ, Off, Dyn); pragma Assert (Dyn = No_Dyn_Name); Actual_Sig := Actual_Base.Val.S; - Conn.Actual_Base := Actual_Sig; - Conn.Actual_Offs := Off; - Conn.Actual_Type := Typ; - Conn.Actual_Link := Signals_Table.Table (Actual_Sig).Connect; - - Conn.Assoc := Assoc; - Conn.Assoc_Inst := Assoc_Inst; + Actual_Ep := (Actual_Sig, Off, Typ); + + Conn := + (Formal => Formal_Ep, + Formal_Link => Signals_Table.Table (Formal_Sig).Connect, + Actual => Actual_Ep, + Actual_Link => Signals_Table.Table (Actual_Sig).Connect, + Drive_Formal => False, + Drive_Actual => False, + Collapsed => False, + Assoc => Assoc, + Assoc_Inst => Assoc_Inst); -- LRM08 6.4.2.3 Signal declarations -- [...], each source is either a driver or an OUT, INOUT, @@ -413,24 +416,24 @@ package body Simul.Vhdl_Elab is raise Internal_Error; end case; + Connect_Table.Append (Conn); Signals_Table.Table (Formal_Sig).Connect := Connect_Table.Last; Signals_Table.Table (Actual_Sig).Connect := Connect_Table.Last; -- Collapse - if Get_Collapse_Signal_Flag (Assoc) then - pragma Assert (Conn.Formal_Offs.Mem_Off = 0); - pragma Assert (Conn.Actual_Offs.Mem_Off = 0); - pragma Assert (Actual_Base.Typ.W = Typ.W); - pragma Assert (Formal_Base.Typ.W = Typ.W); + if Get_Collapse_Signal_Flag (Assoc) + and then Formal_Ep.Offs.Mem_Off = 0 + and then Actual_Ep.Offs.Mem_Off = 0 + and then Actual_Base.Typ.W = Formal_Base.Typ.W + then + -- Full collapse. pragma Assert (Signals_Table.Table (Formal_Sig).Collapsed_By = No_Signal_Index); pragma Assert (Formal_Sig > Actual_Sig); Signals_Table.Table (Formal_Sig).Collapsed_By := Actual_Sig; - else - -- TODO: handle non-collapsed signals in simul. - raise Internal_Error; + Connect_Table.Table (Connect_Table.Last).Collapsed := True; end if; when Iir_Kind_Association_Element_Open | Iir_Kind_Association_Element_By_Individual => @@ -442,22 +445,20 @@ package body Simul.Vhdl_Elab is (Port_Inst, Inter, Formal_Base, Typ, Off, Dyn); pragma Assert (Dyn = No_Dyn_Name); Formal_Sig := Formal_Base.Val.S; - Conn.Formal_Base := Formal_Sig; - Conn.Formal_Offs := Off; - Conn.Formal_Type := Typ; - Conn.Formal_Link := Signals_Table.Table (Formal_Sig).Connect; - - Conn.Actual_Base := No_Signal_Index; - Conn.Actual_Offs := No_Value_Offsets; - Conn.Actual_Type := null; - Conn.Actual_Link := No_Connect_Index; - - Conn.Assoc := Assoc; - Conn.Assoc_Inst := Assoc_Inst; - - -- Always an IN interface. - Conn.Drive_Formal := True; - Conn.Drive_Actual := False; + Formal_Ep := (Formal_Sig, Off, Typ); + + Actual_Ep := (No_Signal_Index, No_Value_Offsets, null); + + Conn := + (Formal => Formal_Ep, + Formal_Link => Signals_Table.Table (Formal_Sig).Connect, + Actual => Actual_Ep, + Actual_Link => No_Connect_Index, + Drive_Formal => True, -- Always an IN interface + Drive_Actual => False, + Collapsed => False, + Assoc => Assoc, + Assoc_Inst => Assoc_Inst); Connect_Table.Append (Conn); diff --git a/src/simul/simul-vhdl_elab.ads b/src/simul/simul-vhdl_elab.ads index ed58ca0d6..14ca462a0 100644 --- a/src/simul/simul-vhdl_elab.ads +++ b/src/simul/simul-vhdl_elab.ads @@ -83,18 +83,20 @@ package Simul.Vhdl_Elab is type Connect_Index_Type is new Nat32; No_Connect_Index : constant Connect_Index_Type := 0; + type Connect_Endpoint is record + Base : Signal_Index_Type; + Offs : Value_Offsets; + Typ : Type_Acc; + end record; + -- Connections. For each associations (block/component/entry), the -- elaborator adds an entry in that table. type Connect_Entry is record - Formal_Base : Signal_Index_Type; - Formal_Offs : Value_Offsets; - Formal_Type : Type_Acc; + Formal : Connect_Endpoint; -- Next connection for the formal. Formal_Link : Connect_Index_Type; - Actual_Base : Signal_Index_Type; - Actual_Offs : Value_Offsets; - Actual_Type : Type_Acc; + Actual : Connect_Endpoint; -- Next connection for the actual. Actual_Link : Connect_Index_Type; @@ -103,6 +105,10 @@ package Simul.Vhdl_Elab is Drive_Formal : Boolean; Drive_Actual : Boolean; + -- If true, the connection is fully collapsed: formal is the same + -- signal as actual. + Collapsed : Boolean; + Assoc : Node; Assoc_Inst : Synth_Instance_Acc; end record; diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb index b4f480c0c..70fdc86cb 100644 --- a/src/simul/simul-vhdl_simul.adb +++ b/src/simul/simul-vhdl_simul.adb @@ -1584,6 +1584,97 @@ package body Simul.Vhdl_Simul is end loop; end Create_Signals; + type Connect_Mode is (Connect_Source, Connect_Effective); + + -- Add a driving value PORT to signal SIG, ie: PORT is a source for SIG. + -- As a side effect, this connect the signal SIG with the port PORT. + -- PORT is the formal, while SIG is the actual. + procedure Connect (Dst : Connect_Endpoint; + Src : Connect_Endpoint; + Mode : Connect_Mode) is + begin + pragma Assert (Dst.Typ.Kind = Src.Typ.Kind); + + case Dst.Typ.Kind is + when Type_Vector => + declare + Len : constant Uns32 := Dst.Typ.Abound.Len; + Etyp : constant Type_Acc := Dst.Typ.Arr_El; + begin + if Len /= Src.Typ.Abound.Len then + raise Internal_Error; + end if; + for I in 1 .. Len loop + Connect ((Dst.Base, + (Dst.Offs.Net_Off + (Len - I) * Etyp.W, + Dst.Offs.Mem_Off + Size_Type (I - 1) * Etyp.Sz), + Etyp), + (Src.Base, + (Src.Offs.Net_Off + (Len - I) * Etyp.W, + Src.Offs.Mem_Off + Size_Type (I - 1) * Etyp.Sz), + Src.Typ.Arr_El), + Mode); + end loop; + end; + return; + when Type_Logic + | Type_Bit => + declare + S, D : Ghdl_Signal_Ptr; + begin + S := Read_Sig (Sig_Index (Signals_Table.Table (Src.Base).Sig, + Src.Offs.Net_Off)); + D := Read_Sig (Sig_Index (Signals_Table.Table (Dst.Base).Sig, + Dst.Offs.Net_Off)); + case Mode is + when Connect_Source => + Grt.Signals.Ghdl_Signal_Add_Source (D, S); + when Connect_Effective => + Grt.Signals.Ghdl_Signal_Effective_Value (D, S); + end case; + end; + when others => + raise Internal_Error; + end case; + end Connect; + + procedure Create_Connect (C : Connect_Entry) is + begin + if C.Drive_Actual then + declare + Out_Conv : constant Iir := Get_Formal_Conversion (C.Assoc); + begin + pragma Assert (Out_Conv = Null_Iir); + -- LRM93 12.6.2 + -- A signal is said to be active [...] if one of its source + -- is active. + Connect (C.Actual, C.Formal, Connect_Source); + end; + end if; + + if C.Drive_Formal then + declare + In_Conv : constant Iir := Get_Actual_Conversion (C.Assoc); + begin + pragma Assert (In_Conv = Null_Iir); + Connect (C.Formal, C.Actual, Connect_Effective); + end; + end if; + end Create_Connect; + + procedure Create_Connects is + begin + for I in Connect_Table.First .. Connect_Table.Last loop + declare + C : Connect_Entry renames Connect_Table.Table (I); + begin + if not C.Collapsed then + Create_Connect (C); + end if; + end; + end loop; + end Create_Connects; + procedure Create_Terminals is begin @@ -1928,7 +2019,7 @@ package body Simul.Vhdl_Simul is Disp_Time_Before_Values := True; Create_Signals; - -- Create_Connects; + Create_Connects; -- Create_Disconnections; Create_Processes; -- Create_PSL; |