diff options
Diffstat (limited to 'src/vhdl/canon.adb')
-rw-r--r-- | src/vhdl/canon.adb | 128 |
1 files changed, 112 insertions, 16 deletions
diff --git a/src/vhdl/canon.adb b/src/vhdl/canon.adb index 9108ece35..951a78d19 100644 --- a/src/vhdl/canon.adb +++ b/src/vhdl/canon.adb @@ -66,6 +66,9 @@ package body Canon is procedure Canon_Subtype_Indication (Def : Iir); procedure Canon_Subtype_Indication_If_Anonymous (Def : Iir); + function Canon_Conditional_Signal_Assignment + (Conc_Stmt : Iir; Proc : Iir; Parent : Iir) return Iir; + procedure Canon_Extract_Sensitivity_Aggregate (Aggr : Iir; Sensitivity_List : Iir_List; @@ -341,7 +344,7 @@ package body Canon is -- the target, and construct the union of the resulting sets. Canon_Extract_Sensitivity (Get_Target (Stmt), List, True); Canon_Extract_Sensitivity (Get_Expression (Stmt), List, False); - when Iir_Kind_Signal_Assignment_Statement => + when Iir_Kind_Simple_Signal_Assignment_Statement => -- LRM08 11.3 -- See variable assignment statement case. Canon_Extract_Sensitivity (Get_Target (Stmt), List, True); @@ -998,6 +1001,60 @@ package body Canon is -- return Res; -- end Canon_Default_Map_Association_List; + function Canon_Conditional_Variable_Assignment_Statement (Stmt : Iir) + return Iir + is + Target : constant Iir := Get_Target (Stmt); + Cond_Expr : Iir; + Expr : Iir; + Asgn : Iir; + Res : Iir; + El, N_El : Iir; + begin + Cond_Expr := Get_Conditional_Expression (Stmt); + Res := Create_Iir (Iir_Kind_If_Statement); + Set_Label (Res, Get_Label (Stmt)); + Set_Suspend_Flag (Res, False); + El := Res; + + loop + -- Fill if/elsif statement. + Set_Parent (El, Get_Parent (Stmt)); + Location_Copy (El, Cond_Expr); + Set_Condition (El, Get_Condition (Cond_Expr)); + + -- Create simple variable assignment. + Asgn := Create_Iir (Iir_Kind_Variable_Assignment_Statement); + Location_Copy (Asgn, Cond_Expr); + Set_Parent (Asgn, El); + Set_Target (Asgn, Target); + Expr := Get_Expression (Cond_Expr); + if Canon_Flag_Expressions then + Canon_Expression (Expr); + end if; + Set_Expression (Asgn, Expr); + + Set_Sequential_Statement_Chain (El, Asgn); + + -- Next condition. + Cond_Expr := Get_Chain (Cond_Expr); + exit when Cond_Expr = Null_Iir; + + N_El := Create_Iir (Iir_Kind_Elsif); + Set_Else_Clause (El, N_El); + El := N_El; + end loop; + + return Res; + end Canon_Conditional_Variable_Assignment_Statement; + + function Canon_Conditional_Signal_Assignment_Statement (Stmt : Iir) + return Iir is + begin + return Canon_Conditional_Signal_Assignment + (Stmt, Null_Iir, Get_Parent (Stmt)); + end Canon_Conditional_Signal_Assignment_Statement; + -- Inner loop if any; used to canonicalize exit/next statement. Cur_Loop : Iir; @@ -1026,7 +1083,7 @@ package body Canon is end loop; end; - when Iir_Kind_Signal_Assignment_Statement => + when Iir_Kind_Simple_Signal_Assignment_Statement => Canon_Expression (Get_Target (Stmt)); Canon_Waveform_Chain (Get_Waveform_Chain (Stmt), Null_Iir_List); @@ -1207,7 +1264,8 @@ package body Canon is Else_Clause := Create_Iir (Iir_Kind_Elsif); Location_Copy (Else_Clause, Stmt); Set_Else_Clause (If_Stmt, Else_Clause); - Dis_Stmt := Create_Iir (Iir_Kind_Signal_Assignment_Statement); + Dis_Stmt := + Create_Iir (Iir_Kind_Simple_Signal_Assignment_Statement); Location_Copy (Dis_Stmt, Stmt); Set_Parent (Dis_Stmt, If_Stmt); Set_Target (Dis_Stmt, Target); @@ -1329,6 +1387,7 @@ package body Canon is return Iir is Stmt : Iir; + Sensitivity_List : Iir_List; begin if Waveform_Chain = Null_Iir then -- LRM 9.5.1 Conditionnal Signal Assignment @@ -1349,9 +1408,14 @@ package body Canon is -- of the form: -- target <= [ delay_mechanism ] waveform_element1, -- waveform_element2, ..., waveform_elementN; - Stmt := Create_Iir (Iir_Kind_Signal_Assignment_Statement); + Stmt := Create_Iir (Iir_Kind_Simple_Signal_Assignment_Statement); Set_Target (Stmt, Get_Target (Orig_Stmt)); - Canon_Waveform_Chain (Waveform_Chain, Get_Sensitivity_List (Proc)); + if Proc = Null_Iir then + Sensitivity_List := Null_Iir_List; + else + Sensitivity_List := Get_Sensitivity_List (Proc); + end if; + Canon_Waveform_Chain (Waveform_Chain, Sensitivity_List); Set_Waveform_Chain (Stmt, Waveform_Chain); Set_Delay_Mechanism (Stmt, Get_Delay_Mechanism (Orig_Stmt)); Set_Reject_Time_Expression @@ -1361,10 +1425,22 @@ package body Canon is return Stmt; end Canon_Wave_Transform; - -- Create signal_transform for a conditional concurrent signal assignment. - procedure Canon_Conditional_Concurrent_Signal_Assigment + -- Create signal_transform for a concurrent simple signal assignment. + procedure Canon_Concurrent_Simple_Signal_Assignment (Conc_Stmt : Iir; Proc : Iir; Parent : Iir) is + Stmt : Iir; + begin + Stmt := Canon_Wave_Transform + (Conc_Stmt, Get_Waveform_Chain (Conc_Stmt), Proc); + Set_Parent (Stmt, Parent); + Set_Sequential_Statement_Chain (Parent, Stmt); + end Canon_Concurrent_Simple_Signal_Assignment; + + -- Create signal_transform for a concurrent conditional signal assignment. + function Canon_Conditional_Signal_Assignment + (Conc_Stmt : Iir; Proc : Iir; Parent : Iir) return Iir + is Expr : Iir; Stmt : Iir; Res1 : Iir; @@ -1380,8 +1456,8 @@ package body Canon is while Cond_Wf /= Null_Iir loop Expr := Get_Condition (Cond_Wf); - Wf := Canon_Wave_Transform - (Conc_Stmt, Get_Waveform_Chain (Cond_Wf), Proc); + Wf := Get_Waveform_Chain (Cond_Wf); + Wf := Canon_Wave_Transform (Conc_Stmt, Wf, Proc); Set_Parent (Wf, Parent); if Expr = Null_Iir and Cond_Wf = Cond_Wf_Chain then Res1 := Wf; @@ -1390,8 +1466,10 @@ package body Canon is if Canon_Flag_Expressions then Canon_Expression (Expr); end if; - Canon_Extract_Sensitivity - (Expr, Get_Sensitivity_List (Proc), False); + if Proc /= Null_Iir then + Canon_Extract_Sensitivity + (Expr, Get_Sensitivity_List (Proc), False); + end if; end if; if Stmt = Null_Iir then Res1 := Create_Iir (Iir_Kind_If_Statement); @@ -1411,10 +1489,20 @@ package body Canon is Last_Res := Res1; Cond_Wf := Get_Chain (Cond_Wf); end loop; + return Stmt; + end Canon_Conditional_Signal_Assignment; + + -- Create signal_transform for a concurrent conditional signal assignment. + procedure Canon_Concurrent_Conditional_Signal_Assignment + (Conc_Stmt : Iir; Proc : Iir; Parent : Iir) + is + Stmt : Iir; + begin + Stmt := Canon_Conditional_Signal_Assignment (Conc_Stmt, Proc, Parent); Set_Sequential_Statement_Chain (Parent, Stmt); - end Canon_Conditional_Concurrent_Signal_Assigment; + end Canon_Concurrent_Conditional_Signal_Assignment; - procedure Canon_Selected_Concurrent_Signal_Assignment + procedure Canon_Concurrent_Selected_Signal_Assignment (Conc_Stmt : Iir; Proc : Iir; Parent : Iir) is Selected_Waveform : Iir; @@ -1446,7 +1534,7 @@ package body Canon is end if; Selected_Waveform := Get_Chain (Selected_Waveform); end loop; - end Canon_Selected_Concurrent_Signal_Assignment; + end Canon_Concurrent_Selected_Signal_Assignment; procedure Canon_Generate_Statement_Body (Top : Iir_Design_Unit; Bod : Iir) is @@ -1505,10 +1593,18 @@ package body Canon is end if; case Get_Kind (El) is + when Iir_Kind_Concurrent_Simple_Signal_Assignment => + Canon_Concurrent_Signal_Assignment (El, Proc, Sub_Chain); + + Canon_Concurrent_Simple_Signal_Assignment (El, Proc, Sub_Chain); + + Replace_Stmt (Proc); + El := Proc; + when Iir_Kind_Concurrent_Conditional_Signal_Assignment => Canon_Concurrent_Signal_Assignment (El, Proc, Sub_Chain); - Canon_Conditional_Concurrent_Signal_Assigment + Canon_Concurrent_Conditional_Signal_Assignment (El, Proc, Sub_Chain); Replace_Stmt (Proc); @@ -1517,7 +1613,7 @@ package body Canon is when Iir_Kind_Concurrent_Selected_Signal_Assignment => Canon_Concurrent_Signal_Assignment (El, Proc, Sub_Chain); - Canon_Selected_Concurrent_Signal_Assignment + Canon_Concurrent_Selected_Signal_Assignment (El, Proc, Sub_Chain); Replace_Stmt (Proc); |