189 lines
5.5 KiB
Systemverilog
189 lines
5.5 KiB
Systemverilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
|
// SPDX-FileCopyrightText: 2006 Wilson Snyder
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
module t (
|
|
input clk
|
|
);
|
|
|
|
// verilator lint_off MULTIDRIVEN
|
|
|
|
wire [31:0] outb0c0;
|
|
wire [31:0] outb0c1;
|
|
wire [31:0] outb1c0;
|
|
wire [31:0] outb1c1;
|
|
|
|
reg [7:0] lclmem[7:0];
|
|
|
|
ma ma0 (
|
|
.outb0c0(outb0c0),
|
|
.outb0c1(outb0c1),
|
|
.outb1c0(outb1c0),
|
|
.outb1c1(outb1c1)
|
|
);
|
|
|
|
global_mod #(32'hf00d) global_cell ();
|
|
global_mod #(32'hf22d) global_cell2 ();
|
|
|
|
integer cyc = 1;
|
|
always @(posedge clk) begin
|
|
cyc <= cyc + 1;
|
|
`ifdef TEST_VERBOSE
|
|
$write("[%0t] cyc%0d: %0x %0x %0x %0x\n", $time, cyc, outb0c0, outb0c1, outb1c0, outb1c1);
|
|
`endif
|
|
if (cyc == 2) begin
|
|
if (global_cell.globali != 32'hf00d) $stop;
|
|
if (global_cell2.globali != 32'hf22d) $stop;
|
|
if ($root.t.global_cell.globali != 32'hf00d) $stop;
|
|
if ($root.t.global_cell2.globali != 32'hf22d) $stop;
|
|
if (outb0c0 != 32'h00) $stop;
|
|
if (outb0c1 != 32'h01) $stop;
|
|
if (outb1c0 != 32'h10) $stop;
|
|
if (outb1c1 != 32'h11) $stop;
|
|
end
|
|
if (cyc == 3) begin
|
|
// Can we scope down and read and write vars?
|
|
ma0.mb0.mc0.out <= ma0.mb0.mc0.out + 32'h100;
|
|
ma0.mb0.mc1.out <= ma0.mb0.mc1.out + 32'h100;
|
|
ma0.mb1.mc0.out <= ma0.mb1.mc0.out + 32'h100;
|
|
ma0.mb1.mc1.out <= ma0.mb1.mc1.out + 32'h100;
|
|
end
|
|
if (cyc == 4) begin
|
|
// Can we do dotted's inside array sels?
|
|
ma0.rmtmem[ma0.mb0.mc0.out[2:0]] = 8'h12;
|
|
lclmem[ma0.mb0.mc0.out[2:0]] = 8'h24;
|
|
if (outb0c0 != 32'h100) $stop;
|
|
if (outb0c1 != 32'h101) $stop;
|
|
if (outb1c0 != 32'h110) $stop;
|
|
if (outb1c1 != 32'h111) $stop;
|
|
end
|
|
if (cyc == 5) begin
|
|
if (ma0.rmtmem[ma0.mb0.mc0.out[2:0]] != 8'h12) $stop;
|
|
if (lclmem[ma0.mb0.mc0.out[2:0]] != 8'h24) $stop;
|
|
if (outb0c0 != 32'h1100) $stop;
|
|
if (outb0c1 != 32'h2101) $stop;
|
|
if (outb1c0 != 32'h2110) $stop;
|
|
if (outb1c1 != 32'h3111) $stop;
|
|
end
|
|
if (cyc == 6) begin
|
|
if (outb0c0 != 32'h31100) $stop;
|
|
if (outb0c1 != 32'h02101) $stop;
|
|
if (outb1c0 != 32'h42110) $stop;
|
|
if (outb1c1 != 32'h03111) $stop;
|
|
end
|
|
if (cyc == 9) begin
|
|
$write("*-* All Finished *-*\n");
|
|
$finish;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
`ifdef USE_INLINE_MID
|
|
`define INLINE_MODULE /*verilator inline_module*/
|
|
`define INLINE_MID_MODULE /*verilator no_inline_module*/
|
|
`else
|
|
`ifdef USE_INLINE
|
|
`define INLINE_MODULE /*verilator inline_module*/
|
|
`define INLINE_MID_MODULE /*verilator inline_module*/
|
|
`else
|
|
`define INLINE_MODULE /*verilator public_module*/
|
|
`define INLINE_MID_MODULE /*verilator public_module*/
|
|
`endif
|
|
`endif
|
|
|
|
module global_mod;
|
|
`INLINE_MODULE
|
|
parameter INITVAL = 0;
|
|
integer globali;
|
|
initial globali = INITVAL;
|
|
endmodule
|
|
|
|
module ma (
|
|
output wire [31:0] outb0c0,
|
|
output wire [31:0] outb0c1,
|
|
output wire [31:0] outb1c0,
|
|
output wire [31:0] outb1c1
|
|
);
|
|
`INLINE_MODULE
|
|
|
|
reg [7:0] rmtmem[7:0];
|
|
|
|
mb #(0) mb0 (
|
|
.outc0(outb0c0),
|
|
.outc1(outb0c1)
|
|
);
|
|
mb #(1) mb1 (
|
|
.outc0(outb1c0),
|
|
.outc1(outb1c1)
|
|
);
|
|
endmodule
|
|
|
|
module mb (
|
|
output wire [31:0] outc0,
|
|
output wire [31:0] outc1
|
|
);
|
|
`INLINE_MID_MODULE
|
|
parameter P2 = 0;
|
|
mc #(P2, 0) mc0 (.out(outc0));
|
|
mc #(P2, 1) mc1 (.out(outc1));
|
|
global_mod #(32'hf33d) global_cell2 ();
|
|
|
|
wire reach_up_clk = t.clk;
|
|
always @(reach_up_clk) begin
|
|
if (P2 == 0) begin // Only for mb0
|
|
// verilog_format: off
|
|
if (outc0 !== t.ma0.mb0.mc0.out) $stop; // Top module name and lower instances
|
|
if (outc0 !== ma0.mb0.mc0.out) $stop; // Upper module name and lower instances
|
|
if (outc0 !== ma .mb0.mc0.out) $stop; // Upper module name and lower instances
|
|
if (outc0 !== mb.mc0.out) $stop; // This module name and lower instances
|
|
if (outc0 !== mb0.mc0.out) $stop; // Upper instance name and lower instances
|
|
if (outc0 !== mc0.out) $stop; // Lower instances
|
|
|
|
if (outc1 !== t.ma0.mb0.mc1.out) $stop; // Top module name and lower instances
|
|
if (outc1 !== ma0.mb0.mc1.out) $stop; // Upper module name and lower instances
|
|
if (outc1 !== ma .mb0.mc1.out) $stop; // Upper module name and lower instances
|
|
if (outc1 !== mb.mc1.out) $stop; // This module name and lower instances
|
|
if (outc1 !== mb0.mc1.out) $stop; // Upper instance name and lower instances
|
|
if (outc1 !== mc1.out) $stop; // Lower instances
|
|
// verilog_format: on
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
module mc (
|
|
output reg [31:0] out
|
|
);
|
|
`INLINE_MODULE
|
|
parameter P2 = 0;
|
|
parameter P3 = 0;
|
|
initial begin
|
|
out = {24'h0, P2[3:0], P3[3:0]};
|
|
//$write("%m P2=%0x p3=%0x out=%x\n",P2, P3, out);
|
|
end
|
|
|
|
// Can we look from the top module name down?
|
|
wire [31:0] reach_up_cyc = t.cyc;
|
|
|
|
always @(posedge t.clk) begin
|
|
//$write("[%0t] %m: Got reachup, cyc=%0d\n", $time, reach_up_cyc);
|
|
if (reach_up_cyc == 2) begin
|
|
if (global_cell.globali != 32'hf00d) $stop;
|
|
if (global_cell2.globali != 32'hf33d) $stop;
|
|
end
|
|
if (reach_up_cyc == 4) begin
|
|
out[15:12] <= {P2[3:0] + P3[3:0] + 4'd1};
|
|
end
|
|
if (reach_up_cyc == 5) begin
|
|
// Can we set another instance?
|
|
if (P3 == 1) begin // Without this, there are two possible correct answers...
|
|
mc0.out[19:16] <= {mc0.out[19:16] + P2[3:0] + P3[3:0] + 4'd2};
|
|
$display("%m Set %x->%x %x %x %x %x", mc0.out, {mc0.out[19:16] + P2[3:0] + P3[3:0] + 4'd2
|
|
}, mc0.out[19:16], P2[3:0], P3[3:0], 4'd2);
|
|
end
|
|
end
|
|
end
|
|
endmodule
|