verilator/test_regress/t/t_paramgraph_comined_iface.v

128 lines
4.1 KiB
Systemverilog

// This program is free software; you can redistribute it and/or modify it
// under the terms of either the GNU Lesser General Public License Version 3
// or the Perl Artistic License Version 2.0.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
// DESCRIPTION: Verilator: TRULY BLENDED test for interface typedef resolution
// This test BLENDS both patterns into a single interacting structure:
// - Sibling cells (like t_lparam_dep_iface10)
// - Nested interface chains (like aerial_wrap)
// - COMBINED: Sibling cells that EACH contain nested interface chains
//
// The key test: A module accesses typedefs from TWO sibling nested interface
// chains, and each must resolve to the correct parameterized type.
//
// 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
typedef struct packed {
int unsigned AddrBits;
int unsigned DataBits;
int unsigned IdBits;
} axi_cfg_t;
// INNERMOST: Parameterized interface with typedefs
interface axi4_if #(
parameter axi_cfg_t cfg = 0
) ();
localparam int unsigned AddrBits = cfg.AddrBits * 2;
localparam int unsigned DataBits = cfg.DataBits * 2;
localparam int unsigned IdBits = cfg.IdBits * 2;
typedef logic [AddrBits-1:0] addr_t;
typedef logic [DataBits-1:0] data_t;
typedef logic [IdBits-1:0] id_t;
typedef struct packed {
id_t id;
addr_t addr;
} ar_chan_t;
typedef struct packed {
id_t id;
data_t data;
} r_chan_t;
ar_chan_t ar;
r_chan_t r;
endinterface
// MIDDLE: Interface that wraps axi4_if and re-exports its typedefs
interface tlb_io_if #(
parameter axi_cfg_t axi_cfg = 0
) ();
axi4_if #(.cfg(axi_cfg)) axi_tlb_io ();
// Re-export typedefs from nested interface
typedef axi_tlb_io.r_chan_t r_chan_t;
typedef axi_tlb_io.ar_chan_t ar_chan_t;
endinterface
// OUTER: Interface with TWO SIBLING tlb_io_if instances with DIFFERENT params
// This is the BLENDED pattern: sibling cells + nested chains
interface cca_io_if #(
parameter axi_cfg_t axi_cfg_a = 0,
parameter axi_cfg_t axi_cfg_b = 0
) ();
// SIBLING CELLS - same interface type, DIFFERENT params
tlb_io_if #(.axi_cfg(axi_cfg_a)) tlb_io_a ();
tlb_io_if #(.axi_cfg(axi_cfg_b)) tlb_io_b ();
// Re-export from each sibling (these should be DIFFERENT types)
typedef tlb_io_a.r_chan_t r_chan_a_t;
typedef tlb_io_b.r_chan_t r_chan_b_t;
endinterface
// MODULE: Accesses typedefs from BOTH sibling nested chains via interface port
// This is the CRITICAL test - must distinguish between tlb_io_a and tlb_io_b
module cca_xbar (
cca_io_if cca_io
);
// Access typedefs through SIBLING nested interface chains
// These MUST resolve to DIFFERENT types based on the different params
typedef cca_io.tlb_io_a.r_chan_t m_r_chan_a_t; // From axi_cfg_a
typedef cca_io.tlb_io_b.r_chan_t m_r_chan_b_t; // From axi_cfg_b
typedef cca_io.tlb_io_a.ar_chan_t m_ar_chan_a_t;
typedef cca_io.tlb_io_b.ar_chan_t m_ar_chan_b_t;
m_r_chan_a_t r_data_a;
m_r_chan_b_t r_data_b;
initial begin
#1;
// axi_cfg_a: AddrBits=32, DataBits=64, IdBits=4
// r_chan_t = id(4) + data(64) = 68 bits * 2 = 136 bits
// ar_chan_t = id(4) + addr(32) = 36 bits * 2 = 72 bits
`checkd($bits(m_r_chan_a_t), 136);
`checkd($bits(m_ar_chan_a_t), 72);
// axi_cfg_b: AddrBits=40, DataBits=128, IdBits=8
// r_chan_t = id(8) + data(128) = 136 bits * 2 = 272 bits
// ar_chan_t = id(8) + addr(40) = 48 bits * 2 = 96 bits
`checkd($bits(m_r_chan_b_t), 272);
`checkd($bits(m_ar_chan_b_t), 96);
end
endmodule
// TOP MODULE
module t;
localparam axi_cfg_t cfg_a = '{AddrBits: 32, DataBits: 64, IdBits: 4};
localparam axi_cfg_t cfg_b = '{AddrBits: 40, DataBits: 128, IdBits: 8};
cca_io_if #(
.axi_cfg_a(cfg_a),
.axi_cfg_b(cfg_b)
) cca_io ();
cca_xbar xbar (.cca_io(cca_io));
initial begin
#2;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule