VHDL 比较中加法器的实现

Implementations of an Adder in VHDL comparison

谁能解释一下为什么这个实现有效

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity Adder is
    port(A: in std_logic_vector(3 downto 0);
    B: in std_logic_vector(3 downto 0);
    SUM: out std_logic_vector(3 downto 0);
    CO: out std_logic);
end;

architecture DescriptionAdders of Adder is

signal temp:  std_logic_vector(4 downto 0);
signal temp1: std_logic_vector(4 downto 0);
signal temp2: std_logic_vector(4 downto 0);

begin

temp1 <= '0' & A;
temp2 <= '0' & B;
temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));

SUM <= temp(3 downto 0);
CO <= temp(4);

end;

虽然这不是(开始时 SUM 是 XX 运行,然后它总是比实际结果落后一步,但温度更新很好)。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity Adder is
    port(A: in std_logic_vector(3 downto 0);
    B: in std_logic_vector(3 downto 0);
    SUM: out std_logic_vector(3 downto 0);
    CO: out std_logic);
end;

architecture DescriptionAdders of Adder is

signal temp:  std_logic_vector(4 downto 0);
signal temp1: std_logic_vector(4 downto 0);
signal temp2: std_logic_vector(4 downto 0);

begin

process(A, B) is
begin
    temp1 <= '0' & A;
    temp2 <= '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

SUM <= temp(3 downto 0);
CO <= temp(4);

end;

对不起,如果问题太简单了,我是初学者。

这个问题似乎是基于对 VHDL 仿真如何工作的常见误解。

process(A, B)

表示该过程将在AB事件时触发。在此过程中发生的是对其他对象的赋值

temp1 <= '0' & A;
temp2 <= '0' & B;
temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));

这意味着将安排三个事件temp1temp2temp 各一个。但是 VHDL 的工作方式,实际分配 直到 下一个增量周期 才会发生。在评估过程 之后发生。因此,即使分配给 temp1temp2 的行位于分配给 temp 之前, 它们的值尚未更改 .

考虑到 temp1temp2 的值在过程完成后发生变化,因此错过了对 temp 的分配。 除非您通过将对象添加到敏感列表重新进入进程。例如

process(A, B, temp1, temp2) is
begin
    temp1 <= '0' & A;
    temp2 <= '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

另一种解决方案是使用可以在流程内部更改的变量。但请注意,如果使用不当,变量会导致逻辑综合困难。这个例子将起作用:

process(A, B) is
    variable temp1, temp2 : std_logic_vector(4 downto 0);
begin
    temp1 := '0' & A;
    temp2 := '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

但问题是:为什么您根本不需要 temp1temp2 。随便写

process(A, B) is
begin
    temp <= std_logic_vector(unsigned('0' & A) + unsigned('0' & B));
end process;

或者更灵活一点

process(A, B) is
begin
    temp <= std_logic_vector(
        resize(unsigned(A), temp'length) +
        resize(unsigned(B), temp'length));
end process;

甚至使用 integer 类型(限制为 32 位!)

process(A, B) is
begin
    temp <= std_logic_vector(to_unsigned(
        to_integer(unsigned(A)) + to_integer(unsigned(B))
        , temp'length));
end process;