aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-07-10 18:56:49 +0200
committerTristan Gingold <tgingold@free.fr>2019-07-10 18:56:49 +0200
commit52536adeb52c88676bbf4141fed7189ace6047c5 (patch)
tree1d341e40bde0d7306819cb38600d246d01691dbc
parent24f55f065dd3eff8ace07a9932308f024f09bc3f (diff)
downloadghdl-52536adeb52c88676bbf4141fed7189ace6047c5.tar.gz
ghdl-52536adeb52c88676bbf4141fed7189ace6047c5.tar.bz2
ghdl-52536adeb52c88676bbf4141fed7189ace6047c5.zip
synth: handle instantiation (WIP)
-rw-r--r--src/synth/netlists-disp_vhdl.adb27
-rw-r--r--src/synth/synth-context.adb19
-rw-r--r--src/synth/synth-context.ads2
-rw-r--r--src/synth/synth-insts.adb478
-rw-r--r--src/synth/synth-insts.ads40
-rw-r--r--src/synth/synth-stmts.adb13
-rw-r--r--src/synth/synth-stmts.ads5
-rw-r--r--src/synth/synth-values.adb9
-rw-r--r--src/synth/synth-values.ads2
-rw-r--r--src/synth/synthesis.adb38
-rw-r--r--src/synth/synthesis.ads2
11 files changed, 587 insertions, 48 deletions
diff --git a/src/synth/netlists-disp_vhdl.adb b/src/synth/netlists-disp_vhdl.adb
index 526d36cb8..d3ef8b728 100644
--- a/src/synth/netlists-disp_vhdl.adb
+++ b/src/synth/netlists-disp_vhdl.adb
@@ -134,7 +134,7 @@ package body Netlists.Disp_Vhdl is
return;
end if;
- if Get_Sname_Kind (N) = Sname_Artificial
+ if Get_Sname_Kind (N) in Sname_User .. Sname_Artificial
and then Get_Sname_Prefix (N) = No_Sname
then
Put (Name_Table.Image (Get_Sname_Suffix (N)));
@@ -238,12 +238,17 @@ package body Netlists.Disp_Vhdl is
else
Put_Name (Name);
end if;
- Put (" : gsynth.gate_");
-- Gate name
Name := Get_Name (Imod);
- pragma Assert (Get_Sname_Kind (Name) = Sname_Artificial
- and then Get_Sname_Prefix (Name) = No_Sname);
- Put_Id (Get_Sname_Suffix (Name));
+ if Get_Id (Imod) < Id_User_None then
+ Put (" : gsynth.gate_");
+ pragma Assert (Get_Sname_Kind (Name) = Sname_Artificial
+ and then Get_Sname_Prefix (Name) = No_Sname);
+ Put_Id (Get_Sname_Suffix (Name));
+ else
+ Put (" : entity work.");
+ Put_Name (Name);
+ end if;
if Get_Nbr_Params (Imod) /= 0 then
Put_Line (" generic map (");
@@ -633,8 +638,15 @@ package body Netlists.Disp_Vhdl is
end case;
end Disp_Instance_Inline;
- procedure Disp_Architecture (M : Module) is
+ procedure Disp_Architecture (M : Module)
+ is
+ Self_Inst : constant Instance := Get_Self_Instance (M);
begin
+ if Self_Inst = No_Instance then
+ -- Not defined.
+ return;
+ end if;
+
Put ("architecture rtl of ");
Put_Name (Get_Name (M));
Put_Line (" is");
@@ -671,11 +683,10 @@ package body Netlists.Disp_Vhdl is
-- Output assignments.
declare
- Inst : constant Instance := Get_Self_Instance (M);
Idx : Port_Idx;
begin
Idx := 0;
- for I of Inputs (Inst) loop
+ for I of Inputs (Self_Inst) loop
Put (" ");
Put_Name (Get_Output_Desc (M, Idx).Name);
Put (" <= ");
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb
index 5ec942e54..0f32e2d7c 100644
--- a/src/synth/synth-context.adb
+++ b/src/synth/synth-context.adb
@@ -69,15 +69,28 @@ package body Synth.Context is
return Create_Value_Instance (Packages_Table.Last);
end Create_Value_Instance;
- function Alloc_Wire (Kind : Wire_Kind; Obj : Iir; Bnd : Value_Bound_Acc)
- return Value_Acc is
+ function Alloc_Wire (Kind : Wire_Kind; Obj : Node) return Wire_Id is
begin
Wire_Id_Table.Append ((Kind => Kind,
Mark_Flag => False,
Decl => Obj,
Gate => No_Net,
Cur_Assign => No_Assign));
- return Create_Value_Wire (Wire_Id_Table.Last, Bnd);
+ return Wire_Id_Table.Last;
+ end Alloc_Wire;
+
+
+ function Alloc_Wire (Kind : Wire_Kind; Obj : Iir; Bnd : Value_Bound_Acc)
+ return Value_Acc
+ is
+ Wire : Wire_Id;
+ begin
+ if Kind = Wire_None then
+ Wire := No_Wire_Id;
+ else
+ Wire := Alloc_Wire (Kind, Obj);
+ end if;
+ return Create_Value_Wire (Wire, Bnd);
end Alloc_Wire;
function Alloc_Object (Kind : Wire_Kind;
diff --git a/src/synth/synth-context.ads b/src/synth/synth-context.ads
index 874962260..061d71e32 100644
--- a/src/synth/synth-context.ads
+++ b/src/synth/synth-context.ads
@@ -74,6 +74,8 @@ package Synth.Context is
return Synth_Instance_Acc;
procedure Free_Instance (Synth_Inst : in out Synth_Instance_Acc);
+ function Alloc_Wire (Kind : Wire_Kind; Obj : Node) return Wire_Id;
+
procedure Create_Object
(Syn_Inst : Synth_Instance_Acc; Decl : Iir; Val : Value_Acc);
diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb
new file mode 100644
index 000000000..e29aed75b
--- /dev/null
+++ b/src/synth/synth-insts.adb
@@ -0,0 +1,478 @@
+-- Instantiation synthesis.
+-- Copyright (C) 2019 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+with Libraries;
+with Hash; use Hash;
+with Interning;
+with Synthesis; use Synthesis;
+
+with Netlists.Builders;
+with Netlists.Utils;
+
+with Vhdl.Utils; use Vhdl.Utils;
+with Vhdl.Annotations; use Vhdl.Annotations;
+
+with Synth.Environment; use Synth.Environment;
+with Synth.Stmts; use Synth.Stmts;
+with Synth.Decls; use Synth.Decls;
+with Synth.Types; use Synth.Types;
+with Synth.Expr; use Synth.Expr;
+
+package body Synth.Insts is
+ procedure Make_Port_Desc (Val : Value_Acc;
+ Name : Sname;
+ Wd : Width;
+ Ports : in out Port_Desc_Array;
+ Idx : in out Port_Nbr;
+ Dir : Port_Kind)
+ is
+ begin
+ case Val.Kind is
+ when Value_Wire =>
+ Idx := Idx + 1;
+ Ports (Idx) := (Name => Name,
+ W => Wd,
+ Dir => Dir,
+ Left | Right => 0);
+ when others =>
+ raise Internal_Error; -- TODO
+ end case;
+ end Make_Port_Desc;
+
+ procedure Make_Port_Desc (Syn_Inst : Synth_Instance_Acc;
+ Inter : Node;
+ Ports : in out Port_Desc_Array;
+ Idx : in out Port_Nbr;
+ Dir : Port_Kind)
+ is
+ Val : constant Value_Acc := Get_Value (Syn_Inst, Inter);
+ Wd : constant Width := Get_Width (Syn_Inst, Get_Type (Inter));
+ Name : Sname;
+ begin
+ Name := New_Sname_User (Get_Identifier (Inter));
+ Make_Port_Desc (Val, Name, Wd, Ports, Idx, Dir);
+ end Make_Port_Desc;
+
+ type Inst_Params is record
+ Arch : Node;
+ Config : Node;
+ Syn_Inst : Synth_Instance_Acc;
+ end record;
+
+ type Inst_Object is record
+ Arch : Node;
+ Config : Node;
+ Syn_Inst : Synth_Instance_Acc;
+ end record;
+
+ function Hash (Params : Inst_Params) return Hash_Value_Type
+ is
+ Res : Hash_Value_Type;
+ begin
+ Res := Hash_Value_Type (Params.Arch);
+ Res := Res xor Hash_Value_Type (Params.Config);
+ -- TODO: hash generics
+ return Res;
+ end Hash;
+
+ function Equal (Obj : Inst_Object; Params : Inst_Params) return Boolean
+ is
+ Ent : Node;
+ Inter : Node;
+ begin
+ if Obj.Arch /= Params.Arch
+ or else Obj.Config /= Params.Config
+ then
+ return False;
+ end if;
+ Ent := Get_Entity (Obj.Arch);
+ Inter := Get_Generic_Chain (Ent);
+ while Inter /= Null_Node loop
+ if not Is_Equal (Get_Value (Obj.Syn_Inst, Inter),
+ Get_Value (Params.Syn_Inst, Inter))
+ then
+ return False;
+ end if;
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ -- TODO: ports size ?
+ return True;
+ end Equal;
+
+ function Build (Params : Inst_Params) return Inst_Object
+ is
+ Arch : constant Node := Params.Arch;
+ Entity : constant Node := Get_Entity (Arch);
+ Syn_Inst : Synth_Instance_Acc;
+ Inter : Node;
+ Nbr_Inputs : Port_Nbr;
+ Nbr_Outputs : Port_Nbr;
+ Num : Uns32;
+ begin
+ -- Create the instance.
+ Syn_Inst := Make_Instance (Global_Instance, Get_Info (Arch));
+ Syn_Inst.Block_Scope := Get_Info (Entity);
+ Syn_Inst.Name := New_Sname_User (Get_Identifier (Entity));
+
+ -- Copy values for generics.
+ Inter := Get_Generic_Chain (Entity);
+ while Inter /= Null_Node loop
+ Create_Object (Syn_Inst, Inter, Get_Value (Params.Syn_Inst, Inter));
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ -- Allocate values and count inputs and outputs
+ Inter := Get_Port_Chain (Entity);
+ Nbr_Inputs := 0;
+ Nbr_Outputs := 0;
+ while Is_Valid (Inter) loop
+ Synth_Declaration_Type (Syn_Inst, Inter);
+ case Mode_To_Port_Kind (Get_Mode (Inter)) is
+ when Port_In =>
+ Make_Object (Syn_Inst, Wire_None, Inter);
+ Num := Get_Nbr_Wire (Get_Value (Syn_Inst, Inter));
+ Nbr_Inputs := Nbr_Inputs + Port_Nbr (Num);
+ when Port_Out
+ | Port_Inout =>
+ Make_Object (Syn_Inst, Wire_None, Inter);
+ Num := Get_Nbr_Wire (Get_Value (Syn_Inst, Inter));
+ Nbr_Outputs := Nbr_Outputs + Port_Nbr (Num);
+ end case;
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ -- Declare module.
+ Syn_Inst.M := New_User_Module
+ (Global_Module, New_Sname_User (Get_Identifier (Entity)),
+ Id_User_None, Nbr_Inputs, Nbr_Outputs, 0);
+
+ -- Add ports to module.
+ declare
+ Inports : Port_Desc_Array (1 .. Nbr_Inputs);
+ Outports : Port_Desc_Array (1 .. Nbr_Outputs);
+ begin
+ Inter := Get_Port_Chain (Entity);
+ Nbr_Inputs := 0;
+ Nbr_Outputs := 0;
+ while Is_Valid (Inter) loop
+ case Mode_To_Port_Kind (Get_Mode (Inter)) is
+ when Port_In =>
+ Make_Port_Desc
+ (Syn_Inst, Inter, Inports, Nbr_Inputs, Port_In);
+ when Port_Out
+ | Port_Inout =>
+ Make_Port_Desc
+ (Syn_Inst, Inter, Outports, Nbr_Outputs, Port_Out);
+ end case;
+ Inter := Get_Chain (Inter);
+ end loop;
+ pragma Assert (Nbr_Inputs = Inports'Last);
+ pragma Assert (Nbr_Outputs = Outports'Last);
+ Set_Port_Desc (Syn_Inst.M, Inports, Outports);
+ end;
+
+ return Inst_Object'(Arch => Arch,
+ Config => Params.Config,
+ Syn_Inst => Syn_Inst);
+ end Build;
+
+ package Insts_Interning is new Interning
+ (Params_Type => Inst_Params,
+ Object_Type => Inst_Object,
+ Hash => Hash,
+ Build => Build,
+ Equal => Equal);
+
+ function Mode_To_Port_Kind (Mode : Iir_Mode) return Port_Kind is
+ begin
+ case Mode is
+ when Iir_In_Mode =>
+ return Port_In;
+ when Iir_Buffer_Mode
+ | Iir_Out_Mode
+ | Iir_Inout_Mode =>
+ return Port_Out;
+ when Iir_Linkage_Mode
+ | Iir_Unknown_Mode =>
+ raise Synth_Error;
+ end case;
+ end Mode_To_Port_Kind;
+
+ function Get_Nbr_Wire (Val : Value_Acc) return Uns32 is
+ begin
+ case Val.Kind is
+ when Value_Wire =>
+ return 1;
+ when others =>
+ raise Internal_Error; -- TODO
+ end case;
+ end Get_Nbr_Wire;
+
+ procedure Synth_Design_Instantiation_Statement
+ (Syn_Inst : Synth_Instance_Acc; Stmt : Node)
+ is
+ Aspect : constant Iir := Get_Instantiated_Unit (Stmt);
+ Arch : Node;
+ Ent : Node;
+ Config : Node;
+ Sub_Inst : Synth_Instance_Acc;
+ Inter : Node;
+ Nbr_Inputs : Port_Nbr;
+ Nbr_Outputs : Port_Nbr;
+ Num : Uns32;
+ Inst_Obj : Inst_Object;
+ Inst : Instance;
+ begin
+ -- Load configured entity + architecture
+ case Iir_Kinds_Entity_Aspect (Get_Kind (Aspect)) is
+ when Iir_Kind_Entity_Aspect_Entity =>
+ Arch := Get_Architecture (Aspect);
+ if Arch = Null_Node then
+ Arch := Libraries.Get_Latest_Architecture (Get_Entity (Aspect));
+ else
+ Arch := Strip_Denoting_Name (Arch);
+ end if;
+ Config := Get_Library_Unit
+ (Get_Default_Configuration_Declaration (Arch));
+ when Iir_Kind_Entity_Aspect_Configuration =>
+ Config := Get_Configuration (Aspect);
+ Arch := Get_Block_Specification (Get_Block_Configuration (Config));
+ when Iir_Kind_Entity_Aspect_Open =>
+ return;
+ end case;
+ Config := Get_Block_Configuration (Config);
+ Ent := Get_Entity (Arch);
+
+ -- Elaborate generic + map aspect
+ Sub_Inst := Make_Instance (Syn_Inst, Get_Info (Ent));
+ Sub_Inst.Name := New_Sname_User (Get_Identifier (Ent));
+ Synth_Subprogram_Association (Sub_Inst, Syn_Inst,
+ Get_Generic_Chain (Ent),
+ Get_Generic_Map_Aspect_Chain (Stmt));
+
+ -- Elaborate port types.
+ -- FIXME: what about unconstrained ports ? Get the type from the
+ -- association.
+ Inter := Get_Port_Chain (Ent);
+ Nbr_Inputs := 0;
+ Nbr_Outputs := 0;
+ while Is_Valid (Inter) loop
+ if not Is_Fully_Constrained_Type (Get_Type (Inter)) then
+ raise Internal_Error;
+ end if;
+ Synth_Declaration_Type (Sub_Inst, Inter);
+ case Mode_To_Port_Kind (Get_Mode (Inter)) is
+ when Port_In =>
+ Make_Object (Sub_Inst, Wire_None, Inter);
+ Num := Get_Nbr_Wire (Get_Value (Sub_Inst, Inter));
+ Nbr_Inputs := Nbr_Inputs + Port_Nbr (Num);
+ when Port_Out
+ | Port_Inout =>
+ Make_Object (Sub_Inst, Wire_None, Inter);
+ Num := Get_Nbr_Wire (Get_Value (Sub_Inst, Inter));
+ Nbr_Outputs := Nbr_Outputs + Port_Nbr (Num);
+ end case;
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ -- Search if corresponding module has already been used.
+ -- If not create a new module
+ -- * create a name from the generics and the library
+ -- * create inputs/outputs
+ -- * add it to the list of module to be synthesized.
+ Inst_Obj := Insts_Interning.Get ((Arch => Arch,
+ Config => Config,
+ Syn_Inst => Sub_Inst));
+
+ -- TODO: free sub_inst.
+
+ Inst := New_Instance (Syn_Inst.M, Inst_Obj.Syn_Inst.M,
+ New_Sname_User (Get_Identifier (Stmt)));
+
+ -- Instantiate the module
+ -- Elaborate ports + map aspect for the inputs (component then entity)
+ -- Elaborate ports + map aspect for the outputs (entity then component)
+
+ declare
+ Assoc : Node;
+ Assoc_Inter : Node;
+ Actual : Node;
+ O : Value_Acc;
+ begin
+ Assoc := Get_Port_Map_Aspect_Chain (Stmt);
+ Assoc_Inter := Get_Port_Chain (Ent);
+ Nbr_Inputs := 0;
+ Nbr_Outputs := 0;
+ while Is_Valid (Assoc) loop
+ Inter := Get_Association_Interface (Assoc, Assoc_Inter);
+
+ case Get_Kind (Assoc) is
+ when Iir_Kind_Association_Element_Open =>
+ Actual := Get_Default_Value (Inter);
+ when Iir_Kind_Association_Element_By_Expression =>
+ Actual := Get_Actual (Assoc);
+ when others =>
+ raise Internal_Error;
+ end case;
+
+ case Mode_To_Port_Kind (Get_Mode (Inter)) is
+ when Port_In =>
+ Connect
+ (Get_Input (Inst, Nbr_Inputs),
+ Get_Net (Synth_Expression_With_Type
+ (Syn_Inst, Actual, Get_Type (Assoc_Inter)),
+ Get_Type (Assoc_Inter)));
+ Nbr_Inputs := Nbr_Inputs + 1;
+ when Port_Out
+ | Port_Inout =>
+ O := Create_Value_Net (Get_Output (Inst, Nbr_Outputs),
+ null);
+ Synth_Assignment (Syn_Inst, Actual, O);
+ Nbr_Outputs := Nbr_Outputs + 1;
+ end case;
+ Next_Association_Interface (Assoc, Assoc_Inter);
+ end loop;
+ end;
+ end Synth_Design_Instantiation_Statement;
+
+ procedure Synth_Component_Instantiation_Statement
+ (Syn_Inst : Synth_Instance_Acc; Stmt : Node)
+ is
+ begin
+ -- Create the sub-instance for the component
+ -- Elaborate generic + map aspect
+
+ -- Load configured entity + architecture
+ -- Elaborate generic + map aspect
+
+ -- Search if corresponding module has already been used.
+ -- * compare with generics value, ports size, configuration.
+ -- If not create a new module
+ -- * create a name from the generics, the library, the configuration
+ -- * create inputs/outputs
+ -- * add it to the list of module to be synthesized.
+
+ -- Instantiate the module
+ -- Elaborate ports + map aspect for the inputs (component then entity)
+ -- Elaborate ports + map aspect for the outputs (entity then component)
+ raise Internal_Error;
+ end Synth_Component_Instantiation_Statement;
+
+ procedure Create_Input_Wire (Self_Inst : Instance;
+ Inter : Node;
+ Idx : in out Port_Idx;
+ Val : Value_Acc) is
+ begin
+ case Val.Kind is
+ when Value_Wire =>
+ Val.W := Alloc_Wire (Wire_Input, Inter);
+ Wire_Id_Table.Table (Val.W).Gate := Get_Output (Self_Inst, Idx);
+ Idx := Idx + 1;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Create_Input_Wire;
+
+ procedure Create_Output_Wire (Self_Inst : Instance;
+ Inter : Node;
+ Idx : in out Port_Idx;
+ Val : Value_Acc)
+ is
+ Value : Net;
+ Inp : Input;
+ W : Width;
+ begin
+ case Val.Kind is
+ when Value_Wire =>
+ -- Create a gate for the output, so that it could be read.
+ Val.W := Alloc_Wire (Wire_Output, Inter);
+ W := Get_Output_Desc (Get_Module (Self_Inst), Idx).W;
+ Value := Builders.Build_Output (Build_Context, W);
+ Inp := Get_Input (Self_Inst, Idx);
+ Connect (Inp, Value);
+ Wire_Id_Table.Table (Val.W).Gate := Value;
+ Idx := Idx + 1;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Create_Output_Wire;
+
+ procedure Synth_Instance (Inst : Inst_Object)
+ is
+ Syn_Inst : constant Synth_Instance_Acc := Inst.Syn_Inst;
+ Entity : constant Node := Get_Entity (Inst.Arch);
+ Arch : constant Node := Inst.Arch;
+ Self_Inst : Instance;
+ Inter : Node;
+ Nbr_Inputs : Port_Nbr;
+ Nbr_Outputs : Port_Nbr;
+ begin
+ Self_Inst := Create_Self_Instance (Syn_Inst.M);
+ Builders.Set_Parent (Build_Context, Syn_Inst.M);
+
+ -- Create wires for inputs and outputs.
+ Inter := Get_Port_Chain (Entity);
+ Nbr_Inputs := 0;
+ Nbr_Outputs := 0;
+ while Is_Valid (Inter) loop
+ case Mode_To_Port_Kind (Get_Mode (Inter)) is
+ when Port_In =>
+ Create_Input_Wire
+ (Self_Inst, Inter, Nbr_Inputs, Get_Value (Syn_Inst, Inter));
+ when Port_Out
+ | Port_Inout =>
+ Create_Output_Wire
+ (Self_Inst, Inter, Nbr_Outputs, Get_Value (Syn_Inst, Inter));
+ end case;
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ Synth_Declarations (Syn_Inst, Get_Declaration_Chain (Entity));
+ Synth_Concurrent_Statements
+ (Syn_Inst, Get_Concurrent_Statement_Chain (Entity));
+
+ Synth_Declarations (Syn_Inst, Get_Declaration_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
+ -- the one created for 'rising_egde (clk) and not rst'.
+ Netlists.Utils.Remove_Unused_Instances (Syn_Inst.M);
+ end Synth_Instance;
+
+ procedure Synth_All_Instances
+ is
+ use Insts_Interning;
+ Idx : Index_Type;
+ begin
+ Idx := First_Index;
+ while Idx <= Last_Index loop
+ Synth_Instance (Get_By_Index (Idx));
+ Idx := Idx + 1;
+ end loop;
+ end Synth_All_Instances;
+
+ procedure Init is
+ begin
+ Insts_Interning.Init;
+ end Init;
+end Synth.Insts;
diff --git a/src/synth/synth-insts.ads b/src/synth/synth-insts.ads
new file mode 100644
index 000000000..4c4c8ca81
--- /dev/null
+++ b/src/synth/synth-insts.ads
@@ -0,0 +1,40 @@
+-- Instantiation synthesis.
+-- Copyright (C) 2019 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+with Types; use Types;
+with Netlists; use Netlists;
+with Vhdl.Nodes; use Vhdl.Nodes;
+
+with Synth.Values; use Synth.Values;
+with Synth.Context; use Synth.Context;
+
+package Synth.Insts is
+ procedure Init;
+ procedure Synth_All_Instances;
+
+ function Mode_To_Port_Kind (Mode : Iir_Mode) return Port_Kind;
+ function Get_Nbr_Wire (Val : Value_Acc) return Uns32;
+
+ procedure Synth_Design_Instantiation_Statement
+ (Syn_Inst : Synth_Instance_Acc; Stmt : Node);
+
+ procedure Synth_Component_Instantiation_Statement
+ (Syn_Inst : Synth_Instance_Acc; Stmt : Node);
+end Synth.Insts;
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index 37c780662..a28367d0a 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -40,8 +40,8 @@ with Synth.Types; use Synth.Types;
with Synth.Errors; use Synth.Errors;
with Synth.Decls; use Synth.Decls;
with Synth.Expr; use Synth.Expr;
-with Synth.Values; use Synth.Values;
with Synth.Environment; use Synth.Environment;
+with Synth.Insts; use Synth.Insts;
with Vhdl.Annotations; use Vhdl.Annotations;
@@ -80,10 +80,6 @@ package body Synth.Stmts is
end case;
end Synth_Assign;
- procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc;
- Target : Node;
- Val : Value_Acc);
-
procedure Synth_Assignment_Aggregate (Syn_Inst : Synth_Instance_Acc;
Target : Node;
Val : Value_Acc)
@@ -1233,8 +1229,11 @@ package body Synth.Stmts is
when Iir_Kind_Concurrent_Assertion_Statement =>
Synth_Concurrent_Assertion_Statement (Syn_Inst, Stmt);
when Iir_Kind_Component_Instantiation_Statement =>
- -- TODO.
- null;
+ if Is_Component_Instantiation (Stmt) then
+ Synth_Component_Instantiation_Statement (Syn_Inst, Stmt);
+ else
+ Synth_Design_Instantiation_Statement (Syn_Inst, Stmt);
+ end if;
when Iir_Kind_Psl_Default_Clock =>
null;
when Iir_Kind_Psl_Restrict_Directive =>
diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads
index 0ee3e3029..8b3a68466 100644
--- a/src/synth/synth-stmts.ads
+++ b/src/synth/synth-stmts.ads
@@ -19,6 +19,7 @@
-- MA 02110-1301, USA.
with Vhdl.Nodes; use Vhdl.Nodes;
+with Synth.Values; use Synth.Values;
with Synth.Context; use Synth.Context;
package Synth.Stmts is
@@ -27,6 +28,10 @@ package Synth.Stmts is
Inter_Chain : Node;
Assoc_Chain : Node);
+ procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc;
+ Target : Node;
+ Val : Value_Acc);
+
procedure Synth_Sequential_Statements
(Syn_Inst : Synth_Instance_Acc; Stmts : Node);
diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb
index b71373b16..c1b83ec71 100644
--- a/src/synth/synth-values.adb
+++ b/src/synth/synth-values.adb
@@ -31,6 +31,15 @@ package body Synth.Values is
function To_Value_Bound_Array_Acc is new Ada.Unchecked_Conversion
(System.Address, Value_Bound_Array_Acc);
+ function Is_Equal (L, R : Value_Acc) return Boolean is
+ begin
+ if L.Kind /= R.Kind then
+ return False;
+ end if;
+ -- TODO.
+ raise Internal_Error;
+ end Is_Equal;
+
function Create_Value_Wire (W : Wire_Id; Bnd : Value_Bound_Acc)
return Value_Acc
is
diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads
index 48d51e0f8..0032538fe 100644
--- a/src/synth/synth-values.ads
+++ b/src/synth/synth-values.ads
@@ -154,6 +154,8 @@ package Synth.Values is
-- Pool for objects allocated in the current instance.
Instance_Pool : Areapool_Acc;
+ function Is_Equal (L, R : Value_Acc) return Boolean;
+
-- Create a Value_Net.
function Create_Value_Net (N : Net; Bnd : Value_Bound_Acc) return Value_Acc;
diff --git a/src/synth/synthesis.adb b/src/synth/synthesis.adb
index fef431e90..222d8a0fe 100644
--- a/src/synth/synthesis.adb
+++ b/src/synth/synthesis.adb
@@ -34,6 +34,7 @@ with Synth.Types; use Synth.Types;
with Synth.Decls; use Synth.Decls;
with Synth.Stmts; use Synth.Stmts;
with Synth.Expr; use Synth.Expr;
+with Synth.Insts; use Synth.Insts;
with Synth.Environment.Debug;
pragma Unreferenced (Synth.Environment.Debug);
@@ -42,31 +43,6 @@ with Errorout; use Errorout;
with Vhdl.Errors; use Vhdl.Errors;
package body Synthesis is
- function Mode_To_Port_Kind (Mode : Iir_Mode) return Port_Kind is
- begin
- case Mode is
- when Iir_In_Mode =>
- return Port_In;
- when Iir_Buffer_Mode
- | Iir_Out_Mode
- | Iir_Inout_Mode =>
- return Port_Out;
- when Iir_Linkage_Mode
- | Iir_Unknown_Mode =>
- raise Synth_Error;
- end case;
- end Mode_To_Port_Kind;
-
- function Get_Nbr_Wire (Val : Value_Acc) return Uns32 is
- begin
- case Val.Kind is
- when Value_Wire =>
- return 1;
- when others =>
- raise Internal_Error; -- TODO
- end case;
- end Get_Nbr_Wire;
-
procedure Make_Port_Desc (Val : Value_Acc;
Name : Sname;
Wd : Width;
@@ -306,7 +282,6 @@ package body Synthesis is
Unit : constant Node := Get_Library_Unit (Design);
Arch : Node;
- Des : Module;
Syn_Inst : Synth_Instance_Acc;
begin
-- Extract architecture from design.
@@ -320,10 +295,12 @@ package body Synthesis is
Error_Kind ("synth_design", Unit);
end case;
- Des := New_Design (New_Sname_Artificial (Get_Identifier ("top")));
- Build_Context := Build_Builders (Des);
+ Global_Module :=
+ New_Design (New_Sname_Artificial (Get_Identifier ("top")));
+ Build_Context := Build_Builders (Global_Module);
Instance_Pool := Global_Pool'Access;
Global_Instance := Make_Instance (null, Global_Info);
+ Synth.Insts.Init;
-- Dependencies first.
Synth_Dependencies
@@ -331,13 +308,14 @@ package body Synthesis is
Synth_Dependencies
(Global_Instance, Get_Design_Unit (Arch));
- Syn_Inst := Synth_Entity (Des, Global_Instance, Arch);
+ Syn_Inst := Synth_Entity (Global_Module, Global_Instance, Arch);
+ Synth_All_Instances;
if Errorout.Nbr_Errors > 0 then
raise Compilation_Error;
end if;
pragma Unreferenced (Syn_Inst);
- return Des;
+ return Global_Module;
end Synth_Design;
end Synthesis;
diff --git a/src/synth/synthesis.ads b/src/synth/synthesis.ads
index cac933572..703d190e0 100644
--- a/src/synth/synthesis.ads
+++ b/src/synth/synthesis.ads
@@ -24,5 +24,7 @@ with Netlists; use Netlists;
package Synthesis is
function Synth_Design (Design : Iir) return Module;
+ Global_Module : Module;
+
Synth_Error : exception;
end Synthesis;