2014-09-27 156 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