// 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: Test nested interface typedef access
// This replicates the pattern from a much larger design that was
// failing with the localparam changes - accessing a typedef from
// a doubly-nested interface
//

// 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 cb;
  typedef struct packed {
    logic [31:0] Rids;
    logic [31:0] Pids;
    logic [31:0] Fnum;
    logic [31:0] XdatSize;
  } cfg_t;
endpackage

package a_pkg;
  typedef struct packed {
    int unsigned p_a;
    int unsigned p_b;
  } cfg_t;
endpackage

interface other_types_if #(
    parameter a_pkg::cfg_t cfg = 0
) ();
  // Create a struct that results in 525 bits
  typedef struct packed {
    logic [cfg.p_a-1:0] field1;
    logic [cfg.p_b-1:0] field2;
  } cmd_beat_t;

endinterface

// Simple interface that takes a parameter
interface simple_if #(
    parameter cb::cfg_t cfg = 0
) ();
  logic [cfg.Rids-1:0] rids;
  logic [cfg.Pids-1:0] pids;
  logic [cfg.Fnum-1:0] fnum;
  logic [cfg.XdatSize-1:0] xdat;
endinterface

module TestMod;
  localparam a_pkg::cfg_t ot_cfg = '{p_a : 8, p_b : 4};

  other_types_if #(ot_cfg) other_types ();

  typedef other_types.cmd_beat_t cmd_beat_t;

  // This pattern assignment should work correctly
  localparam cb::cfg_t cb_cfg = '{
      Rids : 32'h1,
      Pids : 32'h2,
      Fnum : 32'h3,
      XdatSize : $bits(cmd_beat_t)
  };

  // This should trigger the error - cb_cfg is not recognized as constant
  simple_if #(cb_cfg) cb_vc0_io ();

  initial begin
    `checkd(cb_cfg.XdatSize, 12);
    $write("*-* All Finished *-*\n");
    $finish;
  end
endmodule
