【问题标题】:VHDL 2008: Index in external names containing generated instancesVHDL 2008:包含生成实例的外部名称索引
【发布时间】:2020-10-21 12:57:05
【问题描述】:

对于测试平台,我尝试使用外部名称来读取 DUT 中的信号。不希望将这些信号导出到 DUT 之外,因此我得出结论,在这里使用外部名称是最好的选择。

不幸的是,DUT 中有一些for generate 语句,这似乎使得在 DUT 之外分配信号变得相当困难。

其中一个生成系统如下所示:

   gen_block : for i in 0 to gen_loops generate
      entity_block : entity_name
         port map(
            signal_name          => signal_name
         );
   end generate;

我的第一个生成的外部名称定义然后可以通过这样做放入 std_logic_vector 信号alias_signal

alias_signal(0) <= <<DUT_name.gen_block(0).entity_block.signal_name : std_logic>>

这可以正常工作。但是,由于gen_loops的值很大,我想将外部std_logic信号分配到std_logic_vectors中,索引对应于关联的生成索引。

我尝试的第一件事就是这样,只留下索引并将外部名称定义为 std_logic_vector。

alias_signal <= <<DUT_name.gen_block.entity_block.signal_name : std_logic_vector>>

根据 Sigasi 的说法,这完全没问题,但是一旦在 Questasim 中编译,我执行此操作的每一行都会出现此错误:

# ** Error: [location][line]: (vopt-1571) Index required for FOR GENERATE "gen_block".

我认为这意味着无论如何我都必须使用索引。

下一个明显的步骤是使用带有变量 for_val 的 for 循环来处理 entity_block 的每次迭代:

for for_val in 0 to gen_loops loop
   alias_signal(for_val) <= <<DUT_name.gen_block(for_val).entity_block.signal_name : std_logic>>
end loop;

奇怪的是,这会在 Sigasi 中产生一个错误,声称它“找不到对应于 for_val 的声明”。不知何故,在外部名称中,for_val 的值丢失了,并且外部名称中的定义以某种方式与其余代码隔离开来。请注意,写一个数字而不是 for_val 可以让一切正常工作,但由于 gen_loops 的值很大,这是一项相当艰巨的任务。

有人能看出我做错了吗?你有没有比这个更好的方法的建议?西加西是哑巴,还是我?提前感谢您的帮助:)

以下最小可重现示例: tb_name:

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

entity tb_name is
end entity tb_name;

architecture RTL of tb_name is

   constant gen_loops  : integer                              := 10;
   signal alias_signal : std_logic_vector(gen_loops downto 0) := (others => '0');
   signal clk          : std_logic                            := '0';

begin

-- for loop approach
-- p_clk : process is
-- begin
--    loop
--       clk = '0'
--       wait for 1 ns;
--       clk = '1'
--       wait for 1 ns;
--    end loop;
-- end process p_clk;
--
-- p_alias : process(clk) is
-- begin
-- for for_val in 0 to gen_loops loop
--    alias_signal(for_val) <= << signal ^.DUT_block.gen_block(for_val).entity_block.signal_name : std_logic >> ;
-- end loop;
-- end process p_alias;

-- std_logic_vector approach
-- alias_signal <= <<signal ^.DUT_block.gen_block.entity_block.signal_name : std_logic_vector>>

-- working with index
alias_signal(0) <= << signal ^.DUT_block.gen_block(0).entity_block.signal_name : std_logic >> ;

   DUT_block : entity work.DUT_name 
      generic map (gen_loops)
   end entity DUT_block;

end architecture RTL;

DUT_名称:

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

entity DUT_name is
   generic(gen_loops : natural := 10);
end entity DUT_name;

architecture RTL of DUT_name is

   signal signal_name : std_logic_vector (gen_loops downto 0) := (others => '0');

begin

   gen_block : for i in 0 to gen_loops generate
   entity_block : entity work.entity_name
      port map(
         signal_name          => signal_name(i)
      );
   end generate;

end architecture RTL;

实体名称:

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

entity entity_name is
   port(
      signal_name : out std_logic
   );
end entity entity_name;

architecture RTL of entity_name is

begin

   signal_name <= '1';

end architecture RTL;

【问题讨论】:

  • 构建一个minimal reproducible example 来省去我们的麻烦如何?
  • 您的意思是简单地复制并粘贴到您的编辑器中?
  • 是的。我必须用它来回答这个问题。
  • 我希望这就足够了:)

标签: vhdl external names generate array-indexing


【解决方案1】:

我找到了答案。 外部名称需要全局静态索引,而 for 循环中的变量是非静态的。 使用 for generate 语句而不是 for 循环将解决问题;)

for for_val in 0 to gen_loops generate
   alias_signal(for_val) <= <<DUT_name.gen_block(for_val).entity_block.signal_name : std_logic>>
end generate;

【讨论】:

  • 您的minimal reproducible example 中有几个拼写错误。我必须在编译之前更正这些。在阅读此答案之前,我编辑了您的问题,以便 minimal reproducible example 可以编译。其中一项编辑是将for 循环变成generate 循环,因为您不能在进程之外有for 循环。更正你的错别字后,我没有时间花在回答问题上。似乎我将 for 循环更改为 generate 循环与您的答案不兼容。我建议您编辑我的编辑以将您的 for 循环放入进程中,否则这个问题和答案毫无意义。
  • 这个答案不会编译。 (i) generate 循环需要一个标签。 (ii) DUT_name 不低于层次结构中的这一点。你需要说^.DUT_nameedaplayground.com/x/pWYc
  • 值得花时间用问答来整理这些问题,因为它对未来的读者很有用。
  • 谢谢马修,我在我的系统中确实做到了这一点,但制作了一个糟糕的可重现系统。没有看到关于^的东西。不过,在此之前,我会使用它。非常感谢您的帮助!
【解决方案2】:

为什么不直接引用数组信号呢?通过相对路径是:

alias signal_name is <<DUT_block.signal_name : std_logic_vector>> ; 

注意不需要指定std_logic_vector的索引范围。

通过绝对路径(这是我常用的)是:

alias signal_name is <<.tb_name.DUT_block.signal_name : std_logic_vector>> ; 

另外请记住,如果您将它们放在您的测试平台中,您必须将它们放在您的 DUT 实例之后 - 在一个进程或块声明区域中。

【讨论】:

  • 我的问题中已经引用了此方法。你的答案和这个方法有区别吗? alias_signal &lt;= &lt;&lt;DUT_name.gen_block.entity_block.signal_name : std_logic_vector&gt;&gt;。我得到的错误基于 Questasim,定义为:# ** Error: [location][line]: (vopt-1571) Index required for FOR GENERATE "gen_block".
  • 不引用中间实例名称可以解决这个问题吗?编辑:我已经尝试过了,正如预期的那样,它找不到该实例名称的信号。
  • 如果您在体系结构中在其外部声明 std_logic_vector 信号,为什么还要与生成块纠缠不清。这只是参考。你按照我写的方法试过了吗?您的错误消息表明您试图进入生成块。
  • 我写这个的方式,它引用了“DUT_name 的架构 RTL”中的声明。它不会费心尝试进入生成循环。如果设计如上所示,并且您按照显示的方式尝试了它(即引用​​声明点),这确实可以工作。
猜你喜欢
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 2022-08-16
  • 1970-01-01
相关资源
最近更新 更多