128 lines
4.1 KiB
Systemverilog
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
|