@@ -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