diff options
author | Tristan Gingold <tgingold@free.fr> | 2016-10-21 08:50:52 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2016-11-01 13:11:42 +0100 |
commit | d5f2c69f322973e62d4bd61cd659317397efd4bc (patch) | |
tree | dd937d4b86d31b755474d30970b35ed7fe63d648 | |
parent | a98d989710eec4b44d2532bd31c8fbba209c8172 (diff) | |
download | ghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.tar.gz ghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.tar.bz2 ghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.zip |
Add translation for selected signal assignment.
-rw-r--r-- | src/vhdl/disp_vhdl.adb | 48 | ||||
-rw-r--r-- | src/vhdl/errorout.adb | 3 | ||||
-rw-r--r-- | src/vhdl/iirs.adb | 1 | ||||
-rw-r--r-- | src/vhdl/iirs.ads | 9 | ||||
-rw-r--r-- | src/vhdl/iirs_walk.adb | 1 | ||||
-rw-r--r-- | src/vhdl/nodes_meta.adb | 174 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap8.adb | 230 | ||||
-rw-r--r-- | src/vhdl/translate/trans_analyzes.adb | 28 |
8 files changed, 355 insertions, 139 deletions
diff --git a/src/vhdl/disp_vhdl.adb b/src/vhdl/disp_vhdl.adb index a92fcb2b5..b92433fff 100644 --- a/src/vhdl/disp_vhdl.adb +++ b/src/vhdl/disp_vhdl.adb @@ -1855,6 +1855,35 @@ package body Disp_Vhdl is Put_Line (";"); end Disp_Conditional_Signal_Assignment; + procedure Disp_Selected_Waveforms (Stmt : Iir; Indent : Count) + is + Assoc_Chain : constant Iir := Get_Selected_Waveform_Chain (Stmt); + Assoc: Iir; + begin + Assoc := Assoc_Chain; + while Assoc /= Null_Iir loop + if Assoc /= Assoc_Chain then + Put_Line (","); + end if; + Set_Col (Indent + Indentation); + Disp_Waveform (Get_Associated_Chain (Assoc)); + Put (" when "); + Disp_Choice (Assoc); + end loop; + Put_Line (";"); + end Disp_Selected_Waveforms; + + procedure Disp_Selected_Waveform_Assignment (Stmt: Iir; Indent : Count) is + begin + Put ("with "); + Disp_Expression (Get_Expression (Stmt)); + Put (" select "); + Disp_Expression (Get_Target (Stmt)); + Put (" <= "); + Disp_Delay_Mechanism (Stmt); + Disp_Selected_Waveforms (Stmt, Indent); + end Disp_Selected_Waveform_Assignment; + procedure Disp_Variable_Assignment (Stmt: Iir) is begin Disp_Expression (Get_Target (Stmt)); @@ -1929,8 +1958,6 @@ package body Disp_Vhdl is procedure Disp_Concurrent_Selected_Signal_Assignment (Stmt: Iir) is Indent: constant Count := Col; - Assoc: Iir; - Assoc_Chain : Iir; begin Set_Col (Indent); Disp_Label (Stmt); @@ -1944,18 +1971,7 @@ package body Disp_Vhdl is Put ("guarded "); end if; Disp_Delay_Mechanism (Stmt); - Assoc_Chain := Get_Selected_Waveform_Chain (Stmt); - Assoc := Assoc_Chain; - while Assoc /= Null_Iir loop - if Assoc /= Assoc_Chain then - Put_Line (","); - end if; - Set_Col (Indent + Indentation); - Disp_Waveform (Get_Associated_Chain (Assoc)); - Put (" when "); - Disp_Choice (Assoc); - end loop; - Put_Line (";"); + Disp_Selected_Waveforms (Stmt, Indent); end Disp_Concurrent_Selected_Signal_Assignment; procedure Disp_Concurrent_Conditional_Signal_Assignment (Stmt: Iir) is @@ -2152,8 +2168,8 @@ package body Disp_Vhdl is procedure Disp_Sequential_Statements (First : Iir) is - Stmt: Iir; Start: constant Count := Col; + Stmt: Iir; begin Stmt := First; while Stmt /= Null_Iir loop @@ -2190,6 +2206,8 @@ package body Disp_Vhdl is Disp_Simple_Signal_Assignment (Stmt); when Iir_Kind_Conditional_Signal_Assignment_Statement => Disp_Conditional_Signal_Assignment (Stmt); + when Iir_Kind_Selected_Waveform_Assignment_Statement => + Disp_Selected_Waveform_Assignment (Stmt, Start); when Iir_Kind_Variable_Assignment_Statement => Disp_Variable_Assignment (Stmt); when Iir_Kind_Conditional_Variable_Assignment_Statement => diff --git a/src/vhdl/errorout.adb b/src/vhdl/errorout.adb index 7f34d2689..e34c43af7 100644 --- a/src/vhdl/errorout.adb +++ b/src/vhdl/errorout.adb @@ -1153,6 +1153,9 @@ package body Errorout is when Iir_Kind_Conditional_Signal_Assignment_Statement => return Disp_Label (Node, "conditional signal assignment statement"); + when Iir_Kind_Selected_Waveform_Assignment_Statement => + return Disp_Label + (Node, "selected waveform assignment statement"); when Iir_Kind_Variable_Assignment_Statement => return Disp_Label (Node, "variable assignment statement"); when Iir_Kind_Conditional_Variable_Assignment_Statement => diff --git a/src/vhdl/iirs.adb b/src/vhdl/iirs.adb index f2cab3eec..d4f92a57a 100644 --- a/src/vhdl/iirs.adb +++ b/src/vhdl/iirs.adb @@ -513,6 +513,7 @@ package body Iirs is | Iir_Kind_Block_Statement | Iir_Kind_Component_Instantiation_Statement | Iir_Kind_Simple_Simultaneous_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Wait_Statement => return Format_Medium; end case; diff --git a/src/vhdl/iirs.ads b/src/vhdl/iirs.ads index 5e6ab16d9..8483ec68d 100644 --- a/src/vhdl/iirs.ads +++ b/src/vhdl/iirs.ads @@ -3156,6 +3156,7 @@ package Iirs is -- Iir_Kind_Simple_Signal_Assignment_Statement (Short) -- Iir_Kind_Conditional_Signal_Assignment_Statement (Short) + -- Iir_Kind_Selected_Waveform_Assignment_Statement (Medium) -- -- Get/Set_Parent (Field0) -- @@ -3178,6 +3179,12 @@ package Iirs is -- Only for Iir_Kind_Conditional_Signal_Assignment_Statement: -- Get/Set_Conditional_Waveform_Chain (Field5) -- + -- Only for Iir_Kind_Selected_Waveform_Assignment_Statement: + -- Get/Set_Expression (Field5) + -- + -- Only for Iir_Kind_Selected_Waveform_Assignment_Statement: + -- Get/Set_Selected_Waveform_Chain (Field7) + -- -- Get/Set_Delay_Mechanism (Flag1) -- -- Get/Set_Visible_Flag (Flag4) @@ -4168,6 +4175,7 @@ package Iirs is -- Iir_Kind_Sequential_Statement Iir_Kind_Simple_Signal_Assignment_Statement, Iir_Kind_Conditional_Signal_Assignment_Statement, + Iir_Kind_Selected_Waveform_Assignment_Statement, Iir_Kind_Null_Statement, Iir_Kind_Assertion_Statement, Iir_Kind_Report_Statement, @@ -5157,6 +5165,7 @@ package Iirs is subtype Iir_Kinds_Sequential_Statement is Iir_Kind range Iir_Kind_Simple_Signal_Assignment_Statement .. --Iir_Kind_Conditional_Signal_Assignment_Statement + --Iir_Kind_Selected_Waveform_Assignment_Statement --Iir_Kind_Null_Statement --Iir_Kind_Assertion_Statement --Iir_Kind_Report_Statement diff --git a/src/vhdl/iirs_walk.adb b/src/vhdl/iirs_walk.adb index 7d6d91aa7..17e35131f 100644 --- a/src/vhdl/iirs_walk.adb +++ b/src/vhdl/iirs_walk.adb @@ -59,6 +59,7 @@ package body Iirs_Walk is case Iir_Kinds_Sequential_Statement (Get_Kind (Stmt)) is when Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement diff --git a/src/vhdl/nodes_meta.adb b/src/vhdl/nodes_meta.adb index ece6c7044..6669fed53 100644 --- a/src/vhdl/nodes_meta.adb +++ b/src/vhdl/nodes_meta.adb @@ -1396,6 +1396,8 @@ package body Nodes_Meta is return "simple_signal_assignment_statement"; when Iir_Kind_Conditional_Signal_Assignment_Statement => return "conditional_signal_assignment_statement"; + when Iir_Kind_Selected_Waveform_Assignment_Statement => + return "selected_waveform_assignment_statement"; when Iir_Kind_Null_Statement => return "null_statement"; when Iir_Kind_Assertion_Statement => @@ -3836,6 +3838,17 @@ package body Nodes_Meta is Field_Chain, Field_Reject_Time_Expression, Field_Conditional_Waveform_Chain, + -- Iir_Kind_Selected_Waveform_Assignment_Statement + Field_Label, + Field_Delay_Mechanism, + Field_Visible_Flag, + Field_Guarded_Target_State, + Field_Parent, + Field_Target, + Field_Chain, + Field_Reject_Time_Expression, + Field_Expression, + Field_Selected_Waveform_Chain, -- Iir_Kind_Null_Statement Field_Label, Field_Visible_Flag, @@ -4504,74 +4517,75 @@ package body Nodes_Meta is Iir_Kind_If_Generate_Else_Clause => 1432, Iir_Kind_Simple_Signal_Assignment_Statement => 1441, Iir_Kind_Conditional_Signal_Assignment_Statement => 1450, - Iir_Kind_Null_Statement => 1454, - Iir_Kind_Assertion_Statement => 1461, - Iir_Kind_Report_Statement => 1467, - Iir_Kind_Wait_Statement => 1474, - Iir_Kind_Variable_Assignment_Statement => 1480, - Iir_Kind_Conditional_Variable_Assignment_Statement => 1486, - Iir_Kind_Return_Statement => 1492, - Iir_Kind_For_Loop_Statement => 1501, - Iir_Kind_While_Loop_Statement => 1509, - Iir_Kind_Next_Statement => 1515, - Iir_Kind_Exit_Statement => 1521, - Iir_Kind_Case_Statement => 1529, - Iir_Kind_Procedure_Call_Statement => 1535, - Iir_Kind_If_Statement => 1544, - Iir_Kind_Elsif => 1549, - Iir_Kind_Character_Literal => 1557, - Iir_Kind_Simple_Name => 1565, - Iir_Kind_Selected_Name => 1574, - Iir_Kind_Operator_Symbol => 1580, - Iir_Kind_Reference_Name => 1583, - Iir_Kind_Selected_By_All_Name => 1589, - Iir_Kind_Parenthesis_Name => 1594, - Iir_Kind_External_Constant_Name => 1602, - Iir_Kind_External_Signal_Name => 1610, - Iir_Kind_External_Variable_Name => 1618, - Iir_Kind_Package_Pathname => 1622, - Iir_Kind_Absolute_Pathname => 1623, - Iir_Kind_Relative_Pathname => 1624, - Iir_Kind_Pathname_Element => 1629, - Iir_Kind_Base_Attribute => 1631, - Iir_Kind_Left_Type_Attribute => 1636, - Iir_Kind_Right_Type_Attribute => 1641, - Iir_Kind_High_Type_Attribute => 1646, - Iir_Kind_Low_Type_Attribute => 1651, - Iir_Kind_Ascending_Type_Attribute => 1656, - Iir_Kind_Image_Attribute => 1662, - Iir_Kind_Value_Attribute => 1668, - Iir_Kind_Pos_Attribute => 1674, - Iir_Kind_Val_Attribute => 1680, - Iir_Kind_Succ_Attribute => 1686, - Iir_Kind_Pred_Attribute => 1692, - Iir_Kind_Leftof_Attribute => 1698, - Iir_Kind_Rightof_Attribute => 1704, - Iir_Kind_Delayed_Attribute => 1713, - Iir_Kind_Stable_Attribute => 1722, - Iir_Kind_Quiet_Attribute => 1731, - Iir_Kind_Transaction_Attribute => 1740, - Iir_Kind_Event_Attribute => 1744, - Iir_Kind_Active_Attribute => 1748, - Iir_Kind_Last_Event_Attribute => 1752, - Iir_Kind_Last_Active_Attribute => 1756, - Iir_Kind_Last_Value_Attribute => 1760, - Iir_Kind_Driving_Attribute => 1764, - Iir_Kind_Driving_Value_Attribute => 1768, - Iir_Kind_Behavior_Attribute => 1768, - Iir_Kind_Structure_Attribute => 1768, - Iir_Kind_Simple_Name_Attribute => 1775, - Iir_Kind_Instance_Name_Attribute => 1780, - Iir_Kind_Path_Name_Attribute => 1785, - Iir_Kind_Left_Array_Attribute => 1792, - Iir_Kind_Right_Array_Attribute => 1799, - Iir_Kind_High_Array_Attribute => 1806, - Iir_Kind_Low_Array_Attribute => 1813, - Iir_Kind_Length_Array_Attribute => 1820, - Iir_Kind_Ascending_Array_Attribute => 1827, - Iir_Kind_Range_Array_Attribute => 1834, - Iir_Kind_Reverse_Range_Array_Attribute => 1841, - Iir_Kind_Attribute_Name => 1850 + Iir_Kind_Selected_Waveform_Assignment_Statement => 1460, + Iir_Kind_Null_Statement => 1464, + Iir_Kind_Assertion_Statement => 1471, + Iir_Kind_Report_Statement => 1477, + Iir_Kind_Wait_Statement => 1484, + Iir_Kind_Variable_Assignment_Statement => 1490, + Iir_Kind_Conditional_Variable_Assignment_Statement => 1496, + Iir_Kind_Return_Statement => 1502, + Iir_Kind_For_Loop_Statement => 1511, + Iir_Kind_While_Loop_Statement => 1519, + Iir_Kind_Next_Statement => 1525, + Iir_Kind_Exit_Statement => 1531, + Iir_Kind_Case_Statement => 1539, + Iir_Kind_Procedure_Call_Statement => 1545, + Iir_Kind_If_Statement => 1554, + Iir_Kind_Elsif => 1559, + Iir_Kind_Character_Literal => 1567, + Iir_Kind_Simple_Name => 1575, + Iir_Kind_Selected_Name => 1584, + Iir_Kind_Operator_Symbol => 1590, + Iir_Kind_Reference_Name => 1593, + Iir_Kind_Selected_By_All_Name => 1599, + Iir_Kind_Parenthesis_Name => 1604, + Iir_Kind_External_Constant_Name => 1612, + Iir_Kind_External_Signal_Name => 1620, + Iir_Kind_External_Variable_Name => 1628, + Iir_Kind_Package_Pathname => 1632, + Iir_Kind_Absolute_Pathname => 1633, + Iir_Kind_Relative_Pathname => 1634, + Iir_Kind_Pathname_Element => 1639, + Iir_Kind_Base_Attribute => 1641, + Iir_Kind_Left_Type_Attribute => 1646, + Iir_Kind_Right_Type_Attribute => 1651, + Iir_Kind_High_Type_Attribute => 1656, + Iir_Kind_Low_Type_Attribute => 1661, + Iir_Kind_Ascending_Type_Attribute => 1666, + Iir_Kind_Image_Attribute => 1672, + Iir_Kind_Value_Attribute => 1678, + Iir_Kind_Pos_Attribute => 1684, + Iir_Kind_Val_Attribute => 1690, + Iir_Kind_Succ_Attribute => 1696, + Iir_Kind_Pred_Attribute => 1702, + Iir_Kind_Leftof_Attribute => 1708, + Iir_Kind_Rightof_Attribute => 1714, + Iir_Kind_Delayed_Attribute => 1723, + Iir_Kind_Stable_Attribute => 1732, + Iir_Kind_Quiet_Attribute => 1741, + Iir_Kind_Transaction_Attribute => 1750, + Iir_Kind_Event_Attribute => 1754, + Iir_Kind_Active_Attribute => 1758, + Iir_Kind_Last_Event_Attribute => 1762, + Iir_Kind_Last_Active_Attribute => 1766, + Iir_Kind_Last_Value_Attribute => 1770, + Iir_Kind_Driving_Attribute => 1774, + Iir_Kind_Driving_Value_Attribute => 1778, + Iir_Kind_Behavior_Attribute => 1778, + Iir_Kind_Structure_Attribute => 1778, + Iir_Kind_Simple_Name_Attribute => 1785, + Iir_Kind_Instance_Name_Attribute => 1790, + Iir_Kind_Path_Name_Attribute => 1795, + Iir_Kind_Left_Array_Attribute => 1802, + Iir_Kind_Right_Array_Attribute => 1809, + Iir_Kind_High_Array_Attribute => 1816, + Iir_Kind_Low_Array_Attribute => 1823, + Iir_Kind_Length_Array_Attribute => 1830, + Iir_Kind_Ascending_Array_Attribute => 1837, + Iir_Kind_Range_Array_Attribute => 1844, + Iir_Kind_Reverse_Range_Array_Attribute => 1851, + Iir_Kind_Attribute_Name => 1860 ); function Get_Fields (K : Iir_Kind) return Fields_Array @@ -6584,7 +6598,8 @@ package body Nodes_Meta is | Iir_Kind_Concurrent_Conditional_Signal_Assignment | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Simple_Signal_Assignment_Statement - | Iir_Kind_Conditional_Signal_Assignment_Statement => + | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement => return True; when others => return False; @@ -7156,6 +7171,7 @@ package body Nodes_Meta is | Iir_Kind_Simple_Simultaneous_Statement | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement @@ -7939,6 +7955,7 @@ package body Nodes_Meta is | Iir_Kind_Generate_Statement_Body | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement @@ -7987,6 +8004,7 @@ package body Nodes_Meta is | Iir_Kind_Simple_Simultaneous_Statement | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement @@ -8071,6 +8089,7 @@ package body Nodes_Meta is | Iir_Kind_If_Generate_Else_Clause | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement @@ -8403,6 +8422,7 @@ package body Nodes_Meta is | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Variable_Assignment_Statement | Iir_Kind_Conditional_Variable_Assignment_Statement => return True; @@ -8442,7 +8462,8 @@ package body Nodes_Meta is | Iir_Kind_Concurrent_Conditional_Signal_Assignment | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Simple_Signal_Assignment_Statement - | Iir_Kind_Conditional_Signal_Assignment_Statement => + | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement => return True; when others => return False; @@ -8456,7 +8477,8 @@ package body Nodes_Meta is | Iir_Kind_Concurrent_Conditional_Signal_Assignment | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Simple_Signal_Assignment_Statement - | Iir_Kind_Conditional_Signal_Assignment_Statement => + | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement => return True; when others => return False; @@ -8861,6 +8883,7 @@ package body Nodes_Meta is | Iir_Kind_Allocator_By_Expression | Iir_Kind_Concurrent_Selected_Signal_Assignment | Iir_Kind_Case_Generate_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Variable_Assignment_Statement | Iir_Kind_Return_Statement | Iir_Kind_Case_Statement => @@ -8888,7 +8911,13 @@ package body Nodes_Meta is function Has_Selected_Waveform_Chain (K : Iir_Kind) return Boolean is begin - return K = Iir_Kind_Concurrent_Selected_Signal_Assignment; + case K is + when Iir_Kind_Concurrent_Selected_Signal_Assignment + | Iir_Kind_Selected_Waveform_Assignment_Statement => + return True; + when others => + return False; + end case; end Has_Selected_Waveform_Chain; function Has_Conditional_Waveform_Chain (K : Iir_Kind) return Boolean is @@ -9117,6 +9146,7 @@ package body Nodes_Meta is | Iir_Kind_If_Generate_Else_Clause | Iir_Kind_Simple_Signal_Assignment_Statement | Iir_Kind_Conditional_Signal_Assignment_Statement + | Iir_Kind_Selected_Waveform_Assignment_Statement | Iir_Kind_Null_Statement | Iir_Kind_Assertion_Statement | Iir_Kind_Report_Statement diff --git a/src/vhdl/translate/trans-chap8.adb b/src/vhdl/translate/trans-chap8.adb index d17b1f4ec..2311d5d8b 100644 --- a/src/vhdl/translate/trans-chap8.adb +++ b/src/vhdl/translate/trans-chap8.adb @@ -1147,12 +1147,10 @@ package body Trans.Chap8 is -- NBR_CHOICES is the number of non-others choices. procedure Translate_String_Case_Statement_Dichotomy (Stmt : Iir; + Choices_Chain : Iir; Nbr_Choices : Positive; Handler : in out Case_Handler'Class) is - Choices_Chain : constant Iir := - Get_Case_Statement_Alternative_Chain (Stmt); - type Choice_Id is new Integer; subtype Valid_Choice_Id is Choice_Id range 0 .. Choice_Id (Nbr_Choices - 1); @@ -1551,7 +1549,7 @@ package body Trans.Chap8 is -- Case statement whose expression is an unidim array. -- Translate into if/elsif statements (linear search). procedure Translate_String_Case_Statement_Linear - (Stmt : Iir; Handler : in out Case_Handler'Class) + (Stmt : Iir; Choices : Iir; Handler : in out Case_Handler'Class) is Expr_Type : Iir; -- Node containing the address of the selector. @@ -1628,7 +1626,7 @@ package body Trans.Chap8 is Cond_Var := Create_Temp (Std_Boolean_Type_Node); - Translate_String_Choice (Get_Case_Statement_Alternative_Chain (Stmt)); + Translate_String_Choice (Choices); Close_Temp; end Translate_String_Case_Statement_Linear; @@ -1664,7 +1662,18 @@ package body Trans.Chap8 is is Expr : constant Iir := Get_Expression (N); Expr_Type : constant Iir := Get_Type (Expr); + Choices : Iir; begin + -- Get the chain of choices. + case Get_Kind (N) is + when Iir_Kind_Case_Statement => + Choices := Get_Case_Statement_Alternative_Chain (N); + when Iir_Kind_Selected_Waveform_Assignment_Statement => + Choices := Get_Selected_Waveform_Chain (N); + when others => + Error_Kind ("translate_case", N); + end case; + if Get_Kind (Expr_Type) = Iir_Kind_Array_Subtype_Definition then -- Expression is a one-dimensional array. declare @@ -1672,7 +1681,7 @@ package body Trans.Chap8 is Choice : Iir; begin -- Count number of choices. - Choice := Get_Case_Statement_Alternative_Chain (N); + Choice := Choices; while Choice /= Null_Iir loop case Get_Kind (Choice) is when Iir_Kind_Choice_By_Others => @@ -1688,10 +1697,10 @@ package body Trans.Chap8 is -- Select the strategy according to the number of choices. if Nbr_Choices < 3 then - Translate_String_Case_Statement_Linear (N, Handler); + Translate_String_Case_Statement_Linear (N, Choices, Handler); else Translate_String_Case_Statement_Dichotomy - (N, Nbr_Choices, Handler); + (N, Choices, Nbr_Choices, Handler); end if; end; else @@ -1702,7 +1711,7 @@ package body Trans.Chap8 is Stmt_Chain : Iir; begin Start_Case_Stmt (Case_Blk, Chap7.Translate_Expression (Expr)); - Choice := Get_Case_Statement_Alternative_Chain (N); + Choice := Choices; while Choice /= Null_Iir loop Start_Choice (Case_Blk); Stmt_Chain := Get_Associated_Chain (Choice); @@ -3978,83 +3987,113 @@ package body Trans.Chap8 is Update_Data_Record => Gen_Signal_Direct_Update_Data_Record, Finish_Data_Record => Gen_Signal_Direct_Finish_Data_Composite); - procedure Translate_Direct_Signal_Assignment (Stmt : Iir; We : Iir) + procedure Translate_Direct_Signal_Assignment + (Target : Iir; Targ : Mnode; Drv : Mnode; We : Iir) is - Target : constant Iir := Get_Target (Stmt); Target_Type : constant Iir := Get_Type (Target); Arg : Signal_Direct_Assign_Data; - Targ_Sig : Mnode; begin - Chap6.Translate_Direct_Driver (Target, Targ_Sig, Arg.Drv); - + Arg.Drv := Drv; Arg.Expr := E2M (Chap7.Translate_Expression (We, Target_Type), Get_Info (Target_Type), Mode_Value); Arg.Expr_Node := We; - Gen_Signal_Direct_Assign (Targ_Sig, Target_Type, Arg); - Chap9.Destroy_Types (Target); + Gen_Signal_Direct_Assign (Targ, Target_Type, Arg); end Translate_Direct_Signal_Assignment; - procedure Translate_Simple_Signal_Assignment_Statement (Stmt : Iir) - is - Target : constant Iir := Get_Target (Stmt); - Target_Type : constant Iir := Get_Type (Target); - We : Iir_Waveform_Element; - Targ : Mnode; - Val : O_Enode; - Value : Iir; - Is_Simple : Boolean; + -- Return True iff signal assignment statement STMT has a delay mechanism: + -- either transport or a reject delay. + function Is_Reject_Signal_Assignment (Stmt : Iir) return Boolean is + begin + return Get_Delay_Mechanism (Stmt) /= Iir_Inertial_Delay + or else Get_Reject_Time_Expression (Stmt) /= Null_Iir; + end Is_Reject_Signal_Assignment; + + -- Return True if waveform chain WE has only one expression, ie: + -- * no time expression + -- * one element + -- * not a null + -- which corresponds to: + -- ... <= EXPR + function Is_Simple_Waveform (We : Iir) return Boolean is begin - We := Get_Waveform_Chain (Stmt); - if We /= Null_Iir and then Get_Chain (We) = Null_Iir and then Get_Time (We) = Null_Iir - and then Get_Delay_Mechanism (Stmt) = Iir_Inertial_Delay - and then Get_Reject_Time_Expression (Stmt) = Null_Iir then - -- Simple signal assignment ? - Value := Get_We_Value (We); - Is_Simple := Get_Kind (Value) /= Iir_Kind_Null_Literal; + return Get_Kind (Get_We_Value (We)) /= Iir_Kind_Null_Literal; else - Is_Simple := False; + return False; end if; + end Is_Simple_Waveform; + -- Valid only for single_signal_assignment. + -- True iff direct assignment can be used. + function Is_Direct_Signal_Assignment (Target : Iir) return Boolean is + begin + return Flag_Direct_Drivers + and then Get_Kind (Target) /= Iir_Kind_Aggregate + and then Chap4.Has_Direct_Driver (Target); + end Is_Direct_Signal_Assignment; + + type Signal_Assignment_Mechanism is + (Signal_Assignment_Direct, + Signal_Assignment_Simple, + Signal_Assignment_General); + + procedure Translate_Signal_Assignment_Target + (Target : Iir; + Mechanism : Signal_Assignment_Mechanism; + Targ : out Mnode; + Drv : out Mnode) + is + Target_Type : constant Iir := Get_Type (Target); + begin if Get_Kind (Target) = Iir_Kind_Aggregate then Chap3.Translate_Anonymous_Type_Definition (Target_Type); Targ := Create_Temp (Get_Info (Target_Type), Mode_Signal); Chap4.Allocate_Complex_Object (Target_Type, Alloc_Stack, Targ); Translate_Signal_Target_Aggr (Targ, Target, Target_Type); else - if Is_Simple - and then Flag_Direct_Drivers - and then Chap4.Has_Direct_Driver (Target) - then - Translate_Direct_Signal_Assignment (Stmt, Value); - return; + if Mechanism = Signal_Assignment_Direct then + Chap6.Translate_Direct_Driver (Target, Targ, Drv); + else + Targ := Chap6.Translate_Name (Target, Mode_Signal); end if; - Targ := Chap6.Translate_Name (Target, Mode_Signal); + end if; + end Translate_Signal_Assignment_Target; + + procedure Translate_Waveform_Assignment + (Stmt : Iir; + Mechanism : Signal_Assignment_Mechanism; + Wf_Chain : Iir; + Targ : Mnode; + Drv : Mnode) + is + Target : constant Iir := Get_Target (Stmt); + Target_Type : constant Iir := Get_Type (Target); + We : Iir_Waveform_Element; + Val : O_Enode; + Value : Iir; + begin + if Mechanism = Signal_Assignment_Direct then + Translate_Direct_Signal_Assignment + (Target, Targ, Drv, Get_We_Value (Wf_Chain)); + return; end if; - if We = Null_Iir then + if Wf_Chain = Null_Iir then -- Implicit disconnect statment. Register_Signal (Targ, Target_Type, Ghdl_Signal_Disconnect); - Chap9.Destroy_Types (Target); return; end if; -- Handle a simple and common case: only one waveform, inertial, -- and no time (eg: sig <= expr). - Value := Get_We_Value (We); + Value := Get_We_Value (Wf_Chain); Signal_Assign_Line := Get_Line_Number (Value); - if Get_Chain (We) = Null_Iir - and then Get_Time (We) = Null_Iir - and then Get_Delay_Mechanism (Stmt) = Iir_Inertial_Delay - and then Get_Reject_Time_Expression (Stmt) = Null_Iir - and then Get_Kind (Value) /= Iir_Kind_Null_Literal - then + if Mechanism = Signal_Assignment_Simple then Val := Chap7.Translate_Expression (Value, Target_Type); Gen_Simple_Signal_Assign (Targ, Target_Type, Val); - Chap9.Destroy_Types (Target); return; end if; @@ -4068,6 +4107,7 @@ package body Trans.Chap8 is Var_Targ := Stabilize (Targ, True); -- Translate the first waveform element. + We := Wf_Chain; declare Reject_Time : O_Dnode; After_Time : O_Dnode; @@ -4153,9 +4193,97 @@ package body Trans.Chap8 is Close_Temp; end; + end Translate_Waveform_Assignment; + + procedure Translate_Simple_Signal_Assignment_Statement (Stmt : Iir) + is + Target : constant Iir := Get_Target (Stmt); + Wf_Chain : constant Iir := Get_Waveform_Chain (Stmt); + Mechanism : Signal_Assignment_Mechanism; + Targ : Mnode; + Drv : Mnode; + begin + if Is_Reject_Signal_Assignment (Stmt) + or else not Is_Simple_Waveform (Wf_Chain) + then + Mechanism := Signal_Assignment_General; + else + if Is_Direct_Signal_Assignment (Target) then + Mechanism := Signal_Assignment_Direct; + else + Mechanism := Signal_Assignment_Simple; + end if; + end if; + + Translate_Signal_Assignment_Target (Target, Mechanism, Targ, Drv); + + Translate_Waveform_Assignment (Stmt, Mechanism, Wf_Chain, Targ, Drv); + Chap9.Destroy_Types (Target); end Translate_Simple_Signal_Assignment_Statement; + type Selected_Assignment_Handler is new Case_Handler with record + Stmt : Iir; + Mechanism : Signal_Assignment_Mechanism; + Targ : Mnode; + Drv : Mnode; + end record; + + procedure Case_Association_Cb + (Assoc : Iir; Handler : in out Selected_Assignment_Handler) + is + begin + Translate_Waveform_Assignment + (Handler.Stmt, Handler.Mechanism, Assoc, Handler.Targ, Handler.Drv); + end Case_Association_Cb; + + procedure Translate_Selected_Waveform_Assignment_Statement (Stmt : Iir) + is + Target : constant Iir := Get_Target (Stmt); + Swf_Chain : constant Iir := Get_Selected_Waveform_Chain (Stmt); + Swf : Iir; + Wf : Iir; + Handler : Selected_Assignment_Handler; + begin + Handler.Stmt := Stmt; + + -- Compute the mechanism used. + if Is_Reject_Signal_Assignment (Stmt) then + Handler.Mechanism := Signal_Assignment_General; + else + if Is_Direct_Signal_Assignment (Target) then + Handler.Mechanism := Signal_Assignment_Direct; + else + Handler.Mechanism := Signal_Assignment_Simple; + end if; + Swf := Swf_Chain; + while Swf /= Null_Iir loop + Wf := Get_Associated_Chain (Swf); + if Wf /= Null_Iir then + if not Is_Simple_Waveform (Wf) then + Handler.Mechanism := Signal_Assignment_General; + exit; + end if; + end if; + Swf := Get_Chain (Swf); + end loop; + end if; + + Open_Temp; + + Translate_Signal_Assignment_Target + (Target, Handler.Mechanism, Handler.Targ, Handler.Drv); + + Handler.Targ := Stabilize (Handler.Targ, True); + if Handler.Mechanism = Signal_Assignment_Direct then + Handler.Drv := Stabilize (Handler.Drv, True); + end if; + + Translate_Case (Stmt, Handler); + + Close_Temp; + end Translate_Selected_Waveform_Assignment_Statement; + procedure Translate_Statement (Stmt : Iir) is begin @@ -4184,6 +4312,8 @@ package body Trans.Chap8 is when Iir_Kind_Simple_Signal_Assignment_Statement => Translate_Simple_Signal_Assignment_Statement (Stmt); + when Iir_Kind_Selected_Waveform_Assignment_Statement => + Translate_Selected_Waveform_Assignment_Statement (Stmt); when Iir_Kind_Variable_Assignment_Statement => Translate_Variable_Assignment_Statement (Stmt); when Iir_Kind_Conditional_Variable_Assignment_Statement => diff --git a/src/vhdl/translate/trans_analyzes.adb b/src/vhdl/translate/trans_analyzes.adb index 427989935..93701819e 100644 --- a/src/vhdl/translate/trans_analyzes.adb +++ b/src/vhdl/translate/trans_analyzes.adb @@ -66,7 +66,7 @@ package body Trans_Analyzes is Status : Walk_Status; pragma Unreferenced (Status); begin - case Get_Kind (Stmt) is + case Iir_Kinds_Sequential_Statement (Get_Kind (Stmt)) is when Iir_Kind_Simple_Signal_Assignment_Statement => Extract_Has_After (Get_Waveform_Chain (Stmt)); Status := Walk_Assignment_Target @@ -83,6 +83,18 @@ package body Trans_Analyzes is Status := Walk_Assignment_Target (Get_Target (Stmt), Extract_Driver_Target'Access); end; + when Iir_Kind_Selected_Waveform_Assignment_Statement => + declare + Swf : Iir; + begin + Swf := Get_Selected_Waveform_Chain (Stmt); + while Swf /= Null_Iir loop + Extract_Has_After (Get_Associated_Chain (Swf)); + Swf := Get_Chain (Swf); + end loop; + Status := Walk_Assignment_Target + (Get_Target (Stmt), Extract_Driver_Target'Access); + end; when Iir_Kind_Procedure_Call_Statement => declare Call : constant Iir := Get_Procedure_Call (Stmt); @@ -109,7 +121,19 @@ package body Trans_Analyzes is Next_Association_Interface (Assoc, Inter); end loop; end; - when others => + when Iir_Kind_Null_Statement + | Iir_Kind_Assertion_Statement + | Iir_Kind_Report_Statement + | Iir_Kind_Wait_Statement + | Iir_Kind_Return_Statement + | Iir_Kind_Next_Statement + | Iir_Kind_Exit_Statement + | Iir_Kind_Variable_Assignment_Statement + | Iir_Kind_Conditional_Variable_Assignment_Statement + | Iir_Kind_For_Loop_Statement + | Iir_Kind_While_Loop_Statement + | Iir_Kind_Case_Statement + | Iir_Kind_If_Statement => null; end case; return Walk_Continue; |