| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Simulink HDL Coder |
| Contents | Index |
| On this page… |
|---|
The eml_hdl_design_patterns Library Efficient Fixed-Point Algorithms Using Persistent Variables to Model State Creating Intellectual Property with the Embedded MATLAB Function Block |
The eml_hdl_design_patterns library is an extensive collection of examples demonstrating useful applications of the Embedded MATLAB Function block in HDL code generation. The following figure shows the library.

The location of the library in the MATLAB directory structure is
MATLABROOT\toolbox\hdlcoder\hdlcoderdemos\eml_hdl_design_patterns.mdl
Refer to example models in the eml_hdl_design_patterns library while reading the following sections. To open the library, type the following command at the MATLAB command prompt:
eml_hdl_design_patterns
You can use many blocks in the library as cookbook examples of various hardware elements, as follows:
Copy a block from the library to your model and use it as a computational unit, (generating code in a separate HDL file).
Copy the code from the block and use it as a subfunction in an existing Embedded MATLAB Function block (generating inline HDL code).
The Embedded MATLAB Function block supports fixed point arithmetic using the Fixed-Point Toolbox fi function. This function supports rounding and saturation modes that are useful for coding algorithms that manipulate arbitrary word and fraction lengths. The coder supports all fi rounding and overflow modes.
HDL code generated from the Embedded MATLAB Function block is bit-true to MATLAB semantics. Generated code uses bit manipulation and bit access operators (e.g., Slice, Extend, Reduce, Concat, etc.) that are native to VHDL and Verilog.
The following discussion shows how HDL code generated from the Embedded MATLAB Function block follows cast-before-sum semantics, in which addition and subtraction operands are cast to the result type before the addition or subtraction is performed.
Open the eml_hdl_design_patterns library and select the Combinatrics/eml_expr block. eml_expr implements a simple expression containing addition, subtraction, and multiplication operators with differing fixed point data types. The generated HDL code shows the conversion of this expression with fixed point operands. The following listing shows the code embedded in the Embedded MATLAB Function block.
% fixpt arithmetic expression expr = (a*b) - (a+b); % cast the result to (sfix7_En4) output type y = fi(expr, 1, 7, 4);
The default fimath specification for the block determines the behavior of arithmetic expressions using fixed point operands inside the Embedded MATLAB Function block:
fimath(... 'RoundMode', 'ceil',... 'OverflowMode', 'saturate',... 'ProductMode', 'FullPrecision', 'ProductWordLength', 32,... 'SumMode', 'FullPrecision', 'SumWordLength', 32,... 'CastBeforeSum', true)
The data types of operands and output are as follows:
a: (sfix5_En2)
b: (sfix5_En3)
y: (sfix7_En4).
Before HDL Code generation, the operation
expr = (a*b) - (a+b);
is broken down internally into the following substeps:
tmul = a * b;
tadd = a + b;
tsub = tmul - tadd;
y = tsub;
Based on the fimath settings (see Recommended Practices) this expression is further broken down internally as follows:
Based on the specified ProductMode, 'FullPrecision', the output type of tmul is computed as (sfix10_En5).
Since the CastBeforeSum property is set to 'true', substep 2 is broken down as follows:
t1 = (sfix7_En3) a; t2 = (sfix7_En3) b; tadd = t1 + t2;
sfix7_En3 is the result sum type after aligning binary points and accounting for an extra bit to account for possible overflow.
Based on intermediate types of tmul (sfix10_En5) and tadd (sfix7_En3) the result type of the subtraction in substep 3 is computed as sfix11_En5. Accordingly, substep 3 is broken down as follows:
t3 = (sfix11_En5) tmul; t4 = (sfix11_En5) tadd; tsub = t3 - t4;
Finally the result is cast to a smaller type (sfix7_En4) leading to the following final expression statements:
tmul = a * b; t1 = (sfix7_En3) a; t2 = (sfix7_En3) b; tadd = t1 + t2; t3 = (sfix11_En5) tmul; t4 = (sfix11_En5) tadd; tsub = t3 - t4; y = (sfix7_En4) tsub;
The following listings show the generated VHDL and Verilog code from the eml_expr block.
VHDL code excerpt:
BEGIN
--Embedded MATLAB Function 'Subsystem/eml_expr': '<S2>:1'
-- fixpt arithmetic expression
--'<S2>:1:4'
mul_temp <= signed(a) * signed(b);
sub_cast <= resize(mul_temp, 11);
add_cast <= resize(signed(a & '0'), 7);
add_cast_0 <= resize(signed(b), 7);
add_temp <= add_cast + add_cast_0;
sub_cast_0 <= resize(add_temp & '0' & '0', 11);
expr <= sub_cast - sub_cast_0;
-- cast the result to correct output type
--'<S2>:1:7'
y <= "0111111" WHEN ((expr(10) = '0') AND (expr(9 DOWNTO 7) /= "000"))
OR ((expr(10) = '0') AND (expr(7 DOWNTO 1) = "0111111"))
ELSE
"1000000" WHEN (expr(10) = '1') AND (expr(9 DOWNTO 7) /= "111")
ELSE
std_logic_vector(expr(7 DOWNTO 1) + ("0" & expr(0)));
END fsm_SFHDL;Verilog code excerpt:
//Embedded MATLAB Function 'Subsystem/eml_expr': '<S2>:1'
// fixpt arithmetic expression
//'<S2>:1:4'
assign mul_temp = a * b;
assign sub_cast = mul_temp;
assign add_cast = {a[4], {a, 1'b0}};
assign add_cast_0 = b;
assign add_temp = add_cast + add_cast_0;
assign sub_cast_0 = {{2{add_temp[6]}}, {add_temp, 2'b00}};
assign expr = sub_cast - sub_cast_0;
// cast the result to correct output type
//'<S2>:1:7'
assign y = (((expr[10] == 0) && (expr[9:7] != 0))
|| ((expr[10] == 0) && (expr[7:1] == 63)) ? 7'sb0111111 :
((expr[10] == 1) && (expr[9:7] != 7) ? 7'sb1000000 :
expr[7:1] + $signed({1'b0, expr[0]})));These code excerpts show that the generated HDL code from the Embedded MATLAB Function block represents the bit-true behavior of fixed point arithmetic expressions using high level HDL operators. The HDL code is generated using HDL coding rules like high level bitselect and partselect replication operators and explicit sign extension and resize operators.
To model sophisticated control logic, the ability to model registers is a basic requirement. In the Embedded MATLAB Function block programming model, state-holding elements are represented as persistent variables. A variable that is declared persistent retains its value across function calls in software, and across sample time steps during simulation. State-holding elements in hardware also require this behavior. Similarly, state-holding elements should retain their values across clock sample times. The values of persistent variables can also be changed using global and local reset conditions.
The subsystem Delays in the eml_hdl_design_patterns library illustrates how persistent variables can be used to simulate various kinds of delay blocks.
The unit delay block delays the input sample by one simulation time step. A persistent variable is used to hold the value, as shown in the following code listing:
function y = fcn(u)
persistent u_d;
if isempty(u_d)
u_d = fi(-1, numerictype(u), fimath(u));
end
% return delayed input from last sample time hit
y = u_d;
% store the current input to be used later
u_d = u;
In this example, u is a fixed-point operand of type sfix6. In the generated HDL code, initialization of persistent variables is moved into the master reset region in the initialization process as follows.
ENTITY Unit_Delay IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
u : IN std_logic_vector(15 DOWNTO 0);
y : OUT std_logic_vector(15 DOWNTO 0));
END Unit_Delay;
ARCHITECTURE fsm_SFHDL OF Unit_Delay IS
BEGIN
initialize_Unit_Delay : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
y <= std_logic_vector(to_signed(0, 16));
ELSIF clk'EVENT AND clk = '1' THEN
IF clk_enable = '1' THEN
y <= u;
END IF;
END IF;
END PROCESS initialize_Unit_Delay;
Refer to the Delays subsystem to see how vectors of persistent variables can be used to model integer delay, tap delay, and tap delay vector blocks. These design patterns are useful in implementing sequential algorithms that carry state between invocations of the Embedded MATLAB Function block in a model.
The Embedded MATLAB Function block lets you quickly author intellectual property (IP). It also lets you rapidly create alternate implementations of a part of an algorithm.
For example, the subsystem Comparators in the eml_hdl_design_patterns library includes several alternate algorithms for finding the minimum value of a vector. The Comparators/eml_linear_min block finds the minimum of the vector in a linear mode serially. The Comparators/eml_tree_min block compares the elements in a tree structure. The tree implementation can achieve a higher clock frequency by adding pipeline registers between the log2(N) stages. (See eml_hdl_design_patterns/Filters for an example.)
Now consider replacing the simple comparison operation in the Comparators blocks with an arithmetic operation (e.g., addition, subtraction, or multiplication) where intermediate results must be quantized. Using fimath rounding settings, you can fine tune intermediate value computations before intermediate values feed into the next stage. This can be a powerful technique for tuning the generated hardware or customizing your algorithm.
By using Embedded MATLAB Function blocks in this way, you can guide the detailed operation of the HDL code generator even while writing high-level algorithms.
Embedded MATLAB Function block control constructs such as switch/case and if-elseif-else, coupled with fixed point arithmetic operations let you model control logic quickly.
The FSMs/mealy_fsm_blk andFSMs/moore_fsm_blk blocks in the eml_hdl_design_patterns library provide example implementations of Mealy and Moore finite state machines in the Embedded MATLAB Function block.
The following listing implements a Moore state machine.
function Z = moore_fsm(A)
persistent moore_state_reg;
if isempty(moore_state_reg)
moore_state_reg = fi(0, 0, 2, 0);
end
S1 = 0;
S2 = 1;
S3 = 2;
S4 = 3;
switch uint8(moore_state_reg)
case S1,
Z = true;
if (~A)
moore_state_reg(1) = S1;
else
moore_state_reg(1) = S2;
end
case S2,
Z = false;
if (~A)
moore_state_reg(1) = S1;
else
moore_state_reg(1) = S2;
end
case S3,
Z = false;
if (~A)
moore_state_reg(1) = S2;
else
moore_state_reg(1) = S3;
end
case S4,
Z = true;
if (~A)
moore_state_reg(1) = S1;
else
moore_state_reg(1) = S3;
end
otherwise,
Z = false;
end
In this example, a persistent variable (moore_state_reg) models state variables. The output depends only on the state variables, thus modeling a Moore machine.
The FSMs/mealy_fsm_blk block in the eml_hdl_design_patterns library implements a Mealy state machine. A Mealy state machine differs from a Moore state machine in that the outputs depend on inputs as well as state variables.
The Embedded MATLAB Function block can quickly model simple state machines and other control-based hardware algorithms (such as pattern matchers or synchronization-related controllers) using control statements and persistent variables.
For modeling more complex and hierarchical state machines with complicated temporal logic, use a Stateflow chart to model the state machine.
To implement arithmetic and control logic algorithms in Embedded MATLAB Function blocks intended for HDL code generation, there are some simple HDL related coding requirements:
The top level Embedded MATLAB Function block must be called once per time step.
It must be possible to fully unroll program loops.
Persistent variables with proper reset values and update logic must be used to hold values across simulation time steps.
Quantized data variables must be used inside loops.
The following script shows how to model a synchronous up/down counter with preset values and control inputs. The example provides both master reset control of persistent state variables and local reset control using block inputs (e.g. presetClear). The isempty condition enters the initialization process under the control of a synchronous reset. The presetClear section is implemented in the output section in the generated HDL code.
Both the up and down case statements implementing the count loop require that the values of the counter are quantized after addition or subtraction. By default, the Embedded MATLAB Function block automatically propagates fixed-point settings specified for the block. In this script, however, fixed-point settings for intermediate quantities and constants are explicitly specified.
function [Q, QN] = up_down_ctr(upDown, presetClear, loadData, presetData)
% up down result
% 'result' syntheses into sequential element
result_nt = numerictype(0,4,0);
result_fm = fimath('OverflowMode', 'saturate', 'RoundMode', 'floor');
initVal = fi(0, result_nt, result_fm);
persistent count;
if isempty(count)
count = initVal;
end
if presetClear
count = initVal;
elseif loadData
count = presetData;
elseif upDown
inc = count + fi(1, result_nt, result_fm);
-- quantization of output
count = fi(inc, result_nt, result_fm);
else
dec = count - fi(1, result_nt, result_fm);
-- quantization of output
count = fi(dec, result_nt, result_fm);
end
Q = count;
QN = bitcmp(count);
The following code example shows how to model shift registers in Embedded MATLAB Function block code by using the bitsliceget and bitconcat function. This function implements a serial input and output shifters with a 32–bit fixed-point operand input. See the Shift Registers/shift_reg_1by32 block in the eml_hdl_design_patterns library for more details.
function sr_out = fcn(shift, sr_in)
%shift register 1 by 32
persistent sr;
if isempty(sr)
sr = fi(0, 0, 32, 0, 'fimath', fimath(sr_in));
end
% return sr[31]
sr_out = getmsb(sr);
if (shift)
% sr_new[32:1] = sr[31:1] & sr_in
sr = bitconcat(bitsliceget(sr, 31, 1), sr_in);
endThe following code example shows VHDL process code generated for the shift_reg_1by32 block.
shift_reg_1by32 : PROCESS (shift, sr_in, sr)
BEGIN
sr_next <= sr;
--Embedded MATLAB Function 'Subsystem/shift_reg_1by32': '<S2>:1'
--shift register 1 by 32
--'<S2>:1:1
-- return sr[31]
--'<S2>:1:10'
sr_out <= sr(31);
IF shift /= '0' THEN
--'<S2>:1:12'
-- sr_new[32:1] = sr[31:1] & sr_in
--'<S2>:1:14'
sr_next <= sr(30 DOWNTO 0) & sr_in;
END IF;
END PROCESS shift_reg_1by32;The Shift Registers/shift_reg_1by64 block shows a 64 bit shifter. In this case, the shifter uses two fixed point words, to represent the operand, overcoming the 32–bit word length limitation for fixed-point integers.
Browse the eml_hdl_design_patterns model for other useful hardware elements that can be easily implemented using the Embedded MATLAB Function Block.
![]() | Tutorial Example: Incrementer | Using Fixed-Point Bitwise Functions | ![]() |

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |