Generate Reusable Code for Subsystems
HDL Coder™ can detect atomic subsystems that are identical, or identical except for their
mask parameter values, at any level of the model hierarchy, and
generate a single reusable HDL module
or entity
. The
reusable HDL code is generated as a single file and instantiated multiple times.
Requirements for Generating Reusable Code for Atomic Subsystems
The
DefaultParameterBehavior
Simulink® Configuration Parameter must beInlined
. You can set this parameter at the command line by using theset_param
orhdlsetup
function. To specify this setting in the Configuration Parameters dialog box, you must have Simulink Coder™.Note
Using
hdlsetup
setsInlineParams
property toon
. Enabling this parameter is the same as settingDefaultParameterBehavior
toInlined
. SettingInlineParams
tooff
changesDefaultParameterBehavior
value toTunable
.Do not use functionality such as signal logging or using blocks like To Workspace or To File.
The atomic subsystems must be identical, or identical except for their mask parameter values.
MaskParameterAsGeneric
must beon
. For more information, see Generate Parameterized HDL Code from Masked Subsystem.Mask parameters must be nontunable. The code generator does not share atomic subsystems with mask parameters that are tunable.
Mask parameters must be scalar.
Mask parameter data types must be
integer
orfixed-point
with a word length of less than or equal to32
.The tunable parameter must be used in only Constant, Gain, or Compare To Constant blocks.
Port data types must match.
If you change the value of the tunable mask parameter, the output port data type can 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
The
DefaultParameterBehavior
Simulink Configuration Parameter must beInlined
. You can set this parameter at the command line by using theset_param
orhdlsetup
function. To specify this setting in the Configuration Parameters dialog box, you must have Simulink Coder.Note
Using
hdlsetup
setsInlineParams
property toon
. Enabling this parameter is the same as settingDefaultParameterBehavior
toInlined
. SettingInlineParams
tooff
changesDefaultParameterBehavior
value toTunable
.Do not use logging functionality such as signal logging or blocks like To Workspace or To File.
The virtual subsystems must be identical, or identical except for their mask parameter values.
SubsystemReuse
must be set to'Atomic and Virtual'
.Setting
SubsystemReuse
to'Atomic and Virtual'
reduces artificial algebraic errors and improves the recognition of identical subsystems, irrespective of their topology within the rest of the design. Identification of similar subsystems can help resource sharing.To set these values to your required setting, 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, you can change the Code reuse setting to the required option.
The previous commands set the
SubsystemReuse
option for your project. To set this option for only the current code generation session, enter:makehdl(<DUT system>, 'SubsystemReuse', 'Atomic and Virtual')
MaskParameterAsGeneric
must beon
. For more information, see Generate Parameterized HDL Code from Masked Subsystem.Mask parameters must be nontunable. The code generator does not share atomic subsystems with mask parameters that are tunable.
Mask parameters must be scalar.
Mask parameter data types must be
integer
orfixed-point
with a word length of less than or equal to32
.The tunable parameter must be used in only Constant, Gain, or Compare To Constant blocks.
Port data types must match.
If you change the value of the tunable mask parameter, the output port data type can change. If one of the atomic subsystems has a different port data type, the code generated for that subsystem also differs.
Generate Reusable Code for Atomic Subsystems
If your design contains identical atomic subsystems, the coder generates one HDL
module
or entity
for the subsystem and instantiates
it multiple times.
Example
Open the hdlcoder_reusable_code_identical_subsystem
model
to see an example of a DUT subsystem containing three identical atomic subsystems.
HDL Coder generates a single VHDL® file, vsum.vhd
, for the three subsystems.
makehdl('hdlcoder_reusable_code_identical_subsystem/DUT')
### Generating HDL for 'hdlcoder_reusable_code_identical_subsystem/DUT'. ### Starting HDL check. ### Generating new validation model: gm_hdlcoder_reusable_code_identical_subsystem_vnl. ### Validation model generation complete. ### Begin VHDL Code Generation for 'hdlcoder_reusable_code_identical_subsystem'. ### Working on hdlcoder_reusable_code_identical_subsystem/DUT/vsum/Sum of Elements as hdl_prj\hdlsrc\hdlcoder_reusable_code_identical_subsystem\Sum_of_Elements.vhd. ### 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. ### Creating HDL Code Generation Check Report DUT_report.html ### HDL check for 'hdlcoder_reusable_code_identical_subsystem' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
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
If your design contains 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.
To generate reusable code for identical atomic subsystems, enable
MaskParameterAsGeneric
for the model. By default,
MaskParameterAsGeneric
is disabled.
For example, to enable the generation of reusable code for the atomic subsystems with
tunable parameters, open the hdlcoder_reusable_code_parameterized_subsystem
model, then
enter:
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 option.
Example
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.
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
.
With MaskParameterAsGeneric
enabled, HDL Coder generates a single source file, gain_module.v
, for the
three gain module subsystems.
makehdl('hdlcoder_reusable_code_parameterized_subsystem/DUT','MaskParameterAsGeneric','on',... 'TargetLanguage','Verilog')
### Generating HDL for 'hdlcoder_reusable_code_parameterized_subsystem/DUT'. ### Starting HDL check. ### 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. ### Creating HDL Code Generation Check Report DUT_report.html ### HDL check for 'hdlcoder_reusable_code_parameterized_subsystem' complete with 0 errors, 0 warnings, and 0 messages. ### HDL code generation complete.
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.