aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2016-10-21 08:50:52 +0200
committerTristan Gingold <tgingold@free.fr>2016-11-01 13:11:42 +0100
commitd5f2c69f322973e62d4bd61cd659317397efd4bc (patch)
treedd937d4b86d31b755474d30970b35ed7fe63d648
parenta98d989710eec4b44d2532bd31c8fbba209c8172 (diff)
downloadghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.tar.gz
ghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.tar.bz2
ghdl-d5f2c69f322973e62d4bd61cd659317397efd4bc.zip
Add translation for selected signal assignment.
-rw-r--r--src/vhdl/disp_vhdl.adb48
-rw-r--r--src/vhdl/errorout.adb3
-rw-r--r--src/vhdl/iirs.adb1
-rw-r--r--src/vhdl/iirs.ads9
-rw-r--r--src/vhdl/iirs_walk.adb1
-rw-r--r--src/vhdl/nodes_meta.adb174
-rw-r--r--src/vhdl/translate/trans-chap8.adb230
-rw-r--r--src/vhdl/translate/trans_analyzes.adb28
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;