verilator/test_regress/t/t_multidriven_class.v

314 lines
5.1 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// SPDX-License-Identifier: CC0-1.0
// Consolidated class-based task/function multidriven tests
// (formerly t_multidriven_class{0,1,2,3,4,f0,f1}.v)
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
//----------------------------------------------------------------------
// class0: class task writes through ref argument (direct assignment + class task in same always_comb)
class C0;
task automatic set1(ref logic q);
q = 1'b1;
endtask
task automatic set0(ref logic q);
q = 1'b0;
endtask
endclass
module class0 #(
) (
input logic sel,
output logic val
);
logic l0;
C0 c;
initial c = new;
always_comb begin
l0 = 1'b0;
if (sel) begin
c.set1(l0);
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// class1: class task chain - nested method calls write through ref in same always_comb
class C1;
task automatic inner(inout logic q);
q = 1'b1;
endtask
task automatic outer(inout logic q);
inner(q);
endtask
endclass
module class1 #(
) (
input logic sel,
output logic val
);
logic l0;
C1 c;
initial c = new;
always_comb begin
l0 = 1'b0;
if (sel) begin
c.outer(l0);
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// class2: class handle passed through module port - class method writes through ref
class C2;
task automatic set1(ref logic q);
q = 1'b1;
endtask
endclass
module class2 #(
) (
input logic sel,
output logic val,
C2 c
);
logic l0;
always_comb begin
l0 = 1'b0;
if (sel) begin
c.set1(l0);
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// class3: static class task - call via class scope, writes through ref in same always_comb
class C3;
static task automatic set1(ref logic q);
q = 1'b1;
endtask
endclass
module class3 #(
) (
input logic sel,
output logic val
);
logic l0;
always_comb begin
l0 = 1'b0;
if (sel) begin
C3::set1(l0);
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// class4: class composition - one class calls another task, ultimately writes through ref
class C4Inner;
task automatic set1(ref logic q);
q = 1'b1;
endtask
endclass
class C4Outer;
C4Inner inner;
function new();
inner = new;
endfunction
task automatic set1(ref logic q);
inner.set1(q);
endtask
endclass
module class4 #(
) (
input logic sel,
output logic val
);
logic l0;
C4Outer c;
initial c = new;
always_comb begin
l0 = 1'b0;
if (sel) begin
c.set1(l0);
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// classf0: class function returns value - always_comb writes var directly + via class function call
class Cf0;
function automatic logic ret1();
return 1'b1;
endfunction
endclass
module classf0 #(
) (
input logic sel,
output logic val
);
logic l0;
Cf0 c;
initial c = new;
always_comb begin
l0 = 1'b0;
if (sel) begin
l0 = c.ret1();
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// classf1: static class function returns value - always_comb uses class scope call
class Cf1;
static function automatic logic ret1();
return 1'b1;
endfunction
endclass
module classf1 #(
) (
input logic sel,
output logic val
);
logic l0;
always_comb begin
l0 = 1'b0;
if (sel) begin
l0 = Cf1::ret1();
end
end
assign val = l0;
endmodule
//----------------------------------------------------------------------
// Shared TB
module m_tb #() ();
logic sel;
logic val0, val1, val2, val3, val4, valf0, valf1;
C2 c2;
initial c2 = new;
class0 u0 (
.sel(sel),
.val(val0)
);
class1 u1 (
.sel(sel),
.val(val1)
);
class2 u2 (
.sel(sel),
.val(val2),
.c(c2)
);
class3 u3 (
.sel(sel),
.val(val3)
);
class4 u4 (
.sel(sel),
.val(val4)
);
classf0 uf0 (
.sel(sel),
.val(valf0)
);
classf1 uf1 (
.sel(sel),
.val(valf1)
);
task automatic check_all(input logic exp);
`checkd(val0, exp);
`checkd(val1, exp);
`checkd(val2, exp);
`checkd(val3, exp);
`checkd(val4, exp);
`checkd(valf0, exp);
`checkd(valf1, exp);
endtask
initial begin
#1;
sel = 'b0;
#1;
check_all(1'b0);
sel = 'b1;
#1;
check_all(1'b1);
sel = 'b0;
#1;
check_all(1'b0);
end
initial begin
#5;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule