【问题标题】:What causes 'interface resolution' compilation error when working with classes and virtual interfaces使用类和虚拟接口时导致“接口解析”编译错误的原因
【发布时间】:2021-08-27 13:13:40
【问题描述】:

我在设计文件中声明了以下接口:

interface t_clocks;
   ckrs_t ClkRs125MHz_ix;
   ckrs_t ClkRs160MHz_ix;
   ckrs_t [3:0] ClkRsLink_ixb;
   ckrs_t ClkRsLinkx2_ixb;
   logic tdclk_sampling;

   modport producer(output ClkRs125MHz_ix,
            output ClkRs160MHz_ix,
            output ClkRsLink_ixb,
            output tdclk_sampling);

   modport consumer(input ClkRs125MHz_ix,
            input ClkRs160MHz_ix,
            input ClkRsLink_ixb,
            input tdclk_sampling);
endinterface // clocks

interface t_bst(input ckrs_t ClkRs_ix);
   tb_t mark;

   modport consumer(input ClkRs_ix, input mark);
   modport producer(output ClkRs_ix, output mark);
endinterface // t_bst

在使用这些接口的包类中:

package clspkg;
   import DefinitionsPkg::*;

class bst_generator;
   virtual t_bst.producer bst_master;
   ....
endclass // bst_generator

class clock_generator;
   virtual t_clocks.producer clk_tree;
   ....
endclass // clock_generator
endpackage // clspkg

我在测试台中将所有内容粘合在一起,仅使用包中的 clock_generator 类:

module tb_turn_emulator;
   import clspkg::*;

   t_clocks clk_tree();
   clock_generator cgen;

   // ???????????????
   //t_bst blast_radius(clk_tree.ClkRs160MHz_ix);

   default clocking cb @(posedge clk_tree.ClkRs160MHz_ix.clk); endclocking

   `TEST_SUITE begin

      `TEST_SUITE_SETUP begin
         cgen = new;
         cgen.clk_tree = clk_tree;
         cgen.run();
         ##10;
      end

....

endmodule

现在,当我尝试编译这样的示例时,它以Virtual interface resolution cannot find a matching instance for 'virtual t_bst.producer' 失败

我花了很长时间才发现,如果我在 testbench 模块中也实例化了 t_bst 接口(取消注释上面代码中的 t_bst 行),一切顺利,没有编译错误,并且测试台照常通过.

我不明白为什么必须实例化 t_bst 接口,因为它根本没有在代码中使用。确实,我正在导入整个 clspkg 包,但是当我通过import clspkg::clock_generator 仅导入clock_generator 进行挑选时,没有任何变化。

怎么了?我正在使用 Mentor Modelsim

【问题讨论】:

  • 只是附加信息:我正在使用 ModelSim SE-64 2021.1。

标签: class interface virtual system-verilog


【解决方案1】:

首先关于使用

一旦您在设计中import 一个标识符或来自package 的每个标识符,整个package存在在您的设计中。这意味着所有静态变量都被分配和初始化,以及任务和函数的所有代码都被生成。如果静态变量初始化调用类构造函数之类的函数,这意味着执行过程代码而不直接引用它。 (对于那些熟悉factory design pattern and UVM 的人来说,这正是工厂注册的工作原理。)

接下来关于使用接口

module 一样,interface 是一个包含许多不同事物定义的设计元素。他们可以定义变量、例程、导入其他包,并拥有端口连接。但是,在其他设计单元将其实例化或在模块的情况下,将其建立为顶级实例之前,接口内没有任何内容存在或在设计中生成任何代码。

现在关于使用虚拟接口

虚拟接口是用于将基于动态类的测试平台世界的two kingdoms 与基于静态实例的设计世界连接起来的主要方法。虚拟接口的行为很像类类型,除了在代码中使用接口之前没有看到接口定义的规则。分层引用也具有引用编译时不存在但必须在编译的后期处理阶段解决的这种能力。

总而言之,编译器一旦看到对它的引用,就会为虚拟接口生成代码,无论您是否真的认为自己正在使用它。我会尝试将包与它们关联的特定接口对齐。

【讨论】:

    【解决方案2】:

    来自 SV LRM(25.9 虚拟接口):

    • 虚拟接口是表示接口实例的变量。
    • 在引用虚拟接口的组件之前,应初始化虚拟接口; 在初始化之前它的值为 null。尝试使用空虚拟接口将导致致命的运行时错误

    我希望它能回答你的问题。

    【讨论】:

    • 这不是问题。他们没有尝试使用空句柄引用虚拟接口变量。
    • 在问题中, t_bst 接口未实例化,尽管在包中声明为虚拟。是不是和 LRM 中所说的“在引用虚拟接口的组件之前应初始化虚拟接口”相同的情况?
    • 您在回答中也提到了类似的事情,“分层引用也具有引用编译时不存在的东西的能力,但必须在编译的详细阶段稍后解决。 "
    • A null 引用是一个运行时错误; OP 正在处理 compilation 错误。
    猜你喜欢
    • 2022-01-11
    • 2014-10-18
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多