我正在尝试用VHDL构建和合成ALU,但是一旦合成我就会遇到问题。 我希望我的ALU有一个操作码,用于添加我的两个N位输入和一个可以通过输入或先前计算的总和来设置的进位。 我感兴趣的代码部分如下:
process (a, b, op) -- a and b are n bits input en op is the op-code
case op is
when "011" => -- add a + b + c (with c as carry)
y <= ('0' & a) + ('0' & b) + c; -- y is the N-bit output
...
end process;
process (clk)
if (clk'event and clk = '1') then
if (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) > (2**N)) then --basically I'm testing if there is an overflow during the calculation
c <= '1';
elsif (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) < ((2**N)+1))
c <= '0';
...
end process;
我不确定代码是否可以在这里工作,因为我没有定义信号类型,但基本上它归结为我上面所写的内容。 这个问题是,当我使用适当的测试平台模拟我的VHDL时,它可以正常工作,但是当我合成此代码并使用相同的测试平台模拟合成代码时,它无法正常工作,因为不知何故第一个进程是即使a,b或op没有改变,也会再次重复。因此,当总和的结果有一个进位时,使用这个新进位再次进行计算,即使a,b或op没有改变,结果也会增加1!
后来我发现这篇文章说that the sensitivity list is "ignored" by the compiler如何认为他比你更了解程序并制作自己的敏感列表。如果这是真的,我将guest编译器在第一个进程的敏感性列表中添加clk,以便在op =“011”时在每个clk周期运行计算。
我现在提出的问题是:我该如何处理这个问题,以便计算运行一次并且进位在之后发生变化?
亲切的问候
答案 0 :(得分:0)
正如其他人所指出的那样,您的代码存在一些问题。我将尝试建议一些改进,然后显示计算进位标志的可能方法:
区分进位和执行信号。为您的信号使用通信名称,例如carry_in
和carry_out
。这将消除很多混乱。
为ALU操作定义常量或枚举类型。例如:
subtype opcode_type is std_logic_vector(2 downto 0);
constant ADC: opcode_type := "011"; -- ADC: add with carry
最后,如果您使用的是VHDL 2008,则可以使用聚合作为分配目标来生成执行:
(carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
您的代码最终会如下所示:
process (all)
case op is
when ADC => -- add a + b + c (with c as carry)
(carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
...
end process;
process (clk)
if rising_edge(clk) then
carry_flag <= carry_out;
...
end process;