The most interesting head scratching "break" command problem in Simulink these days
Show older comments
Below is a simple snippet to implement in Simulink HDL Coder, however, to my surprise the "break" command is not valid in HDL coder nor is the "for-iterator block", which has led me to wonder if its at all possible to implement this in Simulink for HDL
a) I could avoid the "for-iterator block" (because its not available in HDL), by using a user defined function block and writing the for loop in there (which is where the snippet is from below), but I'm not sure how one can get around a break command
b) I doubt one would find a command similar to "break" for HDL, and so will therefore rule out the user-defined-function block as an option, leaving you with just counter and logical blocks to solve the problem, but in which lies the dilemma
Does anyone know how you can implement the code below? I tried all sorts of limited counters and memory blocks, but cant seem to solve it and break out of the loop. Any tips and help would be greatly appreciated
function y = fcn(gs,g)
%#codegen
n = length(gs);
for i = n:-1:1
if gs(i) >= g
idx = i;
break
else
idx = 0;
end
end
y = idx;
Accepted Answer
More Answers (2)
Tim McBrayer
on 21 Sep 2016
A break statement exits a loop statement at an arbitrary iteration. In your code it is entirely data dependent. A loop will in general get fully unrolled in hardware and implemented in parallel, with each iteration getting its own hardware and computing their values in parallel. In the case of your loop, all possible values of idx will be computed in parallel and the correct value selected. I'm sure you can see how these two concepts (break statements and fully unrolled loops) don't work well together.
You can rewrite the loop to not need the break statement. Here is one possibility for finding the highest index i where gs(i) > g, without using a break statement.
idx = 0;
for i = n:-1:1
if idx == 0 && gs(i) >= g
idx = i;
end
end
Bharath Venkataraman
on 21 Sep 2016
For HDL, having a variable sized for loop is problematic. What you want to do is to loop over all the indices, but only store the index you find to work for you.
function y = fcn(gs,g)
%#codegen
n = length(gs);
idx = 0;
for i = n:-1:1
if gs(i) >= g && ide ~= 0
idx = i;
end
end
y = idx;
What you may also want to do is consider whether gs can be streamed in, in which case you do not need a for loop at all, all you will have is one value of gs at a time compared to g and you can update the index at that time.
function y = fcn(gs,g)
%#codegen
persistent idx; % define index as a register
if isempty(idx)
idx = 0;
end
if gs >= g && idx ~= 0
% if idx has been updated, do not update it again (that is, get "first" update only)
idx = i;
end
y = idx;
You probably want to consider a fixed point type for idx instead of double, say idx = fi(0,0,10,0) for a 10 bit unsigned index value.
Categories
Find more on Speed Optimization in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!