diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-09-28 19:27:54 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-09-29 22:02:30 +0200 |
commit | 5b614ffd0bac865999dd537848115d1f67e170c8 (patch) | |
tree | d93d2fd02cb97db7a5ddcceb577faeae23415d64 /src | |
parent | 1d1db76d1129c1632d4bedde12cbc30d47501be5 (diff) | |
download | ghdl-5b614ffd0bac865999dd537848115d1f67e170c8.tar.gz ghdl-5b614ffd0bac865999dd537848115d1f67e170c8.tar.bz2 ghdl-5b614ffd0bac865999dd537848115d1f67e170c8.zip |
simul: support guarded signal assignments (WIP)
Diffstat (limited to 'src')
-rw-r--r-- | src/simul/simul-vhdl_simul.adb | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/src/simul/simul-vhdl_simul.adb b/src/simul/simul-vhdl_simul.adb index 6b78d4ab8..ba198c676 100644 --- a/src/simul/simul-vhdl_simul.adb +++ b/src/simul/simul-vhdl_simul.adb @@ -887,24 +887,85 @@ package body Simul.Vhdl_Simul is end loop; end Execute_Waveform_Assignment; + procedure Disconnect_Signal (Sig : Memtyp) + is + S : Ghdl_Signal_Ptr; + begin + case Sig.Typ.Kind is + when Type_Logic + | Type_Bit + | Type_Discrete + | Type_Float => + S := Read_Sig (Sig.Mem); + if S.Flags.Sig_Kind /= Kind_Signal_No then + Ghdl_Signal_Disconnect (S); + end if; + when Type_Vector + | Type_Array => + declare + Len : constant Uns32 := Sig.Typ.Abound.Len; + El : constant Type_Acc := Sig.Typ.Arr_El; + begin + for I in 1 .. Len loop + Disconnect_Signal + ((El, Sig_Index (Sig.Mem, (Len - I) * El.W))); + end loop; + end; + when Type_Record => + for I in Sig.Typ.Rec.E'Range loop + declare + E : Rec_El_Type renames Sig.Typ.Rec.E (I); + begin + Disconnect_Signal + ((E.Typ, Sig_Index (Sig.Mem, E.Offs.Net_Off))); + end; + end loop; + when others => + raise Internal_Error; + 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; + begin + Sig := (Target.Targ_Type, Sig_Index (E.Sig, Target.Off.Net_Off)); + Disconnect_Signal (Sig); + end Disconnect_Signal_Target; + procedure Execute_Simple_Signal_Assignment (Inst : Synth_Instance_Acc; - Stmt : Node) + Stmt : Node; + Concurrent : Boolean) is use Synth.Vhdl_Expr; Target : constant Node := Get_Target (Stmt); Marker : Mark_Type; Info : Target_Info; + Guard : Node; begin Mark_Expr_Pool (Marker); Info := Synth_Target (Inst, Target); + if Concurrent then + Guard := Get_Guard (Stmt); + if Guard /= Null_Node + and then not Execute_Condition (Inst, Guard) + then + Disconnect_Signal_Target (Info); + Release_Expr_Pool (Marker); + return; + end if; + end if; + Execute_Waveform_Assignment (Inst, Info, Stmt, Get_Waveform_Chain (Stmt)); Release_Expr_Pool (Marker); end Execute_Simple_Signal_Assignment; procedure Execute_Conditional_Signal_Assignment (Inst : Synth_Instance_Acc; - Stmt : Node) + Stmt : Node; + Concurrent : Boolean) is use Synth.Vhdl_Expr; Target : constant Node := Get_Target (Stmt); @@ -916,6 +977,10 @@ package body Simul.Vhdl_Simul is Mark_Expr_Pool (Marker); Info := Synth_Target (Inst, Target); + if Concurrent and then Get_Guard (Stmt) /= Null_Node then + raise Internal_Error; + end if; + Cw := Get_Conditional_Waveform_Chain (Stmt); while Cw /= Null_Node loop Cond := Get_Condition (Cw); @@ -932,7 +997,8 @@ package body Simul.Vhdl_Simul is end Execute_Conditional_Signal_Assignment; procedure Execute_Selected_Signal_Assignment (Inst : Synth_Instance_Acc; - Stmt : Node) + Stmt : Node; + Concurrent : Boolean) is use Synth.Vhdl_Expr; Target : constant Node := Get_Target (Stmt); @@ -946,6 +1012,10 @@ package body Simul.Vhdl_Simul is Mark_Expr_Pool (Marker); Info := Synth_Target (Inst, Target); + if Concurrent and then Get_Guard (Stmt) /= Null_Node then + raise Internal_Error; + end if; + Sel := Get_Memtyp (Synth_Expression (Inst, Get_Expression (Stmt))); Sw := Get_Selected_Waveform_Chain (Stmt); @@ -1224,10 +1294,10 @@ package body Simul.Vhdl_Simul is Next_Statement (Process, Stmt); when Iir_Kind_Simple_Signal_Assignment_Statement => - Execute_Simple_Signal_Assignment (Inst, Stmt); + Execute_Simple_Signal_Assignment (Inst, Stmt, False); Next_Statement (Process, Stmt); when Iir_Kind_Conditional_Signal_Assignment_Statement => - Execute_Conditional_Signal_Assignment (Inst, Stmt); + Execute_Conditional_Signal_Assignment (Inst, Stmt, False); Next_Statement (Process, Stmt); when Iir_Kind_Wait_Statement => @@ -1452,21 +1522,22 @@ package body Simul.Vhdl_Simul is if Elab.Debugger.Flag_Need_Debug then Elab.Debugger.Debug_Break (Process.Instance, Process.Proc); end if; - Execute_Simple_Signal_Assignment (Process.Instance, Process.Proc); + Execute_Simple_Signal_Assignment + (Process.Instance, Process.Proc, True); pragma Assert (Areapools.Is_Empty (Instance_Pool.all)); when Iir_Kind_Concurrent_Conditional_Signal_Assignment => if Elab.Debugger.Flag_Need_Debug then Elab.Debugger.Debug_Break (Process.Instance, Process.Proc); end if; Execute_Conditional_Signal_Assignment - (Process.Instance, Process.Proc); + (Process.Instance, Process.Proc, True); pragma Assert (Areapools.Is_Empty (Instance_Pool.all)); when Iir_Kind_Concurrent_Selected_Signal_Assignment => if Elab.Debugger.Flag_Need_Debug then Elab.Debugger.Debug_Break (Process.Instance, Process.Proc); end if; Execute_Selected_Signal_Assignment - (Process.Instance, Process.Proc); + (Process.Instance, Process.Proc, True); pragma Assert (Areapools.Is_Empty (Instance_Pool.all)); when Iir_Kind_Association_Element_By_Expression => if Elab.Debugger.Flag_Need_Debug then |