Main Content

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 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.

How Unused Port Removal Works

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. Since 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 the 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 to off with hdlset_param or makehdl. For example, to specify that you want to preserve the unused ports in the hdlcoder_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 is 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 are 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. However, 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;

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.

Related Topics