Skip to content

Commit 8bb2635

Browse files
committed
simul: handle selected signal assignments.
1 parent 787ef6f commit 8bb2635

2 files changed

Lines changed: 69 additions & 45 deletions

File tree

src/vhdl/simulate/simul-annotations.adb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ package body Simul.Annotations is
783783
when Iir_Kind_Return_Statement =>
784784
null;
785785
when Iir_Kind_Simple_Signal_Assignment_Statement
786+
| Iir_Kind_Selected_Waveform_Assignment_Statement
786787
| Iir_Kind_Variable_Assignment_Statement =>
787788
null;
788789
when Iir_Kind_Procedure_Call_Statement =>

src/vhdl/simulate/simul-execution.adb

Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,9 +4081,9 @@ package body Simul.Execution is
40814081

40824082
procedure Execute_Signal_Assignment
40834083
(Instance: Block_Instance_Acc;
4084-
Stmt: Iir_Signal_Assignment_Statement)
4084+
Stmt: Iir_Signal_Assignment_Statement;
4085+
Wf : Iir)
40854086
is
4086-
Wf : constant Iir_Waveform_Element := Get_Waveform_Chain (Stmt);
40874087
Nbr_We : constant Natural := Get_Chain_Length (Wf);
40884088

40894089
Transactions : Transaction_Type (Nbr_We);
@@ -4330,6 +4330,53 @@ package body Simul.Execution is
43304330
end case;
43314331
end Is_In_Choice;
43324332

4333+
function Execute_Choice (Instance : Block_Instance_Acc;
4334+
Expr : Iir;
4335+
First_Assoc : Iir) return Iir
4336+
is
4337+
Value: Iir_Value_Literal_Acc;
4338+
Assoc: Iir;
4339+
Assoc_Res : Iir;
4340+
Marker : Mark_Type;
4341+
begin
4342+
Mark (Marker, Expr_Pool);
4343+
Assoc := First_Assoc;
4344+
4345+
Value := Execute_Expression (Instance, Expr);
4346+
if Get_Type_Staticness (Get_Type (Expr)) /= Locally
4347+
and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression
4348+
then
4349+
-- Choice is not locally constrained, check length.
4350+
declare
4351+
Choice_Type : constant Iir :=
4352+
Get_Type (Get_Choice_Expression (Assoc));
4353+
Choice_Len : Iir_Int64;
4354+
begin
4355+
Choice_Len := Evaluation.Eval_Discrete_Type_Length
4356+
(Get_String_Type_Bound_Type (Choice_Type));
4357+
if Choice_Len /= Iir_Int64 (Value.Bounds.D (1).Length) then
4358+
Error_Msg_Constraint (Expr);
4359+
end if;
4360+
end;
4361+
end if;
4362+
4363+
while Assoc /= Null_Iir loop
4364+
if not Get_Same_Alternative_Flag (Assoc) then
4365+
Assoc_Res := Assoc;
4366+
end if;
4367+
4368+
if Is_In_Choice (Instance, Assoc, Value) then
4369+
Release (Marker, Expr_Pool);
4370+
return Assoc_Res;
4371+
end if;
4372+
4373+
Assoc := Get_Chain (Assoc);
4374+
end loop;
4375+
-- FIXME: infinite loop???
4376+
Error_Msg_Exec ("no choice for expression", Expr);
4377+
raise Internal_Error;
4378+
end Execute_Choice;
4379+
43334380
-- Return TRUE iff VAL is in the range defined by BOUNDS.
43344381
function Is_In_Range (Val : Iir_Value_Literal_Acc;
43354382
Bounds : Iir_Value_Literal_Acc)
@@ -4602,52 +4649,17 @@ package body Simul.Execution is
46024649
is
46034650
Instance : constant Block_Instance_Acc := Proc.Instance;
46044651
Stmt : constant Iir := Instance.Stmt;
4605-
Expr : constant Iir := Get_Expression (Stmt);
4606-
Value: Iir_Value_Literal_Acc;
46074652
Assoc: Iir;
46084653
Stmt_Chain : Iir;
4609-
Marker : Mark_Type;
46104654
begin
4611-
Mark (Marker, Expr_Pool);
4612-
4613-
Value := Execute_Expression (Instance, Expr);
4614-
Assoc := Get_Case_Statement_Alternative_Chain (Stmt);
4615-
if Get_Type_Staticness (Get_Type (Expr)) /= Locally
4616-
and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression
4617-
then
4618-
declare
4619-
Choice_Type : constant Iir :=
4620-
Get_Type (Get_Choice_Expression (Assoc));
4621-
Choice_Len : Iir_Int64;
4622-
begin
4623-
Choice_Len := Evaluation.Eval_Discrete_Type_Length
4624-
(Get_String_Type_Bound_Type (Choice_Type));
4625-
if Choice_Len /= Iir_Int64 (Value.Bounds.D (1).Length) then
4626-
Error_Msg_Constraint (Expr);
4627-
end if;
4628-
end;
4655+
Assoc := Execute_Choice (Instance, Get_Expression (Stmt),
4656+
Get_Case_Statement_Alternative_Chain (Stmt));
4657+
Stmt_Chain := Get_Associated_Chain (Assoc);
4658+
if Stmt_Chain = Null_Iir then
4659+
Update_Next_Statement (Proc);
4660+
else
4661+
Instance.Stmt := Stmt_Chain;
46294662
end if;
4630-
4631-
while Assoc /= Null_Iir loop
4632-
if not Get_Same_Alternative_Flag (Assoc) then
4633-
Stmt_Chain := Get_Associated_Chain (Assoc);
4634-
end if;
4635-
4636-
if Is_In_Choice (Instance, Assoc, Value) then
4637-
if Stmt_Chain = Null_Iir then
4638-
Update_Next_Statement (Proc);
4639-
else
4640-
Instance.Stmt := Stmt_Chain;
4641-
end if;
4642-
Release (Marker, Expr_Pool);
4643-
return;
4644-
end if;
4645-
4646-
Assoc := Get_Chain (Assoc);
4647-
end loop;
4648-
-- FIXME: infinite loop???
4649-
Error_Msg_Exec ("no choice for expression", Stmt);
4650-
raise Internal_Error;
46514663
end Execute_Case_Statement;
46524664

46534665
procedure Execute_Call_Statement (Proc : Process_State_Acc)
@@ -4894,9 +4906,20 @@ package body Simul.Execution is
48944906
Execute_If_Statement (Proc, Stmt);
48954907

48964908
when Iir_Kind_Simple_Signal_Assignment_Statement =>
4897-
Execute_Signal_Assignment (Instance, Stmt);
4909+
Execute_Signal_Assignment
4910+
(Instance, Stmt, Get_Waveform_Chain (Stmt));
48984911
Update_Next_Statement (Proc);
48994912

4913+
when Iir_Kind_Selected_Waveform_Assignment_Statement =>
4914+
declare
4915+
Assoc : Iir;
4916+
begin
4917+
Assoc := Execute_Choice (Instance, Get_Expression (Stmt),
4918+
Get_Selected_Waveform_Chain (Stmt));
4919+
Execute_Signal_Assignment
4920+
(Instance, Stmt, Get_Associated_Chain (Assoc));
4921+
Update_Next_Statement (Proc);
4922+
end;
49004923
when Iir_Kind_Assertion_Statement =>
49014924
declare
49024925
Res : Boolean;

0 commit comments

Comments
 (0)