6

我一直在尝试用 VHDL 代码为我在 Altera DE1 板上实现的简单 16 位处理器编写有限状态机。在有限状态机中,我有一个CASE处理不同 16 位指令的语句,这些指令由 16 位 STD_LOGIC_VECTOR 带入 FSM。但是,在有限状态机对指令进行解码的解码状态下,我遇到了一些麻烦。其中一条指令是 ADD,它将两个寄存器作为操作数,第三个作为目标寄存器。但是,我也有一条 ADD 指令,它将一个寄存器和一个 5 位立即数作为操作数,第二个寄存器作为目标。我的问题是在CASE声明,我需要能够区分两个不同的 ADD 指令。所以,我认为如果我在CASE语句中使用通配符值,如“-”或“X”,我将能够仅用两种情况区分两者,而不是列出所有可能的寄存器/立即数组合。例如:

    CASE IR IS --(IR stands for "Instruction Register")
      WHEN "0001------0-----" => (Go to 3-register add);
      WHEN "0001------1-----" => (Go to 2-register/immediate value add);
      WHEN OTHERS => (Do whatever);
    END CASE;

这些不是我仅有的两个说明,我只是把这两个说明使这篇文章更短一点。当我编译并运行这段代码时,处理器在进入“解码”状态时停止执行。此外,Quartus 给出了很多很多警告,比如“LC3FSM.vhd(37) 处的 VHDL 选择警告:忽略包含元值的选择”“0001------0-----”“”我在关于如何实现这一点的损失。我真的不需要也可能不需要定义每一个 16 位组合,我希望有一种方法可以在 STD_LOGIC_VECTOR 中使用通配符来最小化我必须定义的组合数量。

有谁知道如何做到这一点?

谢谢

4

2 回答 2

6

不幸的是,这是无法做到的。对于大多数用户来说,出乎意料的是,比较运算符=case比较执行的是文字比较。这是因为std_logic类型只是一组字符,由于其他函数(例如andor)的定义方式,它们恰好执行类似的逻辑值。

VHDL-2008 引入了一个新的 case 语句case?,它按您的预期执行 - 您需要告诉您的编译器在 VHDL 2008 模式下运行。此外,?=VHDL 2008 中有一个运算符,它比较两个值,同时考虑到-s。

如果您使用的编译器仍然不支持 VHDL 2008,请向供应商投诉。还有一个std_match函数允许您在较旧的 VHDL 版本中执行比较,但我不知道如何使case语句以这种方式工作。

于 2012-02-09T15:42:22.323 回答
1

假设您不需要指令中的其他位,您可以通过使用预检查过程屏蔽其他位来解决此问题。(或者只是确保在编写指令时重置其他位?)

这真的是一个黑客攻击。

假设 IR 存储为变量

if IR(15 downto 12) == "0001" then
    IR := IR_in(15 downto 12) & "0000000" & IR_in(5) & "00000";
else
    IR := IR_in
end if;

CASE IR IS --(IR stands for "Instruction Register")
  WHEN "0001000000000000" => (Go to 3-register add);
  WHEN "0001000000100000" => (Go to 2-register/immediate value add);
  WHEN OTHERS => (Do whatever);
END CASE;

或者假设您的指令被巧妙地考虑(前四位是命令字还是类似的东西?)您可以执行嵌套的 case 语句并根据需要在这些子块中进行区分。

于 2012-02-09T19:51:13.030 回答