aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2017-12-19 18:12:20 +0100
committerTristan Gingold <tgingold@free.fr>2017-12-21 07:36:47 +0100
commit8bb2635ccecde036d92b242b2d43efd4372793a8 (patch)
tree75475205b06180b935d89d34d97034802a7ae9cf /src
parent787ef6f900f18ea853c01edaf00f0e6836b61834 (diff)
downloadghdl-8bb2635ccecde036d92b242b2d43efd4372793a8.tar.gz
ghdl-8bb2635ccecde036d92b242b2d43efd4372793a8.tar.bz2
ghdl-8bb2635ccecde036d92b242b2d43efd4372793a8.zip
simul: handle selected signal assignments.
Diffstat (limited to 'src')
-rw-r--r--src/vhdl/simulate/simul-annotations.adb1
-rw-r--r--src/vhdl/simulate/simul-execution.adb113
2 files changed, 69 insertions, 45 deletions
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;