data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv
1: b'%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:16: Cannot find include file: tb.svh\n`include "tb.svh" \n         ^~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl,data/full_repos/permissive/509468557/tb.svh\n             data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl,data/full_repos/permissive/509468557/tb.svh.v\n             data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl,data/full_repos/permissive/509468557/tb.svh.sv\n             tb.svh\n             tb.svh.v\n             tb.svh.sv\n             obj_dir/tb.svh\n             obj_dir/tb.svh.v\n             obj_dir/tb.svh.sv\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:17: Cannot find include file: assign.svh\n`include "assign.svh" \n         ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:19: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER\nmodule tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()();\n                 ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:57: syntax error, unexpected TIME NUMBER, expecting TYPE-IDENTIFIER\n  parameter time          TbApplTime         = 2ns;\n                                               ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:59: syntax error, unexpected TIME NUMBER, expecting TYPE-IDENTIFIER\n  parameter time          TbTestTime         = 8ns;\n                                               ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:70: syntax error, unexpected IDENTIFIER\n  amo_req_t                       amo_req_i;\n  ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:86: syntax error, unexpected IDENTIFIER\n  seq_t [2:0] seq_type;\n  ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:123: syntax error, unexpected IDENTIFIER\n  AXI_BUS_DV #(\n  ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:141: Define or directive not defined: \'`AXI_ASSIGN_FROM_REQ\'\n  `AXI_ASSIGN_FROM_REQ(axi_data_dv, axi_data_o)\n  ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:142: Define or directive not defined: \'`AXI_ASSIGN_TO_RESP\'\n  `AXI_ASSIGN_TO_RESP(axi_data_i, axi_data_dv)\n  ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:143: Define or directive not defined: \'`AXI_ASSIGN_FROM_REQ\'\n  `AXI_ASSIGN_FROM_REQ(axi_bypass_dv, axi_bypass_o)\n  ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:144: Define or directive not defined: \'`AXI_ASSIGN_TO_RESP\'\n  `AXI_ASSIGN_TO_RESP(axi_bypass_i, axi_bypass_dv)\n  ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:176: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:176: syntax error, unexpected \',\'\n    `APPL_WAIT_CYC(clk_i, 1)\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:178: Define or directive not defined: \'`APPL_WAIT_SIG\'\n    `APPL_WAIT_SIG(clk_i, &seq_done)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:178: syntax error, unexpected \',\'\n    `APPL_WAIT_SIG(clk_i, &seq_done)\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:179: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:189: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:189: syntax error, unexpected \',\'\n    `APPL_WAIT_CYC(clk_i, 1)\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:191: Define or directive not defined: \'`APPL_WAIT_SIG\'\n    `APPL_WAIT_SIG(clk_i, &seq_done)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:191: syntax error, unexpected \',\'\n    `APPL_WAIT_SIG(clk_i, &seq_done)\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:192: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:198: Define or directive not defined: \'`APPL_WAIT_SIG\'\n    `APPL_WAIT_SIG(clk_i, flush_ack_o);\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:198: syntax error, unexpected \',\'\n    `APPL_WAIT_SIG(clk_i, flush_ack_o);\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:200: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:200: syntax error, unexpected \',\'\n    `APPL_WAIT_CYC(clk_i, 1)\n                        ^\n%Warning-STMTDLY: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:210: Unsupported: Ignoring delay on this delayed statement.\n        clk_i = 1; #(CLK_HI);\n                   ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-STMTDLY: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:211: Unsupported: Ignoring delay on this delayed statement.\n        clk_i = 0; #(CLK_LO);\n                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:212: syntax error, unexpected end\n      end while (end_of_sim == 1\'b0);\n      ^~~\n%Warning-STMTDLY: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:216: Unsupported: Ignoring delay on this delayed statement.\n        clk_i = 1; #(CLK_HI);\n                   ^\n%Warning-STMTDLY: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:217: Unsupported: Ignoring delay on this delayed statement.\n        clk_i = 0; #(CLK_LO);\n                   ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:219: syntax error, unexpected end\n    end\n    ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:233: Define or directive not defined: \'`APPL_WAIT_SIG\'\n    `APPL_WAIT_SIG(clk_i, ~rst_ni)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:233: syntax error, unexpected \',\'\n    `APPL_WAIT_SIG(clk_i, ~rst_ni)\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:234: Define or directive not defined: \'`APPL_WAIT_CYC\'\n    `APPL_WAIT_CYC(clk_i, 1)\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:238: Define or directive not defined: \'`ACQ_WAIT_CYC\'\n      `ACQ_WAIT_CYC(clk_i, 1)\n      ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:238: syntax error, unexpected \',\'\n      `ACQ_WAIT_CYC(clk_i, 1)\n                         ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:242: syntax error, unexpected \';\'\n        for(int k=0; k<8; k++) begin\n                        ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:242: syntax error, unexpected \')\', expecting \';\'\n        for(int k=0; k<8; k++) begin\n                             ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:267: syntax error, unexpected end\n        end else begin\n        ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:279: syntax error, unexpected end\n        end\n        ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:291: syntax error, unexpected end\n          end\n          ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:301: syntax error, unexpected end\n            end else begin\n            ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:304: syntax error, unexpected end\n            end\n            ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:322: syntax error, unexpected default\n          default: amo_result = amo_shadow;\n          ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:325: Define or directive not defined: \'`ACQ_WAIT_CYC\'\n        `ACQ_WAIT_CYC(clk_i,1)\n        ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:328: syntax error, unexpected \';\'\n        for (int k = 0; k < 2**amo_req_i.size; k++) begin\n                                             ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:328: syntax error, unexpected \')\', expecting \';\'\n        for (int k = 0; k < 2**amo_req_i.size; k++) begin\n                                                  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:332: Define or directive not defined: \'`ACQ_WAIT_SIG\'\n        `ACQ_WAIT_SIG(clk_i,amo_resp_o.ack)\n        ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:341: Unsupported: new with arguments\n    bypass_mem_port = new(axi_bypass_dv, BYPASS);\n                      ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:346: syntax error, unexpected ::\n    tb_mem_port_t::init_mem();\n                 ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:351: Unsupported: fork statements\n    fork\n    ^~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:355: syntax error, unexpected end\n  end\n  ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/tb/tb_wb_dcache/hdl/tb.sv:393: syntax error, unexpected generate\n  generate\n  ^~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()();


  timeunit 1ps;
  timeprecision 1ps;


  parameter MemBytes          = 2**DCACHE_INDEX_WIDTH * 4 * 32;
  parameter MemWords          = MemBytes>>3;


  parameter logic [63:0] CachedAddrBeg = MemBytes>>3;
  parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF;


  parameter MemRandHitRate   = 75;
  parameter MemRandInvRate   = 10;
  parameter TlbHitRate       = 95;


  parameter FlushRate         = 10;
  parameter KillRate          = 5;

  parameter Verbose           = 0;


  parameter nReadVectors      = 20000;
  parameter nWriteVectors     = 20000;
  parameter nAMOs             = 20000;


  parameter int unsigned  TbAxiIdWidthFull   = 32'd6;

  parameter int unsigned  TbAxiAddrWidthFull = 32'd64;

  parameter int unsigned  TbAxiDataWidthFull = 32'd64;
  localparam int unsigned TbAxiUserWidthFull = 32'd1;

  parameter time          TbApplTime         = 2ns;

  parameter time          TbTestTime         = 8ns;






  logic                           enable_i;
  logic                           flush_i;
  logic                           flush_ack_o;
  logic                           miss_o;
  amo_req_t                       amo_req_i;
  amo_resp_t                      amo_resp_o;
  dcache_req_i_t [2:0]            req_ports_i;
  dcache_req_o_t [2:0]            req_ports_o;
  ariane_axi::req_t               axi_data_o;
  ariane_axi::resp_t              axi_data_i;
  ariane_axi::req_t               axi_bypass_o;
  ariane_axi::resp_t              axi_bypass_i;





  string test_name;
  logic clk_i, rst_ni;
  logic [31:0] seq_num_resp, seq_num_write, seq_num_amo;
  seq_t [2:0] seq_type;
  logic [3:0] seq_done;
  logic [6:0] req_rate[2:0];
  logic seq_run, seq_last;
  logic end_of_sim;

  logic mem_rand_en;
  logic inv_rand_en;
  logic amo_rand_en;
  logic tlb_rand_en;

  logic write_en;
  logic [63:0] write_paddr, write_data;
  logic [7:0] write_be;

  typedef struct packed  {
    logic [1:0]  size;
    logic [63:0] paddr;
  } resp_fifo_t;

  typedef struct packed {
    logic        valid;
    logic [63:0] paddr;
  } reservation_t;

  logic [63:0] act_paddr[1:0];
  logic [63:0] exp_rdata[1:0];
  logic [63:0] exp_paddr[1:0];
  logic [63:0] amo_act_mem;
  logic [63:0] amo_shadow;
  logic [63:0] amo_exp_result;
  resp_fifo_t  fifo_data_in[1:0];
  resp_fifo_t  fifo_data[1:0];
  logic [1:0]  fifo_push, fifo_pop, fifo_flush;
  logic [2:0]  flush;
  logic        flush_rand_en;

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH ( TbAxiAddrWidthFull       ),
    .AXI_DATA_WIDTH ( TbAxiDataWidthFull       ),
    .AXI_ID_WIDTH   ( TbAxiIdWidthFull + 32'd1 ),
    .AXI_USER_WIDTH ( TbAxiUserWidthFull       )
  ) axi_data_dv (
    .clk_i ( clk_i )
  );

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH ( TbAxiAddrWidthFull       ),
    .AXI_DATA_WIDTH ( TbAxiDataWidthFull       ),
    .AXI_ID_WIDTH   ( TbAxiIdWidthFull + 32'd1 ),
    .AXI_USER_WIDTH ( TbAxiUserWidthFull       )
  ) axi_bypass_dv (
    .clk_i ( clk_i )
  );

  `AXI_ASSIGN_FROM_REQ(axi_data_dv, axi_data_o)
  `AXI_ASSIGN_TO_RESP(axi_data_i, axi_data_dv)
  `AXI_ASSIGN_FROM_REQ(axi_bypass_dv, axi_bypass_o)
  `AXI_ASSIGN_TO_RESP(axi_bypass_i, axi_bypass_dv)

  typedef tb_mem_port #(
    .AW                   ( TbAxiAddrWidthFull       ),
    .DW                   ( TbAxiDataWidthFull       ),
    .IW                   ( TbAxiIdWidthFull + 32'd1 ),
    .UW                   ( TbAxiUserWidthFull       ),
    .TA                   ( TbApplTime               ),
    .TT                   ( TbTestTime               ),
    .AX_MIN_WAIT_CYCLES   ( 0                        ),
    .AX_MAX_WAIT_CYCLES   ( 50                       ),
    .R_MIN_WAIT_CYCLES    ( 10                       ),
    .R_MAX_WAIT_CYCLES    ( 20                       ),
    .RESP_MIN_WAIT_CYCLES ( 10                       ),
    .RESP_MAX_WAIT_CYCLES ( 20                       ),
    .MEM_BYTES            ( MemBytes                 )
  ) tb_mem_port_t;

  tb_mem_port_t data_mem_port;
  tb_mem_port_t bypass_mem_port;






  task automatic runSeq(input int nReadVectors, input int nWriteVectors = 0, input logic last =1'b0);
    seq_last      = last;
    seq_run       = 1'b1;
    seq_num_resp  = nReadVectors;
    seq_num_write = nWriteVectors;
    seq_num_amo   = 0;
    `APPL_WAIT_CYC(clk_i, 1)
    seq_run      = 1'b0;
    `APPL_WAIT_SIG(clk_i, &seq_done)
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : runSeq


  task automatic runAMOs(input int nAMOs, input logic last =1'b0);
    seq_last      = last;
    seq_run       = 1'b1;
    seq_num_resp  = 0;
    seq_num_write = 0;
    seq_num_amo   = nAMOs;
    `APPL_WAIT_CYC(clk_i, 1)
    seq_run      = 1'b0;
    `APPL_WAIT_SIG(clk_i, &seq_done)
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : runAMOs


  task automatic flushCache();
    flush[2]      = 1'b1;
    `APPL_WAIT_SIG(clk_i, flush_ack_o);
    flush[2]      = 0'b0;
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : flushCache





  always @*
    begin
      do begin
        clk_i = 1; #(CLK_HI);
        clk_i = 0; #(CLK_LO);
      end while (end_of_sim == 1'b0);
      repeat (100) begin


        clk_i = 1; #(CLK_HI);
        clk_i = 0; #(CLK_LO);
      end
    end






  initial begin : p_mem
    automatic logic[63:0] amo_result, amo_op_a, amo_op_b, amo_op_a_u, amo_op_b_u;
    reservation_t reservation;


    reservation = '0;
    amo_exp_result = 'x;
    `APPL_WAIT_SIG(clk_i, ~rst_ni)
    `APPL_WAIT_CYC(clk_i, 1)

    forever begin
      amo_exp_result = 'x;
      `ACQ_WAIT_CYC(clk_i, 1)


      if(write_en) begin
        for(int k=0; k<8; k++) begin
          if(write_be[k]) begin
            tb_mem_port_t::shadow_q[write_paddr + k] <= write_data[k*8 +: 8];
          end
        end
      end



      if (amo_req_i.req) begin

        if (amo_req_i.size == 2'h2) begin

          amo_op_a   = $signed(amo_shadow[31:0]);
          amo_op_b   = $signed(amo_req_i.operand_b[31:0]);


          amo_op_a_u = $unsigned(amo_shadow[31:0]);
          amo_op_b_u = $unsigned(amo_req_i.operand_b[31:0]);



          amo_exp_result[31:0] = amo_shadow[31:0];


        end else begin

          amo_op_a   = $signed(amo_shadow);
          amo_op_b   = $signed(amo_req_i.operand_b);


          amo_op_a_u = $unsigned(amo_shadow);
          amo_op_b_u = $unsigned(amo_req_i.operand_b);



          amo_exp_result = amo_shadow;
        end


        case (amo_req_i.amo_op)

          AMO_LR: begin

            reservation.valid = 1'b1;
            reservation.paddr = amo_req_i.operand_a;


            amo_result = amo_shadow;
          end


          AMO_SC: begin

            if (reservation.valid && reservation.paddr == amo_req_i.operand_a) begin
              amo_result     = amo_op_b;
              amo_exp_result = 64'b0;


            end else begin
              amo_result     = amo_shadow;
              amo_exp_result = 64'b1;
            end


            reservation.valid = 1'b0;
          end


          AMO_SWAP: amo_result = amo_op_b;
          AMO_ADD:  amo_result = amo_op_a + amo_op_b;
          AMO_AND:  amo_result = amo_op_a & amo_op_b;
          AMO_OR:   amo_result = amo_op_a | amo_op_b;
          AMO_XOR:  amo_result = amo_op_a ^ amo_op_b;
          AMO_MAX:  amo_result = ($signed(amo_op_a) > $signed(amo_op_b)) ? amo_op_a : amo_op_b;
          AMO_MIN:  amo_result = ($signed(amo_op_a) < $signed(amo_op_b)) ? amo_op_a : amo_op_b;
          AMO_MAXU: amo_result = (amo_op_a_u > amo_op_b_u) ? amo_op_a : amo_op_b;
          AMO_MINU: amo_result = (amo_op_a_u < amo_op_b_u) ? amo_op_a : amo_op_b;


          default: amo_result = amo_shadow;
        endcase

        `ACQ_WAIT_CYC(clk_i,1)


        for (int k = 0; k < 2**amo_req_i.size; k++) begin
          tb_mem_port_t::shadow_q[amo_req_i.operand_a + k] <= amo_result[k*8 +: 8];
        end

        `ACQ_WAIT_SIG(clk_i,amo_resp_o.ack)
      end
    end
  end


  initial begin : p_sim_mem

    data_mem_port   = new(axi_data_dv  , CACHED);
    bypass_mem_port = new(axi_bypass_dv, BYPASS);


    data_mem_port.reset();
    bypass_mem_port.reset();
    tb_mem_port_t::init_mem();

    @(posedge rst_ni);


    fork
      data_mem_port.run();
      bypass_mem_port.run();
    join
  end





  std_nbdcache  #(
    .CACHE_START_ADDR ( CachedAddrBeg )
  ) i_dut (
    .clk_i           ( clk_i           ),
    .rst_ni          ( rst_ni          ),
    .flush_i         ( flush_i         ),
    .flush_ack_o     ( flush_ack_o     ),
    .enable_i        ( enable_i        ),
    .miss_o          ( miss_o          ),
    .amo_req_i       ( amo_req_i       ),
    .amo_resp_o      ( amo_resp_o      ),
    .req_ports_i     ( req_ports_i     ),
    .req_ports_o     ( req_ports_o     ),
    .axi_data_o      ( axi_data_o      ),
    .axi_data_i      ( axi_data_i      ),
    .axi_bypass_o    ( axi_bypass_o    ),
    .axi_bypass_i    ( axi_bypass_i    )
  );






  assign act_paddr[0] = (i_dut.master_ports[0].i_cache_ctrl.state_q == 4'h1) ? {i_dut.tag[1], i_dut.master_ports[0].i_cache_ctrl.mem_req_q.index} :
                        {i_dut.master_ports[0].i_cache_ctrl.mem_req_q.tag,
                         i_dut.master_ports[0].i_cache_ctrl.mem_req_q.index};
  assign act_paddr[1] = (i_dut.master_ports[1].i_cache_ctrl.state_q == 4'h1) ? {i_dut.tag[2], i_dut.master_ports[1].i_cache_ctrl.mem_req_q.index} :
                        {i_dut.master_ports[1].i_cache_ctrl.mem_req_q.tag,
                         i_dut.master_ports[1].i_cache_ctrl.mem_req_q.index};


  generate
    for(genvar k=0; k<2;k++) begin
      assign fifo_data_in[k] =  {req_ports_i[k].data_size,
                                 exp_paddr[k]};

      for (genvar l=0; l<8; l++)
        assign exp_rdata[k][l*8 +: 8] = tb_mem_port_t::shadow_q[{fifo_data[k].paddr[63:3], 3'b0} + l];

      assign fifo_push[k]  = req_ports_i[k].data_req & req_ports_o[k].data_gnt;
      assign fifo_flush[k] = req_ports_i[k].kill_req;
      assign fifo_pop[k]   = req_ports_o[k].data_rvalid & ~req_ports_i[k].kill_req;

      fifo_v3 #(
        .dtype(resp_fifo_t)
      ) i_resp_fifo (
        .clk_i       ( clk_i            ),
        .rst_ni      ( rst_ni           ),
        .flush_i     ( fifo_flush[k]    ),
        .testmode_i  ( '0               ),
        .full_o      (                  ),
        .empty_o     (                  ),
        .usage_o     (                  ),
        .data_i      ( fifo_data_in[k]  ),
        .push_i      ( fifo_push[k]     ),
        .data_o      ( fifo_data[k]     ),
        .pop_i       ( fifo_pop[k]      )
      );
    end
  endgenerate


  for (genvar k=0; k<8; k++) begin
    assign amo_act_mem[k*8 +: 8] = tb_mem_port_t::memory_q[amo_req_i.operand_a + k];
    assign amo_shadow[k*8 +: 8] = tb_mem_port_t::shadow_q[amo_req_i.operand_a + k];
  end

  tb_readport #(
    .PortName      ( "RD0"         ),
    .FlushRate     ( FlushRate     ),
    .KillRate      ( KillRate      ),
    .TlbHitRate    ( TlbHitRate    ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 5555555       ),
    .Verbose       ( Verbose       )
  ) i_tb_readport0 (
    .clk_i           ( clk_i               ),
    .rst_ni          ( rst_ni              ),
    .test_name_i     ( test_name           ),
    .req_rate_i      ( req_rate[0]         ),
    .seq_type_i      ( seq_type[0]         ),
    .tlb_rand_en_i   ( tlb_rand_en         ),
    .flush_rand_en_i ( flush_rand_en       ),
    .seq_run_i       ( seq_run             ),
    .seq_num_resp_i  ( seq_num_resp        ),
    .seq_last_i      ( seq_last            ),
    .seq_done_o      ( seq_done[0]         ),
    .exp_paddr_o     ( exp_paddr[0]        ),
    .exp_size_i      ( fifo_data[0].size   ),
    .exp_paddr_i     ( fifo_data[0].paddr  ),
    .exp_rdata_i     ( exp_rdata[0]        ),
    .act_paddr_i     ( act_paddr[0]        ),
    .flush_o         ( flush[0]            ),
    .flush_ack_i     ( flush_ack_o         ),
    .dut_req_port_o  ( req_ports_i[0]      ),
    .dut_req_port_i  ( req_ports_o[0]      )
    );

  tb_readport #(
    .PortName      ( "RD1"         ),
    .FlushRate     ( FlushRate     ),
    .KillRate      ( KillRate      ),
    .TlbHitRate    ( TlbHitRate    ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 3333333       ),
    .Verbose       ( Verbose       )
  ) i_tb_readport1 (
    .clk_i           ( clk_i               ),
    .rst_ni          ( rst_ni              ),
    .test_name_i     ( test_name           ),
    .req_rate_i      ( req_rate[1]         ),
    .seq_type_i      ( seq_type[1]         ),
    .tlb_rand_en_i   ( tlb_rand_en         ),
    .flush_rand_en_i ( flush_rand_en       ),
    .seq_run_i       ( seq_run             ),
    .seq_num_resp_i  ( seq_num_resp        ),
    .seq_last_i      ( seq_last            ),
    .exp_paddr_o     ( exp_paddr[1]        ),
    .exp_size_i      ( fifo_data[1].size   ),
    .exp_paddr_i     ( fifo_data[1].paddr  ),
    .exp_rdata_i     ( exp_rdata[1]        ),
    .act_paddr_i     ( act_paddr[1]        ),
    .seq_done_o      ( seq_done[1]         ),
    .flush_o         ( flush[1]            ),
    .flush_ack_i     ( flush_ack_o         ),
    .dut_req_port_o  ( req_ports_i[1]      ),
    .dut_req_port_i  ( req_ports_o[1]      )
  );

  tb_writeport #(
    .PortName      ( "WR0"         ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 7777777       ),
    .Verbose       ( Verbose       )
  ) i_tb_writeport (
    .clk_i          ( clk_i               ),
    .rst_ni         ( rst_ni              ),
    .test_name_i    ( test_name           ),
    .req_rate_i     ( req_rate[2]         ),
    .seq_type_i     ( seq_type[2]         ),
    .seq_run_i      ( seq_run             ),
    .seq_num_vect_i ( seq_num_write       ),
    .seq_last_i     ( seq_last            ),
    .seq_done_o     ( seq_done[2]         ),
    .dut_req_port_o ( req_ports_i[2]      ),
    .dut_req_port_i ( req_ports_o[2]      )
  );

  tb_amoport  #(
    .PortName      ("AMO0"),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 1111111       ),
    .Verbose       ( Verbose       )
  ) i_tb_amoport (
    .clk_i               ( clk_i          ),
    .rst_ni              ( rst_ni         ),
    .test_name_i         ( test_name      ),
    .seq_run_i           ( seq_run        ),
    .seq_num_amo_i       ( seq_num_amo    ),
    .seq_last_i          ( seq_last       ),
    .seq_done_o          ( seq_done[3]    ),
    .act_mem_i           ( amo_act_mem    ),
    .exp_mem_i           ( amo_shadow     ),
    .exp_result_i        ( amo_exp_result ),
    .dut_amo_req_port_o  ( amo_req_i      ),
    .dut_amo_resp_port_i ( amo_resp_o     )
  );


  initial begin
    automatic logic       write_en_n;
    automatic logic[63:0] write_paddr_n;
    automatic logic[63:0] write_data_n;
    automatic logic[7:0]  write_be_n;

    write_en_n    = '0;
    write_paddr_n = '0;
    write_data_n  = '0;
    write_be_n    = '0;

    forever begin
      `WAIT_CYC(clk_i,1)

      write_en      = write_en_n;
      write_paddr   = write_paddr_n;
      write_data    = write_data_n;
      write_be      = write_be_n;

      write_en_n    = req_ports_i[2].data_req & req_ports_o[2].data_gnt & req_ports_i[2].data_we;
      write_paddr_n = {req_ports_i[2].address_tag,  req_ports_i[2].address_index};
      write_data_n  = req_ports_i[2].data_wdata;
      write_be_n    = req_ports_i[2].data_be;
    end
  end

  assign flush_i = |flush;









  initial begin : p_stim
    test_name        = "";
    seq_type         = '{default: RANDOM_SEQ};
    req_rate         = '{default: 7'd75};
    seq_run          = 1'b0;
    seq_last         = 1'b0;
    seq_num_resp     = '0;
    seq_num_write    = '0;

    end_of_sim       = 0;
    rst_ni           = 0;

    mem_rand_en      = 0;
    tlb_rand_en      = 0;
    inv_rand_en      = 0;
    amo_rand_en      = 0;
    flush_rand_en    = 0;

    flush[2]         = 0;

    enable_i         = 0;



    $display("TB> current configuration:");
    $display("TB> MemWords        %d",   MemWords);
    $display("TB> CachedAddrBeg   %16X", CachedAddrBeg);
    $display("TB> CachedAddrEnd   %16X", CachedAddrEnd);
    $display("TB> MemRandHitRate  %d",   MemRandHitRate);
    $display("TB> MemRandInvRate  %d",   MemRandInvRate);


    `APPL_WAIT_CYC(clk_i,100)
    rst_ni        = 1'b1;
    `APPL_WAIT_CYC(clk_i,100)

    $display("TB> start with test sequences");



    test_name    = "TEST 0 -- random read -- disabled cache";


    enable_i     = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};


    bypass_mem_port.set_region(0, MemBytes - 1);
    data_mem_port.set_region(0, 0);

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 1 -- linear read -- disabled cache";


    enable_i     = 0;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 2 -- random read -- enabled cache";


    enable_i     = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};



    bypass_mem_port.set_region(0, CachedAddrBeg - 1);
    data_mem_port.set_region(CachedAddrBeg, MemBytes - 1);

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 3 -- linear read -- enabled cache";


    enable_i     = 1;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 4 -- random read -- enabled cache + tlb, mem contentions";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 5 -- linear read -- enabled cache + tlb, mem contentions";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 6 -- random read -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 7 -- random read/write -- disabled cache";


    enable_i     = 0;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};


    bypass_mem_port.set_region(0, MemBytes - 1);
    data_mem_port.set_region(0, 0);

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 8 -- random read/write -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};



    bypass_mem_port.set_region(0, CachedAddrBeg - 1);
    data_mem_port.set_region(CachedAddrBeg, MemBytes - 1);

    runSeq(nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 9 -- random read/write -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};

    runSeq(nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 10 -- linear burst write -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
    req_rate     = '{100, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 11 -- linear burst write with hot cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ};
    req_rate     = '{default:100};

    runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
    seq_type     = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
    runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 12 -- random write bursts -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{BURST_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate     = '{75, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 13 -- random write bursts -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{BURST_SEQ, IDLE_SEQ, IDLE_SEQ};
    req_rate     = '{75, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 14 -- random write/read-- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate     = '{default:25};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 15 -- short wrapping sequences to provoke writebuffer hits";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{WRAP_SEQ, IDLE_SEQ, WRAP_SEQ};
    req_rate     = '{100,0,20};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 16 -- random write/read-- enabled cache + tlb, mem contentions + invalidations + random flushes";


    enable_i      = 1;
    tlb_rand_en   = 1;
    mem_rand_en   = 1;
    inv_rand_en   = 1;
    flush_rand_en = 1;
    seq_type      = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate      = '{default:25};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 17 -- set contention -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
    req_rate     = '{50,0,2};

    runSeq(0.2*nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 18 -- AMOs";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
    req_rate     = '{50,0,2};


    bypass_mem_port.set_region(0, 0);
    data_mem_port.set_region(0, MemBytes-1);

    runAMOs(nAMOs,1);
    flushCache();
    tb_mem_port_t::check_mem();


    end_of_sim = 1;
    $display("TB> end test sequences");
    tb_mem_port_t::report_mem();
  end

endmodule
module tb import ariane_pkg::*;
 import std_cache_pkg::*; import tb_pkg::*; #()();


  timeunit 1ps;
  timeprecision 1ps;


  parameter MemBytes          = 2**DCACHE_INDEX_WIDTH * 4 * 32;
  parameter MemWords          = MemBytes>>3;


  parameter logic [63:0] CachedAddrBeg = MemBytes>>3;
  parameter logic [63:0] CachedAddrEnd = 64'hFFFF_FFFF_FFFF_FFFF;


  parameter MemRandHitRate   = 75;
  parameter MemRandInvRate   = 10;
  parameter TlbHitRate       = 95;


  parameter FlushRate         = 10;
  parameter KillRate          = 5;

  parameter Verbose           = 0;


  parameter nReadVectors      = 20000;
  parameter nWriteVectors     = 20000;
  parameter nAMOs             = 20000;


  parameter int unsigned  TbAxiIdWidthFull   = 32'd6;

  parameter int unsigned  TbAxiAddrWidthFull = 32'd64;

  parameter int unsigned  TbAxiDataWidthFull = 32'd64;
  localparam int unsigned TbAxiUserWidthFull = 32'd1;

  parameter time          TbApplTime         = 2ns;

  parameter time          TbTestTime         = 8ns;






  logic                           enable_i;
  logic                           flush_i;
  logic                           flush_ack_o;
  logic                           miss_o;
  amo_req_t                       amo_req_i;
  amo_resp_t                      amo_resp_o;
  dcache_req_i_t [2:0]            req_ports_i;
  dcache_req_o_t [2:0]            req_ports_o;
  ariane_axi::req_t               axi_data_o;
  ariane_axi::resp_t              axi_data_i;
  ariane_axi::req_t               axi_bypass_o;
  ariane_axi::resp_t              axi_bypass_i;





  string test_name;
  logic clk_i, rst_ni;
  logic [31:0] seq_num_resp, seq_num_write, seq_num_amo;
  seq_t [2:0] seq_type;
  logic [3:0] seq_done;
  logic [6:0] req_rate[2:0];
  logic seq_run, seq_last;
  logic end_of_sim;

  logic mem_rand_en;
  logic inv_rand_en;
  logic amo_rand_en;
  logic tlb_rand_en;

  logic write_en;
  logic [63:0] write_paddr, write_data;
  logic [7:0] write_be;

  typedef struct packed  {
    logic [1:0]  size;
    logic [63:0] paddr;
  } resp_fifo_t;

  typedef struct packed {
    logic        valid;
    logic [63:0] paddr;
  } reservation_t;

  logic [63:0] act_paddr[1:0];
  logic [63:0] exp_rdata[1:0];
  logic [63:0] exp_paddr[1:0];
  logic [63:0] amo_act_mem;
  logic [63:0] amo_shadow;
  logic [63:0] amo_exp_result;
  resp_fifo_t  fifo_data_in[1:0];
  resp_fifo_t  fifo_data[1:0];
  logic [1:0]  fifo_push, fifo_pop, fifo_flush;
  logic [2:0]  flush;
  logic        flush_rand_en;

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH ( TbAxiAddrWidthFull       ),
    .AXI_DATA_WIDTH ( TbAxiDataWidthFull       ),
    .AXI_ID_WIDTH   ( TbAxiIdWidthFull + 32'd1 ),
    .AXI_USER_WIDTH ( TbAxiUserWidthFull       )
  ) axi_data_dv (
    .clk_i ( clk_i )
  );

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH ( TbAxiAddrWidthFull       ),
    .AXI_DATA_WIDTH ( TbAxiDataWidthFull       ),
    .AXI_ID_WIDTH   ( TbAxiIdWidthFull + 32'd1 ),
    .AXI_USER_WIDTH ( TbAxiUserWidthFull       )
  ) axi_bypass_dv (
    .clk_i ( clk_i )
  );

  `AXI_ASSIGN_FROM_REQ(axi_data_dv, axi_data_o)
  `AXI_ASSIGN_TO_RESP(axi_data_i, axi_data_dv)
  `AXI_ASSIGN_FROM_REQ(axi_bypass_dv, axi_bypass_o)
  `AXI_ASSIGN_TO_RESP(axi_bypass_i, axi_bypass_dv)

  typedef tb_mem_port #(
    .AW                   ( TbAxiAddrWidthFull       ),
    .DW                   ( TbAxiDataWidthFull       ),
    .IW                   ( TbAxiIdWidthFull + 32'd1 ),
    .UW                   ( TbAxiUserWidthFull       ),
    .TA                   ( TbApplTime               ),
    .TT                   ( TbTestTime               ),
    .AX_MIN_WAIT_CYCLES   ( 0                        ),
    .AX_MAX_WAIT_CYCLES   ( 50                       ),
    .R_MIN_WAIT_CYCLES    ( 10                       ),
    .R_MAX_WAIT_CYCLES    ( 20                       ),
    .RESP_MIN_WAIT_CYCLES ( 10                       ),
    .RESP_MAX_WAIT_CYCLES ( 20                       ),
    .MEM_BYTES            ( MemBytes                 )
  ) tb_mem_port_t;

  tb_mem_port_t data_mem_port;
  tb_mem_port_t bypass_mem_port;






  task automatic runSeq(input int nReadVectors, input int nWriteVectors = 0, input logic last =1'b0);
    seq_last      = last;
    seq_run       = 1'b1;
    seq_num_resp  = nReadVectors;
    seq_num_write = nWriteVectors;
    seq_num_amo   = 0;
    `APPL_WAIT_CYC(clk_i, 1)
    seq_run      = 1'b0;
    `APPL_WAIT_SIG(clk_i, &seq_done)
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : runSeq


  task automatic runAMOs(input int nAMOs, input logic last =1'b0);
    seq_last      = last;
    seq_run       = 1'b1;
    seq_num_resp  = 0;
    seq_num_write = 0;
    seq_num_amo   = nAMOs;
    `APPL_WAIT_CYC(clk_i, 1)
    seq_run      = 1'b0;
    `APPL_WAIT_SIG(clk_i, &seq_done)
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : runAMOs


  task automatic flushCache();
    flush[2]      = 1'b1;
    `APPL_WAIT_SIG(clk_i, flush_ack_o);
    flush[2]      = 0'b0;
    `APPL_WAIT_CYC(clk_i, 1)
  endtask : flushCache





  always @*
    begin
      do begin
        clk_i = 1; #(CLK_HI);
        clk_i = 0; #(CLK_LO);
      end while (end_of_sim == 1'b0);
      repeat (100) begin


        clk_i = 1; #(CLK_HI);
        clk_i = 0; #(CLK_LO);
      end
    end






  initial begin : p_mem
    automatic logic[63:0] amo_result, amo_op_a, amo_op_b, amo_op_a_u, amo_op_b_u;
    reservation_t reservation;


    reservation = '0;
    amo_exp_result = 'x;
    `APPL_WAIT_SIG(clk_i, ~rst_ni)
    `APPL_WAIT_CYC(clk_i, 1)

    forever begin
      amo_exp_result = 'x;
      `ACQ_WAIT_CYC(clk_i, 1)


      if(write_en) begin
        for(int k=0; k<8; k++) begin
          if(write_be[k]) begin
            tb_mem_port_t::shadow_q[write_paddr + k] <= write_data[k*8 +: 8];
          end
        end
      end



      if (amo_req_i.req) begin

        if (amo_req_i.size == 2'h2) begin

          amo_op_a   = $signed(amo_shadow[31:0]);
          amo_op_b   = $signed(amo_req_i.operand_b[31:0]);


          amo_op_a_u = $unsigned(amo_shadow[31:0]);
          amo_op_b_u = $unsigned(amo_req_i.operand_b[31:0]);



          amo_exp_result[31:0] = amo_shadow[31:0];


        end else begin

          amo_op_a   = $signed(amo_shadow);
          amo_op_b   = $signed(amo_req_i.operand_b);


          amo_op_a_u = $unsigned(amo_shadow);
          amo_op_b_u = $unsigned(amo_req_i.operand_b);



          amo_exp_result = amo_shadow;
        end


        case (amo_req_i.amo_op)

          AMO_LR: begin

            reservation.valid = 1'b1;
            reservation.paddr = amo_req_i.operand_a;


            amo_result = amo_shadow;
          end


          AMO_SC: begin

            if (reservation.valid && reservation.paddr == amo_req_i.operand_a) begin
              amo_result     = amo_op_b;
              amo_exp_result = 64'b0;


            end else begin
              amo_result     = amo_shadow;
              amo_exp_result = 64'b1;
            end


            reservation.valid = 1'b0;
          end


          AMO_SWAP: amo_result = amo_op_b;
          AMO_ADD:  amo_result = amo_op_a + amo_op_b;
          AMO_AND:  amo_result = amo_op_a & amo_op_b;
          AMO_OR:   amo_result = amo_op_a | amo_op_b;
          AMO_XOR:  amo_result = amo_op_a ^ amo_op_b;
          AMO_MAX:  amo_result = ($signed(amo_op_a) > $signed(amo_op_b)) ? amo_op_a : amo_op_b;
          AMO_MIN:  amo_result = ($signed(amo_op_a) < $signed(amo_op_b)) ? amo_op_a : amo_op_b;
          AMO_MAXU: amo_result = (amo_op_a_u > amo_op_b_u) ? amo_op_a : amo_op_b;
          AMO_MINU: amo_result = (amo_op_a_u < amo_op_b_u) ? amo_op_a : amo_op_b;


          default: amo_result = amo_shadow;
        endcase

        `ACQ_WAIT_CYC(clk_i,1)


        for (int k = 0; k < 2**amo_req_i.size; k++) begin
          tb_mem_port_t::shadow_q[amo_req_i.operand_a + k] <= amo_result[k*8 +: 8];
        end

        `ACQ_WAIT_SIG(clk_i,amo_resp_o.ack)
      end
    end
  end


  initial begin : p_sim_mem

    data_mem_port   = new(axi_data_dv  , CACHED);
    bypass_mem_port = new(axi_bypass_dv, BYPASS);


    data_mem_port.reset();
    bypass_mem_port.reset();
    tb_mem_port_t::init_mem();

    @(posedge rst_ni);


    fork
      data_mem_port.run();
      bypass_mem_port.run();
    join
  end





  std_nbdcache  #(
    .CACHE_START_ADDR ( CachedAddrBeg )
  ) i_dut (
    .clk_i           ( clk_i           ),
    .rst_ni          ( rst_ni          ),
    .flush_i         ( flush_i         ),
    .flush_ack_o     ( flush_ack_o     ),
    .enable_i        ( enable_i        ),
    .miss_o          ( miss_o          ),
    .amo_req_i       ( amo_req_i       ),
    .amo_resp_o      ( amo_resp_o      ),
    .req_ports_i     ( req_ports_i     ),
    .req_ports_o     ( req_ports_o     ),
    .axi_data_o      ( axi_data_o      ),
    .axi_data_i      ( axi_data_i      ),
    .axi_bypass_o    ( axi_bypass_o    ),
    .axi_bypass_i    ( axi_bypass_i    )
  );






  assign act_paddr[0] = (i_dut.master_ports[0].i_cache_ctrl.state_q == 4'h1) ? {i_dut.tag[1], i_dut.master_ports[0].i_cache_ctrl.mem_req_q.index} :
                        {i_dut.master_ports[0].i_cache_ctrl.mem_req_q.tag,
                         i_dut.master_ports[0].i_cache_ctrl.mem_req_q.index};
  assign act_paddr[1] = (i_dut.master_ports[1].i_cache_ctrl.state_q == 4'h1) ? {i_dut.tag[2], i_dut.master_ports[1].i_cache_ctrl.mem_req_q.index} :
                        {i_dut.master_ports[1].i_cache_ctrl.mem_req_q.tag,
                         i_dut.master_ports[1].i_cache_ctrl.mem_req_q.index};


  generate
    for(genvar k=0; k<2;k++) begin
      assign fifo_data_in[k] =  {req_ports_i[k].data_size,
                                 exp_paddr[k]};

      for (genvar l=0; l<8; l++)
        assign exp_rdata[k][l*8 +: 8] = tb_mem_port_t::shadow_q[{fifo_data[k].paddr[63:3], 3'b0} + l];

      assign fifo_push[k]  = req_ports_i[k].data_req & req_ports_o[k].data_gnt;
      assign fifo_flush[k] = req_ports_i[k].kill_req;
      assign fifo_pop[k]   = req_ports_o[k].data_rvalid & ~req_ports_i[k].kill_req;

      fifo_v3 #(
        .dtype(resp_fifo_t)
      ) i_resp_fifo (
        .clk_i       ( clk_i            ),
        .rst_ni      ( rst_ni           ),
        .flush_i     ( fifo_flush[k]    ),
        .testmode_i  ( '0               ),
        .full_o      (                  ),
        .empty_o     (                  ),
        .usage_o     (                  ),
        .data_i      ( fifo_data_in[k]  ),
        .push_i      ( fifo_push[k]     ),
        .data_o      ( fifo_data[k]     ),
        .pop_i       ( fifo_pop[k]      )
      );
    end
  endgenerate


  for (genvar k=0; k<8; k++) begin
    assign amo_act_mem[k*8 +: 8] = tb_mem_port_t::memory_q[amo_req_i.operand_a + k];
    assign amo_shadow[k*8 +: 8] = tb_mem_port_t::shadow_q[amo_req_i.operand_a + k];
  end

  tb_readport #(
    .PortName      ( "RD0"         ),
    .FlushRate     ( FlushRate     ),
    .KillRate      ( KillRate      ),
    .TlbHitRate    ( TlbHitRate    ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 5555555       ),
    .Verbose       ( Verbose       )
  ) i_tb_readport0 (
    .clk_i           ( clk_i               ),
    .rst_ni          ( rst_ni              ),
    .test_name_i     ( test_name           ),
    .req_rate_i      ( req_rate[0]         ),
    .seq_type_i      ( seq_type[0]         ),
    .tlb_rand_en_i   ( tlb_rand_en         ),
    .flush_rand_en_i ( flush_rand_en       ),
    .seq_run_i       ( seq_run             ),
    .seq_num_resp_i  ( seq_num_resp        ),
    .seq_last_i      ( seq_last            ),
    .seq_done_o      ( seq_done[0]         ),
    .exp_paddr_o     ( exp_paddr[0]        ),
    .exp_size_i      ( fifo_data[0].size   ),
    .exp_paddr_i     ( fifo_data[0].paddr  ),
    .exp_rdata_i     ( exp_rdata[0]        ),
    .act_paddr_i     ( act_paddr[0]        ),
    .flush_o         ( flush[0]            ),
    .flush_ack_i     ( flush_ack_o         ),
    .dut_req_port_o  ( req_ports_i[0]      ),
    .dut_req_port_i  ( req_ports_o[0]      )
    );

  tb_readport #(
    .PortName      ( "RD1"         ),
    .FlushRate     ( FlushRate     ),
    .KillRate      ( KillRate      ),
    .TlbHitRate    ( TlbHitRate    ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 3333333       ),
    .Verbose       ( Verbose       )
  ) i_tb_readport1 (
    .clk_i           ( clk_i               ),
    .rst_ni          ( rst_ni              ),
    .test_name_i     ( test_name           ),
    .req_rate_i      ( req_rate[1]         ),
    .seq_type_i      ( seq_type[1]         ),
    .tlb_rand_en_i   ( tlb_rand_en         ),
    .flush_rand_en_i ( flush_rand_en       ),
    .seq_run_i       ( seq_run             ),
    .seq_num_resp_i  ( seq_num_resp        ),
    .seq_last_i      ( seq_last            ),
    .exp_paddr_o     ( exp_paddr[1]        ),
    .exp_size_i      ( fifo_data[1].size   ),
    .exp_paddr_i     ( fifo_data[1].paddr  ),
    .exp_rdata_i     ( exp_rdata[1]        ),
    .act_paddr_i     ( act_paddr[1]        ),
    .seq_done_o      ( seq_done[1]         ),
    .flush_o         ( flush[1]            ),
    .flush_ack_i     ( flush_ack_o         ),
    .dut_req_port_o  ( req_ports_i[1]      ),
    .dut_req_port_i  ( req_ports_o[1]      )
  );

  tb_writeport #(
    .PortName      ( "WR0"         ),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 7777777       ),
    .Verbose       ( Verbose       )
  ) i_tb_writeport (
    .clk_i          ( clk_i               ),
    .rst_ni         ( rst_ni              ),
    .test_name_i    ( test_name           ),
    .req_rate_i     ( req_rate[2]         ),
    .seq_type_i     ( seq_type[2]         ),
    .seq_run_i      ( seq_run             ),
    .seq_num_vect_i ( seq_num_write       ),
    .seq_last_i     ( seq_last            ),
    .seq_done_o     ( seq_done[2]         ),
    .dut_req_port_o ( req_ports_i[2]      ),
    .dut_req_port_i ( req_ports_o[2]      )
  );

  tb_amoport  #(
    .PortName      ("AMO0"),
    .MemWords      ( MemWords      ),
    .CachedAddrBeg ( CachedAddrBeg ),
    .CachedAddrEnd ( CachedAddrEnd ),
    .RndSeed       ( 1111111       ),
    .Verbose       ( Verbose       )
  ) i_tb_amoport (
    .clk_i               ( clk_i          ),
    .rst_ni              ( rst_ni         ),
    .test_name_i         ( test_name      ),
    .seq_run_i           ( seq_run        ),
    .seq_num_amo_i       ( seq_num_amo    ),
    .seq_last_i          ( seq_last       ),
    .seq_done_o          ( seq_done[3]    ),
    .act_mem_i           ( amo_act_mem    ),
    .exp_mem_i           ( amo_shadow     ),
    .exp_result_i        ( amo_exp_result ),
    .dut_amo_req_port_o  ( amo_req_i      ),
    .dut_amo_resp_port_i ( amo_resp_o     )
  );


  initial begin
    automatic logic       write_en_n;
    automatic logic[63:0] write_paddr_n;
    automatic logic[63:0] write_data_n;
    automatic logic[7:0]  write_be_n;

    write_en_n    = '0;
    write_paddr_n = '0;
    write_data_n  = '0;
    write_be_n    = '0;

    forever begin
      `WAIT_CYC(clk_i,1)

      write_en      = write_en_n;
      write_paddr   = write_paddr_n;
      write_data    = write_data_n;
      write_be      = write_be_n;

      write_en_n    = req_ports_i[2].data_req & req_ports_o[2].data_gnt & req_ports_i[2].data_we;
      write_paddr_n = {req_ports_i[2].address_tag,  req_ports_i[2].address_index};
      write_data_n  = req_ports_i[2].data_wdata;
      write_be_n    = req_ports_i[2].data_be;
    end
  end

  assign flush_i = |flush;









  initial begin : p_stim
    test_name        = "";
    seq_type         = '{default: RANDOM_SEQ};
    req_rate         = '{default: 7'd75};
    seq_run          = 1'b0;
    seq_last         = 1'b0;
    seq_num_resp     = '0;
    seq_num_write    = '0;

    end_of_sim       = 0;
    rst_ni           = 0;

    mem_rand_en      = 0;
    tlb_rand_en      = 0;
    inv_rand_en      = 0;
    amo_rand_en      = 0;
    flush_rand_en    = 0;

    flush[2]         = 0;

    enable_i         = 0;



    $display("TB> current configuration:");
    $display("TB> MemWords        %d",   MemWords);
    $display("TB> CachedAddrBeg   %16X", CachedAddrBeg);
    $display("TB> CachedAddrEnd   %16X", CachedAddrEnd);
    $display("TB> MemRandHitRate  %d",   MemRandHitRate);
    $display("TB> MemRandInvRate  %d",   MemRandInvRate);


    `APPL_WAIT_CYC(clk_i,100)
    rst_ni        = 1'b1;
    `APPL_WAIT_CYC(clk_i,100)

    $display("TB> start with test sequences");



    test_name    = "TEST 0 -- random read -- disabled cache";


    enable_i     = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};


    bypass_mem_port.set_region(0, MemBytes - 1);
    data_mem_port.set_region(0, 0);

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 1 -- linear read -- disabled cache";


    enable_i     = 0;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 2 -- random read -- enabled cache";


    enable_i     = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};



    bypass_mem_port.set_region(0, CachedAddrBeg - 1);
    data_mem_port.set_region(CachedAddrBeg, MemBytes - 1);

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 3 -- linear read -- enabled cache";


    enable_i     = 1;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 4 -- random read -- enabled cache + tlb, mem contentions";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 5 -- linear read -- enabled cache + tlb, mem contentions";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    seq_type     = '{default: LINEAR_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 6 -- random read -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd50};

    runSeq(nReadVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 7 -- random read/write -- disabled cache";


    enable_i     = 0;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};


    bypass_mem_port.set_region(0, MemBytes - 1);
    data_mem_port.set_region(0, 0);

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 8 -- random read/write -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};



    bypass_mem_port.set_region(0, CachedAddrBeg - 1);
    data_mem_port.set_region(CachedAddrBeg, MemBytes - 1);

    runSeq(nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 9 -- random read/write -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{default: RANDOM_SEQ};
    req_rate     = '{default: 7'd25};

    runSeq(nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 10 -- linear burst write -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
    req_rate     = '{100, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 11 -- linear burst write with hot cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{IDLE_SEQ, IDLE_SEQ, LINEAR_SEQ};
    req_rate     = '{default:100};

    runSeq((CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
    seq_type     = '{LINEAR_SEQ, IDLE_SEQ, IDLE_SEQ};
    runSeq(0,(CachedAddrBeg>>3)+(2**(DCACHE_INDEX_WIDTH-3))*DCACHE_SET_ASSOC);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 12 -- random write bursts -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{BURST_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate     = '{75, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 13 -- random write bursts -- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{BURST_SEQ, IDLE_SEQ, IDLE_SEQ};
    req_rate     = '{75, 0, 0};

    runSeq(0,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 14 -- random write/read-- enabled cache + tlb, mem contentions + invalidations";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 1;
    inv_rand_en  = 1;
    seq_type     = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate     = '{default:25};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 15 -- short wrapping sequences to provoke writebuffer hits";


    enable_i     = 1;
    tlb_rand_en  = 0;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{WRAP_SEQ, IDLE_SEQ, WRAP_SEQ};
    req_rate     = '{100,0,20};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 16 -- random write/read-- enabled cache + tlb, mem contentions + invalidations + random flushes";


    enable_i      = 1;
    tlb_rand_en   = 1;
    mem_rand_en   = 1;
    inv_rand_en   = 1;
    flush_rand_en = 1;
    seq_type      = '{RANDOM_SEQ, RANDOM_SEQ, RANDOM_SEQ};
    req_rate      = '{default:25};

    runSeq(nReadVectors,nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 17 -- set contention -- enabled cache";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
    req_rate     = '{50,0,2};

    runSeq(0.2*nReadVectors,2*nWriteVectors);
    flushCache();
    tb_mem_port_t::check_mem();


    test_name    = "TEST 18 -- AMOs";


    enable_i     = 1;
    tlb_rand_en  = 1;
    mem_rand_en  = 0;
    inv_rand_en  = 0;
    seq_type     = '{CONST_SEQ, IDLE_SEQ, SET_SEQ};
    req_rate     = '{50,0,2};


    bypass_mem_port.set_region(0, 0);
    data_mem_port.set_region(0, MemBytes-1);

    runAMOs(nAMOs,1);
    flushCache();
    tb_mem_port_t::check_mem();


    end_of_sim = 1;
    $display("TB> end test sequences");
    tb_mem_port_t::report_mem();
  end

endmodule