verilator/test_regress/t/t_interface_modport_hier.v

138 lines
4.0 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Leela Pakanati
// SPDX-License-Identifier: CC0-1.0
// Test for Issue #5941 and #2656: Modport interface field access via hierarchy
// Tests:
// - Single-level and deep hierarchical access
// - Multiple interface instances (same modport type, different data)
// - Interface arrays
interface bus_if (input logic clk);
logic [7:0] data;
modport slave (output data, input clk);
endinterface
// l1 module with the actual logic
module l1_mod (bus_if.slave bus);
always_ff @(posedge bus.clk)
bus.data <= 8'h5A;
endmodule
// l0 module wrapping l1 module
module l0_mod (bus_if.slave bus);
l1_mod l1_inst (bus);
endmodule
// Modules for testing multiple instances with same modport
module mod_aa (bus_if.slave bus);
assign bus.data = 8'hAA;
endmodule
module mod_bb (bus_if.slave bus);
assign bus.data = 8'hBB;
endmodule
// Module for testing interface arrays
module array_mod (bus_if.slave bus[2]);
always_ff @(posedge bus[0].clk) begin
bus[0].data <= 8'hA0;
bus[1].data <= 8'hA1;
end
endmodule
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc = 0;
// Deep hierarchy test
bus_if bus (clk);
l0_mod l0_inst (bus);
// Multiple instances test
bus_if bus_a (clk);
bus_if bus_b (clk);
mod_aa inst_aa (bus_a);
mod_bb inst_bb (bus_b);
// Array test
bus_if bus_arr[2] (clk);
array_mod array_inst (bus_arr);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
// === Deep hierarchy tests ===
$display("bus.data = %h (direct)", bus.data);
$display("l0_inst.bus.data = %h (single-level)", l0_inst.bus.data);
$display("l0_inst.l1_inst.bus.data = %h (deep)", l0_inst.l1_inst.bus.data);
if (bus.data !== 8'h5A) begin
$display("%%Error: bus.data = %h, expected 5A", bus.data);
$stop;
end
if (l0_inst.bus.data !== 8'h5A) begin
$display("%%Error: l0_inst.bus.data = %h, expected 5A", l0_inst.bus.data);
$stop;
end
if (l0_inst.l1_inst.bus.data !== 8'h5A) begin
$display("%%Error: l0_inst.l1_inst.bus.data = %h, expected 5A", l0_inst.l1_inst.bus.data);
$stop;
end
if (l0_inst.bus.clk !== clk) begin
$display("%%Error: l0_inst.bus.clk mismatch");
$stop;
end
if (l0_inst.l1_inst.bus.clk !== clk) begin
$display("%%Error: l0_inst.l1_inst.bus.clk mismatch");
$stop;
end
// === Multiple instances tests (bug #2656) ===
$display("inst_aa.bus.data = %h", inst_aa.bus.data);
$display("inst_bb.bus.data = %h", inst_bb.bus.data);
if (inst_aa.bus.data !== 8'hAA) begin
$display("%%Error: inst_aa.bus.data = %h, expected AA", inst_aa.bus.data);
$stop;
end
if (inst_bb.bus.data !== 8'hBB) begin
$display("%%Error: inst_bb.bus.data = %h, expected BB", inst_bb.bus.data);
$stop;
end
// === Interface array tests (bug #2656) ===
$display("bus_arr[0].data = %h (direct)", bus_arr[0].data);
$display("bus_arr[1].data = %h (direct)", bus_arr[1].data);
$display("array_inst.bus[0].data = %h (hierarchical)", array_inst.bus[0].data);
$display("array_inst.bus[1].data = %h (hierarchical)", array_inst.bus[1].data);
if (bus_arr[0].data !== 8'hA0) begin
$display("%%Error: bus_arr[0].data = %h, expected A0", bus_arr[0].data);
$stop;
end
if (bus_arr[1].data !== 8'hA1) begin
$display("%%Error: bus_arr[1].data = %h, expected A1", bus_arr[1].data);
$stop;
end
if (array_inst.bus[0].data !== 8'hA0) begin
$display("%%Error: array_inst.bus[0].data = %h, expected A0", array_inst.bus[0].data);
$stop;
end
if (array_inst.bus[1].data !== 8'hA1) begin
$display("%%Error: array_inst.bus[1].data = %h, expected A1", array_inst.bus[1].data);
$stop;
end
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule