diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-10-13 04:01:58 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-10-13 04:01:58 +0200 |
commit | 10a478df597403fc6c5c268cdaa6ea4ee916a5ef (patch) | |
tree | acd477b6b9d20624b8da5690cedfd6420a685203 | |
parent | 26d6de24d7f93a1dde14ac457d67e3258b946c94 (diff) | |
download | ghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.tar.gz ghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.tar.bz2 ghdl-10a478df597403fc6c5c268cdaa6ea4ee916a5ef.zip |
simul: handle last_event and last_active
-rw-r--r-- | src/simul/simul-vhdl_simul.adb | 102 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.adb | 14 | ||||
-rw-r--r-- | src/synth/synth-vhdl_expr.ads | 2 |
3 files changed, 114 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; diff --git a/src/synth/synth-vhdl_expr.adb b/src/synth/synth-vhdl_expr.adb index 33e5ab8ce..3d2d2f3f8 100644 --- a/src/synth/synth-vhdl_expr.adb +++ b/src/synth/synth-vhdl_expr.adb @@ -2425,6 +2425,20 @@ package body Synth.Vhdl_Expr is Error_Msg_Synth (Syn_Inst, Expr, "last_value attribute not allowed"); return No_Valtyp; + when Iir_Kind_Last_Event_Attribute => + if Hook_Last_Event_Attribute /= null then + return Hook_Last_Event_Attribute (Syn_Inst, Expr); + end if; + Error_Msg_Synth (Syn_Inst, Expr, + "last_event attribute not allowed"); + return No_Valtyp; + when Iir_Kind_Last_Active_Attribute => + if Hook_Last_Active_Attribute /= null then + return Hook_Last_Active_Attribute (Syn_Inst, Expr); + end if; + Error_Msg_Synth (Syn_Inst, Expr, + "last_active attribute not allowed"); + return No_Valtyp; when Iir_Kind_Dot_Attribute => if Hook_Dot_Attribute /= null then return Hook_Dot_Attribute (Syn_Inst, Expr); diff --git a/src/synth/synth-vhdl_expr.ads b/src/synth/synth-vhdl_expr.ads index 941bae57b..74412fe22 100644 --- a/src/synth/synth-vhdl_expr.ads +++ b/src/synth/synth-vhdl_expr.ads @@ -90,6 +90,8 @@ package Synth.Vhdl_Expr is Hook_Event_Attribute : Hook_Attribute_Acc; Hook_Active_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; Hook_Dot_Attribute : Hook_Attribute_Acc; -- Use base type of EXPR to synthesize EXPR. Useful when the type of |