diff options
| author | Tristan Gingold <tgingold@free.fr> | 2019-07-12 19:43:14 +0200 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2019-07-13 08:03:52 +0200 | 
| commit | 26789ce5b0390f34b5655c768e952e8b97e8c79b (patch) | |
| tree | a0b1bb5c55841c705e25a0046bff5c62d8e1eed1 | |
| parent | 570d86eaa2b114930a6e21d1b3ec7b6b4f0b83ea (diff) | |
| download | ghdl-26789ce5b0390f34b5655c768e952e8b97e8c79b.tar.gz ghdl-26789ce5b0390f34b5655c768e952e8b97e8c79b.tar.bz2 ghdl-26789ce5b0390f34b5655c768e952e8b97e8c79b.zip | |
synth: handle simple component instances.
| -rw-r--r-- | src/synth/synth-insts.adb | 292 | 
1 files changed, 256 insertions, 36 deletions
| diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb index 5abc8d89d..5a602379d 100644 --- a/src/synth/synth-insts.adb +++ b/src/synth/synth-insts.adb @@ -30,6 +30,7 @@ with Netlists.Utils;  with Vhdl.Utils; use Vhdl.Utils;  with Vhdl.Annotations; use Vhdl.Annotations; +with Vhdl.Errors;  with Synth.Values; use Synth.Values;  with Synth.Environment; use Synth.Environment; @@ -155,6 +156,8 @@ package body Synth.Insts is        Nbr_Outputs : Port_Nbr;        Num : Uns32;     begin +      pragma Assert (Get_Kind (Params.Config) = Iir_Kind_Block_Configuration); +        --  Create the instance.        Syn_Inst := Make_Instance (Global_Instance, Get_Info (Arch));        Syn_Inst.Block_Scope := Get_Info (Entity); @@ -229,6 +232,60 @@ package body Synth.Insts is        Build => Build,        Equal => Equal); +   procedure Synth_Instantiate_Module (Syn_Inst : Synth_Instance_Acc; +                                       Inst : Instance; +                                       Ports : Node; +                                       Ports_Assoc : Node) +   is +      --  Instantiate the module +      --  Elaborate ports + map aspect for the inputs (component then entity) +      --  Elaborate ports + map aspect for the outputs (entity then component) + +      Assoc : Node; +      Assoc_Inter : Node; +      Inter : Node; +      Actual : Node; +      Port : Net; +      O : Value_Acc; +      Nbr_Inputs : Port_Nbr; +      Nbr_Outputs : Port_Nbr; +   begin +      Assoc := Ports_Assoc; +      Assoc_Inter := Ports; +      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 => +               Port := Get_Output (Inst, Nbr_Outputs); +               Port := Builders.Build_Port (Build_Context, Port); +               O := Create_Value_Net (Port, null); +               Synth_Assignment (Syn_Inst, Actual, O); +               Nbr_Outputs := Nbr_Outputs + 1; +         end case; +         Next_Association_Interface (Assoc, Assoc_Inter); +      end loop; +   end Synth_Instantiate_Module; +     procedure Synth_Design_Instantiation_Statement       (Syn_Inst : Synth_Instance_Acc; Stmt : Node)     is @@ -238,8 +295,6 @@ package body Synth.Insts is        Config : Node;        Sub_Inst : Synth_Instance_Acc;        Inter : Node; -      Nbr_Inputs : Port_Nbr; -      Nbr_Outputs : Port_Nbr;        Inst_Obj : Inst_Object;        Inst : Instance;     begin @@ -304,21 +359,65 @@ package body Synth.Insts is        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) +      Synth_Instantiate_Module +        (Syn_Inst, Inst, +         Get_Port_Chain (Ent), Get_Port_Map_Aspect_Chain (Stmt)); +   end Synth_Design_Instantiation_Statement; + +   procedure Create_Component_Wire (Inter : Node; Val : Value_Acc) +   is +      Value : Net; +   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); +            Value := Builders.Build_Signal +              (Build_Context, New_Sname (No_Sname, Get_Identifier (Inter)), +               Val.W_Bound.Len); +            Wire_Id_Table.Table (Val.W).Gate := Value; +         when others => +            raise Internal_Error; +      end case; +   end Create_Component_Wire; + +   procedure Synth_Component_Instantiation_Statement +     (Syn_Inst : Synth_Instance_Acc; Stmt : Node) +   is +      Component : constant Node := +        Get_Named_Entity (Get_Instantiated_Unit (Stmt)); +      Config : constant Node := Get_Component_Configuration (Stmt); +      Bind : constant Node := Get_Binding_Indication (Config); +      Aspect : constant Node := Get_Entity_Aspect (Bind); +      Comp_Inst : Synth_Instance_Acc; + +      Ent : Node; +      Arch : Node; +      Sub_Config : Node; +      Sub_Inst : Synth_Instance_Acc; +      Inst_Obj : Inst_Object; +      Inst : Instance; +   begin +      pragma Assert (Get_Component_Configuration (Stmt) /= Null_Node); +      pragma Assert (Get_Kind (Aspect) = Iir_Kind_Entity_Aspect_Entity); + +      --  Create the sub-instance for the component +      --  Elaborate generic + map aspect +      Comp_Inst := Make_Instance (Syn_Inst, Get_Info (Component)); +      Comp_Inst.Name := New_Sname_User (Get_Identifier (Component)); +      Synth_Subprogram_Association (Comp_Inst, Syn_Inst, +                                    Get_Generic_Chain (Component), +                                    Get_Generic_Map_Aspect_Chain (Stmt)); +      --  Assign inputs.        declare           Assoc : Node;           Assoc_Inter : Node;           Actual : Node; -         Port : Net; -         O : Value_Acc; +         Inter : Node;        begin           Assoc := Get_Port_Map_Aspect_Chain (Stmt); -         Assoc_Inter := Get_Port_Chain (Ent); -         Nbr_Inputs := 0; -         Nbr_Outputs := 0; +         Assoc_Inter := Get_Port_Chain (Component);           while Is_Valid (Assoc) loop              Inter := Get_Association_Interface (Assoc, Assoc_Inter); @@ -333,46 +432,122 @@ package body Synth.Insts is              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; +                  Create_Object +                    (Comp_Inst, Assoc_Inter, +                     Synth_Expression_With_Type +                       (Syn_Inst, Actual, Get_Type (Assoc_Inter)));                 when Port_Out                   | Port_Inout => -                  Port := Get_Output (Inst, Nbr_Outputs); -                  Port := Builders.Build_Port (Build_Context, Port); -                  O := Create_Value_Net (Port, null); -                  Synth_Assignment (Syn_Inst, Actual, O); -                  Nbr_Outputs := Nbr_Outputs + 1; +                  Make_Object (Comp_Inst, Wire_None, Assoc_Inter); +                  Create_Component_Wire +                    (Assoc_Inter, Get_Value (Comp_Inst, Assoc_Inter));              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 +      case Get_Kind (Aspect) is +         when Iir_Kind_Entity_Aspect_Entity => +            Ent := Get_Entity (Aspect); +            Arch := Get_Architecture (Aspect); +         when others => +            Vhdl.Errors.Error_Kind +              ("Synth_Component_Instantiation_Statement(2)", Aspect); +      end case; + +      if Arch = Null_Node then +         Arch := Libraries.Get_Latest_Architecture (Ent); +         Sub_Config := Get_Library_Unit +           (Get_Default_Configuration_Declaration (Arch)); +         Sub_Config := Get_Block_Configuration (Sub_Config); +      else +         raise Internal_Error; +      end if; -      --  Load configured entity + architecture        --  Elaborate generic + map aspect +      Sub_Inst := Make_Instance (Comp_Inst, Get_Info (Ent)); +      Sub_Inst.Name := New_Sname_User (Get_Identifier (Ent)); +      Synth_Subprogram_Association (Sub_Inst, Comp_Inst, +                                    Get_Generic_Chain (Ent), +                                    Get_Generic_Map_Aspect_Chain (Bind)); + +      --  Elaborate port types. +      --  FIXME: what about unconstrained ports ?  Get the type from the +      --    association. +      declare +         Inter : Node; +      begin +         Inter := Get_Port_Chain (Ent); +         while Is_Valid (Inter) loop +            if not Is_Fully_Constrained_Type (Get_Type (Inter)) then +               --  TODO +               raise Internal_Error; +            end if; +            Synth_Declaration_Type (Sub_Inst, Inter); +            Inter := Get_Chain (Inter); +         end loop; +      end;        --  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 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 => Sub_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))); + +      Synth_Instantiate_Module +        (Comp_Inst, Inst, +         Get_Port_Chain (Ent), Get_Port_Map_Aspect_Chain (Bind)); +      --  Connect out from component to instance.        --  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; +      declare +         Assoc : Node; +         Assoc_Inter : Node; +         Inter : Node; +         Actual : Node; +         Port : Net; +         O : Value_Acc; +         Nbr_Outputs : Port_Nbr; +      begin +         Assoc := Get_Port_Map_Aspect_Chain (Stmt); +         Assoc_Inter := Get_Port_Chain (Component); +         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 => +                  null; +               when Port_Out +                 | Port_Inout => +                  Port := Get_Output (Inst, Nbr_Outputs); +                  Port := Builders.Build_Port (Build_Context, Port); +                  O := Create_Value_Net (Port, 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_Component_Instantiation_Statement;     procedure Synth_Top_Entity (Arch : Node; Config : Node) @@ -415,7 +590,7 @@ package body Synth.Insts is                 Make_Object (Syn_Inst, Wire_None, Inter);              when Port_Out                | Port_Inout => -               Make_Object (Syn_Inst, Wire_None, Inter); +               Make_Object (Syn_Inst, Wire_Output, Inter);           end case;           Inter := Get_Chain (Inter);        end loop; @@ -425,9 +600,10 @@ package body Synth.Insts is        --   * 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 => Syn_Inst)); +      Inst_Obj := Insts_Interning.Get +        ((Arch => Arch, +          Config => Get_Block_Configuration (Config), +          Syn_Inst => Syn_Inst));        pragma Unreferenced (Inst_Obj);     end Synth_Top_Entity; @@ -460,6 +636,7 @@ package body Synth.Insts is              --  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; +            pragma Assert (W = Val.W_Bound.Len);              Value := Builders.Build_Output (Build_Context, W);              Inp := Get_Input (Self_Inst, Idx);              Connect (Inp, Value); @@ -470,6 +647,43 @@ package body Synth.Insts is        end case;     end Create_Output_Wire; +   procedure Apply_Block_Configuration (Cfg : Node; Blk : Node) +   is +      Item : Node; +   begin +      pragma Assert (Get_Block_From_Block_Specification +                       (Get_Block_Specification (Cfg)) = Blk); +      Item := Get_Configuration_Item_Chain (Cfg); +      while Item /= Null_Node loop +         case Get_Kind (Item) is +            when Iir_Kind_Component_Configuration => +               declare +                  List : constant Iir_Flist := +                    Get_Instantiation_List (Item); +                  El : Node; +                  Inst : Node; +               begin +                  for I in Flist_First .. Flist_Last (List) loop +                     El := Get_Nth_Element (List, I); +                     Inst := Get_Named_Entity (El); +                     pragma Assert +                       (Get_Kind (Inst) +                          = Iir_Kind_Component_Instantiation_Statement); +                     pragma Assert +                       (Get_Component_Configuration (Inst) = Null_Node); +                     Set_Component_Configuration (Inst, Item); +                  end loop; +               end; +            when Iir_Kind_Block_Configuration => +               --  TODO +               raise Internal_Error; +            when others => +               Vhdl.Errors.Error_Kind ("apply_block_configuration", Item); +         end case; +         Item := Get_Chain (Item); +      end loop; +   end Apply_Block_Configuration; +     procedure Synth_Instance (Inst : Inst_Object)     is        Syn_Inst : constant Synth_Instance_Acc := Inst.Syn_Inst; @@ -500,6 +714,12 @@ package body Synth.Insts is           Inter := Get_Chain (Inter);        end loop; +      --  Apply configuration. +      --  FIXME: what about inner block configuration ? +      pragma Assert (Get_Kind (Inst.Config) = Iir_Kind_Block_Configuration); +      Apply_Block_Configuration (Inst.Config, Arch); + +        Synth_Declarations (Syn_Inst, Get_Declaration_Chain (Entity));        Synth_Concurrent_Statements          (Syn_Inst, Get_Concurrent_Statement_Chain (Entity)); | 
