Main Content

Generate Reusable Code for Subsystems

HDL Coder™ can generate reusable HDL modules or entities from atomic subsystems—and some virtual subsystems—that are identical or identical except for their mask parameter values. The reusable HDL code is generated as a single file and instantiated multiple times.

Requirements for Generating Reusable Code for Atomic Subsystems

HDL Coder generates reusable HDL modules or entities from atomic subsystems if:

  • The DefaultParameterBehavior model configuration parameter is Inlined. You can set this parameter at the command line by using the set_param or hdlsetup function. To specify this setting in the Configuration Parameters dialog box, you must have Simulink® Coder™.

    Note

    Using hdlsetup sets InlineParams property to on. Enabling this parameter is the same as setting DefaultParameterBehavior to Inlined. Setting InlineParams to off changes DefaultParameterBehavior value to Tunable.

  • You do not use signal logging functionalities, such as To Workspace blocks or To File blocks.

  • The atomic subsystems are identical, or identical except for their mask parameter values.

    • If the reusable subsystems have mask parameters with different values, the MaskParameterAsGeneric configuration parameter must be on for the relevant subsystems or for the model. This parameter has no effect on virtual subsystems. For more information, see Generate parameterized HDL code from masked subsystem.

    • Tunable parameters must be used only in Constant, Gain, or Compare To Constant blocks.

    • Mask parameters must be scalar.

    • Mask parameter data types must be integer or fixed-point with a word length of less than or equal to 32.

    • Port and parameter data types must match.

    • If you change the value of a tunable mask parameter, the output port data type must not change. If one of the atomic subsystems has a different port data type, the code generated for that subsystem also differs.

Requirements for Generating Reusable Code for Virtual Subsystems

HDL Coder generates reusable HDL modules or entities from virtual subsystems if:

  • The DefaultParameterBehavior configuration parameter is Inlined. You can set this parameter at the command line by using the set_param or hdlsetup function. To specify this setting in the Configuration Parameters dialog box, you must have Simulink Coder.

    Note

    Using hdlsetup sets InlineParams property to on. Enabling this parameter is the same as setting DefaultParameterBehavior to Inlined. Setting InlineParams to off changes DefaultParameterBehavior value to Tunable.

  • You do not use signal logging functionalities, such as To Workspace blocks or To File blocks.

  • The SubsystemReuse configuration parameter is set to Atomic and Virtual.

    • Setting SubsystemReuse to Atomic and Virtual reduces artificial algebraic loop errors and improves the recognition of identical subsystems, irrespective of their topology within the rest of the design. Identification of identical subsystems helps resource sharing.

    • To set these values, in the MATLAB Command Window, enter:

      hdlset_param('myHDLModel', 'SubsystemReuse', 'Atomic and Virtual')
    • Alternatively, you can set this option from the top-level HDL Code Generation pane in the Configuration Parameters dialog box. Under Global Settings > Coding style, change the Code reuse parameter to the required option.

    • The previous commands set the SubsystemReuse option for your model. To set this option for only the current code generation session, enter:

      makehdl(<DUT system>, 'SubsystemReuse', 'Atomic and Virtual')
  • The virtual subsystems are identical.

    • Tunable parameters must be used only in Constant, Gain, or Compare To Constant blocks.

    • Port and parameter data types must match.

    • Parameter values must be identical between the subsystems.

Generate Reusable Code for Subsystems

This example shows HDL code generation of a model that has identical subsystems. If your design contains identical subsystems, HDL Coder generates one HDL module or entity for the subsystem and instantiates it multiple times.

Open Model

Open the hdlcoder_reusable_code_identical_subsystem model to see an example of a DUT subsystem containing three identical subsystems.

load_system('hdlcoder_reusable_code_identical_subsystem');
open_system('hdlcoder_reusable_code_identical_subsystem/DUT');

Generate HDL Code

You can generate the HDL code for the model by using makehdl function. To generate HDL code for DUT subsystem, run this command:

makehdl('hdlcoder_reusable_code_identical_subsystem/DUT')
### Working on the model <a href="matlab:open_system('hdlcoder_reusable_code_identical_subsystem')">hdlcoder_reusable_code_identical_subsystem</a>
### Generating HDL for <a href="matlab:open_system('hdlcoder_reusable_code_identical_subsystem/DUT')">hdlcoder_reusable_code_identical_subsystem/DUT</a>
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_reusable_code_identical_subsystem', { 'HDL Code Generation' } )">hdlcoder_reusable_code_identical_subsystem</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_reusable_code_identical_subsystem'.
### Begin compilation of the model 'hdlcoder_reusable_code_identical_subsystem'...
### Working on the model 'hdlcoder_reusable_code_identical_subsystem'...
### Working on... <a href="matlab:configset.internal.open('hdlcoder_reusable_code_identical_subsystem', 'GenerateModel')">GenerateModel</a>
### Begin model generation 'gm_hdlcoder_reusable_code_identical_subsystem'...
### Rendering DUT with optimization related changes (IO, Area, Pipelining)...
### Model generation complete.
### Generated model saved at <a href="matlab:open_system('hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/gm_hdlcoder_reusable_code_identical_subsystem.slx')">hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/gm_hdlcoder_reusable_code_identical_subsystem.slx</a>
### Generating new validation model: '<a href="matlab:open_system('hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/gm_hdlcoder_reusable_code_identical_subsystem_vnl')">gm_hdlcoder_reusable_code_identical_subsystem_vnl</a>'.
### Validation model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_reusable_code_identical_subsystem'.
### Working on hdlcoder_reusable_code_identical_subsystem/DUT/vsum as hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/vsum.vhd.
### Working on hdlcoder_reusable_code_identical_subsystem/DUT as hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/DUT.vhd.
### Generating package file hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/DUT_pkg.vhd.
### Code Generation for 'hdlcoder_reusable_code_identical_subsystem' completed.
### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24b_2725827_3887152/tpc6f3816c/hdlcoder-ex21822210/hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/html/hdlcoder_reusable_code_identical_subsystem_codegen_rpt.html')">hdlcoder_reusable_code_identical_subsystem_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc24b_2725827_3887152/tpc6f3816c/hdlcoder-ex21822210/hdl_prj/hdlsrc/hdlcoder_reusable_code_identical_subsystem/DUT_report.html
### HDL check for 'hdlcoder_reusable_code_identical_subsystem' complete with 0 errors, 0 warnings, and 2 messages.
### HDL code generation complete.

HDL Coder generates a single VHDL® file, vsum.vhd, for the three subsystems. The generated code for the DUT subsystem, DUT.vhd, contains three instantiations of the vsum component.

ARCHITECTURE rtl OF DUT IS
-- Component Declarations
COMPONENT vsum
  PORT( In1                             :   IN    vector_of_std_logic_vector16(0 TO 9);  -- int16 [10]
        Out1                            :   OUT   std_logic_vector(19 DOWNTO 0)  -- sfix20
        );
END COMPONENT;
-- Component Configuration Statements
FOR ALL : vsum
  USE ENTITY work.vsum(rtl);
-- Signals
SIGNAL vsum_out1                        : std_logic_vector(19 DOWNTO 0);  -- ufix20
SIGNAL vsum1_out1                       : std_logic_vector(19 DOWNTO 0);  -- ufix20
SIGNAL vsum2_out1                       : std_logic_vector(19 DOWNTO 0);  -- ufix20
BEGIN
u_vsum : vsum
  PORT MAP( In1 => In1,  -- int16 [10]
            Out1 => vsum_out1  -- sfix20
            );
u_vsum1 : vsum
  PORT MAP( In1 => In2,  -- int16 [10]
            Out1 => vsum1_out1  -- sfix20
            );
u_vsum2 : vsum
  PORT MAP( In1 => In3,  -- int16 [10]
            Out1 => vsum2_out1  -- sfix20
            );
Out1 <= vsum_out1;
Out2 <= vsum1_out1;
Out3 <= vsum2_out1;
END rtl;

Generate Reusable Code for Atomic Subsystems with Tunable Mask Parameters

Using this example, you can generate HDL code for your design containing atomic subsystems that are identical except for their tunable mask parameter values. You can generate one HDL module or entity for the subsystem. In the generated code, the module or entity is instantiated multiple times.

Open Model

The hdlcoder_reusable_code_parameterized_subsystem model shows an example of a DUT subsystem containing atomic subsystems that are identical except for their tunable mask parameter values.

load_system('hdlcoder_reusable_code_parameterized_subsystem');
open_system('hdlcoder_reusable_code_parameterized_subsystem/DUT');

In hdlcoder_reusable_code_parameterized_subsystem/DUT, the gain modules are subsystems with gain values represented by tunable mask parameters. Gain values are: 4 for gain_module, 5 for gain_module1, and 7 for gain_module2.

Generate HDL Code

To generate reusable code for identical atomic subsystems, enable MaskParameterAsGeneric for the model. By default, MaskParameterAsGeneric is disabled.

To enable the generation of reusable code for the atomic subsystems with tunable parameters, set MaskParameterAsGeneric option to on for a model by using hdlset_param function.

hdlset_param('hdlcoder_reusable_code_parameterized_subsystem','MaskParameterAsGeneric','on');

Alternatively, in the Configuration Parameters dialog box, in the HDL Code Generation > Global Settings > Coding Style tab, enable the Generate parameterized HDL code from masked subsystem parameter.

You can also enable MaskParameterAsGeneric by using makehdl function and generate HDL code for a DUT subsystem.

makehdl('hdlcoder_reusable_code_parameterized_subsystem/DUT','MaskParameterAsGeneric','on',...
        'TargetLanguage','Verilog')
### Working on the model <a href="matlab:open_system('hdlcoder_reusable_code_parameterized_subsystem')">hdlcoder_reusable_code_parameterized_subsystem</a>
### Generating HDL for <a href="matlab:open_system('hdlcoder_reusable_code_parameterized_subsystem/DUT')">hdlcoder_reusable_code_parameterized_subsystem/DUT</a>
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_reusable_code_parameterized_subsystem', { 'HDL Code Generation' } )">hdlcoder_reusable_code_parameterized_subsystem</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_reusable_code_parameterized_subsystem'.
### Begin compilation of the model 'hdlcoder_reusable_code_parameterized_subsystem'...
### Working on the model 'hdlcoder_reusable_code_parameterized_subsystem'...
### Working on... <a href="matlab:configset.internal.open('hdlcoder_reusable_code_parameterized_subsystem', 'GenerateModel')">GenerateModel</a>
### Begin model generation 'gm_hdlcoder_reusable_code_parameterized_subsystem'...
### Copying DUT to the generated model....
### Model generation complete.
### Generated model saved at <a href="matlab:open_system('hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/gm_hdlcoder_reusable_code_parameterized_subsystem.slx')">hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/gm_hdlcoder_reusable_code_parameterized_subsystem.slx</a>
### Begin Verilog Code Generation for 'hdlcoder_reusable_code_parameterized_subsystem'.
### Working on hdlcoder_reusable_code_parameterized_subsystem/DUT/gain_module as hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/gain_module.v.
### Working on hdlcoder_reusable_code_parameterized_subsystem/DUT as hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/DUT.v.
### Code Generation for 'hdlcoder_reusable_code_parameterized_subsystem' completed.
### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24b_2725827_3886249/tp3d958c66/hdlcoder-ex53380017/hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/html/hdlcoder_reusable_code_parameterized_subsystem_codegen_rpt.html')">hdlcoder_reusable_code_parameterized_subsystem_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc24b_2725827_3886249/tp3d958c66/hdlcoder-ex53380017/hdlsrc/hdlcoder_reusable_code_parameterized_subsystem/DUT_report.html
### HDL check for 'hdlcoder_reusable_code_parameterized_subsystem' complete with 0 errors, 0 warnings, and 0 messages.
### HDL code generation complete.

With MaskParameterAsGeneric enabled, HDL Coder generates a single source file, gain_module.v, for the three gain module subsystems. The generated code for the DUT subsystem, DUT.v, contains three instantiations of the gain_module component.

module DUT
        (
         In1,
         In2,
         In3,
         Out1,
         Out2,
         Out3
        );
input   [7:0] In1;  // uint8
input   [7:0] In2;  // uint8
input   [7:0] In3;  // uint8
output  [31:0] Out1;  // uint32
output  [31:0] Out2;  // uint32
output  [31:0] Out3;  // uint32
wire [31:0] gain_module_out1;  // uint32
wire [31:0] gain_module1_out1;  // uint32
wire [31:0] gain_module2_out1;  // uint32
gain_module   #  (.myGain(4)
                  )
              u_gain_module   (.In1(In1),  // uint8
                               .Out1(gain_module_out1)  // uint32
                               );
assign Out1 = gain_module_out1;
gain_module   #  (.myGain(5)
                  )
              u_gain_module1   (.In1(In2),  // uint8
                                .Out1(gain_module1_out1)  // uint32
                                );
assign Out2 = gain_module1_out1;
gain_module   #  (.myGain(7)
                  )
              u_gain_module2   (.In1(In3),  // uint8
                                .Out1(gain_module2_out1)  // uint32
                                );
assign Out3 = gain_module2_out1;
endmodule  // DUT

In gain_module.v, the myGain Verilog® parameter is generated for the tunable mask parameter.

module gain_module
        (
         In1,
         Out1
        );
input   [7:0] In1;  // uint8
output  [31:0] Out1;  // uint32
parameter [31:0] myGain = 4;  // ufix32
wire [31:0] kconst;  // ufix32
wire [39:0] Gain_mul_temp;  // ufix40
wire [31:0] Gain_out1;  // uint32
assign kconst = myGain;
assign Gain_mul_temp = kconst * In1;
assign Gain_out1 = Gain_mul_temp[31:0];
assign Out1 = Gain_out1;
endmodule  // gain_module

If the input model has subsystems that contains mask information such as mask variables and mask initialization code, the mask information of those subsystems is preserved in the generated model. If you do not need this information, you can remove it.

Related Topics