diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-07-10 18:56:49 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-07-10 18:56:49 +0200 |
commit | 52536adeb52c88676bbf4141fed7189ace6047c5 (patch) | |
tree | 1d341e40bde0d7306819cb38600d246d01691dbc /src | |
parent | 24f55f065dd3eff8ace07a9932308f024f09bc3f (diff) | |
download | ghdl-52536adeb52c88676bbf4141fed7189ace6047c5.tar.gz ghdl-52536adeb52c88676bbf4141fed7189ace6047c5.tar.bz2 ghdl-52536adeb52c88676bbf4141fed7189ace6047c5.zip |
synth: handle instantiation (WIP)
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/netlists-disp_vhdl.adb | 27 | ||||
-rw-r--r-- | src/synth/synth-context.adb | 19 | ||||
-rw-r--r-- | src/synth/synth-context.ads | 2 | ||||
-rw-r--r-- | src/synth/synth-insts.adb | 478 | ||||
-rw-r--r-- | src/synth/synth-insts.ads | 40 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 13 | ||||
-rw-r--r-- | src/synth/synth-stmts.ads | 5 | ||||
-rw-r--r-- | src/synth/synth-values.adb | 9 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 2 | ||||
-rw-r--r-- | src/synth/synthesis.adb | 38 | ||||
-rw-r--r-- | src/synth/synthesis.ads | 2 |
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; |