verilog - 通过引用传递到 System Verilog 模块或接口
问题描述
我想创建一个可重用的接口或模块,其中外部内存元素的层次结构可以通过引用传递给它。我知道不能按照 LRM 对模块或接口进行引用传递,但是有没有一种方法可以在不使用定义的情况下实现它。请参阅下面的测试用例,其中注释掉的行显示良好的结果将在内存中提供正确的值,但我需要将层次结构传递到特定于此示例的接口中,并且不能使接口更可重用。我想让 badd 结果调用工作,但不知道该怎么做:
---------------------------------------- Verilog------------------------ -------------
module t1_tb();
reg clk;
reg write;
reg [4:0] address;
reg [31:0] data_in;
wire [31:0] data_out;
mem_model mem_model (clk, write, address, data_in, data_out);
mem_intf mem_intf(clk, address, mem_model.memory);
initial
begin
clk = 0;
write = 0;
address = 0;
for (int i = 0; i < 32; i++)
mem_model.memory[i] = 32'haaaaaaaa;
forever clk = #5 ~clk;
end
initial
begin
#200;
$display ("memory locations are %h and %h \n", mem_model.memory[0], mem_model.memory[1]);
$finish;
end
endmodule
module mem_model(input clk, input write, input [4:0] address, input [31:0] data_in, output [31:0] data_out);
reg [31:0] memory [0:31];
assign data_out = memory[address];
always @(posedge clk)
if (write)
memory[address] <= data_in;
endmodule
interface mem_intf (input clk, input [4:0] add, input logic [31:0] mem [0:31]);
import "DPI-C" context send_int = function void send_int_c ();
export "DPI-C" clks_delay = task clks_delay;
task clks_delay(input int unsigned usecs);
for (int i = 0; i < (int'(usecs/3.33) * 1000); ++i)
@(posedge clk);
endtask
task automatic mem_acc( input [4:0] add, ref reg [31:0] memory1 [0:31] );
#10;
memory1[add] = '1;
#10;
$display ("memory locations are %h and %h and add is %h\n", memory1[0], memory1[1], add);
endtask
task monitor_interrupts (input [6:0] interrupts);
send_int_c();
endtask
initial
begin
#100;
mem_acc(0, mem); //bad results
//mem_acc(0, t1_tb.mem_model.memory); // good results
end
endinterface
--------------------C 函数-----
void send_int(void)
{
printf("From C Sending Interrupt..\n");
}
extern void clks_delay(int seconds);
void clks_delay(int seconds)
{
printk("From C clocks_delay: %uld\n", seconds);
}
解决方案
但是您可以通过引用端口来传递任何变量。
interface mem_intf (input clk, input [4:0] add, ref logic [31:0] mem [0:31]);
请参阅 IEEE 1800-2017 LRM 中的第 23.3.3 节端口连接规则
更新
另一种选择是使用绑定构造来实例化接口,并向上引用内存。所有实例的内存名称必须相同。
interface mem_intf (input clk, input [4:0] add);
...
initial
begin
#100;
mem_acc(0, memory); //upward reference
end
endinterface
module t1_tb();
mem_model mem_model1 (clk, write, address, data_in, data_out);
bind mem_model: mem_model1 mem_intf mem_intf(clk, address);
推荐阅读
- javascript - 有没有办法在javascript中将子数组和子子数组合并为一个?
- xquery - 我们如何在 MarkLogic 中获取文档的本地路径
- laravel-6 - 如何在laravel6中根据对象的特定键值匹配合并集合?
- jenkins - 使用 Helm 和 Jenkins 为基于微服务的应用程序部署 Kubernetes
- git - 如何限制远程 git repo 中的交互?
- haskell - 为什么 Haskell 的括号函数在可执行文件中工作但在测试中无法清理?
- c++ - 如何将不同多个数组中的值传递给新的单个数组?
- javascript - 如何从 Promise 解析中获取价值?
- php - 如何在 laravel 验证器中验证时间“10:30 AM”
- regex - 如何在 shell 脚本中使用 sed 将所有出现的环境值替换为其当前值