mirror of
https://github.com/verilator/verilator.git
synced 2025-01-21 05:44:03 +00:00
222 lines
7.1 KiB
Systemverilog
222 lines
7.1 KiB
Systemverilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
|
// any use, without warranty, 2024 by Paul Wright.
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
// A submodule to ensure that __en and __out propagate upwards
|
|
module
|
|
t_sub_io
|
|
(
|
|
inout my_io,
|
|
input drv_en,
|
|
input op_val
|
|
);
|
|
|
|
timeunit 1ns;
|
|
timeprecision 1ps;
|
|
|
|
assign my_io = drv_en ? op_val : 1'bz;
|
|
|
|
endmodule
|
|
|
|
`ifndef T_TRI_TOP_NAME
|
|
`define T_TRI_TOP_NAME t_tri_top_en_out
|
|
`endif
|
|
|
|
// The top module
|
|
// __en and __out should be added for the inout ports
|
|
module
|
|
`T_TRI_TOP_NAME
|
|
(
|
|
inout single_bit_io,
|
|
inout bidir_single_bit_io,
|
|
inout [63:0] bus_64_io,
|
|
inout [63:0] bidir_bus_64_io,
|
|
inout [127:0] bus_128_io,
|
|
inout [127:0] bidir_bus_128_io,
|
|
input [3:0] drv_en,
|
|
input test_en,
|
|
output logic loop_done,
|
|
inout sub_io
|
|
);
|
|
|
|
timeunit 1ns;
|
|
timeprecision 1ps;
|
|
|
|
bit rand_bit;
|
|
|
|
assign single_bit_io = 1'bz;
|
|
assign bidir_single_bit_io = drv_en[0] ? rand_bit : 1'bz;
|
|
assign bus_64_io = {64{1'bz}};
|
|
|
|
assign bidir_bus_64_io[15:0] = drv_en[0] ? {16{rand_bit}} : {16{1'bz}};
|
|
assign bidir_bus_64_io[31:16] = drv_en[1] ? {16{rand_bit}} : {16{1'bz}};
|
|
assign bidir_bus_64_io[47:32] = drv_en[2] ? {16{rand_bit}} : {16{1'bz}};
|
|
assign bidir_bus_64_io[63:48] = drv_en[3] ? {16{rand_bit}} : {16{1'bz}};
|
|
|
|
assign bus_128_io = {128{1'bz}};
|
|
|
|
assign bidir_bus_128_io[31:0] = drv_en[0] ? {32{rand_bit}} : {32{1'bz}};
|
|
assign bidir_bus_128_io[63:32] = drv_en[1] ? {32{rand_bit}} : {32{1'bz}};
|
|
assign bidir_bus_128_io[95:64] = drv_en[2] ? {32{rand_bit}} : {32{1'bz}};
|
|
assign bidir_bus_128_io[127:96] = drv_en[3] ? {32{rand_bit}} : {32{1'bz}};
|
|
|
|
int loop_cnt;
|
|
int error_cnt;
|
|
|
|
initial begin : init_error
|
|
error_cnt = 'd0;
|
|
end
|
|
|
|
initial begin : test_and_loop
|
|
loop_cnt = 0;
|
|
#(1ps);
|
|
while (test_en == 1) begin
|
|
loop_done = 0;
|
|
rand_bit = (($urandom_range(1,0) & 'd1) == 'd1);
|
|
chk_sigs;
|
|
#(1ns) $display("Info:(v): 1ns");
|
|
rand_bit = ~rand_bit;
|
|
chk_sigs;
|
|
#(1ns) $display("Info:(v): 2ns");
|
|
rand_bit = ~rand_bit;
|
|
chk_sigs;
|
|
#(1ns);
|
|
loop_done = 1;
|
|
loop_cnt++;
|
|
#(1ps);
|
|
end
|
|
if (error_cnt == 'd0) begin
|
|
$display("Info:(v): Error count was = %0d", error_cnt);
|
|
$write("*-* All Finished *-*\n");
|
|
end
|
|
else begin
|
|
$display("Info:(v): Error count was non-zero %0d", error_cnt);
|
|
end
|
|
$finish(1);
|
|
end
|
|
|
|
always @(loop_cnt)
|
|
begin
|
|
if (loop_cnt > 32) begin
|
|
$display("%%Error:(v): Excessive loop count");
|
|
$display("drv_en = %b, test_en = %b", drv_en, test_en);
|
|
$finish(1);
|
|
end
|
|
end
|
|
|
|
final begin
|
|
$display("Info:(v): All done at %t", $time);
|
|
$display("Info:(v): Error count = %0d", error_cnt);
|
|
chk_err: assert(error_cnt == 0);
|
|
end
|
|
|
|
wire internal_sub_io;
|
|
|
|
logic [15:0] my_64_segment;
|
|
logic [31:0] my_128_segment;
|
|
|
|
task chk_sigs;
|
|
begin
|
|
#(1ps);
|
|
$display("Info:(v): rand_bit = %b", rand_bit);
|
|
if (|drv_en) begin
|
|
$display("Info:(v): drv_en = %b", drv_en);
|
|
$display("Info:(v): bidir_single_bit_io = %b", bidir_single_bit_io);
|
|
$display("Info:(v): bidir_bus_64_io = %b,%b,%b,%b",
|
|
bidir_bus_64_io[63:48], bidir_bus_64_io[47:32],
|
|
bidir_bus_64_io[31:16],bidir_bus_64_io[15:0]);
|
|
$display("Info:(v): bidir_bus_128_io = %b,%b,%b,%b",
|
|
bidir_bus_128_io[127:96], bidir_bus_128_io[95:64],
|
|
bidir_bus_128_io[63:32], bidir_bus_128_io[31:0]);
|
|
|
|
for (int i=0;i<4;i++) begin
|
|
if (drv_en[0]) begin
|
|
if (bidir_single_bit_io !== rand_bit) begin
|
|
$display("%%Error:(v): bidir_single_bit_io is wrong (expect %b got %b)",
|
|
rand_bit, bidir_single_bit_io);
|
|
error_cnt++;
|
|
end
|
|
if (sub_io !== rand_bit) begin
|
|
$display("%%Error:(v): sub_io is wrong (expect %b, got %b)",
|
|
rand_bit, sub_io);
|
|
end
|
|
end
|
|
|
|
if (drv_en[1]) begin
|
|
if (internal_sub_io !== ~rand_bit) begin
|
|
$display("%%Error:(v): sub_io is wrong");
|
|
error_cnt++;
|
|
end
|
|
end
|
|
|
|
if (drv_en[i]) begin
|
|
int msb, lsb;
|
|
msb = ((i+1)*16-1);
|
|
lsb = i*16;
|
|
|
|
case(i)
|
|
'd0: my_64_segment = bidir_bus_64_io[15:0];
|
|
'd1: my_64_segment = bidir_bus_64_io[31:16];
|
|
'd2: my_64_segment = bidir_bus_64_io[47:32];
|
|
default: my_64_segment = bidir_bus_64_io[63:48];
|
|
endcase
|
|
|
|
case(i)
|
|
'd0: my_128_segment = bidir_bus_128_io[31:0];
|
|
'd1: my_128_segment = bidir_bus_128_io[63:32];
|
|
'd2: my_128_segment = bidir_bus_128_io[95:64];
|
|
default: my_128_segment = bidir_bus_128_io[127:96];
|
|
endcase
|
|
|
|
if (my_64_segment !== {16{rand_bit}}) begin
|
|
$display("%%Error:(v): bidir_bus_64_io is wrong");
|
|
$display("Error:(v): Should be bidir_bus_64_io[%0d:%0d] = %b, was = %b",
|
|
msb, lsb, {16{rand_bit}}, my_64_segment);
|
|
error_cnt++;
|
|
end
|
|
else begin
|
|
$display("Info:(v): Pass: bidir_bus_64_io[%0d:%0d] = %b",
|
|
msb, lsb, {16{rand_bit}});
|
|
end
|
|
|
|
msb = ((i+1)*32-1);
|
|
lsb = i*32;
|
|
if (my_128_segment !== {32{rand_bit}}) begin
|
|
$display("%%Error:(v): bidir_bus_128_io is wrong");
|
|
$display("Error:(v):Should be bidir_bus_128_io[%0d:%0d] = %b, was = %b",
|
|
msb, lsb, {32{rand_bit}}, my_128_segment);
|
|
error_cnt++;
|
|
end
|
|
else
|
|
begin
|
|
$display("Info:(v): Pass: bidir_bus_128_io[%0d:%0d] = %b",
|
|
msb, lsb, {32{rand_bit}});
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endtask
|
|
|
|
// Connects to top level
|
|
t_sub_io
|
|
t_sub_io
|
|
(
|
|
.my_io (sub_io),
|
|
.drv_en (drv_en[0]),
|
|
.op_val (rand_bit)
|
|
);
|
|
|
|
// Does not connect to top-level
|
|
t_sub_io
|
|
t_sub_io_internal
|
|
(
|
|
.my_io (internal_sub_io),
|
|
.drv_en (drv_en[1]),
|
|
.op_val (~rand_bit)
|
|
);
|
|
|
|
endmodule
|