Found unsupported type in switch expression; switch expression must be of discrete type

4 views (last 30 days)
Hello,
I use a Matlab Function block as state machine in my Simulink module. Everything works, except the RTL Code generation in the HDL Workflow Advisor. At this point I get the following error:
Found unsupported type in switch expression; switch expression must be of discrete type, Function 'MNIST_CNN/MAXPOOL_BANK_20/CONTROL/MATLAB Function' (#1650.355.365), line 13, column 9.
When writing the Matlab Code I reffered to this documentation: https://de.mathworks.com/help/hdlcoder/ug/model-a-state-machine-for-hdl-code-generation.html
My Matlab Code looks like this:
function [hStart,hEnd,valid,reset,enable] = maxpool_fsm(hStart_in,hEnd_in,valid_in)
%states:
ready = 0;
vector = 1;
matrix = 2;
wait_for_next_line=3;
% using persistent keyword to model state registers in hardware
persistent curr_state;
if isempty(curr_state)
curr_state = ready;
end
% switch to new state based on the value state register
switch (curr_state)
case ready,
if (hStart_in==true && valid_in==true)
curr_state=vector;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=true;
else
curr_state=ready;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=false;
end
case vector,
if (valid_in == true && hEnd_in==true)
curr_state=wait_for_next_line;
valid=true;
reset=false;
enable=true;
hEnd=true;
hStart=false;
elseif (valid_in == true)
curr_state=matrix;
valid=true;
reset=false;
enable=true;
hEnd=false;
hStart=false;
else
curr_state=vector;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=false;
end
case matrix,
if (hEnd_in==true)
curr_state=wait_for_next_line;
valid = false;
reset = false;
enable = false;
hEnd=true;
hStart=false;
elseif (valid_in==true)
curr_state=vector;
valid = false;
reset = true;
enable = true;
hEnd=false;
hStart=false;
else
curr_state=matrix;
valid=false;
reset=false;
enable=false;
hEnd=false;
hStart=false;
end
case wait_for_next_line,
if (hEnd_in==true)
curr_state=ready;
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
else
curr_state=wait_for_next_line;
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
end
otherwise,
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
end
During compilation and simulation everything works. I have no clue, where the error is. In the Model Advisor the following error appeas:
Failed The model contains constructs that are unsupported for HDL code generation.
The model contains constructs that are unsupported for HDL code generation.
Error in slhdlcoder.HDLCoder/makehdl
Error in slhdlcoder.HDLCoder/makehdlturnkey
Error in downstream.DownstreamIntegrationDriver/runIPCoreCodeGen
Error in generateIPCore
Error in Simulink.ModelAdvisor/executeCheckCallbackFct
Error in Simulink.ModelAdvisor/run
Error in Simulink.ModelAdvisor/runCheck
Error in ModelAdvisor.Node/runTaskAdvisor
Error in ModelAdvisor.Node.runtohere>runToBreakpoint
Error in ModelAdvisor.Node.runtohere
A simple example where the control unit with the state machine is used is attached.
Thanks in advance!
Best Regards
  4 Comments
Tobis Stelzer
Tobis Stelzer on 21 Sep 2020
Edited: Tobis Stelzer on 21 Sep 2020
Here is a simple example/testbench, which uses the same control unit. It is designed for use with an 28x28x1 input image.
Stefan Griebel
Stefan Griebel on 10 Aug 2021
I get the exact same error in R2020b when using a cut-and-paste of the Mathworks example code from Model a State Machine for HDL Code Generation - MATLAB & Simulink (mathworks.com)
The super simple Simulink Model is attached, and here is a copy of the .m code in the function block. The "Accepted Answer" in this thread is to NOT use a persisent variable, and add a delay outside the block, which is contrary to Mathworks own example! Am I missing something here?
%#codegen
function Z = mlhdlc_fsm_mealy(A)
% Mealy State Machine
% y = f(x,u) :
% all actions are condition actions and
% outputs are function of state and input
% define states
S1 = 0;
S2 = 1;
S3 = 2;
S4 = 3;
persistent current_state;
if isempty(current_state)
current_state = S1;
end
% switch to new state based on the value state register
switch (current_state)
case S1,
% value of output 'Z' depends both on state and inputs
if (A)
Z = true;
current_state = S1;
else
Z = false;
current_state = S2;
end
case S2,
if (A)
Z = false;
current_state = S3;
else
Z = true;
current_state = S2;
end
case S3,
if (A)
Z = false;
current_state = S4;
else
Z = true;
current_state = S1;
end
case S4,
if (A)
Z = true;
current_state = S1;
else
Z = false;
current_state = S3;
end
otherwise,
Z = false;
end

Sign in to comment.

Accepted Answer

Tobis Stelzer
Tobis Stelzer on 24 Sep 2020
I solved the issue by not declaring the state variable as persistent, but instead using a delay outside the matlab function block:
function [hStart,hEnd,valid,reset,enable,curr_state_out] = maxpool_fsm(curr_state_in,hStart_in,hEnd_in,valid_in)
%states:
ready = uint8(0);
vctr = uint8(1);
mtrx = uint8(2);
wait_for_next_line=uint8(3);
% using persistent keyword to model state registers in hardware
%persistent curr_state;
curr_state_out=uint8(0);
if isempty(curr_state_out)
curr_state_out = ready;
end
% switch to new state based on the value state register
switch(curr_state_in)
case ready,
if (hStart_in==true && valid_in==true)
curr_state_out=vctr;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=true;
else
curr_state_out=ready;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=false;
end
case vctr,
if (valid_in == true && hEnd_in==true)
curr_state_out=wait_for_next_line;
valid=true;
reset=false;
enable=true;
hEnd=true;
hStart=false;
elseif (valid_in == true)
curr_state_out=mtrx;
valid=true;
reset=false;
enable=true;
hEnd=false;
hStart=false;
else
curr_state_out=vctr;
valid=false;
reset=true;
enable=true;
hEnd=false;
hStart=false;
end
case mtrx,
if (hEnd_in==true)
curr_state_out=wait_for_next_line;
valid = false;
reset = false;
enable = false;
hEnd=true;
hStart=false;
elseif (valid_in==true)
curr_state_out=vctr;
valid = false;
reset = true;
enable = true;
hEnd=false;
hStart=false;
else
curr_state_out=mtrx;
valid=false;
reset=false;
enable=false;
hEnd=false;
hStart=false;
end
case wait_for_next_line,
if (hEnd_in==true)
curr_state_out=ready;
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
else
curr_state_out=wait_for_next_line;
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
end
otherwise,
valid = false;
reset=false;
enable = false;
hEnd=false;
hStart=false;
end

More Answers (1)

Robert Wittig
Robert Wittig on 24 Nov 2022
Apparently state variable must be declared as fixed point as can be found here
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

Products


Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!