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

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 commentaires

Can you share example types or sampel values used for hStart_in,hEnd_in,valid_in? It will help reproduce the issue. You provide this in a testbench file as well.
Thanks for your fast reply! These signals are all boolean and obtained via Pixel Control Bus Selector from the Pixel Control Bus Signal (ctrl) of a Line Buffer (Vision HDL Toolbox).
Here is a simple example/testbench, which uses the same control unit. It is designed for use with an 28x28x1 input image.
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

Connectez-vous pour commenter.

 Réponse acceptée

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

Plus de réponses (1)

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

Catégories

En savoir plus sur Code Generation dans Centre d'aide et File Exchange

Produits

Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by