Using FOR loop in VHDL with a variable - loops

Is there any possible way to create a for loop in the form:
for i in 0 to some_var loop
// blah,blah
end loop;
If not, is there any alternative way to create the same loop? Since While loops allows to use variable as the limit, but they are not synthesizeable in my project.
Thanks in Advance,
Bojan Matovski

The variable works just fine for testbench applications.
For synthesis you can get the same effect by using a static range and an exit condition. Set the range to be the maximum you will need.
for i in 0 to MAX_VALUE loop
exit when i = some_var ;
// blah,blah
end loop;
If your synthesis tool chokes on this, file a bug report. Both 1076.6-1999 and 1076.6-2004 (VHDL RTL Synthesis Standards) indicate that exit conditions are supported for "for" loops with a static range. You may find support issues with respect to using a loop label (1076.6-1999) indicates it is not supported.
If you find a bug (or lack of support) and do not report it, your vendor will think it is a feature you don't care about, and hence, will not invest in changing their tool.

Only loop parameters with static range are synthesizable.
You can implement a FSM(finite state machine) if some_var has a discrete range. Then write a specific loop for each state.

Related

While loop using turtle graphic defined function

I'm using a while loop with user-defined functions to make drawings in turtle graphics based on a number of different conditions. For some reason, the while loop completely ignores the iterator making it an infinite loop when it shouldn't be. If you take out the functions that make the graphics, the loop works the way it should. Why doesn't the loop work with the functions for the graphics?
I need to see your code to have a better understanding of what's happening. Other than that, have you given your loop an end case that will keep it from looping? for example
i=0
while i<10:
print(i)
i+=1
the i variable is incremented at the end of every loop, the loop stops once it exceeds 10.
My guess is that the functions you have that make your graphics are not connected to your while loops stoping case.ex:
continue=True
while continue==True:
if #user action == desired output:
#insert graphic function
continue==False
else:
#enter whatever default action you'd like

Require code to perform this loop in SPSS including looping variable names

I am looking for the spss code to perform the following:
I have three variables: ResponseID and Q1 and Q2 that needs to be copied throughout my data set, I have already included variables for them - it starts with VAR00002, VAR00003 and VAR00004 several times throughout my data set. I now want to populate them, I therefore have to include the name of the variable in the loop and it needs to carry on doing this for the first set of three, the second set (VAR00005,VAR00006 and VAR00007) etc. (depending on the condition included in the Do IF). Then there is also the Else IF (and another Do If) included afterwards.
Loop # = 1 to 27
Do IF (Q[#(23)+2]=2).
COMPUTE (VAR0000(#+1))=ResponseID.
COMPUTE (VAR0000(#+2))=Q1.
COMPUTE (VAR0000(#+3))=Q2.
End if.
Else If.
Do If.
Q[(#-1)*(23)+3])=2.
DELETE VARIABLES Q[#(23)+3] TO Q623.
End If.
End Else If.
I am not sure what you need to do, but take a look at DO REPEAT, which allows you to repeat a set of transformations in a loop.
Niether I understand exactly what you are trying to do, perhaps look into LOOP / VECTOR combination

What is the iteration error in the loop?

loop
if rising_edge (CLOCK) then
fcounter := fcounter+1;
end if;
A<=fcounter(6); --fa=fclock/2^6
if rising_edge (A) then
counter_A:= counter_A+1;
end if;
CIKIS<=A; --40 consecutive "1" consignment to DIN for STARTUP RESET
exit when counter_A=101000; --40
end loop;
ISE gives "ERROR:Xst:1312 - Loop has iterated 64 times. Use "set -loop_iteration_limit XX" to iterate more." What does that mean and what should i do to get rid of it?
Unbounded loops are not generally synthesizable outside of generating constants. The error is telling you that the loop has iterated beyond the preset limit that guards against infinite loops. Increasing the limit will not fix anything because what you have described doesn't map naturally to hardware with the current crop of synthesis tools.
You need to restructure your logic to inhibit that block of code with an enable that is deactivated when the counter reaches its terminal value rather than use a loop.
Synthesizable constructs can't have compile time unbounded loops like this, they are only to be used in testbench code. The reason is that when they expand into hardware, something like this would require infinite resources (which you don't have). You seem to be trying to write this like a piece of software. When using a HDL, you need to be thinking of how it translates into hardware (assuming you plan to synthesize). Instead you might look at using a process where all activity happens inside an "if rising_edge(clock)", and use signals to explicitly use flip flops as opposed to variables which could go either way. It isn't entirely clear to me if you're trying to count when your fcounter rolls over 40 times (what you currently do) or when your fcounter exceeds 0111111 for 40 clock cycles, but you can use a signal indicating the state for either case instead of an exit statement, and an if/elsif statement on that signal to do something else when you don't want to have process counting. Sorry for the poor formatting, short on time.

Is it possible to index using a variable of the for/loop in vhdl?

I'm a novice of VHDL code.
I would like to index a shared variable using the variable defined in the for/loop. It seems to work in simulation although the compiler tells me there are some warning:
(ID: 13024). Output pins are stuck at VCC or GND.
Unfortunately, it doesn't work on board as expected from the warning.
I want to use for/loop because they seem good to reduce the complexity of the "total combinational functions" used, so I want to index in a stupid way, my shared variable.
This is an extract of my code:
for I in I_top to I_top loop
for J in J_top to J_top loop
if type = 1 then
matrix(I,J) := "110";
vector(I) := vector(I) + 1;
end := true;
elsif type = 2 then
...
end if;
end loop;
end loop;
I think I have found a way to solve this problem.
My understanding is that using 10x10 variables in VHDL introduces a lot of complexity because the compiler allocates all the resources they can need for them.
If you want to use a space to save your variables you can use something like a ram chip:
http://www.doulos.com/knowhow/vhdl_designers_guide/models/simple_ram_model/
Then, you need to manage address cycles and reading/writing cycles, but the previous complexity seems to disappear.

What are your tips for keeping track and avoiding bugs in loops?

I just found ... AGAIN ... a real time wastage bug as follows
for (int i = 0; i < length; i++)
{ //...Lots of code
for (int j = 0; i < length; j++)
{
//...Lots of code
}
}
Did you notice straight ahead the inner i which SHOULD BE j ? Neither did I. So from now on I am going to use:
for (int i = 0; i < length; i++)
{
for (int i1 = 0; i1 < length; i1++)
{
}
}
What are your tips for inner and outer while and for loops ?
Edit: Thanks for the valuable responses. Herewith short summary of the proposed tips:
use meaningful variables names for index variables ( instead i use SomeObjCollectionLength )
place the contents of the inner loop into a separate method and call that method from the outer loop
not manageable amount of lines of code between the outer and inner loop is a strong signal for code smell
avoid copy pasting and rushing , write the index vars with care
You might want to check the summary by LBushkin for the following
use foreach and iterators whenever possible
initialize the variables just before entering the loops
Make each loop perform only one function. Avoid mixing responsibilities in a single loop
When possible, make your loops short enough to view all at once
Don't use i & j (or any other single letter variable) as index names. Use proper names and you will not get into this type of problems.
One of the simplest and cleanest solutions is to place the contents of the inner loop into a method so it becomes:
for (int i = 0; i < length; i++)
{
DoSomething();
}
private void DoSomething(int outerValue)
{
for (int i = 0; i < length; i++)
{
// Do something else
}
}
For me, the 'code smell' here is 'lots of code'.
If the amount of code in the loops is particularly large, the distance between the inner and outer loops means that they're not as likely to be compared against each other for correctness.
Admittedly, looking at the start of the inner loop in isolation should bring the issue to your attention, but having the main structure in as small a section of code as possible gives your brain less to digest.
It may be possible to extract the 'lots of code' sections into separate functions/methods, in order to reduce the size of the main structure - but this may not alway be practical.
Also, I'd say that 'i1' isn't a particulary good choice of variable name, as that tends to encourage 'i2', 'i3' etc, which doesn't really lead to understandable code. Maybe replacing all of the loop variables with something more meaningful would help the clarity of the code, and reduce the chances of the original error.
My top advice (in no particular order) for writing better loop code (much of this is from the excellent book Code Complete):
Avoid multiple exit points for loops.
Use continue/break sparingly.
Refactor nested loops into separate routines, when possible.
Use meaningful variable names to make nested loops readable.
Use foreach() loops when possible, rather than for(i=...) loops.
Enter the loop from one location only. Don't jump into a loop with goto's. Ever.
Put initialization code immediately before the loop.
Keep loop initialization statements with the loop they are related to.
Avoid reusing variables between non-nested loops.
10.Limit the scope of loop-index variables to the loop itself.
Use while(true) for infinite loops, rather than for(;;)
In languages that provide block constructs (e.g. '{' and '}') use them rather than indenting to enclose the statements of a loop. Yes, even for single line loops.
Avoid empty loops.
Avoid placing housekeeping chores in the middle of a loop, place them at the beginning and/or end instead.
Make each loop perform only one function. Avoid mixing responsibilities in a single loop.
Make loop termination conditions obvious.
Don't monkey with the loop index variable of a for() loop to make it terminate.
Avoid code that depends on the loop indexer's final value.
Consider using safety counters in complex loops - they can be checked to make sure the loop doesn't execute too many, or too few times.
Use break statements, when possible, to terminate while loops.
When possible, make your loops short enough to view all at once.
That's a copy-paste mistake, avoid copy paste.
As for your solution, its not much better. The mistake can still slip between tons of code. I tend to use meaningful names even for loop temporary variables.
leverage your IDE, on VS, try to use this: http://msdn.microsoft.com/en-us/library/z4c5cc9b(VS.80).aspx
sample: type for, then press Tab Tab successively
I came here to be smart and say "I just write it right the first time". But then I saw your example and, well, I've done that too many times myself.
When you need nested loops like that, my only solution is to be alert and thinking when you write the code.
Where possible, using iterators and for each loops are nice.
Also, I can't see how your suggested solution is going to be any better. And it doesn't look as nice either.
First of all, reduce the loop body size, i.e. move stuff to separate functions. It is generally a bad idea to have functions longer than what can fit into the screen, so loops should be even smaller.
Secondly, use meaningful variable names in cases like this. I would only use i and j in simple loops with a few lines of code. For instance, if you are going through a two-dimensional array, "col" and "row" would make much more sense, make the code easier to read ("which was which?") and easier to spot mistakes like this.
You just have to take extra care of such issues, there's no magic bullet against this. Even with "better naming" you propose you will once in a while lose track of whether this is Nth or (N+M)th level of nested loop and make an error.
If nested loop is necessary write it carefully. If it can be avoided by extracting the outer loop body into a function that would be a good guard against indices misuse.
As in this as in many things, there's some excellent advice in Steve McConnell's Code Complete. It would be well worth your time to read what he's got to say about building good looping code. I don't have my copy of the book handy here but the whole book is worth your time.
I use 'ii' and 'jj' for transient loop counters if I really need them - they are easier to search for than 'i' and 'j' and also easier to spot in examples like the above. To go one better you can actually use a real variable name. If you're looping over a string then you can call it characterIndex or something. It's more typing, but it documents itself and saves time on debugging obscure problems later.
Better still would be to avoid numerical counters and use named iterators over a collection. They make the intent clearer, in my opinion.
Finally, if possible it's nice to do away with the loop entirely: Boost::Foreach is one way of doing this in C++, although I generally prefer to use languages such as Python which natively allow direct iteration over the contents of a container without a need for incrementing an index value or iterator.
Try to use more declarative loop constructs. For instance, if you don't really need indices (those is and js) and your programming environment allows for it, you can use a foreach construct to iterate over the collection.

Resources