The most interesting head scratching "break" command problem in Simulink these days
2 views (last 30 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;
0 Comments
Accepted Answer
Bharath Venkataraman
on 22 Sep 2016
In this case, since you are passing in the 80x1 matrix, here's what you do:
% returns last index that matches gs >= g
for ii = fi(1:80)
if gs(ii) >= g
idx = ii;
end
end
To use the first/smallest index of gs that is >= g, do the following:
% returns smallest index of gs that is >= g
for ii = fi(80:-1:1)
if gs(ii) >= g
idx = ii;
end
end
In both these cases, you are trying to loop over all 80 indices in one clock cycle, which means 80 comparisons in one cycle. If instead, you were able to pass in the 80x1 matrix one value at a time to the function, that would help compare one value of gs at a time.
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
0 Comments
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.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!