2014-10-27 60 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)自动列出灵敏度列表中的所有必要的输入(你的编译器的支持可能会有所不同) 。
  • 您可以选择使用“单进程状态机”风格,这样可以避免此问题。然而,不同风格的国家机器有其优势和缺陷需要考虑。