我正在尝试使用Peter Ashenden的书“VHDL的设计者指南”来学习VHDL,但似乎无法摆脱我错过了与敏感性列表相关的基本项目的感觉 .
例如,一个问题是“编写一个表示具有整数输入和输出的简单ALU的模型,以及一个类型为bit的函数选择输入 . 如果函数选择为'0',则ALU输出应该是输入的总和,否则输出应该是输入的差异 . “
我的解决方案是
entity ALU is
port (
a : in integer; -- A port
b : in integer; -- B port
sel : in bit; -- Fun select
z : out integer); -- result
end entity ALU;
architecture behav of ALU is
begin -- architecture behav
alu_proc: process is
variable result : integer := 0;
begin -- process alu_proc
wait on sel;
if sel = '0' then
result := a + b;
else
result := a - b;
end if;
z <= result;
end process alu_proc;
end architecture behav;
与测试台
entity alu_test is
end entity alu_test;
architecture alu_tb of alu_test is
signal a, b, z : integer;
signal sel : bit;
begin -- architecture alu_tb
dut: entity work.alu(behav)
port map (a, b, sel, z);
test_proc: process is
begin -- process test_proc
a <= 5; b <= 5; wait for 5 ns; sel <= '1'; wait for 5 ns;
assert z = 0;
a <= 10; b <= 5; wait for 5 ns; sel <= '0'; wait for 5 ns;
assert z = 15;
wait;
end process test_proc;
end architecture alu_tb;
我的问题与流程中的敏感性列表有关 . 由于它对选择位的变化敏感,我必须顺序地执行这些功能,首先是减法,然后在测试台中再加一次减法 . 在这个问题中,我感觉你应该能够顺序完成几个加法,之间没有相减 . 当然,我可以添加一个启用信号并让过程对此敏感,但我认为应该在问题中说明 . 我错过了语言中的某些内容还是我的解决方案“正确”?
1 回答
ALU过程的问题是
wait on sel;
不包括a
和b
,因此进程不会唤醒,并且在更改这些输入时不会重新计算输出 . 解决此问题的一种方法是将a
和'b'添加到wait
语句中,例如:但是,为进程写这个的常用方法是使用敏感列表,它是
process
关键字之后的信号列表,因此不是wait
语句 .Ashendens第3版第68页描述了灵敏度列表:
在第152页的Ashendens一书中也描述了灵敏度列表与
wait
语句等效的用法 .如果重写过程以使用敏感度列表,则它将是:
请注意,我删除了
result
变量,因为在这种情况下也可以直接分配z
输出 .当计算中使用的任何值发生更改时,上述内容将重新计算
z
,因为计算z
的所有参数都包含在灵敏度列表中 . 以这种方式进行这种连续计算的风险是,如果在敏感性列表中忘记了一个或多个参数,则如果被遗忘的参数发生变化,则不会重新计算z
的新值 .如果使用
all
,VHDL-2008允许在灵敏度列表中自动包含所有信号和端口,如:最后的注释,然后对于进行异步计算的简单过程,就像显示的ALU一样,如果
z
的生成如下所示,则可以在没有进程的情况下执行:使用并行分配,如上所述,可以跳过灵敏度列表,从而有可能忘记作为计算一部分的信号或端口之一 .