Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16608 Discussions

while loop iteration error

Altera_Forum
Honored Contributor II
3,003 Views

Hi all again! 

 

I'm trying to use a while-loop statement in my code, but it wouldn't compile. I created a separate project to simplify the loop statement but it didn't help. 

Here is the code: 

 

library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity whiler is port( clk:in std_logic; reset:in std_logic; outer:out std_logic); end whiler; architecture behavior of whiler is begin process variable index : integer := 0; begin wait until rising_edge(clk); if (reset = '1') then outer <= '0'; elsif (reset = '0') then while index < 6 loop outer <= '1'; index := index + 1; end loop; end if; end process; end behavior; 

 

I get an error stating that the loop must end within 10k iterations, but as far as I can tell this loop should only run through 6 times, so i can't tell whats throwing this error. 

 

Sorry if this seems a simple problem, i'm still pretty new to this language. 

 

Thanks for your time, 

Zammy
0 Kudos
14 Replies
Altera_Forum
Honored Contributor II
930 Views

You shouldn't put a while loop here anyway. The way you wrote it, the loop will be executed 6 times by the synthesizer within the same clock cycle. The effect will be the same without any while loop. 

I think you should just increase index on each clock cycle and use an 'if' statement to test if you reached the count value you want.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

that while loop does nothing - outer is going to be held high until reset is asserted. While loops are generally useless inside processes for synthesisable code. They are only useful for synthsis inside functions, for eg. finding which index in a bus is high.

0 Kudos
Altera_Forum
Honored Contributor II
930 Views

Thanks for your replies! 

 

So from what it sounds like, you shouldn't use loops inside process statements? How would i go about correcting my code then? I've just tried to use the while loop outside of the process, but i can't get that to work either (complains about the while keyword and expecting "end" somewhere). 

 

Basically what i'm trying to do is a serial output stream of a register. I thought to use a loop statement because using a variable is the only way to select individual bits from a register. I'd rather not shift the reg values because they could be reused and i'm sure there must be a simpler solution than adding a "temp register" to bit shift in.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

In my opinion, an iteration scheme can have a purpose inside a process also in HDL code for synthesis, but it doesn't achieve what you apparently expect from it. Daixiwen already mentioned it: All 6 loop cyclces are "executed" simultaneously. An iteration scheme doesn't create a sequential execution flow in time, as e.g. a while loop in C program does. It's intended to describe parallel logic. 

 

To perform serial output, you have to define a shift register and send out one bit per clock cycle. It's the most simple solution, nothing can be minimized. As a principle example: 

signal sr: std_logic_vector(5 downto 0); process (clk) begin if rising_edge(clk) then if load = '1' then sr <= par_data; else sr <= sr(5 downto 0) & '0'; end if; end if; end process; ser_out <= sr(6);
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

Thanks for the code snippet FvM! 

Could I just ask why is the output line outside the process statement, and not above the bit shifting line? Was that just for the "simplicity", as you put it?
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

 

--- Quote Start ---  

Was that just for the "simplicity", as you put it? 

--- Quote End ---  

 

No. An assignment inside the clock edge sensitive block implies a delay of one clock cycle, the shown construct creates just a wire respectively a copy of sr(6). Of course there other ways to achieve the same.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

Thanks again FvM! 

 

My serial o/p problem is solved, but i'm still curious as to how i'd go about using a while loop, because i still can't get it to work. I've taken the while loop outside the process statement, and increment index inside. It doesn't complain about max iterations anymore but i can't work out where these errors are coming from: 

 

library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity whiler is port( clk:in std_logic; reset:in std_logic; outer:out std_logic); end whiler; architecture behavior of whiler is variable index : integer := 0; begin process begin wait until rising_edge(clk); if (reset = '1') then outer <= '0'; elsif (reset = '0') then index := (index + 1); end if; end process; while index < 6 loop outer <= '1'; end loop; end behavior; 

 

Error (10500): VHDL syntax error at whiler.vhd(23) near text "while"; expecting "end", or "(", or an identifier ("while" is a reserved keyword), or a concurrent statement  

Error (10500): VHDL syntax error at whiler.vhd(25) near text "loop"; expecting ";", or an identifier ("loop" is a reserved keyword), or "architecture"
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

2 things: 

 

1. variables can only exist inside processes, functions or procedures. You cannot have it in the architecture like you have done. 

 

2. While loops are procedural code - they can only exist inside processes, functions or procedures.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

What you probably want to write is this instead: 

 

outer <= '1' when index < 6 else '0';
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

 

--- Quote Start ---  

No. An assignment inside the clock edge sensitive block implies a delay of one clock cycle, the shown construct creates just a wire respectively a copy of sr(6). Of course there other ways to achieve the same. 

--- Quote End ---  

 

 

ser_out <= sr(6); can go after the end if; (associated rising_edge(clk)) before end process; and not infer a register. 

 

was the OP interested in this case? both should have the same result, but i'm not sure if one is better than the other. its clear the way FvM's example that the assignment is not in the process, just simply a wire not a register etc.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

 

--- Quote Start ---  

ser_out <= sr(6); can go after the end if; (associated rising_edge(clk)) before end process; and not infer a register. 

 

 

--- Quote End ---  

 

 

Then you'd get a missmatch between simulation and synthesis. because the process is only sensitive to the clock, in simulation it would only change on any edge of the clock. Because sr(6) will have only been scheduled for a change on the rising edge, and not actually changed yet, ser_out would only get set to the new sr(6) on the falling edge. 

 

You would have to make the process sensitive to sr(6) too to fix this.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

 

--- Quote Start ---  

Then you'd get a missmatch between simulation and synthesis. 

--- Quote End ---  

And a Quartus warning about sr missing in the sensitivity list. I didn't think about this detail, when writing the snippet. Basically I'm used to place combinational code in the concurrent architecture part, except for case statements and similar constructs, that need a process.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

 

--- Quote Start ---  

And a Quartus warning about sr missing in the sensitivity list. I didn't think about this detail, when writing the snippet. Basically I'm used to place combinational code in the concurrent architecture part, except for case statements and similar constructs, that need a process. 

--- Quote End ---  

 

 

 

Same here 

When I see clk and reset in the sensitivity list with other signals, I get scared someones puting the clock through gates.
0 Kudos
Altera_Forum
Honored Contributor II
930 Views

righto, thanks.

0 Kudos
Reply