2014-10-27 63 views
1

所有人。我試圖在VHDL中創建一個4位乘法器。它將使用內置的2x16 LCD和通過C922 IC的3x4鍵盤在Spartan 3E板上實現。嘗試在VHDL中使用3x4鍵盤輸入和2x16 LCD在Spartan 3E板上實現4位乘法器

使用方法如下:用戶通過鍵盤輸入數字,按下確認按鈕,輸入第二個數字,再次按下確認按鈕,產品顯示在LCD上。

到目前爲止,鍵盤+ c922和LCD的代碼都沒問題。乘法器的代碼幾乎沒問題。問題是確認按鈕只有在另一個數字(最終未被使用)被按下時才起作用。

這是我的代碼。繼是賽靈思模擬

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity multi_4bit is 
    Port (CLK : in STD_LOGIC; 
     RESET : in STD_LOGIC; 
     Input : in STD_LOGIC_VECTOR (3 downto 0); 
     DAVBL : in STD_LOGIC; 
     Confirm : in STD_LOGIC; 
     Output : out STD_LOGIC_VECTOR (7 downto 0)); 
end multi_4bit; 

architecture Behavioral of multi_4bit is 

type state is (R,S0,S1,S2,S3,S4); 
signal pstate, nstate: state; 
signal A_sig, B_sig: STD_LOGIC_VECTOR(3 downto 0); 

begin 

state_transition: process(CLK,RESET) 
begin 
    if RESET = '1' then 
     pstate <= R; 
    elsif rising_edge(CLK) then 
     pstate <= nstate; 
    end if; 
end process; 

nstate_output: process(pstate,DAVBL,Input) 
variable temp_var: STD_LOGIC_VECTOR(3 downto 0); 
variable tempMult_var,tempProd_var: STD_LOGIC_VECTOR(7 downto 0); 
begin 
    case pstate is 
     when R => 
      nstate <= S0; 
      tempMult_var := (others => '0'); 
      tempProd_var := (others => '0'); 

      A_sig <= (others => '0'); 
      B_sig <= (others => '0'); 

      Output <= (others => '0'); 
     when S0 => 
      nstate <= S0;   

      if (DAVBL = '1') then 
       A_sig <= Input; 
       nstate <= S1; 
      end if; 
     when S1 => 
      nstate <= S1; 

      if (Confirm = '1') then 
       nstate <= S2; 
      end if; 
     when S2 => 
      nstate <= S2; 

      if (DAVBL = '1') then 
       B_sig <= Input; 
       nstate <= S3; 
      end if; 
     when S3 => 
      nstate <= S3; 

      if (Confirm = '1') then 
       nstate <= S4; 
      end if; 

     when S4 => 
      nstate <= S0; 

      for x in 0 to 3 loop 
       temp_var := (A_sig AND (B_sig(x)&B_sig(x)&B_sig(x)&B_sig(x))); 
       tempMult_var := "0000" & temp_var; 
       if (x=0) then tempMult_var := tempMult_var; 
       elsif (x=1) then tempMult_var := tempMult_var(6 downto 0)&"0"; 
       elsif (x=2) then tempMult_var := tempMult_var(5 downto 0)&"00"; 
       elsif (x=3) then tempMult_var := tempMult_var(4 downto 0)&"000";   
       end if; 
       tempProd_var := tempProd_var + tempMult_var; 
      end loop; 

      Output <= tempProd_var; 
      tempProd_var := (others => '0'); 
    end case; 
end process; 

end Behavioral; 

仿真時按了確認鍵無號的截圖: enter image description here

仿真時數按了確認鍵: enter image description here

我已經通過我的代碼一個小時了,但仍然看不到有什麼問題。 在此先感謝任何可以幫助的人。

+1

你可能想看看你的敏感列表... – fru1tbat 2014-10-27 12:31:28

+1

...又名,2進程狀態機再次咬人。 – 2014-10-27 14:26:40

+1

關於fru1tbat的評論更簡潔一點。 '確認'不在'n_state_output'進程的靈敏度列表中。難怪你必須等待其他事件。 Brian的單一過程爲另一組缺失的靈敏度列表元素進行交易(靈敏度列表中也缺少「A_sig」和「B_sig」,儘管它們沒有以相同的狀態被賦值)。 – user1155120 2014-10-27 19:39:23

回答

0

正如fru1tbat,Brian和David所提到的,您在狀態機的組合部分中遇到了敏感列表問題。具體而言,您錯過了Confirm輸入。由於Confirm輸入不在靈敏度列表中,因此當確認更改狀態時,狀態機將不會「喚醒」以評估新的輸出/狀態轉換。您需要等待另一個條件(按下不同的按鈕)才能正確評估並更新輸出。

有多種方法可以解決這個問題。

  • 您可以確保你有你的狀態機邏輯完整的敏感列表
  • 採用VHDL-2008,您可以使用process(all)自動列出靈敏度列表中的所有必要的輸入(你的編譯器的支持可能會有所不同) 。
  • 您可以選擇使用「單進程狀態機」風格,這樣可以避免此問題。然而,不同風格的國家機器有其優勢和缺陷需要考慮。