首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有非静态信号名称的过程调用循环

具有非静态信号名称的过程调用循环
EN

Stack Overflow用户
提问于 2015-06-25 08:25:43
回答 2查看 3.8K关注 0票数 5

在一些测试平台代码中,我使用一个过程来处理某个信号。然后,我在不同的信号上按顺序多次使用这个过程。只要我显式地定义了信号,它就能正常工作;只要我在循环中索引信号,它就会失败。

(vcom-1450)正式"s“的实际(索引名称)不是静态信号名称。

为什么这是不可能的,我如何才能绕过它呢?也许我可以将它移到一个for ... generate中,但是我希望在一个定义良好的序列中调用do_something

代码语言:javascript
复制
library ieee;
use ieee.std_logic_1164.all;

entity test is
end test;

architecture tb of test is
    signal foo : std_logic_vector(1 downto 0);
begin
    dummy: process is
        procedure do_something (
            signal s : out std_logic
        ) is begin
            s <= '1';
            report "tic";
            wait for 1 ns;
            -- actually we would do something more interesting here
            s <= '0';
            report "toc";
        end procedure;
    begin
        -- This works well, but requires manual loop-unrolling
        do_something(foo(0));
        do_something(foo(1));

        -- This should do the same 
        for i in foo'range loop
            -- This is the offending line:
            do_something(foo(i));
        end loop;
        wait; -- for ever
    end process dummy;
end architecture tb;

我使用的是ModelSim 10.4PE。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-25 09:27:37

有趣的是,如果foo是进程的局部变量,那么ghdl就会编译这个变量(并根据需要对s进行调整)。这突出了原版本中的问题。"for“循环需要一直驱动整个foo,因为您不能随意使信号驱动程序出现或消失--对于它正在驱动哪些位元不可能产生矛盾(正如您所看到的,该过程在不同的时间尝试驱动不同的位元)。

因此,如果您可以重新调整应用程序以允许变量更新语义,并使foo成为进程的局部变量,这将是可行的。(如果您想要看到效果,则必须在每次“等待”之前将其值复制到信号中!)

或者,将整个foo信号和索引传递给子程序,这样子程序总是按以下方式驱动所有foo .(我还添加了缺失的位,并修复了虚假的并发“等待”:将来,在发布之前,请检查您的代码示例实际编译!)

代码语言:javascript
复制
library ieee;
use ieee.std_logic_1164.all;

entity test is
end test;

architecture tb of test is
    signal foo : std_logic_vector(1 downto 0);
begin
    dummy: process is
        procedure do_something (
            signal s : out std_logic_vector(1 downto 0); 
            constant i : in natural
        ) is begin
            s <= (others => '0');
            s(i) <= '1';
            report "tic";
            wait for 1 ns;
            -- actually we would do something more interesting here
            s(i) <= '0';
            report "toc";
        end procedure;

    begin
        -- This works well, but requires manual loop-unrolling
        do_something(foo,0);
        do_something(foo,1);

        -- This should do the same 
        for i in foo'range loop
            -- This is the offending line:
            do_something(foo,i);
        end loop;
        wait; -- for ever
    end process dummy;

end architecture tb;
票数 6
EN

Stack Overflow用户

发布于 2016-03-04 15:49:28

我和你一样认为这是一种愚蠢的语言限制。除去waitreport语句,您的示例当然有一个有效的硬件实现,更不用说定义良好的模拟行为了。

我认为这种情况在大多数情况下是可以避免的。例如,在简单的示例中,您可以将过程的内容复制到流程主体中,或者像Brian建议的那样传递整个向量。如果您真的需要这样做,这是一个解决办法:

代码语言:javascript
复制
architecture tb of test is
    signal foo : std_logic_vector(1 downto 0);
    signal t : std_logic;
    signal p : integer := 0;
begin
    foo(p) <= t;

    dummy: process is
        procedure do_something (
            signal s : out std_logic
        ) is begin
            s <= '1';
            wait for 1 ns;
            s <= '0';
        end procedure;
    begin
        for i in foo'range loop
            p <= idx;
            do_something(t);
            wait for 0 ns;
        end loop;
        wait;
    end process dummy;
end architecture tb;

这只在模拟中工作,每次迭代将导致一个增量周期延迟,而当过程不包含等待语句时,则在零时间内完成循环展开。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31044965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档