aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2023-04-17 09:25:19 +0200
committerTristan Gingold <tgingold@free.fr>2023-04-17 09:26:57 +0200
commit10d6f0c3520c2ebb93091f635014c6cd4c35631f (patch)
treeaf1db89e5b129da38eb4736bd58fac340c3f6719
parent5c0ea8c8b107c5f0be4dff9fbc5d31c43b592b3d (diff)
downloadghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.tar.gz
ghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.tar.bz2
ghdl-10d6f0c3520c2ebb93091f635014c6cd4c35631f.zip
synth: preliminary support of flat netlists
-rw-r--r--src/synth/synth-flags.ads5
-rw-r--r--src/synth/synth-vhdl_insts.adb277
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;