aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-06-08 07:52:43 +0200
committerTristan Gingold <tgingold@free.fr>2019-06-08 07:52:43 +0200
commitc5fbc11795004074b9f2f52e94e13d5907f1c95b (patch)
tree8fbe2aa0d82011bb95d67a3cc3b2ffd205b6b3e7
parent2a21ee61dd73224bec023b3a541c9d4ddaee0f88 (diff)
downloadghdl-c5fbc11795004074b9f2f52e94e13d5907f1c95b.tar.gz
ghdl-c5fbc11795004074b9f2f52e94e13d5907f1c95b.tar.bz2
ghdl-c5fbc11795004074b9f2f52e94e13d5907f1c95b.zip
synth: support conditional signal assignments.
-rw-r--r--src/synth/synth-context.adb8
-rw-r--r--src/synth/synth-expr.adb6
-rw-r--r--src/synth/synth-stmts.adb44
-rw-r--r--src/synth/synth-stmts.ads3
-rw-r--r--src/synth/synth-values.adb11
-rw-r--r--src/synth/synth-values.ads10
-rw-r--r--src/synth/synthesis.adb6
7 files changed, 79 insertions, 9 deletions
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb
index 135b40d7c..d26562481 100644
--- a/src/synth/synth-context.adb
+++ b/src/synth/synth-context.adb
@@ -135,6 +135,14 @@ package body Synth.Context is
return Get_Current_Value (Val.W);
when Value_Net =>
return Val.N;
+ when Value_Mux2 =>
+ declare
+ Cond : constant Net := Get_Net (Val.M_Cond);
+ begin
+ return Build_Mux2 (Ctxt => Build_Context, Sel => Cond,
+ I0 => Get_Net (Val.M_F),
+ I1 => Get_Net (Val.M_T));
+ end;
when Value_Lit =>
case Val.Lit.Kind is
when Iir_Value_B1 =>
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 10ea5123f..39befa21f 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -526,6 +526,12 @@ package body Synth.Expr is
Get_Net (Left),
Synth_Uresize (Right, Get_Width (Left))),
No_Range);
+ when Iir_Predefined_Ieee_Numeric_Std_Eq_Uns_Uns =>
+ -- "=" (Unsigned, Unsigned)
+ return Create_Value_Net
+ (Build_Compare (Build_Context, Id_Eq,
+ Get_Net (Left), Get_Net (Right)),
+ No_Range);
when Iir_Predefined_Array_Element_Concat =>
declare
L : constant Net := Get_Net (Left);
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index cbb96efe9..760057f7c 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -48,8 +48,7 @@ with Netlists.Builders; use Netlists.Builders;
package body Synth.Stmts is
function Synth_Waveform (Syn_Inst : Synth_Instance_Acc;
Wf : Iir;
- Targ_Type : Iir) return Value_Acc
- is
+ Targ_Type : Iir) return Value_Acc is
begin
if Get_Kind (Wf) = Iir_Kind_Unaffected_Waveform then
-- TODO
@@ -67,8 +66,7 @@ package body Synth.Stmts is
(Syn_Inst, Get_We_Value (Wf), Targ_Type);
end Synth_Waveform;
- procedure Synth_Assign (Dest : Value_Acc; Val : Value_Acc)
- is
+ procedure Synth_Assign (Dest : Value_Acc; Val : Value_Acc) is
begin
case Dest.Kind is
when Value_Wire =>
@@ -140,6 +138,37 @@ package body Synth.Stmts is
Synth_Assignment (Syn_Inst, Target, Val);
end Synth_Simple_Signal_Assignment;
+ procedure Synth_Conditional_Signal_Assignment
+ (Syn_Inst : Synth_Instance_Acc; Stmt : Iir)
+ is
+ Target : constant Node := Get_Target (Stmt);
+ Targ_Type : constant Node := Get_Type (Target);
+ Cond : Node;
+ Cwf : Node;
+ Val, Cond_Val : Value_Acc;
+ First, Last : Value_Acc;
+ begin
+ Last := null;
+ Cwf := Get_Conditional_Waveform_Chain (Stmt);
+ while Cwf /= Null_Node loop
+ Val := Synth_Waveform (Syn_Inst, Get_Waveform_Chain (Cwf), Targ_Type);
+ Cond := Get_Condition (Cwf);
+ if Cond /= Null_Node then
+ Cond_Val := Synth_Expression (Syn_Inst, Cond);
+ Val := Create_Value_Mux2 (Cond_Val, Val, null);
+ end if;
+
+ if Last /= null then
+ Last.M_F := Val;
+ else
+ First := Val;
+ end if;
+ Last := Val;
+ Cwf := Get_Chain (Cwf);
+ end loop;
+ Synth_Assignment (Syn_Inst, Target, First);
+ end Synth_Conditional_Signal_Assignment;
+
procedure Synth_Variable_Assignment
(Syn_Inst : Synth_Instance_Acc; Stmt : Iir)
is
@@ -800,7 +829,8 @@ package body Synth.Stmts is
Instance_Pool := null;
end Synth_Process_Statement;
- procedure Synth_Statements (Syn_Inst : Synth_Instance_Acc; Stmts : Iir)
+ procedure Synth_Concurrent_Statements
+ (Syn_Inst : Synth_Instance_Acc; Stmts : Iir)
is
Sim_Child : Block_Instance_Acc;
Stmt : Iir;
@@ -812,6 +842,8 @@ package body Synth.Stmts is
case Get_Kind (Stmt) is
when Iir_Kind_Concurrent_Simple_Signal_Assignment =>
Synth_Simple_Signal_Assignment (Syn_Inst, Stmt);
+ when Iir_Kind_Concurrent_Conditional_Signal_Assignment =>
+ Synth_Conditional_Signal_Assignment (Syn_Inst, Stmt);
when Iir_Kind_Sensitized_Process_Statement =>
Synth_Process_Statement (Syn_Inst, Sim_Child, Stmt);
Sim_Child := Sim_Child.Brother;
@@ -825,5 +857,5 @@ package body Synth.Stmts is
Pop_And_Merge_Phi (Build_Context);
Stmt := Get_Chain (Stmt);
end loop;
- end Synth_Statements;
+ end Synth_Concurrent_Statements;
end Synth.Stmts;
diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads
index 97bce696d..a5da03f56 100644
--- a/src/synth/synth-stmts.ads
+++ b/src/synth/synth-stmts.ads
@@ -23,5 +23,6 @@ with Synth.Context; use Synth.Context;
package Synth.Stmts is
-- Generate netlists for concurrent statements STMTS.
- procedure Synth_Statements (Syn_Inst : Synth_Instance_Acc; Stmts : Iir);
+ procedure Synth_Concurrent_Statements
+ (Syn_Inst : Synth_Instance_Acc; Stmts : Iir);
end Synth.Stmts;
diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb
index 238341627..cb68848e2 100644
--- a/src/synth/synth-values.adb
+++ b/src/synth/synth-values.adb
@@ -53,6 +53,17 @@ package body Synth.Values is
Value_Type_Net'(Kind => Value_Net, N => N, N_Range => Rng)));
end Create_Value_Net;
+ function Create_Value_Mux2 (Cond : Value_Acc; T : Value_Acc; F : Value_Acc)
+ return Value_Acc
+ is
+ subtype Value_Type_Mux2 is Value_Type (Value_Mux2);
+ function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Mux2);
+ begin
+ return To_Value_Acc
+ (Alloc (Current_Pool,
+ (Kind => Value_Mux2, M_Cond => Cond, M_T => T, M_F => F)));
+ end Create_Value_Mux2;
+
function Create_Value_Lit (Val : Iir_Value_Literal_Acc; Typ : Iir)
return Value_Acc
is
diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads
index a889c4e81..cc452a556 100644
--- a/src/synth/synth-values.ads
+++ b/src/synth/synth-values.ads
@@ -38,6 +38,8 @@ package Synth.Values is
-- into a net.
Value_Wire,
+ Value_Mux2,
+
-- A non-vector array.
Value_Array,
@@ -78,6 +80,10 @@ package Synth.Values is
when Value_Wire =>
W : Wire_Id;
W_Range : Value_Range_Acc;
+ when Value_Mux2 =>
+ M_Cond : Value_Acc;
+ M_T : Value_Acc;
+ M_F : Value_Acc;
when Value_Lit =>
Lit : Simul.Environments.Iir_Value_Literal_Acc;
Lit_Type : Iir;
@@ -96,6 +102,10 @@ package Synth.Values is
function Create_Value_Wire (W : Wire_Id; Rng : Value_Range_Acc)
return Value_Acc;
+ -- Create a mux2.
+ function Create_Value_Mux2 (Cond : Value_Acc; T : Value_Acc; F : Value_Acc)
+ return Value_Acc;
+
-- Create a Value_Lit.
function Create_Value_Lit (Val : Iir_Value_Literal_Acc; Typ : Iir)
return Value_Acc;
diff --git a/src/synth/synthesis.adb b/src/synth/synthesis.adb
index 7f42d018c..cd72354e4 100644
--- a/src/synth/synthesis.adb
+++ b/src/synth/synthesis.adb
@@ -221,10 +221,12 @@ package body Synthesis is
end loop;
Synth_Declarations (Syn_Inst, Get_Declaration_Chain (Entity));
- Synth_Statements (Syn_Inst, Get_Concurrent_Statement_Chain (Entity));
+ Synth_Concurrent_Statements
+ (Syn_Inst, Get_Concurrent_Statement_Chain (Entity));
Synth_Declarations (Syn_Inst, Get_Declaration_Chain (Arch));
- Synth_Statements (Syn_Inst, Get_Concurrent_Statement_Chain (Arch));
+ Synth_Concurrent_Statements
+ (Syn_Inst, Get_Concurrent_Statement_Chain (Arch));
-- Remove unused gates. This is not only an optimization but also
-- a correctness point: there might be some unsynthesizable gates, like