将对象传递到 SystemVerilog tasks/functions - Vivado Zynq 验证 IP / API

Passing objects into SystemVerilog tasks/functions - Vivado Zynq Verification IP / API

我在 Vivado 中有一个测试台,它有一个 IP 层次结构——一些自定义 IP 和一些 Xilinx IP,比如 Zynq 处理系统。 Zynq 处理系统还有一个关联的验证 IP 库,它对 API 加载 DDR 等操作很有用。

我想编写一个在其中利用 Zynq 验证 IP(和关联的 API)的任务。我不知道如何在我的测试平台中实现它?我是 SV 的新手,我猜我需要将 zynq 处理系统对象作为参数传递,这样我就可以在我的超级任务中访问它的 API。

更新示例 我在我的测试台上尝试做的事情。我意识到这不是正确的 SystemVerilog,它只是为了演示我试图获得的功能。 TOP 是在其他一些 .sv 文件中定义的模块,其中包含名为 T:

的任务的定义
module tb();

  TOP TIPTOP(), TIPITTYTOP();

  task myTask(input TOP T);
    begin
        T.T;
    end
  endtask
  
initial begin
  
  myTask(TIPTOP);
  myTask(TIPITTYTOP);
  
end
  
endmodule

您可以调用在另一个模块中声明的任务或函数。下面的代码具有以下结构:

P

  TOP       ANOTHER_TOP           
   |            |
BOT bot      BOT bot        

P 和所有模块都声明了一个任务 T。我可以调用模块 TOP:

中的所有任务

我可以使用分数解析运算符:::

调用包P中的任务
P::T;

我可以调用本地任务:

T;

我可以在BOT的实例bot中调用任务:

bot.T;

我可以调用其他顶层模块中的任务,ANOTHER_TOP:

ANOTHER_TOP.T;

我可以在另一个顶级模块中调用 BOT 的实例 bot 中的任务:

ANOTHER_TOP.bot.T;

请注意我是如何“以错误的顺序”声明各种任务和模块的。这没关系,因为 Verilog 需要 3 次编译,并且在第 2 次和第 3 次中整理出各种任务和模块之间的关系。但是,必须先编译包。这是因为在宏伟的计划中,包有点事后才想到。


https://www.edaplayground.com/x/KpJR

package P;
  task T;
    $display("P::T");
  endtask
endpackage

module TOP;
  initial
    begin
      T;
      ANOTHER_TOP.T;
      bot.T;
      ANOTHER_TOP.bot.T;
      P::T;
    end
  task T;
    $display("TOP.T");
  endtask
  BOT bot ();
endmodule

module ANOTHER_TOP;
  task T;
    $display("ANOTHER_TOP.T");
  endtask
  BOT bot ();
endmodule

module BOT;
  task T;
    $display("BOT.T");
  endtask
endmodule

更新问题的另一个答案

只有当模块 TOP 不是一个模块而是一个不同风格的模块时,才可以这样做,称为 接口。有一种特殊的 SystemVerilog 变量称为 virtual interface,它是一种可以存储对接口实例的引用的变量。这就是您在这里需要的。所以,

  1. 你需要让 TOP 成为一个界面并且
  2. 您需要将关键字 virtual 添加到您的任务中:task myTask(input virtual TOP T);

但是接口有限制。 (我们在这里并没有完全将其用于正常目的。)可能影响您的主要问题是您无法在接口内实例化模块。


https://www.edaplayground.com/x/SM33

interface TOP;
  task T;
    $display("TOP.T");
  endtask
endinterface

module tb();

  TOP TIPTOP(), TIPITTYTOP();

  task myTask(input virtual TOP T);
    begin
        T.T;
    end
  endtask
  
initial begin
  
  myTask(TIPTOP);
  myTask(TIPITTYTOP);
  
end
  
endmodule