0

My task is to create a GCD calculator using a state machine in VHDL. Part of the task description says to use a while loop while(tempA /= tempB). When I used this loop I get following compilation error:

Error (10536): VHDL Loop Statement error at GCD_FSM.vhd(64): loop must terminate within 10,000 iterations

After doing some research online, I tried to fix this by implementing a count variable: loop_count, which increments on each iteration upto 10,000. Initially I still got the same error so tried reducing the max count value to only 1,000, which is the current set up in my code below.

For some reason that I cant understand I still get the same error, does anyone know why this is or have a solution? I am using Quartus II 13.1 as that is the latest edition with Cyclone III which is what we use at uni.

-- output function
    process(current_state)
    variable loop_count : integer range 0 to 10000 := 0;
    begin
        if current_state = STATE_load then
            tempA <= unsigned(A);
            tempB <= unsigned(B);
        elsif current_state = STATE_calculate then
            while (tempA /= tempB and loop_count < 1000) loop
                if tempA < tempB then
                    tempB <= tempA - tempB;
                else
                    tempA <= tempA - tempB;
                end if;
                loop_count := loop_count + 1;
            end loop;
        elsif current_state = STATE_done then
            GCD <= std_logic_vector(tempA);
            DONE <= '1';
        end if;
    end process;

Updating to add the full code for context below:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all;

entity GCD_FSM is
    port(
            A, B                    : in std_logic_vector(15 downto 0);
            CLK, RESET, START   : in std_logic;
            GCD                 : out std_logic_vector(15 downto 0);
            DONE                    : inout std_logic
            );
end entity GCD_FSM;

architecture moore_machine of GCD_FSM is
    type STATE is (
                        STATE_idle, STATE_load,
                        STATE_calculate, STATE_done
                        );
    signal current_state, next_state    : STATE;
    
    signal tempA, tempB : unsigned(15 downto 0) := (others => '0');
    
begin
    -- next state fuction
    process(A, B, current_state)
    begin
        case current_state is
            when STATE_idle =>
                if START = '1' then
                    if (unsigned(A) /= 0) and (unsigned(B) /= 0) then
                        next_state <= STATE_load;
                    end if;
                end if;
            when STATE_load =>
                next_state <= STATE_calculate;
            when STATE_calculate =>
                if tempA = tempB then
                    next_state <= STATE_done;
                end if;
            when STATE_done =>
                next_state <= STATE_idle;
        end case;
    end process;
    
    -- state register
    process(CLK, RESET)
    begin
        if RESET = '0' then
            current_state <= STATE_idle;
        elsif rising_edge(CLK) then
            current_state <= next_state;
        end if;
    end process;
    
    -- output function
    process(current_state)
    variable loop_count : integer range 0 to 10000 := 0;
    begin
        if current_state = STATE_load then
            tempA <= unsigned(A);
            tempB <= unsigned(B);
        elsif current_state = STATE_calculate then
            while (tempA /= tempB and loop_count < 1000) loop
                if tempA < tempB then
                    tempB <= tempA - tempB;
                else
                    tempA <= tempA - tempB;
                end if;
                loop_count := loop_count + 1;
            end loop;
        elsif current_state = STATE_done then
            GCD <= std_logic_vector(tempA);
            DONE <= '1';
        end if;
    end process;
end architecture moore_machine;
Ollie Parsons
  • 35
  • 1
  • 9
  • You need to learn about signal assignment semantics before you try this. When does your process suspend? When do your signals get updated? When does the process restart? Also : your mention of Quartus suggests synthesis ... as currently written, that will not go well. You may want to look into clocked processes, and then get it working in simulation before trying synthesis. –  Nov 23 '20 at 18:07
  • @BrianDrummond Thanls for your reply Brian, I have updated the question with the full code to hopefully make things a bit clearer. Let me know if this helped at all? – Ollie Parsons Nov 23 '20 at 18:23
  • Helped what? This link may help you understand the bit about signal assignments. https://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 But you still need to learn what to do (and not do) in an asynchronous process. And be aware tah this approach to a state machine is much harder to get right than the single process form. You also need to think about what you are trying to accomplish here in terms of speed (no. of cycles for the GCD operation vs size of hardware solution. –  Nov 23 '20 at 18:29
  • See [Lesson 93 - Example 63: GCD Algorithm - VHDL while Statement](https://www.youtube.com/watch?v=DMSaYhD1GkM) on Youtube. (There's a follow on [Lesson 94 - Datapaths and Control Units - GCD](https://www.youtube.com/watch?v=1E5_8sGx3_c) leading on to real hardware design). –  Nov 23 '20 at 20:56
  • The companion website for [Pong Chu's book RTL Hardware Design Using VHDL](https://academic.csuohio.edu/chu_p/rtl/rtl_hardware.html) has an example VHDL implementation code listing (list_12_06_07_08_gcd.vhd) and Chapter 12 slides for a VHDL GCD implementation. 12.4 GCD Circuit in the book has a shorter discourse than found for it's components in the Haskell/Hanna book **Digital Design Using Digilent FPGA Boards VHDL/Active-HDL Edition** (the course the videos linked above are derived from uses as a reference.) –  Nov 23 '20 at 20:58

0 Answers0