aboutsummaryrefslogtreecommitdiffstats
path: root/src/simul/simul-vhdl_simul.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-10-13 04:01:58 +0200
committerTristan Gingold <tgingold@free.fr>2022-10-13 04:01:58 +0200
commit10a478df597403fc6c5c268cdaa6ea4ee916a5ef (patch)
treeacd477b6b9d20624b8da5690cedfd6420a685203 /src/simul/simul-vhdl_simul.adb
parent26d6de24d7f93a1dde14ac457d67e3258b946c94 (diff)
downloadghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.tar.gz
ghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.tar.bz2
ghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.zip
simul: handle last_event and last_active
Diffstat (limited to 'src/simul/simul-vhdl_simul.adb')
-rw-r--r--src/simul/simul-vhdl_simul.adb102
1 files changed, 98 insertions, 4 deletions
diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb
index e0dd59b6b..f2525f17a 100644
--- a/src/simul/simul-vhdl_simul.adb
+++ b/src/simul/simul-vhdl_simul.adb
@@ -2062,10 +2062,7 @@ package body Simul.Vhdl_Simul is
S : Ghdl_Signal_Ptr;
begin
case Val.Typ.Kind is
- when Type_Bit
- | Type_Logic
- | Type_Discrete
- | Type_Float =>
+ when Type_Scalars =>
S := Read_Sig (Sig);
case Attr is
when Read_Signal_Driving_Value =>
@@ -2121,6 +2118,99 @@ package body Simul.Vhdl_Simul is
return Res;
end Exec_Last_Value_Attribute;
+ type Read_Signal_Last_Enum is
+ (
+ Read_Signal_Last_Event,
+ Read_Signal_Last_Active
+ );
+
+ function Exec_Read_Signal_Last (Sig: Memory_Ptr;
+ Val : Memtyp;
+ Attr : Read_Signal_Last_Enum)
+ return 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;
+ 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
+ (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);
+ 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);
+ end;
+ end loop;
+ return Res;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Exec_Read_Signal_Last;
+
+ 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 (Expr));
+
+ Res := Create_Value_Memory (Get_Subtype_Object (Inst, Get_Type (Expr)),
+ 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);
+ Write_I64 (Res.Val.Mem, Ghdl_I64 (T));
+ return Res;
+ end Exec_Signal_Last_Attribute;
+
+ function Exec_Last_Event_Attribute (Inst : Synth_Instance_Acc;
+ Expr : Node) return Valtyp is
+ begin
+ return Exec_Signal_Last_Attribute (Inst, Expr, Read_Signal_Last_Event);
+ end Exec_Last_Event_Attribute;
+
+ function Exec_Last_Active_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;
+
type Write_Signal_Enum is
(Write_Signal_Driving_Value,
Write_Signal_Effective_Value);
@@ -3453,6 +3543,10 @@ package body Simul.Vhdl_Simul is
Synth.Vhdl_Expr.Hook_Active_Attribute := Exec_Active_Attribute'Access;
Synth.Vhdl_Expr.Hook_Last_Value_Attribute :=
Exec_Last_Value_Attribute'Access;
+ Synth.Vhdl_Expr.Hook_Last_Event_Attribute :=
+ Exec_Last_Event_Attribute'Access;
+ Synth.Vhdl_Expr.Hook_Last_Active_Attribute :=
+ Exec_Last_Active_Attribute'Access;
Synth.Vhdl_Oper.Hook_Bit_Rising_Edge := Exec_Bit_Rising_Edge'Access;
Synth.Vhdl_Oper.Hook_Bit_Falling_Edge := Exec_Bit_Falling_Edge'Access;