From 2fb32502d2a12ac78cc3f5fb4068104b66018ea5 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 13 Jan 2021 18:20:52 +0100 Subject: synth: always finalize declarations. Fix #1591 --- src/synth/synth-decls.adb | 22 ++++++++++++++---- src/synth/synth-decls.ads | 3 +++ src/synth/synth-environment.adb | 29 +++++++++++++++-------- src/synth/synth-environment.ads | 5 +++- src/synth/synth-insts.adb | 15 ++++++++++-- src/synth/synth-stmts.adb | 51 ++++++++++++++++++++++++++++++++++------- 6 files changed, 101 insertions(+), 24 deletions(-) (limited to 'src') 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; -- cgit v1.2.3