aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-01-13 18:20:52 +0100
committerTristan Gingold <tgingold@free.fr>2021-01-13 18:55:30 +0100
commit2fb32502d2a12ac78cc3f5fb4068104b66018ea5 (patch)
tree268ee539a8a7ba8362ecc1a896a488f1f2e13f28 /src
parentb510f0ea03bc88cbf375ce13c29e97941b561a72 (diff)
downloadghdl-2fb32502d2a12ac78cc3f5fb4068104b66018ea5.tar.gz
ghdl-2fb32502d2a12ac78cc3f5fb4068104b66018ea5.tar.bz2
ghdl-2fb32502d2a12ac78cc3f5fb4068104b66018ea5.zip
synth: always finalize declarations. Fix #1591
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-decls.adb22
-rw-r--r--src/synth/synth-decls.ads3
-rw-r--r--src/synth/synth-environment.adb29
-rw-r--r--src/synth/synth-environment.ads5
-rw-r--r--src/synth/synth-insts.adb15
-rw-r--r--src/synth/synth-stmts.adb51
6 files changed, 101 insertions, 24 deletions
diff --git a/src/synth/synth-decls.adb b/src/synth/synth-decls.adb
index 9fabb7a49..047eac454 100644
--- a/src/synth/synth-decls.adb
+++ b/src/synth/synth-decls.adb
@@ -1094,14 +1094,24 @@ package body Synth.Decls is
pragma Assert (Is_Error (Syn_Inst));
return;
end if;
+ if Vt.Val.Kind = Value_Net then
+ -- Could be a net for in ports.
+ return;
+ end if;
+
+ Finalize_Assignment (Get_Build (Syn_Inst), Vt.Val.W);
Gate_Net := Get_Wire_Gate (Vt.Val.W);
Gate := Get_Net_Parent (Gate_Net);
case Get_Id (Gate) is
- when Id_Signal =>
+ when Id_Signal
+ | Id_Output
+ | Id_Inout =>
Drv := Get_Input_Net (Gate, 0);
Def_Val := No_Net;
- when Id_Isignal =>
+ when Id_Isignal
+ | Id_Ioutput
+ | Id_Iinout =>
Drv := Get_Input_Net (Gate, 0);
Def_Val := Get_Input_Net (Gate, 1);
when others =>
@@ -1140,14 +1150,18 @@ package body Synth.Decls is
declare
Vt : constant Valtyp := Get_Value (Syn_Inst, Decl);
begin
- if Vt /= No_Valtyp then
+ if Vt /= No_Valtyp
+ and then Vt.Val.Kind = Value_Wire
+ then
+ Finalize_Assignment (Get_Build (Syn_Inst), Vt.Val.W);
Free_Wire (Vt.Val.W);
end if;
end;
end if;
when Iir_Kind_Constant_Declaration =>
null;
- when Iir_Kind_Signal_Declaration =>
+ when Iir_Kind_Signal_Declaration
+ | Iir_Kind_Interface_Signal_Declaration =>
pragma Assert (not Is_Subprg);
Finalize_Signal (Syn_Inst, Decl);
when Iir_Kind_Anonymous_Signal_Declaration =>
diff --git a/src/synth/synth-decls.ads b/src/synth/synth-decls.ads
index d0b47e3fc..fdaadf0f1 100644
--- a/src/synth/synth-decls.ads
+++ b/src/synth/synth-decls.ads
@@ -59,6 +59,9 @@ package Synth.Decls is
Decls : Iir;
Is_Subprg : Boolean := False);
+ procedure Finalize_Declaration (Syn_Inst : Synth_Instance_Acc;
+ Decl : Iir;
+ Is_Subprg : Boolean);
procedure Finalize_Declarations (Syn_Inst : Synth_Instance_Acc;
Decls : Iir;
Is_Subprg : Boolean := False);
diff --git a/src/synth/synth-environment.adb b/src/synth/synth-environment.adb
index d1d07a66b..a6795d108 100644
--- a/src/synth/synth-environment.adb
+++ b/src/synth/synth-environment.adb
@@ -76,7 +76,9 @@ package body Synth.Environment is
-- Check the wire was not already free.
pragma Assert (Wire_Rec.Kind /= Wire_None);
+ -- All the assignments have been handled.
pragma Assert (Wire_Rec.Cur_Assign = No_Seq_Assign);
+
Wire_Rec.Kind := Wire_None;
end Free_Wire;
@@ -398,7 +400,11 @@ package body Synth.Environment is
when True =>
-- Create a net. No inference to do.
Res := Synth.Context.Get_Memtyp_Net (Ctxt, Asgn_Rec.Val.Val);
- Add_Conc_Assign (Wid, Res, 0, Stmt);
+ if Wire_Rec.Kind = Wire_Enable then
+ Connect (Get_Input (Get_Net_Parent (Outport), 0), Res);
+ else
+ Add_Conc_Assign (Wid, Res, 0, Stmt);
+ end if;
when False =>
P := Asgn_Rec.Val.Asgns;
pragma Assert (P /= No_Partial_Assign);
@@ -412,8 +418,10 @@ package body Synth.Environment is
elsif Wire_Rec.Kind = Wire_Enable then
-- Possibly infere a idff/iadff.
pragma Assert (Pa.Offset = 0);
+ pragma Assert (Pa.Next = No_Partial_Assign);
Res := Inference.Infere_Assert
(Ctxt, Pa.Value, Outport, Stmt);
+ Connect (Get_Input (Get_Net_Parent (Outport), 0), Res);
else
-- Note: lifetime is currently based on the kind of the
-- wire (variable -> not reused beyond this process).
@@ -421,9 +429,8 @@ package body Synth.Environment is
Res := Inference.Infere
(Ctxt, Pa.Value, Pa.Offset, Outport, Stmt,
Wire_Rec.Kind = Wire_Variable);
+ Add_Conc_Assign (Wid, Res, Pa.Offset, Stmt);
end if;
-
- Add_Conc_Assign (Wid, Res, Pa.Offset, Stmt);
P := Pa.Next;
end;
end loop;
@@ -996,9 +1003,10 @@ package body Synth.Environment is
end Finalize_Complex_Assignment;
procedure Finalize_Assignment
- (Ctxt : Builders.Context_Acc; Wire_Rec : Wire_Id_Record)
+ (Ctxt : Builders.Context_Acc; Wid : Wire_Id)
is
use Vhdl.Nodes;
+ Wire_Rec : Wire_Id_Record renames Wire_Id_Table.Table (Wid);
Gate_Inst : constant Instance := Get_Net_Parent (Wire_Rec.Gate);
Inp : constant Input := Get_Input (Gate_Inst, 0);
Value : Net;
@@ -1036,15 +1044,17 @@ package body Synth.Environment is
Finalize_Complex_Assignment (Ctxt, Wire_Rec, Value);
end if;
end;
+ Wire_Rec.Final_Assign := No_Conc_Assign;
when others =>
-- Multiple assignments.
Finalize_Complex_Assignment (Ctxt, Wire_Rec, Value);
+ Wire_Rec.Final_Assign := No_Conc_Assign;
end case;
Connect (Inp, Value);
end Finalize_Assignment;
- procedure Finalize_Assignments (Ctxt : Builders.Context_Acc) is
+ procedure Finalize_Wires is
begin
pragma Assert (Phis_Table.Last = No_Phi_Id);
-- pragma Assert (Assign_Table.Last = No_Seq_Assign);
@@ -1053,14 +1063,15 @@ package body Synth.Environment is
declare
Wire_Rec : Wire_Id_Record renames Wire_Id_Table.Table (Wid);
begin
- pragma Assert (Wire_Rec.Kind /= Wire_None);
- pragma Assert (Wire_Rec.Cur_Assign = No_Seq_Assign);
- Finalize_Assignment (Ctxt, Wire_Rec);
+ pragma Assert (Wire_Rec.Kind = Wire_None
+ or Wire_Rec.Kind = Wire_Enable);
+ pragma Assert (Wire_Rec.Final_Assign = No_Conc_Assign);
+ null;
end;
end loop;
Wire_Id_Table.Set_Last (No_Wire_Id);
- end Finalize_Assignments;
+ end Finalize_Wires;
-- Sort the LEN first wires of chain W (linked by Chain) in Id increasing
-- values. The result is assigned to FIRST and the first non-sorted wire
diff --git a/src/synth/synth-environment.ads b/src/synth/synth-environment.ads
index 9205512a3..d5e1e2d87 100644
--- a/src/synth/synth-environment.ads
+++ b/src/synth/synth-environment.ads
@@ -232,7 +232,10 @@ package Synth.Environment is
procedure Add_Conc_Assign
(Wid : Wire_Id; Val : Net; Off : Uns32; Stmt : Source.Syn_Src);
- procedure Finalize_Assignments (Ctxt : Builders.Context_Acc);
+ procedure Finalize_Assignment
+ (Ctxt : Builders.Context_Acc; Wid : Wire_Id);
+
+ procedure Finalize_Wires;
-- A static wire is a wire_signal which has one whole (same width as the
-- wire) assignment and whose assignment value is a const net.
diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb
index 3598d594b..8b815b286 100644
--- a/src/synth/synth-insts.adb
+++ b/src/synth/synth-insts.adb
@@ -966,8 +966,12 @@ package body Synth.Insts is
New_Sname_User (Get_Identifier (Stmt), Get_Sname (Syn_Inst)));
Set_Location (Inst, Stmt);
+ Push_Phi;
+
Synth_Instantiate_Module
(Syn_Inst, Inst, Inst_Obj, Get_Port_Map_Aspect_Chain (Stmt));
+
+ Pop_And_Merge_Phi (Get_Build (Syn_Inst), Stmt);
end Synth_Direct_Instantiation_Statement;
procedure Synth_Design_Instantiation_Statement
@@ -1057,6 +1061,8 @@ package body Synth.Insts is
pragma Assert (Get_Component_Configuration (Stmt) /= Null_Node);
pragma Assert (Get_Kind (Aspect) = Iir_Kind_Entity_Aspect_Entity);
+ Push_Phi;
+
Inst_Name := New_Sname_User (Get_Identifier (Stmt),
Get_Sname (Syn_Inst));
@@ -1186,6 +1192,10 @@ package body Synth.Insts is
Next_Association_Interface (Assoc, Assoc_Inter);
end loop;
end;
+
+ Pop_And_Merge_Phi (Ctxt, Stmt);
+
+ Finalize_Declarations (Comp_Inst, Get_Port_Chain (Component));
end Synth_Component_Instantiation_Statement;
procedure Synth_Dependencies (Parent_Inst : Synth_Instance_Acc; Unit : Node)
@@ -1536,9 +1546,10 @@ package body Synth.Insts is
Synth_Verification_Units (Syn_Inst, Arch);
end if;
- Finalize_Assignments (Get_Build (Syn_Inst));
-
Finalize_Declarations (Syn_Inst, Get_Declaration_Chain (Arch));
+ Finalize_Declarations (Syn_Inst, Get_Port_Chain (Entity));
+
+ Finalize_Wires;
-- Remove unused gates. This is not only an optimization but also
-- a correctness point: there might be some unsynthesizable gates, like
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index 1109b9491..d58730df0 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -3057,9 +3057,9 @@ package body Synth.Stmts is
Mark (M, Proc_Pool);
Instance_Pool := Proc_Pool'Access;
- if Is_Valid (Decls_Chain) then
- Synth_Declarations (C.Inst, Decls_Chain);
- end if;
+ Push_Phi;
+
+ Synth_Declarations (C.Inst, Decls_Chain);
Set_Wire_Gate (C.W_En, Build_Control_Signal (Syn_Inst, 1, Proc));
Phi_Assign_Static (C.W_En, Bit1);
@@ -3075,11 +3075,16 @@ package body Synth.Stmts is
end case;
end if;
- -- FIXME: free W_En ?
+ Pop_And_Merge_Phi (Ctxt, Proc);
+
+ Finalize_Declarations (C.Inst, Decls_Chain);
Free_Instance (C.Inst);
Release (M, Proc_Pool);
Instance_Pool := Prev_Instance_Pool;
+
+ Finalize_Assignment (Ctxt, C.W_En);
+ Free_Wire (C.W_En);
end Synth_Process_Statement;
function Synth_User_Function_Call
@@ -3167,6 +3172,7 @@ package body Synth.Stmts is
Synth_Declarations (Blk_Inst, Get_Declaration_Chain (Blk));
Synth_Concurrent_Statements
(Blk_Inst, Get_Concurrent_Statement_Chain (Blk));
+ Finalize_Declarations (Blk_Inst, Get_Declaration_Chain (Blk));
Free_Instance (Blk_Inst);
Release (M, Proc_Pool);
@@ -3440,6 +3446,8 @@ package body Synth.Stmts is
Synth_Concurrent_Statements
(Bod_Inst, Get_Concurrent_Statement_Chain (Bod));
+ Finalize_Declarations (Bod_Inst, Decls_Chain);
+
Free_Instance (Bod_Inst);
Release (M, Proc_Pool);
Instance_Pool := Prev_Instance_Pool;
@@ -3553,15 +3561,12 @@ package body Synth.Stmts is
Synth_Procedure_Call (Syn_Inst, Stmt);
Pop_And_Merge_Phi (Ctxt, Stmt);
when Iir_Kinds_Process_Statement =>
- Push_Phi;
Synth_Process_Statement (Syn_Inst, Stmt);
- Pop_And_Merge_Phi (Ctxt, Stmt);
when Iir_Kind_If_Generate_Statement =>
Synth_If_Generate_Statement (Syn_Inst, Stmt);
when Iir_Kind_For_Generate_Statement =>
Synth_For_Generate_Statement (Syn_Inst, Stmt);
when Iir_Kind_Component_Instantiation_Statement =>
- Push_Phi;
if Is_Component_Instantiation (Stmt) then
declare
Comp_Config : constant Node :=
@@ -3579,7 +3584,6 @@ package body Synth.Stmts is
else
Synth_Design_Instantiation_Statement (Syn_Inst, Stmt);
end if;
- Pop_And_Merge_Phi (Ctxt, Stmt);
when Iir_Kind_Block_Statement =>
Synth_Block_Statement (Syn_Inst, Stmt);
when Iir_Kind_Psl_Default_Clock =>
@@ -3756,6 +3760,37 @@ package body Synth.Stmts is
Synth_Attribute_Values (Unit_Inst, Unit);
+ -- Finalize
+ Item := Get_Vunit_Item_Chain (Unit);
+ while Item /= Null_Node loop
+ case Get_Kind (Item) is
+ when Iir_Kind_Psl_Default_Clock
+ | Iir_Kind_Psl_Assert_Directive
+ | Iir_Kind_Psl_Assume_Directive
+ | Iir_Kind_Psl_Restrict_Directive
+ | Iir_Kind_Psl_Cover_Directive =>
+ null;
+ when Iir_Kinds_Concurrent_Signal_Assignment
+ | Iir_Kinds_Process_Statement
+ | Iir_Kinds_Generate_Statement
+ | Iir_Kind_Block_Statement
+ | Iir_Kind_Concurrent_Procedure_Call_Statement
+ | Iir_Kind_Component_Instantiation_Statement =>
+ null;
+ when Iir_Kind_Signal_Declaration
+ | Iir_Kind_Function_Declaration
+ | Iir_Kind_Procedure_Declaration
+ | Iir_Kind_Function_Body
+ | Iir_Kind_Procedure_Body
+ | Iir_Kind_Attribute_Declaration
+ | Iir_Kind_Attribute_Specification =>
+ Finalize_Declaration (Unit_Inst, Item, False);
+ when others =>
+ Error_Kind ("synth_verification_unit(2)", Item);
+ end case;
+ Item := Get_Chain (Item);
+ end loop;
+
Free_Instance (Unit_Inst);
Release (M, Proc_Pool);
Instance_Pool := Prev_Instance_Pool;