2014-09-27 46 views
0

在我的波形图中,我想知道为什么我的“rdy”值在400ns后不会变为1。 为什么我的“d”值在前两个输出之后不输出任何内容?我试图找到几个小时的错误,但无济于事。请提前帮助,谢谢。VHDL。为什么我的“rdy”值不变为1?仍然困惑

这里是我的波形图:

waveform diagram

这是我的主要代码。

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

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

architecture behav of GCD is 
type state is (S0, S1, S2, S3, S4, S5, S6, S7); 

--temporary clk 
--signal clk : std_logic; 

signal new_state : state; 
signal eq : boolean; 
signal eq1 : boolean; 
signal lt : boolean; 

begin 
    --State transition 
    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 and not lt then curr_state := S7; 
       elsif lt and not eq then curr_state := S4; 
       elsif not eq and not lt then curr_state := S3; 
       end if; 
      when S3 => 
       curr_state := S4; 
      when S4 => 
       curr_state := S5; 
      when S5 => 
       if eq1 = true then curr_state := S7; 
       else curr_state := S6; 
       end if; 
      when S6 => 
       curr_state := S1; 
      when S7 => 
       if st = '0' then curr_state := S0; 
       end if; 
     end case; 
     new_state <= curr_state; 
     end if; 
     wait on clk; 
    end process; 


--Asserted Output Process 
process is 
variable M, N, dout_val, tmp: std_logic_vector(7 downto 0); 
variable rdy_val : std_logic; 
variable lt_val, eq_val, eq1_val : boolean; 
begin 
    rdy_val := '0'; 
    case new_state is 

     when S0 => 
      M := d1; 
      N := d2; 
     when S1 => 
      if (to_integer(M) = to_integer(N)) then eq_val := true; 
      elsif (to_integer(M) < to_integer(N)) then lt_val := true; 
      end if; 

     when S2 => 
     when S3 => 
      M := N; 
      N := M;   
     when S4 => 
      if (to_integer(M) = 1) then eq1_val := true; 
      end if; 
     when S5 => 
     when S6 => 
      N := (N - M); 
     when S7 => 
      rdy_val := '1'; 
      dout_val := M; 
    end case; 
    dout <= dout_val; 
    rdy <= rdy_val; 
    lt <= lt_val; 
    eq <= eq_val; 
    eq1 <= eq1_val; 
    wait on new_state; 
end process; 
end behav; 

这里是我的测试平台:

library IEEE; 

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

use work.all; 

entity test_GCD is 
end test_GCD; 

architecture testbench of test_GCD is 
signal m, n ,d: std_logic_vector(7 downto 0); 
signal clk, st, rdy : std_logic; 

begin 

    --Component Instantiation 
    device : GCD 
    port map(clk => clk, st => st, d1 => m, 
       d2 => n, dout => d, rdy => rdy); 


    --Process to Generate Test Data 
    process is 
    begin 
     st <= '0'; 
     wait for 10ns; 
     m <= "00001001"; --9 , 15  
     n <= "00001111"; 
     wait for 10ns; 
     st <= '1'; 
     wait until rdy = '1'; 
     wait for 10ns; 

     st <= '0'; 
     wait for 10ns; 
     m <= "00001111"; --15, 9 
     n <= "00001001";   
     wait for 10ns; 
     st <= '1'; 
     wait until rdy = '1'; 
     wait for 10ns; 

     st <= '0'; 
     wait for 10ns;  --15 , 14 
     m <= "00001111"; 
     n <= "00001110"; 
     wait for 10ns; 
     st <= '1'; 
     wait until rdy = '1'; 
     wait for 10ns; 

     st <= '0'; 
     wait for 10ns; 
     m <= "00010010"; --18 , 36 
     n <= "00100100"; 
     wait for 30ns; 
     st <= '1'; 
     wait until rdy = '1'; 
     wait for 10ns; 

     st <= '0'; 
     wait for 10ns; 
     m <= "01011011"; --91 = 01011011 , 39 = 00100111 
     n <= "00100111"; 
     wait for 10ns; 
     st <= '1'; 
     --wait for 10ns; 
     wait until rdy = '1'; 
     wait for 10ns; 

     st <= '0'; 
     wait for 10ns; 
     m <= "01111111"; --127, 127 
     n <= "01111111"; 
     wait for 10ns; 
     st <= '1'; 
     wait until rdy = '1'; 
     wait for 10ns; 

     wait; 
    end process; 

process is 
begin 
    clk <= '0', '1' after 15ns; 
    wait for 30ns; 
end process; 

end testbench; 
+0

出于您使用VHDL工具的好奇心,数字文字和单位之间不需要空格(例如10ns)?此外,它不需要GCD的组件声明,并且没有用于synopsys软件包std_logic_unsigned(或numeric_std_unsigned)的使用条款。 – user1155120 2014-09-27 09:27:34

+0

我使用Capilano Computing的DesignWorks 5。 – 2014-09-27 15:10:00

+0

您的DesignWorks在代码中演示的三种方式并不严格符合VHDL标准。 – user1155120 2014-09-27 21:29:09

回答

0

你是第二个今天在这里提出一个问题,用相同的分配。

在第三ST/RDY设置你心烦的时间关系:

st <= '0'; 
    wait for 10ns; 
    m <= "00010010"; --18 , 36 
    n <= "00100100"; 
    wait for 30ns; 
    st <= '1'; 
    wait until rdy = '1'; 
    wait for 10ns; 

前两个集有等待10纳秒。这个有30纳秒。这是做什么的?

您是未标记状态转换过程中的状态机缺少st < ='1',因为它在发生时没有找到它,在GCD中添加波形,尝试new_state。

在帮助某人并为他们完成任务之间有一个很好的平衡。


你能否解释一下你的意思是由我缺少我的状态转变的ST < = '1'?我宣布st为std_logic,因此我无法使用“< =”作业。你的意思是我在我的测试平台中错过了st < ='1'吗?

这个想法是让你看看状态机分布在两个未标记过程中的操作。

即使您的代码未写入合成条件,您的状态机仍在正时钟边沿上运行。该过程仅由一个事件驱动,clk并且在第一个if语句条件中评估表达式clk = '1'

如果添加new_state到您的波形转储(显示它的波形显示):

test_GCD_ghw.png (您可以在一个单独的标签或窗口中打开的图像,这是一个链接到本身)

(注意第一个GCD的答案全部是U的第二个答案似乎也不是15和9之间最大的共同点)

你会看到你的状态机退出转换,继续停留在评估的S2中和eq,但不会在断言输出过程中修改它们(您可以使用标签而不是注释,任何语句都可以用VHDL标记)。

我们看看之前的状态S1,其中eq_vallt_val被分配。它们依赖于在S0中从d1d2分配的MN

早在S2通知:

 when S2 => 
      if eq and not lt then 
       curr_state := S7; 
      elsif lt and not eq then 
       curr_state := S4; 
      elsif not eq and not lt then 
       curr_state := S3; 
      end if; 

如果你在你看他们都true上述波形看eqlt。怎么可能?有转型条件,你坚持在S2

那么这两个条件怎么能在同一时间是true

when S1 => 
     if (to_integer(M) = to_integer(N)) then 
      eq_val := true; 
     elsif (to_integer(M) < to_integer(N)) then 
      lt_val := true; 
     end if; 

您只分配其中的一个。

但是,另一个仍处于之前的状态,锁存new_state

作为一个短期演示,我将它们分配eq_vallt_val两个false就在它们被评估之前。那最多只会留下一个true

不幸的是,揭示了另一个漏洞在您的设计:

test_GCD_ghw_only_one_lt_eq.png

而这还不是你的问题的主题。

您似乎在链接中找到的PDF中使用流程图(图1)中显示的Euclid (GCD)算法。布尔类型似乎是一个分配要求(另一个学生也使用它们)。由此产生的VHDL表示至少有一个以上的错误。

您使用N作为寻找GCD的累加器,并且还更改了M的内容。 N有三个来源,d2,N-M的结果S6 and swapping M and N in S3 (which has the effect of assigning N to M , and N`自己,变量赋值立即)。 M和N应该是信号,或者您需要中间值进行交换。 (他们应该是信号)。

您可以使用波形显示来排除设计故障。当你推断锁存器时,你应该知道,当你有条件分配而没有等同于'else'时发生锁存器。

我用过的查看您的设计(ghdl和gtkwave)的开源工具不捕获波形转储中的变量。我怀疑DesignWorks 5不会(也可能是错误的)。 这样做的影响是您无法在模拟过程中看到数据的作用。您的设计足够小,您可以在整个过程中使用信号,而不会显着影响仿真时间。直接在S1中指定eqlt将需要其他指派(false)。如果您需要为分配使用变量,则可以将它们分配给信号以使其可见,但DesignWorks 5不显示变量。一旦你完成,你可以删除信号。

的回答为什么我的“rdy”值不变为1?是您推断的锁存器创建了一个您未检测到分支出S2的情况。

一旦你理清MN交换S3看起来它可能有一个很好的机会或工作(可能有另一个陷阱或两个在那里)。

而当你使用tmp持有M的(未使用的信号)的值:你开始得到正确的答案

 when S3 => 
      tmp := M; 
      M := N; 
      N := tmp;  

test_GCD_ghw_using_tmp.png

没有看到你的讲义给你的项目,我预计你从伪代码中工作,就像在链接的PDF图1中找到的一样。它可能是在预期使用信号的情况下编写的。

+0

谢谢你的回应David。 你能详细说明我的状态转换中缺少st <='1'的意思吗?我声明st为std_logic,所以我不能使用“<=”赋值。你的意思是我在测试平台中缺少st <='1'吗? – 2014-09-27 15:11:11

+0

谢谢大卫。我已经读过它,似乎解决了大部分问题。 – 2014-09-28 04:20:43