1

每个人。我正在尝试在 VHDL 中制作一个 4 位乘法器。它将使用内置的 2x16 LCD 和通过 C922 IC 的 3x4 键盘在 Spartan 3E 板上实现。

使用过程是这样的:用户通过键盘输入一个数字,按下一个按钮进行确认,输入第二个数字,再次按下确认按钮,产品就会显示在 LCD 上。

到目前为止,keypad+c922 和 LCD 的代码都没有问题。乘数的代码几乎没问题。问题是确认按钮仅在按下另一个数字(最终未使用)时才起作用。

这是我的代码。以下是 Xilinx 仿真的屏幕截图

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;

确认键没有按下数字时的模拟: 在此处输入图像描述

使用确认按钮按下数字时的模拟: 在此处输入图像描述

我已经浏览了我的代码一个小时,但仍然看不出有什么问题。提前感谢任何可以提供帮助的人。

4

1 回答 1

0

正如 fru1tbat、Brian 和 David 所提到的,您的状态机组合部分的敏感度列表存在问题。具体来说,您缺少Confirm输入。由于Confirm输入不在敏感列表中,因此当确认更改状态时,状态机不会“唤醒”以评估新的输出/状态转换。您需要等待另一个条件(按下不同的按钮)才能正确评估并更新输出。

有多种方法可以解决这个问题。

  • 您可以确保您拥有状态机逻辑的完整敏感度列表
  • 使用 VHDL-2008,您可以使用process(all)在敏感度列表中自动列出所有必要的输入(您的编译器支持可能会有所不同)。
  • 您可以选择使用“单进程状态机”样式,从而避免此问题。然而,不同风格的状态机有它们的优点和需要考虑的缺陷。
于 2015-02-11T01:59:44.270 回答