Search code examples
vhdlfpga

VHDL: How can I execute the for loop once in process statement


I am new to vhdl and FPGA. For my project I need to use for loop. When I simulate my code it keeps counting and not stopping. I want my code to execute only once, my point is when the loop reaches it's limit code will stop executing. Here is my code.

process(clk)
begin
        
        report "Hello";
      
        for j in 0 to 3 loop 
            if (j<4) then
              cA <= cA + 1;
              report "middle";
              exit;

            end if;
        end loop;  
        
        report "done";
      
 end process;

Solution

  • As probably explained in your textbook, a VHDL process is an infinite loop. After the last instruction has been executed, the first one executes.

    A process with sensitivity list (clk in your case) is equivalent to the same process without sensitivity list but with a final wait statement on the list. Your process is thus equivalent to:

    process
    begin    
      report "Hello";
      for j in 0 to 3 loop 
        if (j<4) then
          cA <= cA + 1;
          report "middle";
          exit;
        end if;
      end loop;  
      report "done";
      wait on clk;
    end process;
    

    So, your loop executes a first time at the very beginning of the simulation and the process suspends, waiting for a clk change. It resumes each time clk changes, executes the loop again, and suspends. If your clock never stops, your process will always be resumed twice a clock period (once on the rising edge and once on the falling edge).

    If you want to execute this loop only once at the very beginning of the simulation, remove the sensitivity list and add wait as last statement. A simple wait means "wait forever". It suspends the process definitely:

    process
    begin    
      report "Hello";
      for j in 0 to 3 loop 
        if (j<4) then
          cA <= cA + 1;
          report "middle";
          exit;
        end if;
      end loop;  
      report "done";
      wait;
    end process;
    

    If, instead, you want to execute the loop and stop only after a particular event happened, say a rising edge of the clock where signal go is asserted high, add another wait statement at the beginning of the process:

    process
    begin
      wait until rising_edge(clk) and go = '1';
      report "Hello";
      for j in 0 to 3 loop 
        if (j<4) then
          cA <= cA + 1;
          report "middle";
          exit;
        end if;
      end loop;  
      report "done";
      wait;
    end process;