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
的信号分配永远不会执行。这是因为 start
和 clk
永远不会同时改变。它们之间总是至少有一个模拟步骤(“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 将其声明为过程变量。
我有一个从来没有 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
的信号分配永远不会执行。这是因为 start
和 clk
永远不会同时改变。它们之间总是至少有一个模拟步骤(“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 将其声明为过程变量。