简体   繁体   中英

Syntax errors in VHDL - in case statements

I'm very new to VHDL. Here I have a program that calculates GCD of two numbers. I have a bunch of cases and if statements. When I try to simulate, it gives me 6 errors without much description

Errors: 'U:\\GCD.dwv' Error 0 line 41 : Syntax error 'U:\\GCD.dwv' Error 0 line 43 : Syntax error

The interesting thing is each of them is separated by 2 lines. So it starts with line 33 and goes up to 43 with the same error. It starts on line where "when S3 =>". Here is my code. Thank you!

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity GCD is
    port(clk, st : in std_logic; d1, d2 : in std_logic_vector(15 downto 0); dout : out std_logic_vector(15 downto 0); rdy : out std_logic);
end GCD;


architecture behav of GCD is
type state is (S0, S1, S2, S3, S4, S5, S6, S7);
signal new_state : state;
signal eq, It, eq1 : boolean;

begin
        --State Transition Process 
    process is
    variable curr_state : state := S0;
    begin

    if clk ='1' then
        case curr_state is
            when S0 =>
                if st='1' then curr_state := S1;
                end if;
            when S1 =>
                curr_state := S2;
            when S2 =>
                if eq then curr_state := S7;
                else if It then curr_state := S4;
                else if not(eq or It) then curr_state := S3;
                end if;
            when S3 =>
                curr_state := S4;
            when S4 =>
                curr_state := S5;
            when S5 =>
                if eq1 then curr_state := S7;
                else curr_state := S6;
                end if;
            when S6 =>
                curr_state := S1;
            when S7 =>
                if not(st) then curr_state := S0;
                end if;
        end case;
        new_state <= curr_state;
    end if;
    wait on clk;
end process;


-- Asserted Outputs Process:

process is

variable M, N, T, dout_val : std_logic_vector(15 downto 0);
variable rdy_val : std_logic;
variable eq_val, It_val, eq1_val : boolean;
begin

    rdy_val := '0';
    case new_state is
        when S0 =>
            M := d1; N := d2;
        when S1 =>
            eq_val := M=N; It_val := to_integer(M) < to_integer(N);
        when S2 =>
        when S3 =>
            M := T; M := N; N := T;
        when S4 =>
            eq1_val := to_integer(M) = 1;
        when S5 =>
        when S6 =>
            N := N - M; 
        when S7 =>
            rdy_val := '1'; dout_val := M; 
    end case;
    eq <= eq_val;
    It <= It_val;
    eq1 <= eq1_val;
    rdy <= rdy_val;
    dout <= dout_val;
    wait on new_state;
end process;


end behav;

Instead of else if use elsif . There may be a couple more errors lurking in there.

use ieee.std_logic_unsigned.all;  -- because you use std_logic_arith

... State Transition Process:

        when S7 =>
            if st = '0' then -- not (st) then 
                curr_state := S0;
            end if;

... Output Process:

        when S1 =>
            eq_val := M = N; 
            -- It_val := to_integer(M) < to_integer(N);
            It_val := M < N;

        when S4 =>
            -- eq1_val := to_integer(M) = 1;
            eq_val := conv_integer(M) = 1;

VHDL has explicit requirements for separators, the rest is style. Your code requires careful reading because of the lack of consistent style.

Other readers will undoubtedly suggest use use package numeric_std , and if you are using a VHDL -2008 compliant tool, package std_numeric_unsigned instead of Synopsys - non standard use of packages std_logic_arith and std_logic_unsigned . Your attempted use of to_integer is from std_logic_unsigned .

I'd like to give you an example on how I use to write a FSM. I hope It could be useful for your purpose.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY FSM IS
  PORT(
     Clk           : IN  STD_LOGIC;
     nResetLogic   : IN  STD_LOGIC;
     A             : IN  STD_LOGIC;
     B             : IN  STD_LOGIC;
     OUT_A              : OUT STD_LOGIC;
     OUT_B              : OUT STD_LOGIC;
    );
END ENTITY FSM;

ARCHITECTURE RTL OF FSM IS

-- states
TYPE state IS (stateA, stateB, stateC);
signal present_state, next_state : state;

-- Segnals for outputs
signal s_OUT_A              : STD_LOGIC;  
signal s_OUT_B              : STD_LOGIC;  



BEGIN

  -- Sequential section

  PROCESS (nResetLogic, Clk)
  BEGIN

    IF nResetLogic = '0' THEN
      present_state <= stateA;
    ELSIF (RISING_EDGE(Clk)) THEN
      present_state <= next_state;
    END IF;

  END PROCESS;

  -- Comb Section

  PROCESS (A,B,present_state)

  BEGIN
    --defaults
    s_OUT_A <= '0';         
    s_OUT_B <= '0';

    next_state <= present_state;

    CASE present_state IS
        WHEN stateA =>
            -- state definition
            IF (B = '0' AND A = '1') THEN 
                next_state <= stateB;
            ELSIF (B = '1' AND  A = '0') THEN
                next_state <= stateC;
            END IF;

            --output definition
            s_OUT_A <= '0';         
            s_OUT_B <= '1';


        WHEN stateB =>
            -- state definition
            IF (B = '1' AND A = '1') THEN 
                next_state <= stateC;
            ELSIF (B = '1' AND A = '0') THEN 
                next_state <= stateA;

            END IF;

            --output definition
            s_OUT_A <= '1';         
            s_OUT_B <= '1';


        WHEN stateC =>
            -- state definition
            IF (B = '0' AND A = '1') THEN 
                next_state <= statoA;
            ELSIF (B = '1' AND A = '0') THEN
                next_state <= statonB;
            END IF;

            --output definition
            --get defaults        

    END CASE;

  END PROCESS;

  -- Outputs
  OUT_A <= s_OUT_A;         
  OUT_B <= s_OUT_B;  

END ARCHITECTURE RTL;

There are some good comments on coding style above, but to answer the original question directly, your error is pretty clear when you layout your 'if' statements nicely:

when S2 =>
    if eq then curr_state := S7;
    else if It then curr_state := S4;
    else if not(eq or It) then curr_state := S3;
    end if;

becomes:

when S2 =>
    if eq then
        curr_state := S7;
    else
        if It then
            curr_state := S4;
        else
            if not(eq or It) then
                curr_state := S3;
            end if;

As you can see, there are two missing 'end if' statements. Very often, you will find that an error produced by an FPGA tool, will actually be caused by something on the previous line(s). In this case, the line "when S3 =>" produced the error, because you can't have a "when" by itself in the middle of an "else" block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM