aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ghdldrv/ghdlsimul.adb2
-rw-r--r--src/grt/grt-signals.adb11
-rw-r--r--src/grt/grt-signals.ads3
-rw-r--r--src/grt/grt-strings.adb3
-rw-r--r--src/grt/grt-strings.ads4
-rw-r--r--src/simul/simul-vhdl_elab.adb9
-rw-r--r--src/simul/simul-vhdl_simul.adb287
-rw-r--r--src/synth/elab-vhdl_context.adb43
-rw-r--r--src/synth/elab-vhdl_context.ads25
-rw-r--r--src/synth/elab-vhdl_debug.adb2
-rw-r--r--src/synth/elab-vhdl_expr.adb128
-rw-r--r--src/synth/elab-vhdl_expr.ads2
-rw-r--r--src/synth/elab-vhdl_insts.adb10
-rw-r--r--src/synth/elab-vhdl_values-debug.adb3
-rw-r--r--src/synth/elab-vhdl_values.adb26
-rw-r--r--src/synth/elab-vhdl_values.ads13
-rw-r--r--src/synth/synth-vhdl_context.adb3
-rw-r--r--src/synth/synth-vhdl_expr.adb39
-rw-r--r--src/synth/synth-vhdl_expr.ads2
-rw-r--r--src/synth/synth-vhdl_insts.adb3
-rw-r--r--src/synth/synth-vhdl_oper.adb14
-rw-r--r--src/synth/synth-vhdl_stmts.adb37
-rw-r--r--src/synth/synth-vhdl_stmts.ads19
-rw-r--r--src/vhdl/vhdl-canon.adb1
24 files changed, 595 insertions, 94 deletions
diff --git a/src/ghdldrv/ghdlsimul.adb b/src/ghdldrv/ghdlsimul.adb
index 08377c1e1..1e5c0f557 100644
--- a/src/ghdldrv/ghdlsimul.adb
+++ b/src/ghdldrv/ghdlsimul.adb
@@ -79,7 +79,7 @@ package body Ghdlsimul is
Lib_Unit : Node;
Inst : Synth_Instance_Acc;
begin
- Common_Compile_Elab (Cmd_Name, Args, False, Opt_Arg, Config);
+ Common_Compile_Elab (Cmd_Name, Args, True, Opt_Arg, Config);
for I in Opt_Arg .. Args'Last loop
if Args (I).all = "--expect-failure" then
diff --git a/src/grt/grt-signals.adb b/src/grt/grt-signals.adb
index 5c542a38e..b81a86fd3 100644
--- a/src/grt/grt-signals.adb
+++ b/src/grt/grt-signals.adb
@@ -1803,7 +1803,8 @@ package body Grt.Signals is
end if;
end Ghdl_Signal_Driving;
- function Ghdl_Signal_Driving_Value_B1 (Sig : Ghdl_Signal_Ptr) return Ghdl_B1
+ function Ghdl_Signal_Driving_Value (Sig : Ghdl_Signal_Ptr)
+ return Value_Union
is
Drv : Driver_Acc;
begin
@@ -1811,8 +1812,14 @@ package body Grt.Signals is
if Drv = null or else Drv.First_Trans.Kind /= Trans_Value then
Error ("'driving_value: no active driver in process for signal");
else
- return Drv.First_Trans.Val.B1;
+ return Drv.First_Trans.Val;
end if;
+ end Ghdl_Signal_Driving_Value;
+
+ function Ghdl_Signal_Driving_Value_B1 (Sig : Ghdl_Signal_Ptr)
+ return Ghdl_B1 is
+ begin
+ return Ghdl_Signal_Driving_Value (Sig).B1;
end Ghdl_Signal_Driving_Value_B1;
function Ghdl_Signal_Driving_Value_E8 (Sig : Ghdl_Signal_Ptr)
diff --git a/src/grt/grt-signals.ads b/src/grt/grt-signals.ads
index 618ec8805..76977d37a 100644
--- a/src/grt/grt-signals.ads
+++ b/src/grt/grt-signals.ads
@@ -599,6 +599,9 @@ package Grt.Signals is
function Ghdl_Signal_Driving (Sig : Ghdl_Signal_Ptr) return Ghdl_B1;
+ function Ghdl_Signal_Driving_Value (Sig : Ghdl_Signal_Ptr)
+ return Value_Union;
+
-- Generic version.
procedure Ghdl_Signal_Start_Assign_Any (Sign : Ghdl_Signal_Ptr;
Rej : Std_Time;
diff --git a/src/grt/grt-strings.adb b/src/grt/grt-strings.adb
index 5d6fc8706..3f8f8ed29 100644
--- a/src/grt/grt-strings.adb
+++ b/src/grt/grt-strings.adb
@@ -23,9 +23,8 @@
package body Grt.Strings is
function Is_Whitespace (C : in Character) return Boolean is
- use ASCII;
begin
- return C = ' ' or C = NBSP or C = HT;
+ return C = ' ' or C = NBSP;
end Is_Whitespace;
function First_Non_Whitespace_Pos (Str : String) return Integer is
diff --git a/src/grt/grt-strings.ads b/src/grt/grt-strings.ads
index 7b8535425..1d52a62fc 100644
--- a/src/grt/grt-strings.ads
+++ b/src/grt/grt-strings.ads
@@ -26,7 +26,9 @@ package Grt.Strings is
NBSP : constant Character := Character'Val (160);
- -- Return True IFF C is a whitespace character (as defined in LRM93 14.3)
+ -- Return True IFF C is a whitespace character as defined by LRM93 13.1
+ -- Note: this is different from the definition in LRM93 14.3 (for files,
+ -- which includes HT).
function Is_Whitespace (C : in Character) return Boolean;
-- The following functions return -1 in case there is no match in string ---
diff --git a/src/simul/simul-vhdl_elab.adb b/src/simul/simul-vhdl_elab.adb
index 5c41511d6..36bc1df23 100644
--- a/src/simul/simul-vhdl_elab.adb
+++ b/src/simul/simul-vhdl_elab.adb
@@ -360,6 +360,15 @@ package body Simul.Vhdl_Elab is
No_Sensitivity_Index, No_Signal_Index,
No_Connect_Index, T, Pfx));
end;
+ when Iir_Kind_Transaction_Attribute =>
+ declare
+ Pfx : Sub_Signal_Type;
+ begin
+ Pfx := Compute_Sub_Signal (Inst, Get_Prefix (Decl));
+ Gather_Signal ((Mode_Transaction, Decl, Inst, null, null, null,
+ No_Sensitivity_Index, No_Signal_Index,
+ No_Connect_Index, 0, Pfx));
+ end;
when Iir_Kind_Delayed_Attribute =>
declare
T : Std_Time;
diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb
index 0ebb719f0..354ca062f 100644
--- a/src/simul/simul-vhdl_simul.adb
+++ b/src/simul/simul-vhdl_simul.adb
@@ -69,6 +69,9 @@ package body Simul.Vhdl_Simul is
procedure Process_Executer (Self : Grt.Processes.Instance_Acc);
pragma Convention (C, Process_Executer);
+ procedure Update_Signal_Individual_Assocs_Values
+ (Inst : Synth_Instance_Acc);
+
type Ghdl_Signal_Ptr_Ptr is access all Ghdl_Signal_Ptr;
function To_Ghdl_Signal_Ptr_Ptr is
new Ada.Unchecked_Conversion (Memory_Ptr, Ghdl_Signal_Ptr_Ptr);
@@ -110,20 +113,32 @@ package body Simul.Vhdl_Simul is
function Hook_Signal_Expr (Val : Valtyp) return Valtyp is
begin
- if Val.Val.Kind = Value_Alias then
- declare
- E : Signal_Entry renames Signals_Table.Table (Val.Val.A_Obj.S);
- begin
- return Create_Value_Memtyp
- ((Val.Typ, E.Val + Val.Val.A_Off.Mem_Off));
- end;
- else
- declare
- E : Signal_Entry renames Signals_Table.Table (Val.Val.S);
- begin
- return Create_Value_Memtyp ((E.Typ, E.Val));
- end;
- end if;
+ case Val.Val.Kind is
+ when Value_Alias =>
+ declare
+ E : Signal_Entry renames Signals_Table.Table (Val.Val.A_Obj.S);
+ begin
+ return Create_Value_Memtyp
+ ((Val.Typ, E.Val + Val.Val.A_Off.Mem_Off));
+ end;
+ when Value_Signal =>
+ declare
+ E : Signal_Entry renames Signals_Table.Table (Val.Val.S);
+ begin
+ return Create_Value_Memtyp ((E.Typ, E.Val));
+ end;
+ when Value_Sig_Val =>
+ return Create_Value_Memtyp ((Val.Typ, Val.Val.I_Vals));
+ when Value_Net
+ | Value_Wire
+ | Value_Memory
+ | Value_File
+ | Value_Quantity
+ | Value_Terminal
+ | Value_Dyn_Alias
+ | Value_Const =>
+ raise Internal_Error;
+ end case;
end Hook_Signal_Expr;
function Hook_Quantity_Expr (Val : Valtyp) return Valtyp is
@@ -331,6 +346,29 @@ package body Simul.Vhdl_Simul is
end loop;
end Create_Process_Drivers;
+ function Get_Sig_Mem (Val : Value_Acc; Idx : Uns32) return Memory_Ptr
+ is
+ Base : Memory_Ptr;
+ begin
+ case Val.Kind is
+ when Value_Signal =>
+ Base := Signals_Table.Table (Val.S).Sig;
+ when Value_Sig_Val =>
+ Base := Val.I_Sigs;
+ when Value_Net
+ | Value_Wire
+ | Value_Memory
+ | Value_File
+ | Value_Quantity
+ | Value_Terminal
+ | Value_Const
+ | Value_Dyn_Alias
+ | Value_Alias =>
+ raise Internal_Error;
+ end case;
+ return Sig_Index (Base, Idx);
+ end Get_Sig_Mem;
+
type Read_Signal_Flag_Enum is
(Read_Signal_Event,
Read_Signal_Active,
@@ -407,10 +445,10 @@ package body Simul.Vhdl_Simul is
pragma Assert (Pfx.Obj.Val /= null
and then Pfx.Obj.Val.Kind = Value_Signal);
E := Read_Signal_Flag
- ((Pfx.Targ_Type,
- Sig_Index (Signals_Table.Table (Pfx.Obj.Val.S).Sig,
- Pfx.Off.Net_Off)),
- Kind);
+ ((Pfx.Targ_Type, Get_Sig_Mem (Pfx.Obj.Val, Pfx.Off.Net_Off)), Kind);
+ if Kind = Read_Signal_Not_Driving then
+ E := not E;
+ end if;
Res := Create_Value_Memory (Boolean_Type, Expr_Pool'Access);
Write_U8 (Res.Val.Mem, Boolean'Pos (E));
return Res;
@@ -428,6 +466,12 @@ package body Simul.Vhdl_Simul is
return Exec_Signal_Flag_Attribute (Inst, Expr, Read_Signal_Active);
end Exec_Active_Attribute;
+ function Exec_Driving_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp is
+ begin
+ return Exec_Signal_Flag_Attribute (Inst, Expr, Read_Signal_Not_Driving);
+ end Exec_Driving_Attribute;
+
function Exec_Dot_Attribute (Inst : Synth_Instance_Acc;
Expr : Node) return Valtyp
is
@@ -696,9 +740,8 @@ package body Simul.Vhdl_Simul is
while Is_Valid (It) loop
El := Get_Element (It);
Info := Synth_Target (Inst, El);
- Sig := Signals_Table.Table (Info.Obj.Val.S).Sig;
- Add_Wait_Sensitivity
- (Info.Targ_Type, Sig_Index (Sig, Info.Off.Net_Off));
+ Sig := Get_Sig_Mem (Info.Obj.Val, Info.Off.Net_Off);
+ Add_Wait_Sensitivity (Info.Targ_Type, Sig);
Next (It);
end loop;
end;
@@ -715,6 +758,21 @@ package body Simul.Vhdl_Simul is
function Resume_Wait_Statement (Inst : Synth_Instance_Acc;
Stmt : Node) return Boolean is
begin
+ -- For all procedures in the activation chain, update individual
+ -- signal associations.
+ declare
+ Cinst : Synth_Instance_Acc;
+ begin
+ Cinst := Inst;
+ loop
+ if Get_Indiv_Signal_Assoc_Flag (Cinst) then
+ Update_Signal_Individual_Assocs_Values (Cinst);
+ end if;
+ exit when not Get_Indiv_Signal_Assoc_Parent_Flag (Cinst);
+ Cinst := Get_Instance_Parent (Cinst);
+ end loop;
+ end;
+
-- LRM93 8.1
-- The suspended process will resume, at the latest, immediately
-- after the timeout interval has expired.
@@ -895,6 +953,11 @@ package body Simul.Vhdl_Simul is
Aft : Node;
Rej : Node;
begin
+ -- Nothing to assign.
+ if Get_Kind (Waveform) = Iir_Kind_Unaffected_Waveform then
+ return;
+ end if;
+
Rej := Get_Reject_Time_Expression (Stmt);
if Rej /= Null_Node then
raise Internal_Error;
@@ -965,13 +1028,35 @@ package body Simul.Vhdl_Simul is
end case;
end Disconnect_Signal;
- procedure Disconnect_Signal_Target (Target : Target_Info)
- is
- E : Signal_Entry renames Signals_Table.Table (Target.Obj.Val.S);
- Sig : Memtyp;
+ procedure Disconnect_Signal_Target (Inst : Synth_Instance_Acc;
+ Target : Target_Info) is
begin
- Sig := (Target.Targ_Type, Sig_Index (E.Sig, Target.Off.Net_Off));
- Disconnect_Signal (Sig);
+ case Target.Kind is
+ when Target_Simple =>
+ declare
+ Sig : Memtyp;
+ begin
+ Sig := (Target.Targ_Type,
+ Get_Sig_Mem (Target.Obj.Val, Target.Off.Net_Off));
+ Disconnect_Signal (Sig);
+ end;
+ when Target_Aggregate =>
+ declare
+ Choice : Node;
+ Assoc_Expr : Node;
+ Sub_Targ : Target_Info;
+ begin
+ Choice := Get_Association_Choices_Chain (Target.Aggr);
+ while Choice /= Null_Node loop
+ Assoc_Expr := Get_Associated_Expr (Choice);
+ Sub_Targ := Synth_Target (Inst, Assoc_Expr);
+ Disconnect_Signal_Target (Inst, Sub_Targ);
+ Choice := Get_Chain (Choice);
+ end loop;
+ end;
+ when Target_Memory =>
+ raise Internal_Error;
+ end case;
end Disconnect_Signal_Target;
function Execute_Maybe_Guarded_Assignment (Inst : Synth_Instance_Acc;
@@ -984,7 +1069,7 @@ package body Simul.Vhdl_Simul is
if Guard /= Null_Node
and then not Execute_Condition (Inst, Guard)
then
- Disconnect_Signal_Target (Targ);
+ Disconnect_Signal_Target (Inst, Targ);
return True;
else
return False;
@@ -2047,10 +2132,10 @@ package body Simul.Vhdl_Simul is
-- For conversion functions.
Read_Signal_Driving_Value,
- Read_Signal_Effective_Value --,
+ Read_Signal_Effective_Value,
-- 'Driving_Value
--- Read_Signal_Driver_Value
+ Read_Signal_Driver_Value
);
procedure Exec_Read_Signal (Sig: Memory_Ptr;
@@ -2069,6 +2154,8 @@ package body Simul.Vhdl_Simul is
Write_Ghdl_Value (Val, S.Value_Ptr.all);
when Read_Signal_Last_Value =>
Write_Ghdl_Value (Val, S.Last_Value);
+ when Read_Signal_Driver_Value =>
+ Write_Ghdl_Value (Val, Ghdl_Signal_Driving_Value (S));
end case;
when Type_Vector
| Type_Array =>
@@ -2098,24 +2185,38 @@ package body Simul.Vhdl_Simul is
end case;
end Exec_Read_Signal;
- function Exec_Last_Value_Attribute (Inst : Synth_Instance_Acc;
- Expr : Node) return Valtyp
+ function Exec_Signal_Value_Attribute (Inst : Synth_Instance_Acc;
+ Attr : Node;
+ Kind : Read_Signal_Enum) return Valtyp
is
Pfx : Target_Info;
Res : Valtyp;
S : Memory_Ptr;
begin
- Pfx := Synth_Target (Inst, Get_Prefix (Expr));
+ Pfx := Synth_Target (Inst, Get_Prefix (Attr));
Res := Create_Value_Memory (Pfx.Targ_Type, Expr_Pool'Access);
S := Sig_Index (Signals_Table.Table (Pfx.Obj.Val.S).Sig,
Pfx.Off.Net_Off);
- Exec_Read_Signal (S, Get_Memtyp (Res), Read_Signal_Last_Value);
+ Exec_Read_Signal (S, Get_Memtyp (Res), Kind);
return Res;
+ end Exec_Signal_Value_Attribute;
+
+ function Exec_Last_Value_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp is
+ begin
+ return Exec_Signal_Value_Attribute (Inst, Expr, Read_Signal_Last_Value);
end Exec_Last_Value_Attribute;
+ function Exec_Driving_Value_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp is
+ begin
+ return Exec_Signal_Value_Attribute
+ (Inst, Expr, Read_Signal_Driver_Value);
+ end Exec_Driving_Value_Attribute;
+
type Read_Signal_Last_Enum is
(
Read_Signal_Last_Event,
@@ -2193,6 +2294,11 @@ package body Simul.Vhdl_Simul is
Pfx.Off.Net_Off);
T := Exec_Read_Signal_Last (S, Get_Memtyp (Res), Attr);
+ if T < 0 then
+ T := Std_Time'Last;
+ else
+ T := Current_Time - T;
+ end if;
Write_I64 (Res.Val.Mem, Ghdl_I64 (T));
return Res;
end Exec_Signal_Last_Attribute;
@@ -2668,14 +2774,15 @@ package body Simul.Vhdl_Simul is
end case;
end Register_Prefix;
- function Alloc_Signal_Memory (Vtype : Type_Acc) return Memory_Ptr
+ function Alloc_Signal_Memory
+ (Vtype : Type_Acc; Pool : Areapools.Areapool_Acc) return Memory_Ptr
is
function To_Memory_Ptr is new Ada.Unchecked_Conversion
(System.Address, Memory_Ptr);
M : System.Address;
begin
- Areapools.Allocate (Global_Pool,
- M, Sig_Size * Size_Type (Vtype.W), Sig_Size);
+ Areapools.Allocate
+ (Pool.all, M, Sig_Size * Size_Type (Vtype.W), Sig_Size);
return To_Memory_Ptr (M);
end Alloc_Signal_Memory;
@@ -2694,7 +2801,7 @@ package body Simul.Vhdl_Simul is
E : Signal_Entry renames Signals_Table.Table (Idx);
S : Ghdl_Signal_Ptr;
begin
- E.Sig := Alloc_Signal_Memory (E.Typ);
+ E.Sig := Alloc_Signal_Memory (E.Typ, Global_Pool'Access);
case E.Kind is
when Mode_Guard =>
Create_Guard_Signal (Idx);
@@ -2709,9 +2816,10 @@ package body Simul.Vhdl_Simul is
Write_Sig (E.Sig, S);
Register_Prefix (E.Pfx.Typ, To_Memory_Ptr (E.Pfx));
when Mode_Transaction =>
- -- Create_Implicit_Signal
- -- (E.Sig, E.Val, E.Time, E.Prefix, E.Kind);
- raise Internal_Error;
+ S := Grt.Signals.Ghdl_Create_Transaction_Signal
+ (To_Ghdl_Value_Ptr (To_Address (E.Val)));
+ Write_Sig (E.Sig, S);
+ Register_Prefix (E.Pfx.Typ, To_Memory_Ptr (E.Pfx));
when Mode_Delayed =>
Create_Delayed_Signal (E.Sig, E.Val, To_Memory_Ptr (E.Pfx),
E.Typ, E.Time);
@@ -3089,7 +3197,7 @@ package body Simul.Vhdl_Simul is
if Out_Conv /= Null_Node then
-- From formal to actual.
Ctyp := C.Actual.Typ;
- Csig := Alloc_Signal_Memory (Ctyp);
+ Csig := Alloc_Signal_Memory (Ctyp, Global_Pool'Access);
Cval := Alloc_Memory (Ctyp, Global_Pool'Access);
Create_Shadow_Signal (Csig, Cval, Ctyp);
Form2 := (Ctyp, Csig);
@@ -3124,7 +3232,7 @@ package body Simul.Vhdl_Simul is
if In_Conv /= Null_Node then
Ctyp := C.Formal.Typ;
- Csig := Alloc_Signal_Memory (Ctyp);
+ Csig := Alloc_Signal_Memory (Ctyp, Global_Pool'Access);
Cval := Alloc_Memory (Ctyp, Global_Pool'Access);
Create_Shadow_Signal (Csig, Cval, Ctyp);
Act2 := (Ctyp, Csig);
@@ -3223,8 +3331,93 @@ package body Simul.Vhdl_Simul is
end loop;
end Create_Connects;
- procedure Create_Terminals
+ procedure Update_Sig_Val (Typ : Type_Acc;
+ Sigs : Memory_Ptr;
+ Vals : Memory_Ptr)
is
+ Sig : Ghdl_Signal_Ptr;
+ begin
+ case Typ.Kind is
+ when Type_Logic
+ | Type_Bit
+ | Type_Discrete
+ | Type_Float =>
+ Sig := Read_Sig (Sigs);
+ Write_Ghdl_Value ((Typ, Vals), Sig.Value_Ptr.all);
+ 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
+ Update_Sig_Val (El,
+ Sig_Index (Sigs, (Len - I) * El.W),
+ Vals + Size_Type (I - 1) * El.Sz);
+ 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
+ Update_Sig_Val (E.Typ,
+ Sig_Index (Sigs, E.Offs.Net_Off),
+ Vals + E.Offs.Mem_Off);
+ end;
+ end loop;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Update_Sig_Val;
+
+ procedure Update_Signal_Individual_Assocs_Values (Inst : Synth_Instance_Acc)
+ is
+ Bod : constant Node := Get_Source_Scope (Inst);
+ Spec : constant Node := Get_Subprogram_Specification (Bod);
+ Inter : Node;
+ Obj : Valtyp;
+ begin
+ Inter := Get_Interface_Declaration_Chain (Spec);
+ while Inter /= Null_Node loop
+ Obj := Get_Value (Inst, Inter);
+ if Obj.Val.Kind = Value_Sig_Val then
+ Update_Sig_Val (Obj.Typ, Obj.Val.I_Sigs, Obj.Val.I_Vals);
+ end if;
+ Inter := Get_Chain (Inter);
+ end loop;
+ end Update_Signal_Individual_Assocs_Values;
+
+ function Hook_Create_Value_For_Signal_Individual_Assocs
+ (Inst : Synth_Instance_Acc;
+ Assocs : Assoc_Array;
+ Typ : Type_Acc) return Valtyp
+ is
+ Sigs : Memory_Ptr;
+ Vals : Memory_Ptr;
+ begin
+ Set_Indiv_Signal_Assoc_Flag (Inst);
+
+ Sigs := Alloc_Signal_Memory (Typ, Instance_Pool);
+ for I in Assocs'Range loop
+ declare
+ A : Assoc_Record renames Assocs (I);
+ begin
+ -- TODO: individual assoc using individual assoc formal.
+ Copy_Memory
+ (Sig_Index (Sigs, A.Form_Off.Net_Off),
+ Sig_Index (Exec_Sig_Sig (A.Act_Base.Val), A.Act_Off.Net_Off),
+ Size_Type (A.Act_Typ.W) * Sig_Size);
+ end;
+ end loop;
+
+ Vals := Alloc_Memory (Typ, Instance_Pool);
+ Update_Sig_Val (Typ, Sigs, Vals);
+
+ return Create_Value_Sig_Val (Sigs, Vals, Typ, Instance_Pool);
+ end Hook_Create_Value_For_Signal_Individual_Assocs;
+
+ procedure Create_Terminals is
begin
for I in Terminal_Table.First .. Terminal_Table.Last loop
declare
@@ -3588,6 +3781,9 @@ package body Simul.Vhdl_Simul is
Synth.Vhdl_Expr.Hook_Signal_Expr := Hook_Signal_Expr'Access;
Synth.Vhdl_Expr.Hook_Event_Attribute := Exec_Event_Attribute'Access;
Synth.Vhdl_Expr.Hook_Active_Attribute := Exec_Active_Attribute'Access;
+ Synth.Vhdl_Expr.Hook_Driving_Attribute := Exec_Driving_Attribute'Access;
+ Synth.Vhdl_Expr.Hook_Driving_Value_Attribute :=
+ Exec_Driving_Value_Attribute'Access;
Synth.Vhdl_Expr.Hook_Last_Value_Attribute :=
Exec_Last_Value_Attribute'Access;
Synth.Vhdl_Expr.Hook_Last_Event_Attribute :=
@@ -3606,6 +3802,9 @@ package body Simul.Vhdl_Simul is
Synth.Vhdl_Static_Proc.Hook_Finish := Exec_Finish'Access;
+ Synth.Vhdl_Stmts.Hook_Create_Value_For_Signal_Individual_Assocs :=
+ Hook_Create_Value_For_Signal_Individual_Assocs'Access;
+
-- if Flag_Interractive then
-- Debug (Reason_Elab);
-- end if;
diff --git a/src/synth/elab-vhdl_context.adb b/src/synth/elab-vhdl_context.adb
index 136cc50f0..56de0563e 100644
--- a/src/synth/elab-vhdl_context.adb
+++ b/src/synth/elab-vhdl_context.adb
@@ -53,6 +53,7 @@ package body Elab.Vhdl_Context is
new Synth_Instance_Type'(Max_Objs => Global_Info.Nbr_Objects,
Is_Const => False,
Is_Error => False,
+ Flag1 | Flag2 => False,
Id => Inst_Tables.Last + 1,
Block_Scope => Global_Info,
Up_Block => null,
@@ -101,6 +102,7 @@ package body Elab.Vhdl_Context is
Res := new Synth_Instance_Type'(Max_Objs => Nbr_Objs,
Is_Const => False,
Is_Error => False,
+ Flag1 | Flag2 => False,
Id => Inst_Tables.Last + 1,
Block_Scope => Scope,
Up_Block => Parent,
@@ -142,6 +144,7 @@ package body Elab.Vhdl_Context is
Res := new Synth_Instance_Type'(Max_Objs => Object_Slot_Type (Len),
Is_Const => False,
Is_Error => False,
+ Flag1 | Flag2 => False,
Id => Inst_Tables.Last + 1,
Block_Scope => Info,
Up_Block => Parent,
@@ -237,6 +240,28 @@ package body Elab.Vhdl_Context is
return Inst.Foreign;
end Get_Instance_Foreign;
+ procedure Set_Indiv_Signal_Assoc_Flag (Inst : Synth_Instance_Acc) is
+ begin
+ Inst.Flag1 := True;
+ end Set_Indiv_Signal_Assoc_Flag;
+
+ function Get_Indiv_Signal_Assoc_Flag (Inst : Synth_Instance_Acc)
+ return Boolean is
+ begin
+ return Inst.Flag1;
+ end Get_Indiv_Signal_Assoc_Flag;
+
+ procedure Set_Indiv_Signal_Assoc_Parent_Flag (Inst : Synth_Instance_Acc) is
+ begin
+ Inst.Flag2 := True;
+ end Set_Indiv_Signal_Assoc_Parent_Flag;
+
+ function Get_Indiv_Signal_Assoc_Parent_Flag (Inst : Synth_Instance_Acc)
+ return Boolean is
+ begin
+ return Inst.Flag2;
+ end Get_Indiv_Signal_Assoc_Parent_Flag;
+
procedure Add_Extra_Instance (Inst : Synth_Instance_Acc;
Extra : Synth_Instance_Acc) is
begin
@@ -590,15 +615,21 @@ package body Elab.Vhdl_Context is
end case;
end Get_Instance_By_Scope;
- function Get_Parent_Scope (Blk : Node) return Sim_Info_Acc
+ function Get_Info_Scope (Blk : Node) return Sim_Info_Acc
is
- Parent : Node;
+ N : Node;
begin
- Parent := Get_Parent (Blk);
- if Get_Kind (Parent) = Iir_Kind_Architecture_Body then
- Parent := Vhdl.Utils.Get_Entity (Parent);
+ if Get_Kind (Blk) = Iir_Kind_Architecture_Body then
+ N := Vhdl.Utils.Get_Entity (Blk);
+ else
+ N := Blk;
end if;
- return Get_Info (Parent);
+ return Get_Info (N);
+ end Get_Info_Scope;
+
+ function Get_Parent_Scope (Blk : Node) return Sim_Info_Acc is
+ begin
+ return Get_Info_Scope (Get_Parent (Blk));
end Get_Parent_Scope;
function Get_Value (Syn_Inst: Synth_Instance_Acc; Obj : Node)
diff --git a/src/synth/elab-vhdl_context.ads b/src/synth/elab-vhdl_context.ads
index 8598bbf56..3a85cd089 100644
--- a/src/synth/elab-vhdl_context.ads
+++ b/src/synth/elab-vhdl_context.ads
@@ -74,6 +74,8 @@ package Elab.Vhdl_Context is
procedure Set_Error (Inst : Synth_Instance_Acc);
+ -- Get/Set the const flag.
+ -- This is for subprograms, and set when all parameters are static.
function Get_Instance_Const (Inst : Synth_Instance_Acc) return Boolean;
procedure Set_Instance_Const (Inst : Synth_Instance_Acc; Val : Boolean);
@@ -90,6 +92,19 @@ package Elab.Vhdl_Context is
procedure Set_Instance_Foreign (Inst : Synth_Instance_Acc; N : Int32);
function Get_Instance_Foreign (Inst : Synth_Instance_Acc) return Int32;
+ -- For simulation: set a flag if a signal parameter has individual
+ -- association. In that case, the value of the parameter must be
+ -- updated after a wait statement.
+ procedure Set_Indiv_Signal_Assoc_Flag (Inst : Synth_Instance_Acc);
+ function Get_Indiv_Signal_Assoc_Flag (Inst : Synth_Instance_Acc)
+ return Boolean;
+
+ -- For simulation: set if a parent has the Indiv_Signal_Assoc_Flag set.
+ -- In that case, update must continue in the parent.
+ procedure Set_Indiv_Signal_Assoc_Parent_Flag (Inst : Synth_Instance_Acc);
+ function Get_Indiv_Signal_Assoc_Parent_Flag (Inst : Synth_Instance_Acc)
+ return Boolean;
+
-- Add/Get extra instances.
-- Those instances are verification units.
procedure Add_Extra_Instance (Inst : Synth_Instance_Acc;
@@ -175,6 +190,9 @@ package Elab.Vhdl_Context is
function Get_Component_Instance
(Syn_Inst : Synth_Instance_Acc) return Synth_Instance_Acc;
+ -- Return the scope of BLK. Deals with architecture bodies.
+ function Get_Info_Scope (Blk : Node) return Sim_Info_Acc;
+
-- Return the scope of the parent of BLK. Deals with architecture bodies.
function Get_Parent_Scope (Blk : Node) return Sim_Info_Acc;
@@ -233,6 +251,13 @@ private
-- of this instance.
Is_Error : Boolean;
+ -- For simulation: set if a subprogram has a signal parameter
+ -- associated by individual elements.
+ Flag1 : Boolean;
+
+ -- For simulation: set if a parent instance has Flag1 set.
+ Flag2 : Boolean;
+
Id : Instance_Id_Type;
-- The corresponding info for this instance.
diff --git a/src/synth/elab-vhdl_debug.adb b/src/synth/elab-vhdl_debug.adb
index d47c310f0..e5e40011e 100644
--- a/src/synth/elab-vhdl_debug.adb
+++ b/src/synth/elab-vhdl_debug.adb
@@ -280,6 +280,8 @@ package body Elab.Vhdl_Debug is
Disp_Memtyp (Get_Memtyp (Vt), Vtype);
when Value_Dyn_Alias =>
Put ("dyn alias");
+ when Value_Sig_Val =>
+ Put ("sig val");
when Value_Memory =>
Disp_Memtyp (Get_Memtyp (Vt), Vtype);
end case;
diff --git a/src/synth/elab-vhdl_expr.adb b/src/synth/elab-vhdl_expr.adb
index ee15c7e52..d9ad9f27d 100644
--- a/src/synth/elab-vhdl_expr.adb
+++ b/src/synth/elab-vhdl_expr.adb
@@ -23,6 +23,7 @@ with Str_Table;
with Netlists;
with Vhdl.Errors; use Vhdl.Errors;
+with Vhdl.Scanner;
with Vhdl.Utils; use Vhdl.Utils;
with Vhdl.Evaluation; use Vhdl.Evaluation;
@@ -36,7 +37,9 @@ with Synth.Vhdl_Eval; use Synth.Vhdl_Eval;
with Synth.Errors; use Synth.Errors;
with Grt.Types;
+with Grt.Vhdl_Types;
with Grt.To_Strings;
+with Grt.Vstrings;
package body Elab.Vhdl_Expr is
function Synth_Bounds_From_Length (Atype : Node; Len : Int32)
@@ -124,17 +127,48 @@ package body Elab.Vhdl_Expr is
end if;
declare
- Str : constant String := Value_To_String (V);
+ Value : constant String := Value_To_String (V);
+ First, Last : Integer;
Res_N : Node;
Val : Int64;
begin
+ -- LRM93 14.1 Predefined attributes.
+ -- Leading and trailing whitespace are ignored.
+ First := Value'First;
+ Last := Value'Last;
+ while First <= Last loop
+ exit when not Vhdl.Scanner.Is_Whitespace (Value (First));
+ First := First + 1;
+ end loop;
+ while Last >= First loop
+ exit when not Vhdl.Scanner.Is_Whitespace (Value (Last));
+ Last := Last - 1;
+ end loop;
+
case Get_Kind (Btype) is
when Iir_Kind_Enumeration_Type_Definition =>
- Res_N := Eval_Value_Attribute (Str, Etype, Attr);
+ Res_N := Eval_Value_Attribute
+ (Value (First .. Last), Etype, Attr);
Val := Int64 (Get_Enum_Pos (Res_N));
Free_Iir (Res_N);
when Iir_Kind_Integer_Type_Definition =>
- Val := Int64'Value (Str);
+ declare
+ use Grt.To_Strings;
+ use Grt.Types;
+ use Grt.Vhdl_Types;
+ Value1 : String renames Value (First .. Last);
+ Res : Value_I64_Result;
+ begin
+ Res := Value_I64 (To_Std_String_Basep (Value1'Address),
+ Value1'Length, 0);
+ if Res.Status = Value_Ok then
+ Val := Int64 (Res.Val);
+ else
+ Error_Msg_Synth
+ (Syn_Inst, Attr, "incorrect 'value string");
+ return No_Valtyp;
+ end if;
+ end;
when others =>
Error_Msg_Elab (+Attr, "unhandled type for 'value");
return No_Valtyp;
@@ -420,4 +454,92 @@ package body Elab.Vhdl_Expr is
return Res;
end Exec_String_Literal;
+ function Exec_Path_Instance_Name_Attribute
+ (Inst : Synth_Instance_Acc; Attr : Iir) return Memtyp
+ is
+ use Grt.Vstrings;
+ use Name_Table;
+
+ Is_Instance : constant Boolean :=
+ Get_Kind (Attr) = Iir_Kind_Instance_Name_Attribute;
+
+ Atype : constant Node := Get_Type (Attr);
+ Str_Typ : constant Type_Acc := Get_Subtype_Object (Inst, Atype);
+ Name : constant Path_Instance_Name_Type :=
+ Get_Path_Instance_Name_Suffix (Attr);
+ Instance, Parent : Synth_Instance_Acc;
+ Rstr : Rstring;
+ Label : Node;
+ begin
+ if Name.Path_Instance = Null_Iir then
+ return String_To_Memtyp (Name.Suffix, Str_Typ);
+ end if;
+
+ Instance := Get_Instance_By_Scope
+ (Inst, Get_Info_Scope (Name.Path_Instance));
+
+ loop
+ Parent := Get_Instance_Parent (Instance);
+ if Parent = Root_Instance then
+ Parent := null;
+ end if;
+ Label := Get_Source_Scope (Instance);
+
+ case Get_Kind (Label) is
+ when Iir_Kind_Entity_Declaration =>
+ if Parent = null then
+ Prepend (Rstr, Image (Get_Identifier (Label)));
+ exit;
+ end if;
+ when Iir_Kind_Architecture_Body =>
+ if Is_Instance then
+ Prepend (Rstr, ')');
+ Prepend (Rstr, Image (Get_Identifier (Label)));
+ Prepend (Rstr, '(');
+ end if;
+
+ if Is_Instance or else Parent = null then
+ Prepend (Rstr, Image (Get_Identifier (Get_Entity (Label))));
+ end if;
+ if Parent = null then
+ Prepend (Rstr, ':');
+ exit;
+ end if;
+ when Iir_Kind_Block_Statement =>
+ Prepend (Rstr, Image (Get_Label (Label)));
+ Prepend (Rstr, ':');
+ when Iir_Kind_Iterator_Declaration =>
+ declare
+ Val : Valtyp;
+ begin
+ Val := Get_Value (Instance, Label);
+ Prepend (Rstr, ')');
+ Prepend (Rstr,
+ Synth_Image_Attribute_Str (Val, Get_Type (Label)));
+ Prepend (Rstr, '(');
+ end;
+ when Iir_Kind_Generate_Statement_Body =>
+ Prepend (Rstr, Image (Get_Label (Get_Parent (Label))));
+ Prepend (Rstr, ':');
+ when Iir_Kind_Component_Instantiation_Statement =>
+ if Is_Instance then
+ Prepend (Rstr, '@');
+ end if;
+ Prepend (Rstr, Image (Get_Label (Label)));
+ Prepend (Rstr, ':');
+ when others =>
+ Error_Kind ("Execute_Path_Instance_Name_Attribute",
+ Label);
+ end case;
+ Instance := Parent;
+ end loop;
+ declare
+ Str1 : String (1 .. Length (Rstr));
+ Len1 : Natural;
+ begin
+ Copy (Rstr, Str1, Len1);
+ Free (Rstr);
+ return String_To_Memtyp (Str1 & ':' & Name.Suffix, Str_Typ);
+ end;
+ end Exec_Path_Instance_Name_Attribute;
end Elab.Vhdl_Expr;
diff --git a/src/synth/elab-vhdl_expr.ads b/src/synth/elab-vhdl_expr.ads
index 3ef89d02c..244f89154 100644
--- a/src/synth/elab-vhdl_expr.ads
+++ b/src/synth/elab-vhdl_expr.ads
@@ -55,6 +55,8 @@ package Elab.Vhdl_Expr is
return Valtyp;
function Exec_Instance_Name_Attribute
(Syn_Inst : Synth_Instance_Acc; Attr : Node) return Valtyp;
+ function Exec_Path_Instance_Name_Attribute
+ (Inst : Synth_Instance_Acc; Attr : Iir) return Memtyp;
function Exec_Simple_Aggregate (Syn_Inst : Synth_Instance_Acc;
Aggr : Node) return Valtyp;
diff --git a/src/synth/elab-vhdl_insts.adb b/src/synth/elab-vhdl_insts.adb
index be7d5a7d5..389a816a4 100644
--- a/src/synth/elab-vhdl_insts.adb
+++ b/src/synth/elab-vhdl_insts.adb
@@ -910,11 +910,17 @@ package body Elab.Vhdl_Insts is
Em : Mark_Type;
Val : Valtyp;
Inter_Typ : Type_Acc;
+ Defval : Node;
begin
Mark_Expr_Pool (Em);
Inter_Typ := Elab_Declaration_Type (Top_Inst, Inter);
- Val := Synth_Expression_With_Type
- (Top_Inst, Get_Default_Value (Inter), Inter_Typ);
+ Defval := Get_Default_Value (Inter);
+ if Defval /= Null_Node then
+ Val := Synth_Expression_With_Type (Top_Inst, Defval, Inter_Typ);
+ else
+ -- Only for simulation, expect override.
+ Val := Create_Value_Default (Inter_Typ);
+ end if;
pragma Assert (Is_Static (Val.Val));
Val := Unshare (Val, Instance_Pool);
Val.Typ := Unshare_Type_Instance (Val.Typ, Inter_Typ);
diff --git a/src/synth/elab-vhdl_values-debug.adb b/src/synth/elab-vhdl_values-debug.adb
index aec0b1e20..c995c0204 100644
--- a/src/synth/elab-vhdl_values-debug.adb
+++ b/src/synth/elab-vhdl_values-debug.adb
@@ -324,6 +324,9 @@ package body Elab.Vhdl_Values.Debug is
when Value_Dyn_Alias =>
Put ("dyn alias: ");
Debug_Typ1 (V.Typ);
+ when Value_Sig_Val =>
+ Put ("sig val: ");
+ Debug_Typ1 (V.Typ);
end case;
end Debug_Valtyp;
diff --git a/src/synth/elab-vhdl_values.adb b/src/synth/elab-vhdl_values.adb
index 045fcce2e..deb0d0ccb 100644
--- a/src/synth/elab-vhdl_values.adb
+++ b/src/synth/elab-vhdl_values.adb
@@ -34,6 +34,7 @@ package body Elab.Vhdl_Values is
| Value_Wire
| Value_Signal
| Value_Dyn_Alias
+ | Value_Sig_Val
| Value_Quantity
| Value_Terminal =>
return False;
@@ -268,6 +269,26 @@ package body Elab.Vhdl_Values is
end if;
end Strip_Const;
+ function Create_Value_Sig_Val (Sigs : Memory_Ptr;
+ Vals : Memory_Ptr;
+ Pool : Areapool_Acc) return Value_Acc
+ is
+ subtype Value_Type_Sig_Val is Value_Type (Value_Sig_Val);
+ function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Sig_Val);
+ begin
+ return To_Value_Acc (Alloc (Pool, (Kind => Value_Sig_Val,
+ I_Sigs => Sigs,
+ I_Vals => Vals)));
+ end Create_Value_Sig_Val;
+
+ function Create_Value_Sig_Val (Sigs : Memory_Ptr;
+ Vals : Memory_Ptr;
+ Typ : Type_Acc;
+ Pool : Areapool_Acc) return Valtyp is
+ begin
+ return (Typ, Create_Value_Sig_Val (Sigs, Vals, Pool));
+ end Create_Value_Sig_Val;
+
procedure Write_Value (Dest : Memory_Ptr; Vt : Valtyp)
is
Mt : Memtyp;
@@ -315,6 +336,8 @@ package body Elab.Vhdl_Values is
Src.Val.D_Poff, Src.Val.D_Ptyp,
Src.Val.D_Voff, Src.Val.D_Eoff,
Current_Pool));
+ when Value_Sig_Val =>
+ raise Internal_Error;
end case;
return Res;
end Copy;
@@ -545,7 +568,8 @@ package body Elab.Vhdl_Values is
when Value_Net
| Value_Wire
| Value_Signal
- | Value_Dyn_Alias =>
+ | Value_Dyn_Alias
+ | Value_Sig_Val =>
raise Internal_Error;
when Value_Memory =>
return (V.Typ, V.Val.Mem);
diff --git a/src/synth/elab-vhdl_values.ads b/src/synth/elab-vhdl_values.ads
index 4ed86da22..0e72fd128 100644
--- a/src/synth/elab-vhdl_values.ads
+++ b/src/synth/elab-vhdl_values.ads
@@ -60,7 +60,10 @@ package Elab.Vhdl_Values is
Value_Alias,
-- Used only for associations.
- Value_Dyn_Alias
+ Value_Dyn_Alias,
+
+ -- Used only for individual signal associations in simulation
+ Value_Sig_Val
);
type Value_Type (Kind : Value_Kind);
@@ -114,6 +117,9 @@ package Elab.Vhdl_Values is
D_Ptyp : Type_Acc; -- Type of the prefix (after offset).
D_Voff : Uns32; -- Variable offset
D_Eoff : Uns32; -- Fixed offset.
+ when Value_Sig_Val =>
+ I_Sigs : Memory_Ptr;
+ I_Vals : Memory_Ptr;
end case;
end record;
@@ -187,6 +193,11 @@ package Elab.Vhdl_Values is
function Create_Value_Const (Val : Valtyp; Loc : Node; Pool : Areapool_Acc)
return Valtyp;
+ function Create_Value_Sig_Val (Sigs : Memory_Ptr;
+ Vals : Memory_Ptr;
+ Typ : Type_Acc;
+ Pool : Areapool_Acc) return Valtyp;
+
-- If VAL is a const, replace it by its value.
procedure Strip_Const (Vt : in out Valtyp);
diff --git a/src/synth/synth-vhdl_context.adb b/src/synth/synth-vhdl_context.adb
index 81143bea9..7d05e203a 100644
--- a/src/synth/synth-vhdl_context.adb
+++ b/src/synth/synth-vhdl_context.adb
@@ -464,7 +464,8 @@ package body Synth.Vhdl_Context is
return True;
when Value_Net
| Value_Signal
- | Value_Dyn_Alias =>
+ | Value_Dyn_Alias
+ | Value_Sig_Val =>
return False;
when Value_Quantity
| Value_Terminal =>
diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb
index 036e5a27e..6e397aa1a 100644
--- a/src/synth/synth-vhdl_expr.adb
+++ b/src/synth/synth-vhdl_expr.adb
@@ -2060,6 +2060,7 @@ package body Synth.Vhdl_Expr is
Res := Synth_Name (Syn_Inst, Expr);
if Res.Val /= null then
if (Res.Val.Kind = Value_Signal
+ or else Res.Val.Kind = Value_Sig_Val
or else (Res.Val.Kind = Value_Alias
and then Res.Val.A_Obj.Kind = Value_Signal))
then
@@ -2316,6 +2317,7 @@ package body Synth.Vhdl_Expr is
declare
Param : constant Node := Get_Parameter (Expr);
V : Valtyp;
+ Vi : Int64;
Dtype : Type_Acc;
begin
Dtype := Get_Subtype_Object (Syn_Inst, Get_Type (Expr));
@@ -2323,10 +2325,16 @@ package body Synth.Vhdl_Expr is
-- FIXME: to be generalized. Not always as simple as a
-- subtype conversion.
if Is_Static (V.Val) then
- V := Create_Value_Discrete (Read_Discrete (V), Dtype);
+ Vi := Read_Discrete (V);
+ if not In_Range (Dtype.Drange, Vi) then
+ Error_Msg_Synth (Syn_Inst, Expr, "value out of range");
+ return No_Valtyp;
+ end if;
+ return Create_Value_Discrete (Vi, Dtype);
+ else
+ return Synth_Subtype_Conversion
+ (Syn_Inst, V, Dtype, False, Expr);
end if;
- return Synth_Subtype_Conversion
- (Syn_Inst, V, Dtype, False, Expr);
end;
when Iir_Kind_Low_Type_Attribute =>
return Synth_Low_High_Type_Attribute (Syn_Inst, Expr, Dir_To);
@@ -2366,9 +2374,15 @@ package body Synth.Vhdl_Expr is
return Elab.Vhdl_Expr.Exec_Value_Attribute (Syn_Inst, Expr);
when Iir_Kind_Image_Attribute =>
return Elab.Vhdl_Expr.Exec_Image_Attribute (Syn_Inst, Expr);
- when Iir_Kind_Instance_Name_Attribute =>
- return Elab.Vhdl_Expr.Exec_Instance_Name_Attribute
- (Syn_Inst, Expr);
+ when Iir_Kind_Path_Name_Attribute
+ | Iir_Kind_Instance_Name_Attribute =>
+ declare
+ Mt : Memtyp;
+ begin
+ Mt := Elab.Vhdl_Expr.Exec_Path_Instance_Name_Attribute
+ (Syn_Inst, Expr);
+ return Create_Value_Memtyp (Mt);
+ end;
when Iir_Kind_Null_Literal =>
return Create_Value_Access (Null_Heap_Index, Expr_Type);
when Iir_Kind_Allocator_By_Subtype =>
@@ -2422,6 +2436,19 @@ package body Synth.Vhdl_Expr is
end if;
Error_Msg_Synth (Syn_Inst, Expr, "active attribute not allowed");
return No_Valtyp;
+ when Iir_Kind_Driving_Attribute =>
+ if Hook_Driving_Attribute /= null then
+ return Hook_Driving_Attribute (Syn_Inst, Expr);
+ end if;
+ Error_Msg_Synth (Syn_Inst, Expr, "driving attribute not allowed");
+ return No_Valtyp;
+ when Iir_Kind_Driving_Value_Attribute =>
+ if Hook_Driving_Value_Attribute /= null then
+ return Hook_Driving_Value_Attribute (Syn_Inst, Expr);
+ end if;
+ Error_Msg_Synth (Syn_Inst, Expr,
+ "driving_value attribute not allowed");
+ return No_Valtyp;
when Iir_Kind_Last_Value_Attribute =>
if Hook_Last_Value_Attribute /= null then
return Hook_Last_Value_Attribute (Syn_Inst, Expr);
diff --git a/src/synth/synth-vhdl_expr.ads b/src/synth/synth-vhdl_expr.ads
index 74412fe22..c991f388a 100644
--- a/src/synth/synth-vhdl_expr.ads
+++ b/src/synth/synth-vhdl_expr.ads
@@ -89,6 +89,8 @@ package Synth.Vhdl_Expr is
function (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Valtyp;
Hook_Event_Attribute : Hook_Attribute_Acc;
Hook_Active_Attribute : Hook_Attribute_Acc;
+ Hook_Driving_Attribute : Hook_Attribute_Acc;
+ Hook_Driving_Value_Attribute : Hook_Attribute_Acc;
Hook_Last_Value_Attribute : Hook_Attribute_Acc;
Hook_Last_Event_Attribute : Hook_Attribute_Acc;
Hook_Last_Active_Attribute : Hook_Attribute_Acc;
diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb
index fc9788f78..88f023354 100644
--- a/src/synth/synth-vhdl_insts.adb
+++ b/src/synth/synth-vhdl_insts.adb
@@ -230,7 +230,8 @@ package body Synth.Vhdl_Insts is
| Value_File
| Value_Quantity
| Value_Terminal
- | Value_Dyn_Alias =>
+ | Value_Dyn_Alias
+ | Value_Sig_Val =>
raise Internal_Error;
end case;
end Hash_Const;
diff --git a/src/synth/synth-vhdl_oper.adb b/src/synth/synth-vhdl_oper.adb
index b46a8ec57..5d5d9cb5c 100644
--- a/src/synth/synth-vhdl_oper.adb
+++ b/src/synth/synth-vhdl_oper.adb
@@ -1449,6 +1449,7 @@ package body Synth.Vhdl_Oper is
| Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Log
| Iir_Predefined_Ieee_Numeric_Std_Add_Sgn_Log
| Iir_Predefined_Ieee_Numeric_Std_Add_Log_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Slv_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Log
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Log_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Slv_Slv
@@ -1466,7 +1467,8 @@ package body Synth.Vhdl_Oper is
| Iir_Predefined_Ieee_Std_Logic_Arith_Add_Log_Sgn_Slv =>
-- "+" (Unsigned, Unsigned)
return Synth_Dyadic_Uns_Uns (Ctxt, Id_Add, L, R, Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat =>
+ when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Slv_Nat =>
-- "+" (Unsigned, Natural)
return Synth_Dyadic_Uns_Nat (Ctxt, Id_Add, L, R, Expr);
when Iir_Predefined_Ieee_Std_Logic_Arith_Add_Uns_Int_Slv
@@ -1475,6 +1477,7 @@ package body Synth.Vhdl_Oper is
-- "+" (Unsigned, Integer)
return Synth_Dyadic_Sgn_Int (Ctxt, Id_Add, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Add_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Add_Nat_Slv
| Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Uns_Uns
| Iir_Predefined_Ieee_Std_Logic_Arith_Add_Int_Uns_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Add_Int_Slv =>
@@ -1511,6 +1514,7 @@ package body Synth.Vhdl_Oper is
| Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Log
| Iir_Predefined_Ieee_Numeric_Std_Sub_Sgn_Log
| Iir_Predefined_Ieee_Numeric_Std_Sub_Log_Sgn
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Slv_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Log_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Slv_Log
@@ -1534,7 +1538,8 @@ package body Synth.Vhdl_Oper is
| Iir_Predefined_Ieee_Std_Logic_Signed_Sub_Slv_Slv =>
-- "-" (Signed, Signed)
return Synth_Dyadic_Sgn_Sgn (Ctxt, Id_Sub, L, R, Expr);
- when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat =>
+ when Iir_Predefined_Ieee_Numeric_Std_Sub_Uns_Nat
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Slv_Nat =>
-- "-" (Unsigned, Natural)
return Synth_Dyadic_Uns_Nat (Ctxt, Id_Sub, L, R, Expr);
when Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Uns_Int_Uns
@@ -1543,6 +1548,7 @@ package body Synth.Vhdl_Oper is
-- "-" (Unsigned, Integer)
return Synth_Dyadic_Sgn_Int (Ctxt, Id_Sub, L, R, Expr);
when Iir_Predefined_Ieee_Numeric_Std_Sub_Nat_Uns
+ | Iir_Predefined_Ieee_Numeric_Std_Unsigned_Sub_Nat_Slv
| Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Uns_Uns
| Iir_Predefined_Ieee_Std_Logic_Arith_Sub_Int_Uns_Slv
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Sub_Int_Slv =>
@@ -1985,7 +1991,8 @@ package body Synth.Vhdl_Oper is
| Iir_Predefined_Ieee_Numeric_Std_To_01_Uns
| Iir_Predefined_Ieee_Numeric_Std_To_01_Sgn
| Iir_Predefined_Ieee_1164_To_X01_Slv
- | Iir_Predefined_Ieee_1164_To_UX01_Slv =>
+ | Iir_Predefined_Ieee_1164_To_UX01_Slv
+ | Iir_Predefined_Ieee_1164_To_X01Z_Slv =>
if Is_Static (L.Val) then
raise Internal_Error;
end if;
@@ -1994,6 +2001,7 @@ package body Synth.Vhdl_Oper is
when Iir_Predefined_Ieee_1164_To_Bit
| Iir_Predefined_Ieee_1164_To_X01_Log
| Iir_Predefined_Ieee_1164_To_UX01_Log
+ | Iir_Predefined_Ieee_1164_To_X01Z_Log
| Iir_Predefined_Ieee_1164_To_Stdulogic =>
-- A no-op.
return Create_Value_Net (Get_Net (Ctxt, L), Res_Typ);
diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb
index 58e04afad..bba8c823b 100644
--- a/src/synth/synth-vhdl_stmts.adb
+++ b/src/synth/synth-vhdl_stmts.adb
@@ -466,7 +466,8 @@ package body Synth.Vhdl_Stmts is
-- Need to reverse offsets.
Copy_Memory
(Res.Val.Mem,
- Val.Val.Mem + (Val.Typ.Sz - Size_Type (Off + 1) * El_Typ.Sz),
+ Val.Val.Mem
+ + (Val.Typ.Sz - Typ.Sz - Size_Type (Off) * El_Typ.Sz),
Typ.Sz);
return Res;
end;
@@ -769,7 +770,8 @@ package body Synth.Vhdl_Stmts is
| Value_Const
| Value_Alias
| Value_Dyn_Alias
- | Value_Signal =>
+ | Value_Signal
+ | Value_Sig_Val =>
raise Internal_Error;
end case;
when Target_Aggregate =>
@@ -2030,17 +2032,6 @@ package body Synth.Vhdl_Stmts is
return Count;
end Count_Individual_Associations;
- type Assoc_Record is record
- Formal : Node;
- Form_Off : Value_Offsets;
-
- Act_Base : Valtyp;
- Act_Typ : Type_Acc;
- Act_Off : Value_Offsets;
- Act_Dyn : Dyn_Name;
- end record;
-
- type Assoc_Array is array (Natural range <>) of Assoc_Record;
type Assoc_Array_Acc is access Assoc_Array;
procedure Free_Assoc_Array is new Ada.Unchecked_Deallocation
(Assoc_Array, Assoc_Array_Acc);
@@ -2144,18 +2135,24 @@ package body Synth.Vhdl_Stmts is
A.Act_Typ.Sz);
end;
end loop;
- declare
- D : Destroy_Type;
- begin
- Destroy_Init (D, Subprg_Inst);
- Destroy_Object (D, Inter);
- Destroy_Finish (D);
- end;
+ elsif Flags.Flag_Simulation then
+ Res := Hook_Create_Value_For_Signal_Individual_Assocs
+ (Subprg_Inst, Assocs.all, Formal_Typ);
else
Res := No_Valtyp;
raise Internal_Error;
end if;
+ -- Destroy the object. It will be recreated by
+ -- Synth_Subprogram_Association.
+ declare
+ D : Destroy_Type;
+ begin
+ Destroy_Init (D, Subprg_Inst);
+ Destroy_Object (D, Inter);
+ Destroy_Finish (D);
+ end;
+
Free_Assoc_Array (Assocs);
return Res;
diff --git a/src/synth/synth-vhdl_stmts.ads b/src/synth/synth-vhdl_stmts.ads
index c07dc7224..ac9cd13d8 100644
--- a/src/synth/synth-vhdl_stmts.ads
+++ b/src/synth/synth-vhdl_stmts.ads
@@ -211,6 +211,25 @@ package Synth.Vhdl_Stmts is
Val : Valtyp;
Loc : Node);
+ type Assoc_Record is record
+ Formal : Node;
+ Form_Off : Value_Offsets;
+
+ Act_Base : Valtyp;
+ Act_Typ : Type_Acc;
+ Act_Off : Value_Offsets;
+ Act_Dyn : Dyn_Name;
+ end record;
+
+ type Assoc_Array is array (Natural range <>) of Assoc_Record;
+
+ -- For simulation: create a value for individual signal associations.
+ type Create_Value_For_Signal_Individual_Assocs_Acc is
+ access function (Inst : Synth_Instance_Acc;
+ Assocs : Assoc_Array;
+ Typ : Type_Acc) return Valtyp;
+ Hook_Create_Value_For_Signal_Individual_Assocs :
+ Create_Value_For_Signal_Individual_Assocs_Acc;
private
-- There are 2 execution mode:
diff --git a/src/vhdl/vhdl-canon.adb b/src/vhdl/vhdl-canon.adb
index 95f531cf8..8e4bfd588 100644
--- a/src/vhdl/vhdl-canon.adb
+++ b/src/vhdl/vhdl-canon.adb
@@ -362,6 +362,7 @@ package body Vhdl.Canon is
begin
We := Chain;
while We /= Null_Iir loop
+ exit when Get_Kind (We) = Iir_Kind_Unaffected_Waveform;
Canon_Extract_Sensitivity_Expression (Get_We_Value (We), List);
Canon_Extract_Sensitivity_If_Not_Null (Get_Time (We), List);
We := Get_Chain (We);