diff options
Diffstat (limited to 'src/vhdl/vhdl-canon.adb')
-rw-r--r-- | src/vhdl/vhdl-canon.adb | 285 |
1 files changed, 250 insertions, 35 deletions
diff --git a/src/vhdl/vhdl-canon.adb b/src/vhdl/vhdl-canon.adb index d37f26493..2a8ef8aa0 100644 --- a/src/vhdl/vhdl-canon.adb +++ b/src/vhdl/vhdl-canon.adb @@ -334,7 +334,7 @@ package body Vhdl.Canon is end Canon_Extract_Sensitivity_If_Not_Null; procedure Canon_Extract_Sensitivity_Procedure_Call - (Sensitivity_List : Iir_List; Call : Iir) + (Call : Iir; Sensitivity_List : Iir_List) is Assoc : Iir; Inter : Iir; @@ -365,22 +365,76 @@ package body Vhdl.Canon is end loop; end Canon_Extract_Sensitivity_Waveform; + procedure Canon_Extract_Sensitivity_Signal_Assignment_Common + (Stmt : Iir; List : Iir_List) is + begin + Canon_Extract_Sensitivity_Expression (Get_Target (Stmt), List, True); + Canon_Extract_Sensitivity_If_Not_Null + (Get_Reject_Time_Expression (Stmt), List); + end Canon_Extract_Sensitivity_Signal_Assignment_Common; + + procedure Canon_Extract_Sensitivity_Conditional_Signal_Assignment + (Stmt : Iir; List : Iir_List) + is + Cwe : Iir; + begin + Canon_Extract_Sensitivity_Signal_Assignment_Common (Stmt, List); + Cwe := Get_Conditional_Waveform_Chain (Stmt); + while Cwe /= Null_Iir loop + Canon_Extract_Sensitivity_If_Not_Null (Get_Condition (Cwe), List); + Canon_Extract_Sensitivity_Waveform (Get_Waveform_Chain (Cwe), List); + Cwe := Get_Chain (Cwe); + end loop; + end Canon_Extract_Sensitivity_Conditional_Signal_Assignment; + + procedure Canon_Extract_Sensitivity_Simple_Signal_Assignment + (Stmt : Iir; List : Iir_List) is + begin + Canon_Extract_Sensitivity_Signal_Assignment_Common (Stmt, List); + Canon_Extract_Sensitivity_Waveform (Get_Waveform_Chain (Stmt), List); + end Canon_Extract_Sensitivity_Simple_Signal_Assignment; + + procedure Canon_Extract_Sensitivity_Selected_Signal_Assignment + (Stmt : Iir; List : Iir_List) + is + Swf : Node; + Wf : Node; + begin + Canon_Extract_Sensitivity_Signal_Assignment_Common (Stmt, List); + Canon_Extract_Sensitivity_Expression (Get_Expression (Stmt), List); + + Swf := Get_Selected_Waveform_Chain (Stmt); + while Swf /= Null_Node loop + Wf := Get_Associated_Chain (Swf); + if Wf /= Null_Iir then + Canon_Extract_Sensitivity_Waveform (Wf, List); + end if; + Swf := Get_Chain (Swf); + end loop; + end Canon_Extract_Sensitivity_Selected_Signal_Assignment; + + procedure Canon_Extract_Sensitivity_Assertion_Statement + (Stmt : Iir; List : Iir_List) is + begin + Canon_Extract_Sensitivity_Expression + (Get_Assertion_Condition (Stmt), List); + Canon_Extract_Sensitivity_If_Not_Null + (Get_Severity_Expression (Stmt), List); + Canon_Extract_Sensitivity_If_Not_Null + (Get_Report_Expression (Stmt), List); + end Canon_Extract_Sensitivity_Assertion_Statement; + procedure Canon_Extract_Sensitivity_Statement (Stmt : Iir; List : Iir_List) is begin - case Get_Kind (Stmt) is + case Iir_Kinds_Sequential_Statement_Ext (Get_Kind (Stmt)) is when Iir_Kind_Assertion_Statement => -- LRM08 11.3 -- * For each assertion, report, next, exit or return -- statement, apply the rule of 10.2 to each expression -- in the statement, and construct the union of the -- resulting sets. - Canon_Extract_Sensitivity_Expression - (Get_Assertion_Condition (Stmt), List); - Canon_Extract_Sensitivity_If_Not_Null - (Get_Severity_Expression (Stmt), List); - Canon_Extract_Sensitivity_If_Not_Null - (Get_Report_Expression (Stmt), List); + Canon_Extract_Sensitivity_Assertion_Statement (Stmt, List); when Iir_Kind_Report_Statement => -- LRM08 11.3 -- See assertion_statement case. @@ -412,29 +466,10 @@ package body Vhdl.Canon is when Iir_Kind_Simple_Signal_Assignment_Statement => -- LRM08 11.3 -- See variable assignment statement case. - Canon_Extract_Sensitivity_Expression - (Get_Target (Stmt), List, True); - Canon_Extract_Sensitivity_If_Not_Null - (Get_Reject_Time_Expression (Stmt), List); - Canon_Extract_Sensitivity_Waveform - (Get_Waveform_Chain (Stmt), List); + Canon_Extract_Sensitivity_Simple_Signal_Assignment (Stmt, List); when Iir_Kind_Conditional_Signal_Assignment_Statement => - Canon_Extract_Sensitivity_Expression - (Get_Target (Stmt), List, True); - Canon_Extract_Sensitivity_If_Not_Null - (Get_Reject_Time_Expression (Stmt), List); - declare - Cwe : Iir; - begin - Cwe := Get_Conditional_Waveform_Chain (Stmt); - while Cwe /= Null_Iir loop - Canon_Extract_Sensitivity_If_Not_Null - (Get_Condition (Cwe), List); - Canon_Extract_Sensitivity_Waveform - (Get_Waveform_Chain (Cwe), List); - Cwe := Get_Chain (Cwe); - end loop; - end; + Canon_Extract_Sensitivity_Conditional_Signal_Assignment + (Stmt, List); when Iir_Kind_If_Statement => -- LRM08 11.3 -- * For each if statement, apply the rule of 10.2 to the @@ -509,8 +544,14 @@ package body Vhdl.Canon is -- with each formal parameter of mode IN or INOUT, and -- construct the union of the resulting sets. Canon_Extract_Sensitivity_Procedure_Call - (List, Get_Procedure_Call (Stmt)); - when others => + (Get_Procedure_Call (Stmt), List); + when Iir_Kind_Selected_Waveform_Assignment_Statement + | Iir_Kind_Conditional_Variable_Assignment_Statement + | Iir_Kind_Signal_Force_Assignment_Statement + | Iir_Kind_Signal_Release_Assignment_Statement + | Iir_Kind_Break_Statement + | Iir_Kind_Wait_Statement + | Iir_Kind_Suspend_State_Statement => Error_Kind ("canon_extract_sensitivity_statement", Stmt); end case; end Canon_Extract_Sensitivity_Statement; @@ -1129,7 +1170,7 @@ package body Vhdl.Canon is -- Keep the same statement by default. N_Stmt := Stmt; - case Get_Kind (Stmt) is + case Iir_Kinds_Sequential_Statement_Ext (Get_Kind (Stmt)) is when Iir_Kind_If_Statement => declare Cond: Iir; @@ -1255,7 +1296,11 @@ package body Vhdl.Canon is when Iir_Kind_Return_Statement => Canon_Expression (Get_Expression (Stmt)); - when others => + when Iir_Kind_Selected_Waveform_Assignment_Statement + | Iir_Kind_Signal_Force_Assignment_Statement + | Iir_Kind_Signal_Release_Assignment_Statement + | Iir_Kind_Break_Statement + | Iir_Kind_Suspend_State_Statement => Error_Kind ("canon_sequential_stmts", Stmt); end case; @@ -1267,6 +1312,162 @@ package body Vhdl.Canon is return Res; end Canon_Sequential_Stmts; + function Canon_Insert_Suspend_State_Statement (Stmt : Iir; Var : Iir) + return Iir + is + Last : Iir; + Num : Int32; + Res : Iir; + begin + Res := Create_Iir (Iir_Kind_Suspend_State_Statement); + Location_Copy (Res, Stmt); + Set_Parent (Res, Get_Parent (Stmt)); + Set_Chain (Res, Stmt); + + Last := Get_Suspend_State_Chain (Var); + if Last = Null_Iir then + Num := 0; + else + Num := Get_Suspend_State_Index (Last); + end if; + + Set_Suspend_State_Index (Res, Num + 1); + Set_Suspend_State_Chain (Res, Last); + Set_Suspend_State_Chain (Var, Res); + return Res; + end Canon_Insert_Suspend_State_Statement; + + function Canon_Add_Suspend_State_Statement (First : Iir; Var : Iir) + return Iir + is + Stmt: Iir; + S_Stmt : Iir; + Res, Last : Iir; + begin + Chain_Init (Res, Last); + + Stmt := First; + while Stmt /= Null_Iir loop + + S_Stmt := Null_Iir; + + case Get_Kind (Stmt) is + when Iir_Kind_Simple_Signal_Assignment_Statement + | Iir_Kind_Conditional_Signal_Assignment_Statement => + null; + + when Iir_Kind_Variable_Assignment_Statement + | Iir_Kind_Conditional_Variable_Assignment_Statement => + null; + + when Iir_Kind_If_Statement => + if Get_Suspend_Flag (Stmt) then + declare + Clause: Iir; + Stmts : Iir; + begin + Clause := Stmt; + while Clause /= Null_Iir loop + Stmts := Get_Sequential_Statement_Chain (Clause); + Stmts := Canon_Add_Suspend_State_Statement + (Stmts, Var); + Set_Sequential_Statement_Chain (Clause, Stmts); + Clause := Get_Else_Clause (Clause); + end loop; + end; + end if; + + when Iir_Kind_Wait_Statement => + S_Stmt := Canon_Insert_Suspend_State_Statement (Stmt, Var); + + when Iir_Kind_Case_Statement => + if Get_Suspend_Flag (Stmt) then + declare + Choice: Iir; + Stmts : Iir; + begin + Choice := Get_Case_Statement_Alternative_Chain (Stmt); + while Choice /= Null_Iir loop + -- FIXME: canon choice expr. + Stmts := Get_Associated_Chain (Choice); + Stmts := Canon_Add_Suspend_State_Statement + (Stmts, Var); + Set_Associated_Chain (Choice, Stmts); + Choice := Get_Chain (Choice); + end loop; + end; + end if; + + when Iir_Kind_Assertion_Statement + | Iir_Kind_Report_Statement => + null; + + when Iir_Kind_For_Loop_Statement + | Iir_Kind_While_Loop_Statement => + if Get_Suspend_Flag (Stmt) then + declare + Stmts : Iir; + begin + Stmts := Get_Sequential_Statement_Chain (Stmt); + Stmts := Canon_Add_Suspend_State_Statement + (Stmts, Var); + Set_Sequential_Statement_Chain (Stmt, Stmts); + end; + end if; + + when Iir_Kind_Next_Statement + | Iir_Kind_Exit_Statement => + null; + + when Iir_Kind_Procedure_Call_Statement => + if Get_Suspend_Flag (Stmt) then + S_Stmt := Canon_Insert_Suspend_State_Statement (Stmt, Var); + end if; + + when Iir_Kind_Null_Statement => + null; + + when Iir_Kind_Return_Statement => + null; + + when others => + Error_Kind ("canon_add_suspend_state_statement", Stmt); + end case; + + if S_Stmt /= Null_Iir then + Chain_Append (Res, Last, S_Stmt); + end if; + Chain_Append (Res, Last, Stmt); + + Stmt := Get_Chain (Stmt); + end loop; + + return Res; + end Canon_Add_Suspend_State_Statement; + + procedure Canon_Add_Suspend_State (Proc : Iir) + is + Var : Iir; + Stmts : Iir; + begin + pragma Assert (Kind_In (Proc, Iir_Kind_Process_Statement, + Iir_Kind_Procedure_Body)); + + -- Create suspend state variable. + Var := Create_Iir (Iir_Kind_Suspend_State_Declaration); + Set_Location (Var, Get_Location (Proc)); + Set_Parent (Var, Proc); + + -- Insert it. + Set_Chain (Var, Get_Declaration_Chain (Proc)); + Set_Declaration_Chain (Proc, Var); + + -- Add suspend state statements. + Stmts := Get_Sequential_Statement_Chain (Proc); + Stmts := Canon_Add_Suspend_State_Statement (Stmts, Var); + Set_Sequential_Statement_Chain (Proc, Stmts); + end Canon_Add_Suspend_State; + -- Create a statement transform from concurrent_signal_assignment -- statement STMT (either selected or conditional). -- waveform transformation is not done. @@ -1428,7 +1629,7 @@ package body Vhdl.Canon is -- the union of the sets constructed by applying th rule of Section 8.1 -- to each actual part associated with a formal parameter. Sensitivity_List := Create_Iir_List; - Canon_Extract_Sensitivity_Procedure_Call (Sensitivity_List, Call); + Canon_Extract_Sensitivity_Procedure_Call (Call, Sensitivity_List); if Is_Sensitized then Set_Sensitivity_List (Proc, Sensitivity_List); Set_Is_Ref (Proc, True); @@ -2050,6 +2251,11 @@ package body Vhdl.Canon is when Iir_Kind_Sensitized_Process_Statement | Iir_Kind_Process_Statement => + if Canon_Flag_Add_Suspend_State + and then Get_Kind (Stmt) = Iir_Kind_Process_Statement + then + Canon_Add_Suspend_State (Stmt); + end if; Canon_Declarations (Top, Stmt, Null_Iir); if Canon_Flag_Sequentials_Stmts then declare @@ -2953,6 +3159,12 @@ package body Vhdl.Canon is when Iir_Kind_Procedure_Body | Iir_Kind_Function_Body => Canon_Declarations (Top, Decl, Null_Iir); + if Canon_Flag_Add_Suspend_State + and then Get_Kind (Decl) = Iir_Kind_Procedure_Body + and then Get_Suspend_Flag (Decl) + then + Canon_Add_Suspend_State (Decl); + end if; if Canon_Flag_Sequentials_Stmts then Stmts := Get_Sequential_Statement_Chain (Decl); Stmts := Canon_Sequential_Stmts (Stmts); @@ -3058,6 +3270,9 @@ package body Vhdl.Canon is when Iir_Kind_Psl_Default_Clock => null; + when Iir_Kind_Suspend_State_Declaration => + null; + when others => Error_Kind ("canon_declaration", Decl); end case; |