aboutsummaryrefslogtreecommitdiffstats
path: root/src/simul
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-08-17 03:19:30 +0200
committerTristan Gingold <tgingold@free.fr>2022-08-17 03:19:30 +0200
commita546ecfe5c8643c72435318de3973cbf83993fa4 (patch)
tree76c82ce2422c8e110efa496a8d13dc9f591a447d /src/simul
parente57ba3e335d1f3692805f46d7d9cba49ffea4219 (diff)
downloadghdl-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.adb4
-rw-r--r--src/simul/simul-vhdl_elab.adb75
-rw-r--r--src/simul/simul-vhdl_elab.ads18
-rw-r--r--src/simul/simul-vhdl_simul.adb93
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;