// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// xbar_${xbar.name}_tb module generated by `tlgen.py` tool for smoke check
<%
  import random
%>
module xbar_${xbar.name}_tb;

  import tlul_pkg::*;

  // Clock generator
% for clock in xbar.clocks:
  localparam CLK_${clock.upper()}_PERIOD = ${random.randint(10,40)};
% endfor

% for clock in xbar.clocks:
  logic clk_${clock};
  initial begin
    clk_${clock} = 1'b0;
    forever begin
      #(CLK_${clock.upper()}_PERIOD/2)
      clk_${clock} = ~clk_${clock};
    end
  end

% endfor

  // One reset but synchronized to multiple reset
  logic rst_n ;
  initial begin
    rst_n = 1'b0;
    #117ns
    rst_n = 1'b1;
  end

% for clock in xbar.clocks:
  logic rst_${clock}_n;
  initial begin
    rst_${clock}_n = 1'b0;

    wait(rst_n == 1'b1);
    @(negedge clk_${clock});
    rst_${clock}_n = 1'b1;
  end

% endfor

  // Signals
% for node in xbar.hosts + xbar.devices:
  tl_h2d_t tl_${node.name}_h2d ;
  tl_d2h_t tl_${node.name}_d2h ;
% endfor

  // Instance of xbar_${xbar.name}
  xbar_${xbar.name} dut (
% for clock in xbar.clocks:
    .clk_${clock}_i   (clk_${clock}),
    .rst_${clock}_ni  (rst_${clock}_n),
% endfor

    // Host interfaces
% for node in xbar.hosts:
    .tl_${node.name}_i  (tl_${node.name}_h2d),
    .tl_${node.name}_o  (tl_${node.name}_d2h),
% endfor

    // Device interfaces
% for node in xbar.devices:
    .tl_${node.name}_o  (tl_${node.name}_h2d),
    .tl_${node.name}_i  (tl_${node.name}_d2h),
% endfor

    .scanmode_i (1'b0)

  );

  task automatic tl_write(ref clk, ref tl_h2d_t tl_h2d, ref tl_d2h_t tl_d2h,
    input [31:0] addr, input [31:0] wdata);
    tl_h2d.a_address = addr;
    tl_h2d.a_opcode = PutFullData;
    tl_h2d.a_param = '0;
    tl_h2d.a_size = 2'h2;
    tl_h2d.a_user = '0;
    tl_h2d.a_data = wdata;
    tl_h2d.a_mask = 'hF;
    tl_h2d.a_source = 0;
    tl_h2d.a_valid = 1'b1;
    @(posedge clk iff tl_d2h.a_ready == 1'b1);
    tl_h2d.a_valid = 1'b0;
    tl_h2d.d_ready = 1'b1;
    @(posedge clk iff tl_d2h.d_valid == 1'b1);
    if (tl_d2h.d_error == 1'b1) $error("TL-UL interface error occurred");
    tl_h2d.d_ready = 1'b0;
  endtask : tl_write

  task automatic tl_read(ref clk, ref tl_h2d_t tl_h2d, ref tl_d2h_t tl_d2h,
    input [31:0] addr, output logic [31:0] rdata);
    tl_h2d.a_address = addr;
    tl_h2d.a_opcode = Get;
    tl_h2d.a_param = '0;
    tl_h2d.a_size = 2'h2;
    tl_h2d.a_user = '0;
    tl_h2d.a_source = 0;
    tl_h2d.a_valid = 1'b1;
    @(posedge clk iff tl_d2h.a_ready == 1'b1);
    tl_h2d.a_valid = 1'b0;
    tl_h2d.d_ready = 1'b1;
    @(posedge clk iff tl_d2h.d_valid == 1'b1);
    if (tl_d2h.d_error == 1'b1) $error("TL-UL interface error occurred");
    rdata = tl_d2h.d_data;
    tl_h2d.d_ready = 1'b0;
  endtask : tl_read

  task automatic tl_compare(ref clk, ref tl_h2d_t tl_h2d, ref tl_d2h_t tl_d2h,
    input [31:0] addr, input [31:0] wdata);
    automatic logic [31:0] rdata;
    tl_write(clk, tl_h2d, tl_d2h, addr, wdata);
    tl_read(clk, tl_h2d, tl_d2h, addr, rdata);
    if (wdata != rdata) $error("Addr(%x) mismatch: Exp(%x), Got(%x)", addr, wdata, rdata);
  endtask : tl_compare

  // Transaction generator
  //
  // Goal: Each host creates random sequence
  //  1. select random device
  //  2. select random burst (not implemented)
  //  3. select random address range within the device
  //  4. Write and read then compare
  //  Note: There's chance that another host updates content at the same address location when a host
  //        reads. This is unavoidable but the change is unlikely. But remind that it is possible.
  typedef struct {
    logic [31:0] addr_from;
    logic [31:0] addr_to;
  } addr_range_t;
% for host in xbar.hosts:
<%
  clkname = "clk_" + host.clocks[0]
  rstname = "rst_" + host.clocks[0] + "_n"
  num_dev = len(xbar.get_s1n_if_exist(host).ds)

  addrs = list(map(xbar.get_addr, xbar.get_devices_from_host(host)))
%>\
  addr_range_t ${host.name}_map [${num_dev}] = '{
% for addr in addrs:
% if loop.last:
    '{addr_from: 32'h${"%x"%(addr[0])}, addr_to: 32'h${"%x" %(addr[1])}}
% else:
    '{addr_from: 32'h${"%x"%(addr[0])}, addr_to: 32'h${"%x" %(addr[1])}},
% endif
% endfor
  };
  initial begin
    // Wait until reset is released
    tl_${host.name}_h2d.a_valid = 1'b0;
    tl_${host.name}_h2d.d_ready = 1'b0;
    wait(${rstname} == 1'b1);
    @(negedge ${clkname});
    forever begin
      // choose among the device
      automatic int dev_sel = $urandom_range(${num_dev-1},0);

      // determine address
      automatic logic [31:0] addr = $urandom_range(${host.name}_map[dev_sel].addr_to,
                                                   ${host.name}_map[dev_sel].addr_from);
      addr = addr & 32'h FFFF_FFFC;

      // compare
      tl_compare(${clkname}, tl_${host.name}_h2d, tl_${host.name}_d2h, addr, $urandom());
    end
  end
% endfor

  // Instantiate generic TL-UL sram
% for device in xbar.devices:
<%
  tl_h2d_sig = "tl_" + device.name + "_h2d"
  tl_d2h_sig = "tl_" + device.name + "_d2h"
%>
  device_sram u_device_${device.name} (
    .clk_i      (clk_${device.clocks[0]}),
    .tl_i       (${tl_h2d_sig}),
    .tl_o       (${tl_d2h_sig})
  );
% endfor

  initial begin
    #100us
    $finish(1);
  end
endmodule


