VHDL 中的程序从不 returns 值

Procedure in VHDL never returns the value

我有一个从来没有 return 值的过程。

procedure gen_start_impulse (
    signal rising_signal        : out std_logic;                             
    signal carier_clk           : in std_logic;
    constant duration           : in integer)    is                         
variable clk_counter    : integer := 0;
begin 
    if (rising_edge(carier_clk)) then
        if (clk_counter = duration) then
            rising_signal <= '0';
            clk_counter := 0;
        else
            rising_signal <= '1';
            clk_counter := clk_counter + 1;
        end if;
    end if;
end gen_start_impulse;

我这里叫它

process (start)
begin
    if (start = '1') then
        gen_start_impulse(start_impulse, clk, 1);           
    end if;
end process;

在测试台中 start_impulse 未初始化。

Result of testbench

我不明白为什么波形 start_impulse 未初始化。

欢迎使用 Whosebug。你的问题很有趣,但它并没有真正包含足够的信息来获得完整的答案(如果你愿意,快速浏览 help center and especially at the How to create a Minimal, Complete, and Verifiable example 部分可能会帮助你改进它)。

总之,我们来猜一猜吧。每次 start 更改时,您的过程都会恢复,并且由于您的 if 语句,只有当 start 的新值为 '1' 时,它才会调用您的 gen_start_impulse 过程。所以,为了澄清事情,我们可能会展平你的模型并像这样重写你的过程:

process (start)
    variable clk_counter: integer := 0;
    constant duration: integer := 1;
begin
    if (start = '1') then
        if (rising_edge(clk)) then
            if (clk_counter = duration) then
                start_impulse <= '0';
                clk_counter := 0;
            else
                start_impulse <= '1';
                clk_counter := clk_counter + 1;
            end if;
        end if;
    end if;
end process;

重要说明:这并不严格等同于您的初始代码,因为在您的代码中,每次 gen_start_impulse 时都会重新初始化 clk_counter 变量过程被调用,而这里它保持其先前的值。

现在,如果 start 是同步的,您认为会发生什么?也就是说,如果它总是在 clk 的上升沿之后改变?简单:条件:

if (rising_edge(clk)) then

语句始终为假,您对 start_impulse 的信号分配永远不会执行。这是因为 startclk 永远不会同时改变。它们之间总是至少有一个模拟步骤(“delta-cycle”)。

如果您设计同步系统,请等待或检查时钟的上升沿,然后测试其他信号,而不是相反。示例:

procedure gen_start_impulse (
    signal rising_signal        : out std_logic;                             
    signal starter              : in std_logic;
    constant duration           : in integer)    is                         
    variable clk_counter    : integer := 0;
begin 
    if (starter = '1') then
        if (clk_counter = duration) then
            rising_signal <= '0';
            clk_counter := 0;
        else
            rising_signal <= '1';
            clk_counter := clk_counter + 1;
        end if;
    end if;
end gen_start_impulse;
...
process (clk)
begin
    if (rising_edge(clk)) then
        gen_start_impulse(start_impulse, start, 1);           
    end if;
end process;

重要说明:由于每次调用 gen_start_impulse 过程时都会重新初始化 clk_counter 变量(请参阅前面的说明),这不会像你期望的那样工作。如果你想让它起作用,你需要稍微修改一下,要么完全删除这个过程(顺便说一句,你为什么需要它?)并只使用一个同步过程,要么添加第四个 inout clk_counter 变量的过程参数 ans 将其声明为过程变量。