diff options
author | Tristan Gingold <tgingold@free.fr> | 2023-04-17 09:25:19 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2023-04-17 09:26:57 +0200 |
commit | 10d6f0c3520c2ebb93091f635014c6cd4c35631f (patch) | |
tree | af1db89e5b129da38eb4736bd58fac340c3f6719 | |
parent | 5c0ea8c8b107c5f0be4dff9fbc5d31c43b592b3d (diff) | |
download | ghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.tar.gz ghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.tar.bz2 ghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.zip |
synth: preliminary support of flat netlists
-rw-r--r-- | src/synth/synth-flags.ads | 5 | ||||
-rw-r--r-- | src/synth/synth-vhdl_insts.adb | 277 |
2 files changed, 211 insertions, 71 deletions
diff --git a/src/synth/synth-flags.ads b/src/synth/synth-flags.ads index aa3a0b8aa..541663543 100644 --- a/src/synth/synth-flags.ads +++ b/src/synth/synth-flags.ads @@ -74,6 +74,11 @@ package Synth.Flags is -- Synthesize PSL and assertions. Flag_Formal : Boolean := True; + -- True to keep hierarchy: an module/entity instantiation is synthesized + -- as an instantiation. + -- If false, the netlist is flat. + Flag_Keep_Hierarchy : Boolean := True; + -- If true, automatically add a cover on PSL asserts to know if the -- asserted has been started. Flag_Assert_Cover : Boolean := True; diff --git a/src/synth/synth-vhdl_insts.adb b/src/synth/synth-vhdl_insts.adb index 2a20d06a9..35c8ac392 100644 --- a/src/synth/synth-vhdl_insts.adb +++ b/src/synth/synth-vhdl_insts.adb @@ -60,6 +60,10 @@ with Synth.Vhdl_Context; use Synth.Vhdl_Context; package body Synth.Vhdl_Insts is Global_Base_Instance : Base_Instance_Acc; + procedure Synth_Instance_Design (Syn_Inst : Synth_Instance_Acc; + Entity : Node; + Arch : Node); + function Mode_To_Port_Kind (Mode : Iir_Mode) return Port_Kind is begin case Mode is @@ -479,7 +483,9 @@ package body Synth.Vhdl_Insts is Inter := Get_Chain (Inter); end loop; - -- Allocate values and count inputs and outputs + -- There are already valtyp for ports (created during elab), but they + -- are signals. Convert ports valtyp to nets/wires. + -- Count inputs and outputs. Inter := Get_Port_Chain (Decl); Nbr_Inputs := 0; Nbr_Outputs := 0; @@ -818,7 +824,8 @@ package body Synth.Vhdl_Insts is procedure Synth_Individual_Output_Assoc (Outp : Net; Syn_Inst : Synth_Instance_Acc; Inter_Typ : Type_Acc; - Assoc : Node) + Assoc : Node; + Add_Port : Boolean) is Marker : Mark_Type; Iassoc : Node; @@ -830,8 +837,12 @@ package body Synth.Vhdl_Insts is begin Mark_Expr_Pool (Marker); - Port := Builders.Build_Port (Get_Build (Syn_Inst), Outp); - Set_Location (Port, Assoc); + if Add_Port then + Port := Builders.Build_Port (Get_Build (Syn_Inst), Outp); + Set_Location (Port, Assoc); + else + Port := Outp; + end if; Iassoc := Get_Chain (Assoc); while Iassoc /= Null_Node @@ -855,14 +866,16 @@ package body Synth.Vhdl_Insts is end loop; end Synth_Individual_Output_Assoc; + -- Associate output according to ASSOC. + -- If ADD_PORT is true, a port gate is added. procedure Synth_Output_Assoc (Outp : Net; Syn_Inst : Synth_Instance_Acc; Assoc : Node; Inter_Inst : Synth_Instance_Acc; - Inter : Node) + Inter : Node; + Add_Port : Boolean) is Marker : Mark_Type; - Actual : Node; Formal_Typ : Type_Acc; Port : Net; O : Valtyp; @@ -872,23 +885,24 @@ package body Synth.Vhdl_Insts is case Get_Kind (Assoc) is when Iir_Kind_Association_Element_Open => -- Not connected. - return; + null; when Iir_Kinds_Association_Element_By_Actual => - Actual := Get_Actual (Assoc); + Mark_Expr_Pool (Marker); + -- Create a port gate (so that is has a name). + if Add_Port then + Port := Builders.Build_Port (Get_Build (Syn_Inst), Outp); + Set_Location (Port, Assoc); + else + Port := Outp; + end if; + O := Create_Value_Net (Port, Formal_Typ); + -- Assign the port output to the actual (a net). + Synth_Assignment (Syn_Inst, Get_Actual (Assoc), O, Assoc); + Release_Expr_Pool (Marker); when others => Synth_Individual_Output_Assoc - (Outp, Syn_Inst, Formal_Typ, Assoc); - return; + (Outp, Syn_Inst, Formal_Typ, Assoc, Add_Port); end case; - - Mark_Expr_Pool (Marker); - -- Create a port gate (so that is has a name). - Port := Builders.Build_Port (Get_Build (Syn_Inst), Outp); - Set_Location (Port, Assoc); - O := Create_Value_Net (Port, Formal_Typ); - -- Assign the port output to the actual (a net). - Synth_Assignment (Syn_Inst, Actual, O, Assoc); - Release_Expr_Pool (Marker); end Synth_Output_Assoc; procedure Inst_Input_Connect (Syn_Inst : Synth_Instance_Acc; @@ -1013,7 +1027,7 @@ package body Synth.Vhdl_Insts is (Syn_Inst, Inst, Nbr_Outputs, Inter_Typ, N); Synth_Output_Assoc - (N, Syn_Inst, Assoc, Ent_Inst, Inter); + (N, Syn_Inst, Assoc, Ent_Inst, Inter, True); end case; pragma Assert (Areapools.Is_At_Mark (Expr_Pool, Marker)); @@ -1113,6 +1127,106 @@ package body Synth.Vhdl_Insts is pragma Assert (Is_Expr_Pool_Empty); end Synth_Direct_Instantiation_Statement; + procedure Synth_Flat_Instantiation_Statement + (Syn_Inst : Synth_Instance_Acc; + Stmt : Node; + Sub_Inst : Synth_Instance_Acc; + Entity : Node; + Arch : Node) + is + Ctxt : constant Context_Acc := Get_Build (Syn_Inst); + Inter : Node; + Inter_Typ : Type_Acc; + Val : Valtyp; + N : Net; + Name : Sname; + Wid : Wire_Id; + begin + pragma Assert (Is_Expr_Pool_Empty); + + Name := New_Sname_User (Get_Identifier (Stmt), Get_Sname (Syn_Inst)); + Set_Extra (Sub_Inst, Syn_Inst, Name); + + -- There are already valtyp for ports (created during elab), but they + -- are signals. Convert ports valtyp to nets/wires. + Inter := Get_Port_Chain (Entity); + Current_Pool := Process_Pool'Access; + while Is_Valid (Inter) loop + Inter_Typ := Get_Value (Sub_Inst, Inter).Typ; + + Name := New_Sname_User (Get_Identifier (Inter), Get_Sname (Sub_Inst)); + N := Build_Signal + (Ctxt, New_Internal_Name (Ctxt, Name), Get_Type_Width (Inter_Typ)); + Set_Location (N, Inter); + + case Mode_To_Port_Kind (Get_Mode (Inter)) is + when Port_In => + -- TODO: default value (isignal). + Val := Create_Value_Net (N, Inter_Typ); + when Port_Out + | Port_Inout => + Wid := Alloc_Wire (Wire_Output, (Inter, Inter_Typ)); + Set_Wire_Gate (Wid, N); + Val := Create_Value_Wire (Wid, Inter_Typ, Current_Pool); + end case; + Replace_Signal (Sub_Inst, Inter, Val); + Inter := Get_Chain (Inter); + end loop; + Current_Pool := Expr_Pool'Access; + + -- Connections. + Push_Phi; + + declare + Marker : Mark_Type; + + Assoc : Node; + Assoc_Inter : Node; + Inter : Node; + Inter_Typ : Type_Acc; + N : Net; + Vt : Valtyp; + Inst : Instance; + begin + Mark_Expr_Pool (Marker); + + Assoc := Get_Port_Map_Aspect_Chain (Stmt); + Assoc_Inter := Get_Port_Chain (Entity); + while Is_Valid (Assoc) loop + if Get_Whole_Association_Flag (Assoc) then + Inter := Get_Association_Interface (Assoc, Assoc_Inter); + Inter_Typ := Get_Subtype_Object (Sub_Inst, Get_Type (Inter)); + Vt := Get_Value (Sub_Inst, Inter); + + case Mode_To_Port_Kind (Get_Mode (Inter)) is + when Port_In => + -- Connect the net to the input. + N := Synth_Input_Assoc + (Syn_Inst, Assoc, Sub_Inst, Inter, Inter_Typ); + if N /= No_Net then + -- Ignore errors. + Inst := Get_Net_Parent (Get_Value_Net (Vt.Val)); + Connect (Get_Input (Inst, 0), N); + end if; + + when Port_Out + | Port_Inout => + N := Get_Wire_Gate (Get_Value_Wire (Vt.Val)); + Synth_Output_Assoc + (N, Syn_Inst, Assoc, Sub_Inst, Inter, False); + end case; + + Release_Expr_Pool (Marker); + end if; + Next_Association_Interface (Assoc, Assoc_Inter); + end loop; + end; + + Pop_And_Merge_Phi (Ctxt, Get_Location (Stmt)); + + Synth_Instance_Design (Sub_Inst, Entity, Arch); + end Synth_Flat_Instantiation_Statement; + procedure Synth_Design_Instantiation_Statement (Syn_Inst : Synth_Instance_Acc; Stmt : Node) is @@ -1122,8 +1236,20 @@ package body Synth.Vhdl_Insts is Ent : constant Node := Get_Entity (Arch); Config : constant Node := Get_Instance_Config (Sub_Inst); begin - Synth_Direct_Instantiation_Statement - (Syn_Inst, Stmt, Sub_Inst, Ent, Arch, Config); + if Flag_Keep_Hierarchy then + Synth_Direct_Instantiation_Statement + (Syn_Inst, Stmt, Sub_Inst, Ent, Arch, Config); + else + -- Dependencies + -- Set files root dir + -- Create name prefix + -- Build ports + -- For in: net + -- For out/inout: wires + -- Connect + Synth_Flat_Instantiation_Statement + (Syn_Inst, Stmt, Sub_Inst, Ent, Arch); + end if; end Synth_Design_Instantiation_Statement; procedure Synth_Blackbox_Instantiation_Statement @@ -1301,7 +1427,8 @@ package body Synth.Vhdl_Insts is if Mode_To_Port_Kind (Get_Mode (Inter)) = Port_Out then O := Get_Value (Comp_Inst, Inter); Port := Get_Net (Ctxt, O); - Synth_Output_Assoc (Port, Syn_Inst, Assoc, Comp_Inst, Inter); + Synth_Output_Assoc + (Port, Syn_Inst, Assoc, Comp_Inst, Inter, True); Nbr_Outputs := Nbr_Outputs + 1; end if; end if; @@ -1444,7 +1571,7 @@ package body Synth.Vhdl_Insts is N : Net; begin pragma Assert (Val.Val.Kind = Value_Net); - N := Get_Value_Net (Val.Val); + -- Get the net from the port(s). Inst_Output_Connect (Syn_Inst, Self_Inst, Idx, Val.Typ, N); Set_Value_Net (Val.Val, N); end Create_Input_Wire; @@ -1526,6 +1653,60 @@ package body Synth.Vhdl_Insts is end loop; end Synth_Verification_Units; + procedure Synth_Instance_Design (Syn_Inst : Synth_Instance_Acc; + Entity : Node; + Arch : Node) + is + begin + -- Entity + Synth_Concurrent_Declarations (Syn_Inst, Get_Declaration_Chain (Entity)); + if not Is_Error (Syn_Inst) then + Synth_Concurrent_Statements + (Syn_Inst, Get_Concurrent_Statement_Chain (Entity)); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + if not Is_Error (Syn_Inst) then + Synth_Attribute_Values (Syn_Inst, Entity); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + -- Architecture + if not Is_Error (Syn_Inst) then + Synth_Concurrent_Declarations + (Syn_Inst, Get_Declaration_Chain (Arch)); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + if not Is_Error (Syn_Inst) then + Synth_Concurrent_Statements + (Syn_Inst, Get_Concurrent_Statement_Chain (Arch)); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + if not Is_Error (Syn_Inst) then + Synth_Attribute_Values (Syn_Inst, Arch); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + -- Vunits + if not Is_Error (Syn_Inst) then + Synth_Verification_Units (Syn_Inst); + end if; + + pragma Assert (Is_Expr_Pool_Empty); + + -- Finalize + Finalize_Declarations (Syn_Inst, Get_Declaration_Chain (Arch)); + Finalize_Declarations (Syn_Inst, Get_Declaration_Chain (Entity)); + Finalize_Declarations (Syn_Inst, Get_Port_Chain (Entity)); + end Synth_Instance_Design; + procedure Synth_Instance (Inst : Inst_Object) is Entity : constant Node := Inst.Decl; @@ -1586,53 +1767,7 @@ package body Synth.Vhdl_Insts is -- FIXME: what about inner block configuration ? pragma Assert (Get_Kind (Inst.Config) = Iir_Kind_Block_Configuration); - -- Entity - Synth_Concurrent_Declarations (Syn_Inst, Get_Declaration_Chain (Entity)); - if not Is_Error (Syn_Inst) then - Synth_Concurrent_Statements - (Syn_Inst, Get_Concurrent_Statement_Chain (Entity)); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - if not Is_Error (Syn_Inst) then - Synth_Attribute_Values (Syn_Inst, Entity); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - -- Architecture - if not Is_Error (Syn_Inst) then - Synth_Concurrent_Declarations - (Syn_Inst, Get_Declaration_Chain (Arch)); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - if not Is_Error (Syn_Inst) then - Synth_Concurrent_Statements - (Syn_Inst, Get_Concurrent_Statement_Chain (Arch)); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - if not Is_Error (Syn_Inst) then - Synth_Attribute_Values (Syn_Inst, Arch); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - -- Vunits - if not Is_Error (Syn_Inst) then - Synth_Verification_Units (Syn_Inst); - end if; - - pragma Assert (Is_Expr_Pool_Empty); - - -- Finalize - Finalize_Declarations (Syn_Inst, Get_Declaration_Chain (Arch)); - Finalize_Declarations (Syn_Inst, Get_Declaration_Chain (Entity)); - Finalize_Declarations (Syn_Inst, Get_Port_Chain (Entity)); + Synth_Instance_Design (Syn_Inst, Entity, Arch); Finalize_Wires; |