Main Content

Using the State Control Block to Generate More Efficient Code with HDL Coder

This example shows how to use the State Control block to generate hardware-friendly HDL code using HDL Coder™.

Introduction to the State Control block

The State Control block is a block that modifies the Simulink® simulation behavior for its containing subsystem and all subsystems nested beneath it. Its purpose is to more closely model the synchronous behavior of clocked digital hardware, particularly with respect to blocks that have state and use explicit enable and reset signals.

When a State Control block is placed in a subsystem and has its parameter set to Synchronous, the generated HDL code will be more hardware friendly. When a subsystem is in the Synchronous mode it is marked with a graphic S in its lower left corner. A State Control block with its parameter set to Classic behaves identically to when there is no State Control block in the subsystem.

The simulation behavior difference between the two modes is small, but significant to generating efficient HDL code. The differences focus around the simulation behavior involving explicit reset and enable signals. For example, in Synchronous mode, the explicit block reset input has priority over the block enable input signal.

Classic mode behavior for Delay with explicit enable input port

HDL code generated by HDL Coder simulates identically to the model that it is generated from. In Classic State Control mode, the generated code for certain constructs implements sub-optimal hardware due to this requirement. For example, a Delay block with explicit enable input will generate a bypass register, comprised of a register and a multiplexer, in addition to the modeled register, to capture the Simulink Classic mode behavior.

Examine the contents of Enabled_Delay.vhd to observe the additional register signals and the bypass register.

load_system('hdlcoder_statecontrol_model');
open_system('hdlcoder_statecontrol_model');
set_param('hdlcoder_statecontrol_model', 'SimulationCommand', 'update');
makehdl('hdlcoder_statecontrol_model/MAC FIR Block', 'TargetDirectory', 'hdlsrc_classic');
### Working on the model <a href="matlab:open_system('hdlcoder_statecontrol_model')">hdlcoder_statecontrol_model</a>
### Generating HDL for <a href="matlab:open_system('hdlcoder_statecontrol_model/MAC FIR Block')">hdlcoder_statecontrol_model/MAC FIR Block</a>
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_statecontrol_model', { 'HDL Code Generation' } )">hdlcoder_statecontrol_model</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_statecontrol_model'.
### Begin compilation of the model 'hdlcoder_statecontrol_model'...
### Begin compilation of the model 'hdlcoder_statecontrol_model'...
### Working on the model 'hdlcoder_statecontrol_model'...
### Working on... <a href="matlab:configset.internal.open('hdlcoder_statecontrol_model', 'GenerateModel')">GenerateModel</a>
### Begin model generation 'gm_hdlcoder_statecontrol_model'...
### Rendering DUT with optimization related changes (IO, Area, Pipelining)...
### Model generation complete.
### Generated model saved at <a href="matlab:open_system('hdlsrc_classic/hdlcoder_statecontrol_model/gm_hdlcoder_statecontrol_model.slx')">hdlsrc_classic/hdlcoder_statecontrol_model/gm_hdlcoder_statecontrol_model.slx</a>
### Begin VHDL Code Generation for 'hdlcoder_statecontrol_model'.
### Unused logic removed during HDL code generation. To highlight the logic removed, click the following MATLAB script: hdlsrc_classic/hdlcoder_statecontrol_model/highlightRemovedDeadBlocks.m
### To clear highlighting, click the following MATLAB script: hdlsrc_classic/hdlcoder_statecontrol_model/clearHighlightingRemovedDeadBlocks.m
### Working on hdlcoder_statecontrol_model/MAC FIR Block/Coeff ROM as hdlsrc_classic/hdlcoder_statecontrol_model/Coeff_ROM.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block/Enabled_Delay as hdlsrc_classic/hdlcoder_statecontrol_model/Enabled_Delay.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block/RAM delay line/circular buffer logic as hdlsrc_classic/hdlcoder_statecontrol_model/circular_buffer_logic.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block/RAM delay line/SimpleDualPortRAM_generic as hdlsrc_classic/hdlcoder_statecontrol_model/SimpleDualPortRAM_generic.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block/RAM delay line as hdlsrc_classic/hdlcoder_statecontrol_model/RAM_delay_line.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block as hdlsrc_classic/hdlcoder_statecontrol_model/MAC_FIR_Block.vhd.
### Generating package file hdlsrc_classic/hdlcoder_statecontrol_model/MAC_FIR_Block_pkg.vhd.
### Code Generation for 'hdlcoder_statecontrol_model' completed.
### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24a_2528353_2768217/tpcc1347d7/hdlcoder-ex66924147/hdlsrc_classic/hdlcoder_statecontrol_model/html/hdlcoder_statecontrol_model_codegen_rpt.html')">hdlcoder_statecontrol_model_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc24a_2528353_2768217/tpcc1347d7/hdlcoder-ex66924147/hdlsrc_classic/hdlcoder_statecontrol_model/MAC_FIR_Block_report.html
### HDL check for 'hdlcoder_statecontrol_model' complete with 0 errors, 1 warnings, and 1 messages.
### HDL code generation complete.

type hdlsrc_classic/hdlcoder_statecontrol_model/Enabled_Delay.vhd
-- -------------------------------------------------------------
-- 
-- File Name: hdlsrc_classic/hdlcoder_statecontrol_model/Enabled_Delay.vhd
-- Created: 2024-02-13 02:14:02
-- 
-- Generated by MATLAB 24.1, HDL Coder 24.1, and Simulink 24.1
-- 
-- -------------------------------------------------------------


-- -------------------------------------------------------------
-- 
-- Module: Enabled_Delay
-- Source Path: hdlcoder_statecontrol_model/MAC FIR Block/Enabled_Delay
-- Hierarchy Level: 1
-- Model version: 15.0
-- 
-- -------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;

ENTITY Enabled_Delay IS
  PORT( clk                               :   IN    std_logic;
        reset                             :   IN    std_logic;
        enb                               :   IN    std_logic;
        din_re                            :   IN    std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        din_im                            :   IN    std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        LocalEnable                       :   IN    std_logic;
        Out1_re                           :   OUT   std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        Out1_im                           :   OUT   std_logic_vector(33 DOWNTO 0)  -- sfix34_En31
        );
END Enabled_Delay;


ARCHITECTURE rtl OF Enabled_Delay IS

  -- Signals
  SIGNAL din_re_signed                    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL din_im_signed                    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL Enabled_Delay_bypass_delay_re    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL Enabled_Delay_bypass_delay_im    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL Enabled_Delay_reg_re             : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL Enabled_Delay_reg_im             : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL dout_re                          : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL dout_im                          : signed(33 DOWNTO 0);  -- sfix34_En31

BEGIN
  din_re_signed <= signed(din_re);

  din_im_signed <= signed(din_im);

  Enabled_Delay_1_process : PROCESS (clk, reset)
  BEGIN
    IF reset = '1' THEN
      Enabled_Delay_bypass_delay_re <= to_signed(0, 34);
      Enabled_Delay_bypass_delay_im <= to_signed(0, 34);
      Enabled_Delay_reg_re <= to_signed(0, 34);
      Enabled_Delay_reg_im <= to_signed(0, 34);
    ELSIF clk'EVENT AND clk = '1' THEN
      IF enb = '1' AND LocalEnable = '1' THEN
        Enabled_Delay_bypass_delay_im <= Enabled_Delay_reg_im;
        Enabled_Delay_reg_im <= din_im_signed;
        Enabled_Delay_bypass_delay_re <= Enabled_Delay_reg_re;
        Enabled_Delay_reg_re <= din_re_signed;
      END IF;
    END IF;
  END PROCESS Enabled_Delay_1_process;

  
  dout_re <= Enabled_Delay_reg_re WHEN LocalEnable = '1' ELSE
      Enabled_Delay_bypass_delay_re;
  
  dout_im <= Enabled_Delay_reg_im WHEN LocalEnable = '1' ELSE
      Enabled_Delay_bypass_delay_im;

  Out1_re <= std_logic_vector(dout_re);

  Out1_im <= std_logic_vector(dout_im);

END rtl;

Synchronous mode behavior for Delay with explicit enable input port

A Delay block with explicit enable in Synchronous State Control mode will generate HDL code that creates more efficient hardware. The implementation does not contain a bypass register.

Examine Enabled_Delay_Sync.vhd and note the improvement in the generated code as compared to the Classic mode output.

makehdl('hdlcoder_statecontrol_model/MAC FIR Block Sync', 'TargetDirectory', 'hdlsrc_sync');
### Working on the model <a href="matlab:open_system('hdlcoder_statecontrol_model')">hdlcoder_statecontrol_model</a>
### Generating HDL for <a href="matlab:open_system('hdlcoder_statecontrol_model/MAC FIR Block Sync')">hdlcoder_statecontrol_model/MAC FIR Block Sync</a>
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_statecontrol_model', { 'HDL Code Generation' } )">hdlcoder_statecontrol_model</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_statecontrol_model'.
### Begin compilation of the model 'hdlcoder_statecontrol_model'...
### Begin compilation of the model 'hdlcoder_statecontrol_model'...
### Working on the model 'hdlcoder_statecontrol_model'...
### Working on... <a href="matlab:configset.internal.open('hdlcoder_statecontrol_model', 'GenerateModel')">GenerateModel</a>
### Begin model generation 'gm_hdlcoder_statecontrol_model'...
### Rendering DUT with optimization related changes (IO, Area, Pipelining)...
### Model generation complete.
### Generated model saved at <a href="matlab:open_system('hdlsrc_sync/hdlcoder_statecontrol_model/gm_hdlcoder_statecontrol_model.slx')">hdlsrc_sync/hdlcoder_statecontrol_model/gm_hdlcoder_statecontrol_model.slx</a>
### Begin VHDL Code Generation for 'hdlcoder_statecontrol_model'.
### Unused logic removed during HDL code generation. To highlight the logic removed, click the following MATLAB script: hdlsrc_sync/hdlcoder_statecontrol_model/highlightRemovedDeadBlocks.m
### To clear highlighting, click the following MATLAB script: hdlsrc_sync/hdlcoder_statecontrol_model/clearHighlightingRemovedDeadBlocks.m
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync/Coeff ROM as hdlsrc_sync/hdlcoder_statecontrol_model/Coeff_ROM.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync/Enabled Delay Sync as hdlsrc_sync/hdlcoder_statecontrol_model/Enabled_Delay_Sync.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line/circular buffer logic as hdlsrc_sync/hdlcoder_statecontrol_model/circular_buffer_logic.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line/SimpleDualPortRAM_generic as hdlsrc_sync/hdlcoder_statecontrol_model/SimpleDualPortRAM_generic.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line as hdlsrc_sync/hdlcoder_statecontrol_model/RAM_delay_line.vhd.
### Working on hdlcoder_statecontrol_model/MAC FIR Block Sync as hdlsrc_sync/hdlcoder_statecontrol_model/MAC_FIR_Block_Sync.vhd.
### Generating package file hdlsrc_sync/hdlcoder_statecontrol_model/MAC_FIR_Block_Sync_pkg.vhd.
### Code Generation for 'hdlcoder_statecontrol_model' completed.
### Generating HTML files for code generation report at <a href="matlab:hdlcoder.report.openDdg('/tmp/Bdoc24a_2528353_2768217/tpcc1347d7/hdlcoder-ex66924147/hdlsrc_sync/hdlcoder_statecontrol_model/html/hdlcoder_statecontrol_model_codegen_rpt.html')">hdlcoder_statecontrol_model_codegen_rpt.html</a>
### Creating HDL Code Generation Check Report file:///tmp/Bdoc24a_2528353_2768217/tpcc1347d7/hdlcoder-ex66924147/hdlsrc_sync/hdlcoder_statecontrol_model/MAC_FIR_Block_Sync_report.html
### HDL check for 'hdlcoder_statecontrol_model' complete with 0 errors, 1 warnings, and 1 messages.
### HDL code generation complete.
type hdlsrc_sync/hdlcoder_statecontrol_model/Enabled_Delay_Sync.vhd
-- -------------------------------------------------------------
-- 
-- File Name: hdlsrc_sync/hdlcoder_statecontrol_model/Enabled_Delay_Sync.vhd
-- Created: 2024-02-13 02:14:25
-- 
-- Generated by MATLAB 24.1, HDL Coder 24.1, and Simulink 24.1
-- 
-- -------------------------------------------------------------


-- -------------------------------------------------------------
-- 
-- Module: Enabled_Delay_Sync
-- Source Path: hdlcoder_statecontrol_model/MAC FIR Block Sync/Enabled Delay Sync
-- Hierarchy Level: 1
-- Model version: 15.0
-- 
-- -------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;

ENTITY Enabled_Delay_Sync IS
  PORT( clk                               :   IN    std_logic;
        reset                             :   IN    std_logic;
        enb                               :   IN    std_logic;
        din_re                            :   IN    std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        din_im                            :   IN    std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        LocalEnable                       :   IN    std_logic;
        Out1_re                           :   OUT   std_logic_vector(33 DOWNTO 0);  -- sfix34_En31
        Out1_im                           :   OUT   std_logic_vector(33 DOWNTO 0)  -- sfix34_En31
        );
END Enabled_Delay_Sync;


ARCHITECTURE rtl OF Enabled_Delay_Sync IS

  -- Signals
  SIGNAL din_re_signed                    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL din_im_signed                    : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL dout_re                          : signed(33 DOWNTO 0);  -- sfix34_En31
  SIGNAL dout_im                          : signed(33 DOWNTO 0);  -- sfix34_En31

BEGIN
  din_re_signed <= signed(din_re);

  din_im_signed <= signed(din_im);

  Enabled_Delay_process : PROCESS (clk, reset)
  BEGIN
    IF reset = '1' THEN
      dout_re <= to_signed(0, 34);
      dout_im <= to_signed(0, 34);
    ELSIF clk'EVENT AND clk = '1' THEN
      IF enb = '1' AND LocalEnable = '1' THEN
        dout_re <= din_re_signed;
        dout_im <= din_im_signed;
      END IF;
    END IF;
  END PROCESS Enabled_Delay_process;


  Out1_re <= std_logic_vector(dout_re);

  Out1_im <= std_logic_vector(dout_im);

END rtl;

Enabled Subsystems

When a model has an Enabled subsystem in Synchronous mode, the code generated for it will also be improved. A Synchronous mode Enabled subsystem will no longer generate bypass registers on the subsystem outputs. In addition, any registers inside the Enabled subsystem that have explicit enable inputs will also show the same improvements as discussed previously.

MATLAB Function Blocks and Synchronous Mode

MATLAB Function Blocks require more precise configuration in order to be used in Synchronous mode. If the block contains a direct combinatorial path from block input to output, you must enable direct feedthrough:

  1. Open the Property Inspector. In the Modeling tab, in the Design section, click the Property Inspector.

  2. Click the MATLAB Function block.

  3. Expand the Advanced section. Select Allow direct feedthrough for each block containing a combinatorial output path.

This setting allows the code to be generated in Synchronous mode from a MATLAB Function block, when that block has both combinatorial and sequential paths in its code.

open_system('hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line')
%   open_system('hdlcoder_statecontrol_model/MAC FIR Block Sync/RAM delay line/circular buffer logic')

For additional information

To learn more about the State Control block, see State Control.