61 lines
1.7 KiB
Systemverilog
61 lines
1.7 KiB
Systemverilog
// DESCRIPTION: Verilator: Hierarchical interface pass-through with FUNCREF LPARAMs
|
|
//
|
|
// 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
|
|
|
|
// 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
|
|
|
|
package pkg;
|
|
function automatic int decode_width(int value);
|
|
return (value > 0) ? value * 2 : 0;
|
|
endfunction
|
|
endpackage
|
|
|
|
interface ifc #(
|
|
parameter int WIDTH = 8
|
|
);
|
|
localparam int DEPTH = $clog2(WIDTH);
|
|
localparam int DECODED = pkg::decode_width(DEPTH);
|
|
endinterface
|
|
|
|
// Leaf module: uses interface LPARAM in a FUNCREF-based localparam
|
|
module leaf (
|
|
ifc i
|
|
);
|
|
localparam int BUF_SIZE = pkg::decode_width(i.DEPTH);
|
|
localparam int OUT_W = i.DECODED + 1;
|
|
endmodule
|
|
|
|
// Intermediate wrapper: passes interface through to leaf
|
|
module wrapper (
|
|
ifc i
|
|
);
|
|
leaf u_leaf (.i);
|
|
endmodule
|
|
|
|
// Second level wrapper: adds another layer of hierarchy
|
|
module subsystem (
|
|
ifc bus
|
|
);
|
|
wrapper u_wrap (.i(bus));
|
|
endmodule
|
|
|
|
module t;
|
|
ifc #(.WIDTH(64)) bus ();
|
|
subsystem u_sub (.bus);
|
|
|
|
initial begin
|
|
// WIDTH=64, DEPTH=$clog2(64)=6, DECODED=decode_width(6)=12
|
|
`checkd(u_sub.u_wrap.u_leaf.BUF_SIZE, 12); // decode_width(6) = 12
|
|
`checkd(u_sub.u_wrap.u_leaf.OUT_W, 13); // 12 + 1 = 13
|
|
$write("*-* All Finished *-*\n");
|
|
$finish;
|
|
end
|
|
endmodule
|