我对执行并行总线读写的 SystemVerilog 任务有疑问。它使用打包的 struct ref 参数。任务不编译。
我有一个包含总线所有信号的结构
typedef struct packed {
logic clk;
logic rst;
logic [31:0] addr;
logic read;
logic write;
logic [31:0] write_data;
logic [31:0] read_data;
logic read_data_valid;
} sv_lb_type
然后我想写一个程序/任务来写。像这样的东西:
task automatic lb_write(
input [31:0] writeAddr,
input [31:0] writeData,
ref struct {
logic clk;
logic rst;
logic [31:0] addr;
logic read;
logic write;
logic [31:0] write_data;
logic [31:0] read_data;
logic read_data_valid;
} lb
);
begin
$display("Waiting for LB reset to be deasserted");
while (lb.rst != 1'b0) begin
@(posedge lb.clk);
end
@(posedge lb.clk);
lb.read = 1'b1;
lb.write = 1'b0;
lb.addr = writeAddr;
lb.write_data = writeData;
@(posedge lb.clk);
lb.read = 1'b0;
lb.write = 1'b0;
lb.addr = '0;
lb.write_data = '0;
@(posedge lb.clk);
end
endtask
非常简化的测试平台如下所示:
`timescale 1 ps / 1 ps
`include "svInterfaces.sv"
module tb ( );
import simMainPackage::*;
wire rfClk;
wire rfRst;
// Local bus interface
wire sv_lb_type lb_ds;
////////////////////////////////////////////////////////////////////////////
// Testbench clock and reset generation
////////////////////////////////////////////////////////////////////////////
clock_gen #(
.FREQ (100000)
) rfClk_inst (
.enable (1'b1),
.clk (rfClk),
.rst (rfRst)
);
assign lb_ds.clk = rfClk;
assign lb_ds.rst = rfRst;
////////////////////////////////////////////////////////////////////////////
// DUT
////////////////////////////////////////////////////////////////////////////
model_runner # (
.ADDRESS (0)
) dut_inst (
.clk (rfClk),
.rst (rfRst),
// Local bus interface
.lb_us (lb_ds)
);
////////////////////////////////////////////////////////////////////////////
// Driving Process
////////////////////////////////////////////////////////////////////////////
task run();
$display("Starting Simulation");
#10
@(posedge lb_ds.clk);
$display("Configuring Interface");
lb_write(32'h00000001, 1, lb_ds);
#10
$stop();
endtask
endmodule
但是我找不到一种方法来编写那个不仅给我错误的任务。
在这里,结构和任务位于基于 OP 的测试平台中。
有两个问题阻止了 OP 任务的编译;一个测试台,一个任务定义(除了缺失的模型和包)。
问题已更正并评论 **** issue **** inline below.
第二期是 OP 评论中提到的那个。
测试平台:
module tb ( );
// def of packed struct
typedef struct packed {
logic clk;
logic rst;
logic [31:0] addr;
logic read;
logic write;
logic [31:0] write_data;
logic [31:0] read_data;
logic read_data_valid;
} sv_lb_type ;
// clk & reset
bit rfClk;
bit rfRst;
// **** issue #1 remove 'wire' ****
sv_lb_type lb_ds;
// clk
always #5 rfClk = ! rfClk;
// task def
task automatic lb_write(
input [31:0] writeAddr,
input [31:0] writeData,
// **** issue #2 wrong syntax ****
ref sv_lb_type lb);
// task body
while (lb.rst != 1'b0) begin
@(posedge lb.clk);
$display("Waiting for LB reset to be deasserted");
end
@(posedge lb.clk);
lb.read = 1'b1;
lb.write = 1'b0;
lb.addr = writeAddr;
lb.write_data = writeData;
@(posedge lb.clk);
lb.read = 1'b0;
lb.write = 1'b0;
lb.addr = '0;
lb.write_data = '0;
@(posedge lb.clk);
$display("COmpleting task");
endtask
assign lb_ds.clk = rfClk;
assign lb_ds.rst = rfRst;
// control
initial begin
$monitor("time = %0t, lb_ds.addr = %h, lb_ds.write_data = %h, lb_ds.read = %h",
$time, lb_ds.addr, lb_ds.write_data, lb_ds.read);
#20;
lb_write(32'h00000001, 1, lb_ds);
#20;
$finish;
end
// reset
initial begin
rfRst = 1;
#30;
rfRst = 0;
end
endmodule
出品:
# run -all
# time = 0, lb_ds.addr = xxxxxxxx, lb_ds.write_data = xxxxxxxx, lb_ds.read = x
# Waiting for LB reset to be deasserted
# Waiting for LB reset to be deasserted
# time = 45, lb_ds.addr = 00000001, lb_ds.write_data = 00000001, lb_ds.read = 1
# time = 55, lb_ds.addr = 00000000, lb_ds.write_data = 00000000, lb_ds.read = 0
# COmpleting task
# ** Note: $finish : testbench.sv(60)