2014-09-25 53 views
0

我對VHDL非常陌生。在這裏我有一個計算兩個數字的GCD的程序。我有一堆案例和if語句。 當我試圖模擬,它給了我6個錯誤沒有太多的描述VHDL中的語法錯誤 - 在case語句中

錯誤: 'U:\ GCD.dwv' 錯誤0行41:語法錯誤 'U:\ GCD.dwv' 錯誤0線43 :語法錯誤

有趣的是他們每個人都被2行隔開。所以它從第33行開始,並且上升到43,同樣的錯誤。它在「S3 =>」時開始。 這是我的代碼。謝謝!

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; 
+0

另外請注意,雖然模擬器可能不會在意,但綜合工具可能會忽略生成觸發器,因爲您只指定'if clk ='1''而不是'如果clk'event和clk ='1''。也要小心變量。我經常看到他們被初學者使用,但他們很少需要(特別是在相當簡單的系統中),並且容易犯錯誤。您在這段代碼中使用的變量都不是必需的。用信號替換它們或直接分配最終的輸出/信號將清理代碼。 – QuantumRipple 2014-09-27 01:53:47

+0

你在'M:= T'行也有一個邏輯錯誤; M:= N; N:= T;'用於交換N和M.對於信號這是一個非問題 - 您不需要臨時值,因爲信號分配的右側使用流程執行開始時的值('M < = N; N <= M'將按照預期的信號工作)。 – QuantumRipple 2014-09-27 01:56:34

+0

@QuantumRipple感謝您的幫助。對於第二個,它們不是信號而是普通變量,所以我需要一個臨時變量。對? – NoorUllah 2014-09-29 03:58:16

回答

1

而不是else if使用elsif。潛伏在那裏的可能會有更多的錯誤。

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

...狀態轉變過程:

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

...輸出過程:

 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有分隔明確要求,剩下的就是風格。由於缺乏一致的風格,您的代碼需要仔細閱讀。

其他讀者無疑會建議使用使用的軟件包numeric_std,如果你使用的是VHDL -2008兼容的工具,包裝std_numeric_unsigned,而不是新思 - 非標準使用包std_logic_arithstd_logic_unsigned的。您嘗試使用to_integer是從std_logic_unsigned

+0

謝謝大衛。有效。也適用於其他跡象! 我不能使用其他軟件包或庫,因爲這是一個任務,它是我的第一個VHDL程序。我不確定我們是否被允許。 – NoorUllah 2014-09-26 05:55:14

0

我想給你舉例說明我如何使用寫一個FSM。我希望它可以用於你的目的。

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; 

變爲:

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; 
+0

感謝@MtScor,這真的很有幫助。你的代碼看起來很乾淨並且更易於調試。 – NoorUllah 2014-09-29 03:59:36

+0

歡迎您:)請投票給我,以增加我的聲譽:)我在這個網站上很新 – MtScor 2014-09-29 07:17:08

0

有上面的編碼風格的一些很好的意見,而是直接回答原來的問題,當你佈置你的「如果」語句好聽你的錯誤是相當清楚的

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; 

正如您所看到的,有兩個缺少'end if'語句。很多時候,你會發現FPGA工具產生的錯誤實際上是由前一行產生的。在這種情況下,「when S3 =>」這一行會產生錯誤,因爲在「else」塊中間本身不能有「when」。