Optimize Unconnected Ports in HDL Code for Simulink Models
HDL code generation improves code readability, reduces code size, and reduces area usage by removing unconnected ports from the generated code. This improvement includes removing unconnected vector and scalar ports, bus element ports, and bus ports. Unconnected port removal can help avoid synthesis failure caused by unused ports in the generated code.
Unused Port Removal
Unused port removal works in conjunction with removal of unused blocks in your design. See Remove Redundant Logic and Unused Blocks in Generated HDL Code.
You can see the effect of unused port removal in the generated HDL code. Ports are not removed from top-level DUT models or subsystems, implementation models, or validation models.
Open the model hdlcoder_RemoveUnconnectedPorts
containing Bus Element ports and a port connected to an inactive output.
open_system('hdlcoder_RemoveUnconnectedPorts') set_param('hdlcoder_RemoveUnconnectedPorts', 'SimulationCommand', 'update');
Open the dut
Subsystem block, and then open the mid_Subsystem
block. The mid_Subsystem
contains the Bus Element ports. One of the output signals is connected to a Terminator block.
open_system('hdlcoder_RemoveUnconnectedPorts/dut/mid_Subsystem')
To generate HDL code for the design, at the MATLAB® command prompt, enter:
makehdl('hdlcoder_RemoveUnconnectedPorts/dut')
The generated code mid_Subsystem.vhd
shows that unconnected ports are removed during HDL code generation. The input InBus_signal3
at the DUT input port is multiplied by a Gain block, and then connected to the output port OutBus_signal2
, which is then passed to the DUT output port. Because the other input and output ports are unused at the DUT level, these ports are removed from the generated HDL code.
ARCHITECTURE rtl OF mid_Subsystem IS
-- Component Declarations COMPONENT inner_Subsystem PORT( clk : IN std_logic; reset : IN std_logic; enb : IN std_logic; InBus_signal3 : IN std_logic_vector(31 DOWNTO 0); -- single OutBus_signal2 : OUT std_logic_vector(31 DOWNTO 0) -- single ); END COMPONENT;
...
END rtl;
Disable Unused Port Deletion Optimization
By default, the optimization is enabled and unused ports are removed in the generated HDL code.
If you do not want unconnected ports to be removed from your design:
In the Configuration Parameters dialog box, clear the Remove Unused Ports check box.
When you run the HDL Workflow Advisor, in the Set Code Generation Options > Set Optimization Options task, clear the Remove Unused Ports check box.
At the command line, set
DeleteUnusedPorts
tooff
withhdlset_param
ormakehdl
. For example, to specify that you want to preserve the unused ports in thehdlcoder_RemoveUnconnectedPorts
model, run this command:
makehdl('hdlcoder_RemoveUnconnectedPorts/dut', 'DeleteUnusedPorts', 'off')
The generated HDL code preserves the unused Bus Elements ports.
ARCHITECTURE rtl OF mid_Subsystem IS
-- Component Declarations COMPONENT inner_Subsystem PORT( clk : IN std_logic; reset : IN std_logic; enb : IN std_logic; InBus_signal1 : IN std_logic_vector(31 DOWNTO 0); -- single InBus_signal2 : IN std_logic_vector(31 DOWNTO 0); -- single InBus_signal3 : IN std_logic_vector(31 DOWNTO 0); -- single InBus_signal4 : IN std_logic_vector(31 DOWNTO 0); -- single OutBus_signal1 : OUT std_logic_vector(31 DOWNTO 0); -- single OutBus_signal2 : OUT std_logic_vector(31 DOWNTO 0) -- single ); END COMPONENT;
...
END rtl;
Unused Port Deletion for Subsystem Ports
This optimization can remove unused subsystem data ports. Control ports and ports of a referenced model are not removed.
A subsystem data port is considered to be active when it contributes to a DUT output port downstream or is connected to an active black box subsystem, or a component that is preserved during HDL code generation.
Open the model hdlcoder_subsys_ports_unused
.
open_system('hdlcoder_subsys_ports_unused') sim('hdlcoder_subsys_ports_unused');
The model contains a normal_subsys_dead_out
subsystem that contains an output port out3
that is terminated and does not contribute to the DUT output.
open_system('hdlcoder_subsys_ports_unused/DUT')
To generate HDL code for the DUT subsystem, run this command:
makehdl('hdlcoder_subsys_ports_unused/DUT')
By default, when DeleteUnusedPorts
is on
, the Add block calculation and output port Out3
are removed in the generated HDL code.
ENTITY normal_subsys_dead_out IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END normal_subsys_dead_out;
ARCHITECTURE rtl OF normal_subsys_dead_out IS
...
Out1 <= std_logic_vector(Gain_out1);
...
Out2 <= std_logic_vector(Gain1_out1);
END rtl;
To disable DeleteUnusedPorts
optimization, run this command:
makehdl('hdlcoder_subsys_ports_unused/DUT', 'DeleteUnusedPorts', 'off')
When you set DeleteUnusedPorts
to off
, this port and the Add block calculation are preserved in the generated HDL code.
ENTITY normal_subsys_dead_out IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out3 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END normal_subsys_dead_out;
ARCHITECTURE rtl OF normal_subsys_dead_out IS
...
Out1 <= std_logic_vector(Gain_out1);
...
Out2 <= std_logic_vector(Gain1_out1
Add_out1 <= to_signed(16#0000#, 16);
Out3 <= std_logic_vector(Add_out1);
END rtl;
Unused Port Deletion for Atomic Subsystems
For unused ports outside atomic subsystems, atomic subsystem instances are removed from the generated HDL code.
Open the model hdlcoder_atomic_subsys3_redundant
open_system('hdlcoder_atomic_subsys3_redundant') sim('hdlcoder_atomic_subsys3_redundant');
The DUT
subsystem contains three atomic subsystem instances. The outputs of two of the atomic subsystem instances are connected to Terminator blocks.
open_system('hdlcoder_atomic_subsys3_redundant/DUT')
To generate HDL code for the DUT subsystem, run this command:
makehdl('hdlcoder_atomic_subsys3_redundant/DUT')
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT atomic_subsys_dead_out_instance_1 PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
...
END rtl;
To set DeleteUnusedPorts
to off
, run this command:
makehdl('hdlcoder_atomic_subsys3_redundant/DUT', 'DeleteUnusedPorts', 'off')
If you set DeleteUnusedPorta
to off
, the input port In2
is preserved in the generated HDL code but it is feeding into an input port that is driving an unused component.
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT atomic_subsys_dead_out_instance_1 PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 In2 : IN std_logic_vector(7 DOWNTO 0); -- int8 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
...
END rtl;
Unused Port Deletion for Output Ports of Atomic Subsystems
When you have multiple active atomic subsystem instances, the redundant logic across the boundary including any ports is preserved in the HDL code independent of the DeleteUnusedPorts
setting. When you have only one Atomic Subsystem instance, by default, when DeleteUnusedPorts
is on
, any redundant logic and ports across the subsystem boundary are removed. If you set DeleteUnusedPorts
to off
, any unused port is preserved though the logic is redundant.
Open the model hdlcoder_atomic_subsys2_ports_redundant
.
open_system('hdlcoder_atomic_subsys2_ports_redundant') sim('hdlcoder_atomic_subsys2_ports_redundant');
The DUT
subsystem contains an Atomic Subsystem block that contains an Add block connected to an output port terminated outside the subsystem.
open_system('hdlcoder_atomic_subsys2_ports_redundant/DUT')
To generate HDL code for the DUT
subsystem, run this command:
makehdl('hdlcoder_atomic_subsys2_ports_redundant/DUT')
In the generated HDL code, the Add block and corresponding output port Out3 is removed because it does not contribute to an active output.
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT single_instance_atomic_subsys_dead_out PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
...
END rtl;
To set DeleteUnusedPorts
to off
, run this command:
makehdl('hdlcoder_atomic_subsys2_ports_redundant/DUT', 'DeleteUnusedPorts', 'off')
If you set DeleteUnusedPorts
to off
, the output port Out3
is preserved in the generated HDL code.
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT single_instance_atomic_subsys_dead_out PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 Out3 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
...
END rtl;
ENTITY single_instance_atomic_subsys_dead_out IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out3 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END single_instance_atomic_subsys_dead_out;
ARCHITECTURE rtl OF single_instance_atomic_subsys_dead_out IS
...
Add_out1 <= to_signed(16#0000#, 16);
Out3 <= std_logic_vector(Add_out1);
END rtl;
If there are multiple atomic subsystem instances that are not active, the unused port and logic are removed or preserved depending on the DeleteUnusedPorts
setting.
Open the model hdlcoder_atomic_subsys3_ports_redundant
.
open_system('hdlcoder_atomic_subsys3_ports_redundant') sim('hdlcoder_atomic_subsys3_ports_redundant');
The DUT
subsystem contains an Atomic Subsystem block that contains an Add block connected to an output port terminated outside the subsystem.
open_system('hdlcoder_atomic_subsys3_ports_redundant/DUT')
The two atomic subsystem instances that have the output ports terminated are removed in the generated HDL code. In the other Atomic Subsystem block, the Add block calculation and its output is removed.
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT atomic_subsys_instance_1 PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
...
-- Removed -- -- Removed
u_atomic_subsys_instance_1 : atomic_subsys_instance_1 PORT MAP( In1 => In1, -- int16 Out1 => atomic_subsys_instance_1_out1, -- int16 Out2 => atomic_subsys_instance_1_out2 -- int16 );
Out1 <= atomic_subsys_instance_1_out1;
Out2 <= atomic_subsys_instance_1_out2;
END rtl;
To set DeleteUnusedPorts
to off
, run this command:
makehdl('hdlcoder_atomic_subsys3_ports_redundant/DUT', 'DeleteUnusedPorts', 'off')
If you set DeleteUnusedPorts
to off
, the output port Out3
is preserved in the generated HDL code.
ENTITY DUT IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END DUT;
ARCHITECTURE rtl OF DUT IS
-- Component Declarations COMPONENT atomic_subsys_instance_1 PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out3 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END COMPONENT;
If you see the generated HDL code for the Atomic Subsystem instance, it shows that the Add block computation and Out3 is preserved in the generated HDL code.
ENTITY atomic_subsys_instance_1 IS PORT( In1 : IN std_logic_vector(15 DOWNTO 0); -- int16 Out1 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out2 : OUT std_logic_vector(15 DOWNTO 0); -- int16 Out3 : OUT std_logic_vector(15 DOWNTO 0) -- int16 ); END atomic_subsys_instance_1;
ARCHITECTURE rtl OF atomic_subsys_instance_1 IS
...
Add_out1 <= In1_signed + In1_signed;
Out3 <= std_logic_vector(Add_out1);
END rtl;
Upstream Logic Preservation of Unused Port
You can preserve logic upstream from a Terminator block, its unused logic, while still removing other unconnected ports and unused logic. You can choose specific unused logic that you want to preserve for generated HDL code while still optimizing the rest of your model. Enable the HDL block property PreserveUpstreamLogic
for the Terminator block for which you want to preserve the logic upstream. See PreserveUpstreamLogic.
Open the model hdlcoder_subsys_port_preserve
.
open_system('hdlcoder_subsys_ports_preserved') sim('hdlcoder_subsys_ports_preserved');
The model contains a DUT
subsystem that has two Terminator blocks as output ports for the subsystem. The Terminator block TermPres
has the HDL block property PreserveUpstreamLogic
set to on. The Terminator block TermRem
does not (the default setting). The model property DeleteUnusedPorts
is enabled by default.
open_system('hdlcoder_subsys_ports_preserved/DUT') hdlget_param('hdlcoder_subsys_ports_preserved/DUT/TermPres', 'PreserveUpstreamLogic')
ans = 'on'
When you generate HDL code, the logic connected upstream from the TermPres
block is preserved in the HDL code, including the outport Out2
from the normal_subsys_dead_out
subsystem. Enabling PreserveUpstreamLogic
for a Terminator block takes priority over the enabled DeleteUnusedPorts
option. The logic connected upstream from the TermRem
block is not preserved, including not preserving the outport from the normal_subsys_dead_out
subsystem.
To generate HDL code for the DUT subsystem, run this command:
makehdl('hdlcoder_subsys_ports_preserved/DUT')
In the code traceability report, click the G1
gain connected to TermPres
. The corresponding HDL code shows that the logic connected upstream from TermPres
, such as G1
, is preserved. No corresponding HDL code exists for the logic upstream from TermRem
.
You can highlight the removed logic blocks upstream from TermRem
by clicking the script highlightRemovedDeadBlocks.m
in the output of the makehdl
command. The removed blocks appear in red in the model. To clear the highlighting, click the script clearHighlightingRemovedDeadBlocks.m
.
You can also view all eliminated and virtual blocks in the code generation report. Click Traceability Report, then view the Eliminated / Virtual Blocks section.
You can preserve the output port from the normal_subsys_dead_out
subsystem connected to TermRem
but still remove any upstream logic by disabling DeleteUnusedPorts
for the model.
hdlset_param('hdlcoder_subsys_ports_preserved', 'DeleteUnusedPorts', 'off')
Generate HDL code for the DUT subsystem:
makehdl('hdlcoder_subsys_ports_preserved/DUT');
The traceability report now highlights the difference between the last HDL code generated and this HDL code. The logic upstream from TermRem
, such as the gain block G2
, is still removed because PreserveUpstreamLogic
is off. The outport Out3
is now in the generated HDL code because DeleteUnusedPorts
is set to off
for the model.
Limitations
If your model contains multiple instances of atomic subsystems, model references, or Foreach Subsystem blocks, and these blocks are active during HDL code generation, then ports are preserved in the generated code. Components connected upstream to these ports are also considered active. The ports are preserved independently of whether you enable or disable the DeleteUnusedPorts
setting.
This limitation also applies to bus signals. In this case, the entire bus is preserved in the generated HDL code. For an example, see Remove Redundant Logic and Unused Blocks in Generated HDL Code.