2014-09-25 38 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”。