From 8bb2635ccecde036d92b242b2d43efd4372793a8 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Tue, 19 Dec 2017 18:12:20 +0100 Subject: simul: handle selected signal assignments. --- src/vhdl/simulate/simul-annotations.adb | 1 + src/vhdl/simulate/simul-execution.adb | 113 +++++++++++++++++++------------- 2 files changed, 69 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/vhdl/simulate/simul-annotations.adb b/src/vhdl/simulate/simul-annotations.adb index 9db4aad02..ba1d8c7ed 100644 --- a/src/vhdl/simulate/simul-annotations.adb +++ b/src/vhdl/simulate/simul-annotations.adb @@ -783,6 +783,7 @@ package body Simul.Annotations is when Iir_Kind_Return_Statement => null; when Iir_Kind_Simple_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Variable_Assignment_Statement => null; when Iir_Kind_Procedure_Call_Statement => diff --git a/src/vhdl/simulate/simul-execution.adb b/src/vhdl/simulate/simul-execution.adb index 990ff8e2e..1edcd4da8 100644 --- a/src/vhdl/simulate/simul-execution.adb +++ b/src/vhdl/simulate/simul-execution.adb @@ -4081,9 +4081,9 @@ package body Simul.Execution is procedure Execute_Signal_Assignment (Instance: Block_Instance_Acc; - Stmt: Iir_Signal_Assignment_Statement) + Stmt: Iir_Signal_Assignment_Statement; + Wf : Iir) is - Wf : constant Iir_Waveform_Element := Get_Waveform_Chain (Stmt); Nbr_We : constant Natural := Get_Chain_Length (Wf); Transactions : Transaction_Type (Nbr_We); @@ -4330,6 +4330,53 @@ package body Simul.Execution is end case; end Is_In_Choice; + function Execute_Choice (Instance : Block_Instance_Acc; + Expr : Iir; + First_Assoc : Iir) return Iir + is + Value: Iir_Value_Literal_Acc; + Assoc: Iir; + Assoc_Res : Iir; + Marker : Mark_Type; + begin + Mark (Marker, Expr_Pool); + Assoc := First_Assoc; + + Value := Execute_Expression (Instance, Expr); + if Get_Type_Staticness (Get_Type (Expr)) /= Locally + and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression + then + -- Choice is not locally constrained, check length. + declare + Choice_Type : constant Iir := + Get_Type (Get_Choice_Expression (Assoc)); + Choice_Len : Iir_Int64; + begin + Choice_Len := Evaluation.Eval_Discrete_Type_Length + (Get_String_Type_Bound_Type (Choice_Type)); + if Choice_Len /= Iir_Int64 (Value.Bounds.D (1).Length) then + Error_Msg_Constraint (Expr); + end if; + end; + end if; + + while Assoc /= Null_Iir loop + if not Get_Same_Alternative_Flag (Assoc) then + Assoc_Res := Assoc; + end if; + + if Is_In_Choice (Instance, Assoc, Value) then + Release (Marker, Expr_Pool); + return Assoc_Res; + end if; + + Assoc := Get_Chain (Assoc); + end loop; + -- FIXME: infinite loop??? + Error_Msg_Exec ("no choice for expression", Expr); + raise Internal_Error; + end Execute_Choice; + -- Return TRUE iff VAL is in the range defined by BOUNDS. function Is_In_Range (Val : Iir_Value_Literal_Acc; Bounds : Iir_Value_Literal_Acc) @@ -4602,52 +4649,17 @@ package body Simul.Execution is is Instance : constant Block_Instance_Acc := Proc.Instance; Stmt : constant Iir := Instance.Stmt; - Expr : constant Iir := Get_Expression (Stmt); - Value: Iir_Value_Literal_Acc; Assoc: Iir; Stmt_Chain : Iir; - Marker : Mark_Type; begin - Mark (Marker, Expr_Pool); - - Value := Execute_Expression (Instance, Expr); - Assoc := Get_Case_Statement_Alternative_Chain (Stmt); - if Get_Type_Staticness (Get_Type (Expr)) /= Locally - and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression - then - declare - Choice_Type : constant Iir := - Get_Type (Get_Choice_Expression (Assoc)); - Choice_Len : Iir_Int64; - begin - Choice_Len := Evaluation.Eval_Discrete_Type_Length - (Get_String_Type_Bound_Type (Choice_Type)); - if Choice_Len /= Iir_Int64 (Value.Bounds.D (1).Length) then - Error_Msg_Constraint (Expr); - end if; - end; + Assoc := Execute_Choice (Instance, Get_Expression (Stmt), + Get_Case_Statement_Alternative_Chain (Stmt)); + Stmt_Chain := Get_Associated_Chain (Assoc); + if Stmt_Chain = Null_Iir then + Update_Next_Statement (Proc); + else + Instance.Stmt := Stmt_Chain; end if; - - while Assoc /= Null_Iir loop - if not Get_Same_Alternative_Flag (Assoc) then - Stmt_Chain := Get_Associated_Chain (Assoc); - end if; - - if Is_In_Choice (Instance, Assoc, Value) then - if Stmt_Chain = Null_Iir then - Update_Next_Statement (Proc); - else - Instance.Stmt := Stmt_Chain; - end if; - Release (Marker, Expr_Pool); - return; - end if; - - Assoc := Get_Chain (Assoc); - end loop; - -- FIXME: infinite loop??? - Error_Msg_Exec ("no choice for expression", Stmt); - raise Internal_Error; end Execute_Case_Statement; procedure Execute_Call_Statement (Proc : Process_State_Acc) @@ -4894,9 +4906,20 @@ package body Simul.Execution is Execute_If_Statement (Proc, Stmt); when Iir_Kind_Simple_Signal_Assignment_Statement => - Execute_Signal_Assignment (Instance, Stmt); + Execute_Signal_Assignment + (Instance, Stmt, Get_Waveform_Chain (Stmt)); Update_Next_Statement (Proc); + when Iir_Kind_Selected_Waveform_Assignment_Statement => + declare + Assoc : Iir; + begin + Assoc := Execute_Choice (Instance, Get_Expression (Stmt), + Get_Selected_Waveform_Chain (Stmt)); + Execute_Signal_Assignment + (Instance, Stmt, Get_Associated_Chain (Assoc)); + Update_Next_Statement (Proc); + end; when Iir_Kind_Assertion_Statement => declare Res : Boolean; -- cgit v1.2.3