VHDL:为什么输出延迟这么多?

VHDL: Why is output delayed so much?

我正在学习 VHDL,以描述和演示具有危险检测和分支预测等功能的超标量流水线 CPU 的工作

我从小做起,所以为了练习,我尝试制作一个非常简单的 "calculator" 设计,如下所示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

entity calculator is
    port(
        in_A  : in  std_logic_vector(3 downto 0);
        in_B  : in  std_logic_vector(3 downto 0);
        add : in std_logic;
        sub : in std_logic;
        out_C : out std_logic_vector(3 downto 0)
    );
end entity calculator;

architecture RTL of calculator is
    signal next_output : std_logic_vector(3 downto 0);
begin
    process(in_A, in_B, add, sub)
        variable temp_x, temp_y, temp_z : integer;
    begin

        temp_x := conv_integer(in_A);
        temp_y := conv_integer(in_B);

        if(add = '1') and (sub = '0') then
            temp_z := temp_x + temp_y;
            next_output <= std_logic_vector(to_unsigned(temp_z, 4));
        elsif(add = '0') and (sub = '1') then
            temp_z := temp_x - temp_y;
            next_output <= std_logic_vector(to_unsigned(temp_z,4));
        else
            temp_z := 0;
            next_output <= std_logic_vector(to_unsigned(temp_z,4));
        end if;

        out_C <= next_output;
    end process;
end architecture RTL;

但是,我不明白为什么只有在输入更改后才设置输出,如此处所示(我猜测试台代码无关紧要):

我想知道我应该怎么做才能使输出正确并立即可用。如果add是1,那么输出应该根据输入来设置,没有延迟(好吧,我希望它是,我写的方式,它不是:))

此外,有人可以向我解释一下何时会在触发器中记住输出,以及是否按照我写描述的方式在触发器中记住它。

我也非常感谢所有帮助我的建议、批评和指导。这只是一个简单的 ADD/SUB 计算器,我要在大约两个月内用一个指令集描述一个完整的处理器!也许你可以给我指出好的学习教程,因为我的 类 没用:(

提前致谢! :)

最简单的方法是移动作业

out_C <= next_output;

进程外(使其成为并发信号分配)。

您还可以使 next_output 成为过程中声明的变量,并将信号赋值保留在原处。

延迟的发生是因为信号分配在它们发生的模拟周期中没有生效。如果没有对 next_output 敏感的进程,它的新值将在下一次进程以其他方式执行时看到。

并发信号分配语句具有等效过程,其中右侧的信号在敏感列表中。

将 next_output 设为变量使其值立即可用。

你也可以重写你的过程:

    process(in_A, in_B, add, sub)
        variable temp_x, temp_y, temp_z : integer;
    begin

        temp_x := conv_integer(in_A);
        temp_y := conv_integer(in_B);

        if(add = '1') and (sub = '0') then
            temp_z := temp_x + temp_y;
        elsif(add = '0') and (sub = '1') then
            temp_z := temp_x - temp_y;
        else
            temp_z := 0;
        end if;

        out_C <= std_logic_vector(to_unsigned(temp_z,4));
    end process;

并消除next_output。

信号分配 <= 到中间信号 next_output 不是 在同一个 运行 的进程中可见,所以它需要另一个 运行 的进程 直到 out_C <= next_output 看到新值,因此延迟。

正如 David Koontz 所写,那么您可以将 out_C <= next_output 移到 过程。

另一种方法是获取所有中间信号和变量的脊线,并且 重写代码如下,包括只使用IEEE标准包 numeric_std,并跳过 Synopsys 专有包 std_logic_signed.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
...
architecture RTL of calculator is
begin
    process(in_A, in_B, add, sub)
    begin
        if(add = '1') and (sub = '0') then
            out_C <= std_logic_vector(signed(in_A) + signed(in_B));
        elsif(add = '0') and (sub = '1') then
            out_C <= std_logic_vector(signed(in_A) - signed(in_B));
        else
            out_C <= std_logic_vector(to_signed(0, out_C'length));
        end if;
    end process;
end architecture RTL;

我看到 David 提出了类似的建议,但无论如何你都可以得到我的 :-)