aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2023-01-18 18:19:18 +0100
committerTristan Gingold <tgingold@free.fr>2023-01-18 18:19:18 +0100
commitde7fe2bf3f78a2753809b4533fcc8575892fa000 (patch)
tree4670816b7e8c9fa789821679777a4eda77b01e6a /src
parent1b0c3819af5eb1f481db51e4dbdfd7e00757ddaf (diff)
downloadghdl-de7fe2bf3f78a2753809b4533fcc8575892fa000.tar.gz
ghdl-de7fe2bf3f78a2753809b4533fcc8575892fa000.tar.bz2
ghdl-de7fe2bf3f78a2753809b4533fcc8575892fa000.zip
simul: fix last_value for post vhdl 87
Diffstat (limited to 'src')
-rw-r--r--src/simul/simul-vhdl_debug.adb2
-rw-r--r--src/simul/simul-vhdl_simul.adb246
2 files changed, 145 insertions, 103 deletions
diff --git a/src/simul/simul-vhdl_debug.adb b/src/simul/simul-vhdl_debug.adb
index 33ffdb798..d4dde12f7 100644
--- a/src/simul/simul-vhdl_debug.adb
+++ b/src/simul/simul-vhdl_debug.adb
@@ -227,6 +227,8 @@ package body Simul.Vhdl_Debug is
Disp_Value (Sig.Value_Ptr, Sig.Mode, Stype);
Put ("; drv=");
Disp_Value (Sig.Driving_Value, Sig.Mode, Stype);
+ Put ("; last_val=");
+ Disp_Value (Sig.Last_Value, Sig.Mode, Stype);
if Sig.Nbr_Ports > 0 then
Put (';');
Put_Int32 (Int32 (Sig.Nbr_Ports));
diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb
index c03da08f1..d17ca0534 100644
--- a/src/simul/simul-vhdl_simul.adb
+++ b/src/simul/simul-vhdl_simul.adb
@@ -21,6 +21,7 @@ with Ada.Unchecked_Conversion;
with Simple_IO;
with Utils_IO;
+with Flags;
with Vhdl.Types;
with Vhdl.Errors;
@@ -2378,194 +2379,231 @@ package body Simul.Vhdl_Simul is
end case;
end Resolver_Read_Value;
- type Read_Signal_Enum is
+ type Read_Signal_Last_Enum is
(
- Read_Signal_Last_Value,
-
- -- For conversion functions.
- Read_Signal_Driving_Value,
- Read_Signal_Effective_Value,
-
- -- 'Driving_Value
- Read_Signal_Driver_Value
+ Read_Signal_Last_Event,
+ Read_Signal_Last_Active
);
- procedure Exec_Read_Signal (Sig: Memory_Ptr;
- Val : Memtyp;
- Attr : Read_Signal_Enum)
+ function Exec_Read_Signal_Last (Sig: Memory_Ptr;
+ Typ : Type_Acc;
+ Attr : Read_Signal_Last_Enum)
+ return Std_Time
is
+ Res, T : Std_Time;
S : Ghdl_Signal_Ptr;
begin
- case Val.Typ.Kind is
+ case Typ.Kind is
when Type_Scalars =>
S := Read_Sig (Sig);
case Attr is
- when Read_Signal_Driving_Value =>
- Write_Ghdl_Value (Val, S.Driving_Value);
- when Read_Signal_Effective_Value =>
- 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));
+ when Read_Signal_Last_Event =>
+ return S.Last_Event;
+ when Read_Signal_Last_Active =>
+ return S.Last_Active;
end case;
when Type_Vector
| Type_Array =>
declare
- Typ : constant Type_Acc := Val.Typ;
Len : constant Uns32 := Typ.Abound.Len;
+ Sigel : Memory_Ptr;
begin
+ Res := Std_Time'First;
for I in 1 .. Len loop
- Exec_Read_Signal
- (Sig_Index (Sig, (Len - I) * Typ.Arr_El.W),
- (Typ.Arr_El, Val.Mem + Size_Type (I - 1) * Typ.Arr_El.Sz),
- Attr);
+ Sigel := Sig_Index (Sig, (Len - I) * Typ.Arr_El.W);
+ T := Exec_Read_Signal_Last (Sigel, Typ.Arr_El, Attr);
+ Res := Std_Time'Max (Res, T);
end loop;
+ return Res;
end;
when Type_Record =>
- for I in Val.Typ.Rec.E'Range loop
+ Res := Std_Time'First;
+ for I in Typ.Rec.E'Range loop
declare
- E : Rec_El_Type renames Val.Typ.Rec.E (I);
+ E : Rec_El_Type renames Typ.Rec.E (I);
+ Sigel : Memory_Ptr;
begin
- Exec_Read_Signal (Sig_Index (Sig, E.Offs.Net_Off),
- (E.Typ, Val.Mem + E.Offs.Mem_Off),
- Attr);
+ Sigel := Sig_Index (Sig, E.Offs.Net_Off);
+ T := Exec_Read_Signal_Last (Sigel, E.Typ, Attr);
+ Res := Std_Time'Max (Res, T);
end;
end loop;
+ return Res;
when others =>
raise Internal_Error;
end case;
- end Exec_Read_Signal;
+ end Exec_Read_Signal_Last;
- function Exec_Signal_Value_Attribute (Inst : Synth_Instance_Acc;
- Attr : Node;
- Kind : Read_Signal_Enum) return Valtyp
+ function Exec_Signal_Last_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node;
+ Attr : Read_Signal_Last_Enum)
+ return Valtyp
is
Pfx : Target_Info;
Res : Valtyp;
+ T : Std_Time;
S : Memory_Ptr;
begin
- Pfx := Synth_Target (Inst, Get_Prefix (Attr));
-
- Res := Create_Value_Memory (Pfx.Targ_Type, Expr_Pool'Access);
+ Pfx := Synth_Target (Inst, Get_Prefix (Expr));
S := Sig_Index (Signals_Table.Table (Pfx.Obj.Val.S).Sig,
Pfx.Off.Net_Off);
- Exec_Read_Signal (S, Get_Memtyp (Res), Kind);
+ T := Exec_Read_Signal_Last (S, Pfx.Targ_Type, Attr);
+ if T < 0 then
+ T := Std_Time'Last;
+ else
+ T := Current_Time - T;
+ end if;
+
+ Res := Create_Value_Memory (Get_Subtype_Object (Inst, Get_Type (Expr)),
+ Expr_Pool'Access);
+ Write_I64 (Res.Val.Mem, Ghdl_I64 (T));
return Res;
- end Exec_Signal_Value_Attribute;
+ end Exec_Signal_Last_Attribute;
- function Exec_Last_Value_Attribute (Inst : Synth_Instance_Acc;
+ function Exec_Last_Event_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;
+ return Exec_Signal_Last_Attribute (Inst, Expr, Read_Signal_Last_Event);
+ end Exec_Last_Event_Attribute;
- function Exec_Driving_Value_Attribute (Inst : Synth_Instance_Acc;
- Expr : Node) return Valtyp is
+ function Exec_Last_Active_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;
+ return Exec_Signal_Last_Attribute (Inst, Expr, Read_Signal_Last_Active);
+ end Exec_Last_Active_Attribute;
- type Read_Signal_Last_Enum is
+ type Read_Signal_Enum is
(
- Read_Signal_Last_Event,
- Read_Signal_Last_Active
+ Read_Signal_Last_Value,
+ Read_Signal_Last_Value_87,
+
+ -- For conversion functions.
+ Read_Signal_Driving_Value,
+ Read_Signal_Effective_Value,
+
+ -- 'Driving_Value
+ Read_Signal_Driver_Value
);
- function Exec_Read_Signal_Last (Sig: Memory_Ptr;
- Val : Memtyp;
- Attr : Read_Signal_Last_Enum)
- return Std_Time
+ -- T is used only for last_value.
+ procedure Exec_Read_Signal (Sig: Memory_Ptr;
+ Val : Memtyp;
+ Attr : Read_Signal_Enum;
+ T : Std_Time)
is
- Res, T : Std_Time;
- S : Ghdl_Signal_Ptr;
begin
case Val.Typ.Kind is
when Type_Scalars =>
- S := Read_Sig (Sig);
- case Attr is
- when Read_Signal_Last_Event =>
- return S.Last_Event;
- when Read_Signal_Last_Active =>
- return S.Last_Active;
- end case;
+ declare
+ S : Ghdl_Signal_Ptr;
+ V : Value_Union;
+ begin
+ S := Read_Sig (Sig);
+ case Attr is
+ when Read_Signal_Driving_Value =>
+ V := S.Driving_Value;
+ when Read_Signal_Effective_Value =>
+ V := S.Value_Ptr.all;
+ when Read_Signal_Last_Value_87 =>
+ V := S.Last_Value;
+ when Read_Signal_Last_Value =>
+ if S.Last_Event < T then
+ V := S.Value_Ptr.all;
+ else
+ V := S.Last_Value;
+ end if;
+ when Read_Signal_Driver_Value =>
+ V := Ghdl_Signal_Driving_Value (S);
+ end case;
+ Write_Ghdl_Value (Val, V);
+ end;
when Type_Vector
| Type_Array =>
declare
Typ : constant Type_Acc := Val.Typ;
Len : constant Uns32 := Typ.Abound.Len;
begin
- Res := Std_Time'First;
for I in 1 .. Len loop
- T := Exec_Read_Signal_Last
+ Exec_Read_Signal
(Sig_Index (Sig, (Len - I) * Typ.Arr_El.W),
(Typ.Arr_El, Val.Mem + Size_Type (I - 1) * Typ.Arr_El.Sz),
- Attr);
- Res := Std_Time'Max (Res, T);
+ Attr, T);
end loop;
- return Res;
end;
when Type_Record =>
- Res := Std_Time'First;
for I in Val.Typ.Rec.E'Range loop
declare
E : Rec_El_Type renames Val.Typ.Rec.E (I);
begin
- T := Exec_Read_Signal_Last
- (Sig_Index (Sig, E.Offs.Net_Off),
- (E.Typ, Val.Mem + E.Offs.Mem_Off),
- Attr);
- Res := Std_Time'Max (Res, T);
+ Exec_Read_Signal (Sig_Index (Sig, E.Offs.Net_Off),
+ (E.Typ, Val.Mem + E.Offs.Mem_Off),
+ Attr, T);
end;
end loop;
- return Res;
when others =>
raise Internal_Error;
end case;
- end Exec_Read_Signal_Last;
+ end Exec_Read_Signal;
- function Exec_Signal_Last_Attribute (Inst : Synth_Instance_Acc;
- Expr : Node;
- Attr : Read_Signal_Last_Enum)
- 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;
- T : Std_Time;
S : Memory_Ptr;
begin
- Pfx := Synth_Target (Inst, Get_Prefix (Expr));
+ Pfx := Synth_Target (Inst, Get_Prefix (Attr));
- Res := Create_Value_Memory (Get_Subtype_Object (Inst, Get_Type (Expr)),
- Expr_Pool'Access);
+ 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);
- 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));
+ Exec_Read_Signal (S, Get_Memtyp (Res), Kind, 0);
return Res;
- end Exec_Signal_Last_Attribute;
+ end Exec_Signal_Value_Attribute;
- function Exec_Last_Event_Attribute (Inst : Synth_Instance_Acc;
- Expr : Node) return Valtyp is
+ function Exec_Last_Value_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp
+ is
+ use Flags;
+ T : Std_Time;
begin
- return Exec_Signal_Last_Attribute (Inst, Expr, Read_Signal_Last_Event);
- end Exec_Last_Event_Attribute;
+ if Vhdl_Std >= Vhdl_93 then
+ declare
+ Pfx : Target_Info;
+ Res : Valtyp;
+ S : Memory_Ptr;
+ begin
+ Pfx := Synth_Target (Inst, Get_Prefix (Expr));
- function Exec_Last_Active_Attribute (Inst : Synth_Instance_Acc;
- Expr : Node) return Valtyp is
+ S := Sig_Index (Signals_Table.Table (Pfx.Obj.Val.S).Sig,
+ Pfx.Off.Net_Off);
+
+ T := Exec_Read_Signal_Last
+ (S, Pfx.Targ_Type, Read_Signal_Last_Event);
+
+ Res := Create_Value_Memory (Pfx.Targ_Type, Expr_Pool'Access);
+
+ Exec_Read_Signal
+ (S, Get_Memtyp (Res), Read_Signal_Last_Value, T);
+ return Res;
+ end;
+ else
+ return Exec_Signal_Value_Attribute
+ (Inst, Expr, Read_Signal_Last_Value_87);
+ end if;
+ end Exec_Last_Value_Attribute;
+
+ function Exec_Driving_Value_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp is
begin
- return Exec_Signal_Last_Attribute (Inst, Expr, Read_Signal_Last_Active);
- end Exec_Last_Active_Attribute;
+ return Exec_Signal_Value_Attribute
+ (Inst, Expr, Read_Signal_Driver_Value);
+ end Exec_Driving_Value_Attribute;
type Write_Signal_Enum is
(Write_Signal_Driving_Value,
@@ -3378,9 +3416,11 @@ package body Simul.Vhdl_Simul is
Val := Create_Memory (Conv.Src_Typ);
case Conv.Mode is
when Convert_In =>
- Exec_Read_Signal (Conv.Src_Sig, Val, Read_Signal_Effective_Value);
+ Exec_Read_Signal
+ (Conv.Src_Sig, Val, Read_Signal_Effective_Value, 0);
when Convert_Out =>
- Exec_Read_Signal (Conv.Src_Sig, Val, Read_Signal_Driving_Value);
+ Exec_Read_Signal
+ (Conv.Src_Sig, Val, Read_Signal_Driving_Value, 0);
end case;
Dst_Val := Create_Value_Memory (Val, Current_Pool);