// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// FPV CSR read and write assertions auto-generated by `reggen` containing data structure
// Do Not Edit directly
// TODO: This automation does not support: shadow reg, has_d has_de not has_q (right now does not
// have internal storage if de=0)
<% from reggen import (gen_fpv)
%>\
<% from topgen import lib
%>\
<%def name="construct_classes(block)">\
% for b in block.blocks:
${construct_classes(b)}
% endfor

`include "prim_assert.sv"

// Block: ${block.name}
module ${block.name}_csr_assert_fpv import tlul_pkg::*; import ${block.name}_reg_pkg::*;
    import top_pkg::*;(
  input clk_i,
  input rst_ni,

  // tile link ports
  input tl_h2d_t h2d,
  input tl_d2h_t d2h,

  // reg and hw ports
  input ${block.name}_reg2hw_t reg2hw,
  input ${block.name}_hw2reg_t hw2reg
);

`ifndef VERILATOR
`ifndef SYNTHESIS

`ifdef UVM
  import uvm_pkg::*;
  % if block.hier_path:
  `define REGWEN_PATH dut.${block.hier_path}.u_reg
  % elif block.name == "flash_ctrl":
  `define REGWEN_PATH dut.u_flash_ctrl.u_reg
  % else:
  `define REGWEN_PATH dut.u_reg
  % endif
`else
  `define REGWEN_PATH u_reg
`endif

  bit disable_sva;

  // mask register to convert byte to bit
  logic [TL_DW-1:0] a_mask_bit;

  assign a_mask_bit[7:0]   = h2d.a_mask[0] ? '1 : '0;
  assign a_mask_bit[15:8]  = h2d.a_mask[1] ? '1 : '0;
  assign a_mask_bit[23:16] = h2d.a_mask[2] ? '1 : '0;
  assign a_mask_bit[31:24] = h2d.a_mask[3] ? '1 : '0;

<%
  addr_msb       = block.addr_width - 1
  reg_width      = block.addr_width
%>\
  // normalized address only take the [${addr_msb}:2] address from the TLUL a_address
  bit [${addr_msb}:0] normalized_addr;
  assign normalized_addr = {h2d.a_address[${addr_msb}:2], 2'b0};

  // declare common read and write sequences
  sequence device_wr_S(logic [${addr_msb}:0] addr);
    normalized_addr == addr && h2d.a_opcode inside {PutFullData, PutPartialData} &&
        h2d.a_valid && h2d.d_ready && !d2h.d_valid;
  endsequence

  sequence device_rd_S(logic [${addr_msb}:0] addr);
    normalized_addr == addr && h2d.a_opcode inside {Get} && h2d.a_valid && h2d.d_ready &&
        !d2h.d_valid;
  endsequence

  // declare common read and write properties
  // for homog registers, we check by a reg; for non-homog regs, we check by field.
  // `mask` is used for checking by field. It masks out any act_data that are not within the field
  // `lsb` is used to check non-homog multi_reg. Because we are using a local copy `_fpv` variable
  // to store all the multi-reg within one basefield, we need to shift the `_fpv` value to the
  // correct bits, then compare with read/write exp_data.

  property wr_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit regen,
                bit [TL_DW-1:0] mask, int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_wr_S(addr), id = h2d.a_source, exp_data = h2d.a_data & a_mask_bit & mask) ##1
        first_match(##[0:$] d2h.d_valid && d2h.d_source == id) |->
        (d2h.d_error || (act_data << lsb) == exp_data || !regen);
  endproperty

  // external reg will use one clk cycle to update act_data from external
  property wr_ext_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit regen,
                    bit [TL_DW-1:0] mask, int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_wr_S(addr), id = h2d.a_source, exp_data = h2d.a_data & a_mask_bit & mask) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || ($past(act_data) << lsb) == exp_data || !regen);
  endproperty

  // W1C register, if write 1 external data will be cleared to 0;
  // if write 0, internal data won't change
  property w1c_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit regen,
                 bit [TL_DW-1:0] mask, int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_wr_S(addr), id = h2d.a_source, exp_data = h2d.a_data & a_mask_bit & mask) ##1
        first_match(##[0:$] d2h.d_valid && d2h.d_source == id) |->
        (d2h.d_error || ((act_data << lsb) & exp_data) == 0 || !regen);
  endproperty

  property w1c_ext_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit regen,
                     bit [TL_DW-1:0] mask, int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_wr_S(addr), id = h2d.a_source, exp_data = h2d.a_data & a_mask_bit & mask) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || ($past(act_data) << lsb) == exp_data || !regen);
  endproperty

  property rd_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit [TL_DW-1:0] mask, int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_rd_S(addr), id = h2d.a_source, exp_data = $past(act_data)) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || (d2h.d_data & mask) >> lsb == exp_data);
  endproperty

  property rd_ext_P(bit [${addr_msb}:0] addr, bit [TL_DW-1:0] act_data, bit [TL_DW-1:0] mask,
      int lsb);
    logic [TL_DW-1:0] id, exp_data;
    (device_rd_S(addr), id = h2d.a_source, exp_data = act_data) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || (d2h.d_data & mask) >> lsb == exp_data);
  endproperty

% for r in block.regs:
<%
  has_q  = r.get_n_bits(["q"]) > 0
  has_d  = r.get_n_bits(["d"]) > 0
  has_de = r.get_n_bits(["de"]) > 0
%>\
  % if not r.get_field_flat(0).shadowed:
  % if r.is_multi_reg():
<%
      mreg_name          = r.name
      mreg_width_list    = list()
      mreg_fpv_name_list = list()
      mreg_dut_path_list = list()
      mreg_has_q_list    = list()
      mreg_has_d_list    = list()
      mreg_has_de_list   = list()
      mreg_num_regs      = r.get_n_fields_flat()

      mreg_msb = -1
      mreg_lsb = 0
      i        = 0
%>\
   % if not r.ishomog:
     % for field in r.get_reg_flat(0).fields:
<%
  mreg_fpv_name_list.append(mreg_name + "_" + field.get_basename())
  mreg_dut_path_list.append(mreg_name + "[s]." + field.get_basename())
  mreg_width_list.append(field.msb - field.lsb + 1)
  mreg_has_q_list.append(field.get_n_bits(["q"]) > 0)
  mreg_has_d_list.append(field.get_n_bits(["d"]) > 0)
  mreg_has_de_list.append(field.get_n_bits(["de"]) > 0)
%>\
     % endfor
<%
  mreg_num_base_fields = len(mreg_fpv_name_list)
  mreg_num_regs        = mreg_num_regs / mreg_num_base_fields
%>\
   % else:
<%
  f = r.get_field_flat(0)
  mreg_num_base_fields = 1
  mreg_fpv_name_list.append(mreg_name)
  mreg_dut_path_list.append(mreg_name + "[s]")
  mreg_width_list.append(f.msb - f.lsb + 1)
  mreg_has_q_list.append(has_q)
  mreg_has_d_list.append(has_d)
  mreg_has_de_list.append(has_de)
%>\
   % endif

  // define local fpv variable for multi-reg
   % if r.get_n_bits(["q", "d"]):
     % for fpv_name in mreg_fpv_name_list:
${declare_fpv_var(fpv_name, int(mreg_width_list[loop.index] * mreg_num_regs - 1), loop.index)}\
     % endfor
  for (genvar s = 0; s < ${int(mreg_num_regs)}; s++) begin : gen_${mreg_name}_q
     % for fpv_name in mreg_fpv_name_list:
${assign_fpv_var(fpv_name, mreg_dut_path_list[loop.index], int(mreg_width_list[loop.index]), loop.index)}\
     % endfor
  end
   % endif
  % endif

  % for reg_flat in r.get_regs_flat():
<%
  reg_name    = reg_flat.name
  reg_offset  =  str(reg_width) + "'h" + "%x" % reg_flat.offset
  reg_msb     = reg_flat.width - 1
  regwen      = reg_flat.regwen
  reg_wr_mask = 0
%>\
  // assertions for register: ${reg_name}
    % if regwen:
<% reg_wen = "`REGWEN_PATH." + regwen + "_qs" %>\
    % else:
<% reg_wen = "1" %>\
    % endif
    % for f in reg_flat.get_fields_flat():
<%
      field_name      = f.name
      assert_path     = reg_name + "." + field_name
      assert_name     = reg_name + "_" + field_name
      field_access    = f.swaccess.name
      field_wr_mask   = ((1 << (f.msb-f.lsb + 1)) -1) << f.lsb
      field_wr_mask_h = format(field_wr_mask, 'x')
      reg_wr_mask    |= field_wr_mask
      reg_wr_mask_h   = format(reg_wr_mask, 'x')
      lsb             = f.lsb
      sw_rdaccess     = f.swrdaccess.name
      had_q           = f.get_n_bits(["q"]) > 0
      has_d           = f.get_n_bits(["d"]) > 0
      has_de          = f.get_n_bits(["de"]) > 0
%>\
      % if not r.ishomog:
        % if r.is_multi_reg():
  // this is a non-homog multi-reg
<%
      mreg_lsb = i * mreg_width_list[loop.index]
      mreg_msb = mreg_lsb + mreg_width_list[loop.index] - 1
%>\
${gen_multi_reg_asserts_by_category(assert_name, mreg_name + "_" + f.get_basename(), mreg_msb, mreg_lsb, reg_flat.hwext, field_wr_mask_h)}\
        % else:
${gen_asserts_by_category(assert_name, assert_path, reg_flat.hwext, field_wr_mask_h)}\
        % endif
      % endif
    % endfor
    % if r.is_multi_reg():
<%
      mreg_lsb = i * (mreg_msb - mreg_lsb + 1)
      mreg_msb = mreg_lsb + reg_msb
      i += 1
%>\
    % endif
    % if r.ishomog:
      % if r.is_multi_reg():
${gen_multi_reg_asserts_by_category(reg_name, mreg_name, mreg_msb, mreg_lsb, reg_flat.hwext, reg_wr_mask_h)}\
      % else:
${gen_asserts_by_category(reg_name, reg_name, reg_flat.hwext, reg_wr_mask_h)}\
      % endif
    % endif
  % endfor
  % endif
% endfor

  `ifdef UVM
    initial forever begin
      bit csr_assert_en;
      uvm_config_db#(bit)::wait_modified(null, "%m", "csr_assert_en");
      if (!uvm_config_db#(bit)::get(null, "%m", "csr_assert_en", csr_assert_en)) begin
        `uvm_fatal("csr_assert", "Can't find csr_assert_en")
      end
      disable_sva = !csr_assert_en;
    end
  `endif

<%def name="gen_asserts_by_category(assert_name, assert_path, is_ext, wr_mask)">\
  % if has_q:
<% reg_w_path = "reg2hw." + assert_path + ".q" %>\
${gen_wr_asserts(assert_name, is_ext, reg_w_path, wr_mask)}\
    % if not has_d:
${gen_rd_asserts(assert_name, is_ext, reg_w_path, wr_mask)}\
    % endif
  % endif
  % if has_d:
    % if has_de and has_q:
<% reg_r_path = "hw2reg." + assert_path + ".de ? hw2reg." + assert_path + ".d :reg2hw." + assert_path + ".q" %>\
${gen_rd_asserts(assert_name, is_ext, reg_r_path, wr_mask)}\
    % elif not has_de:
<% reg_r_path = "hw2reg." + assert_path + ".d" %>\
${gen_rd_asserts(assert_name, is_ext, reg_r_path, wr_mask)}\
    % endif
  % endif
</%def>\
<%def name="gen_multi_reg_asserts_by_category(assert_name, multi_reg_name, mreg_msb, mreg_lsb, is_ext, wr_mask)">\
  % if has_q:
<% reg_w_path = multi_reg_name + "_q_fpv[" + str(mreg_msb) + ":" + str(mreg_lsb) + "]"%>\
${gen_wr_asserts(assert_name, is_ext, reg_w_path, wr_mask)}\
    % if not has_d:
${gen_rd_asserts(assert_name, is_ext, reg_w_path, wr_mask)}\
    % endif
  % endif
  % if has_d:
    % if not has_de:
<% reg_r_path = multi_reg_name + "_d_fpv[" + str(mreg_msb) + ":" + str(mreg_lsb) + "]"%>\
${gen_rd_asserts(assert_name, is_ext, reg_r_path, wr_mask)}\
    % endif
  % endif
</%def>\
<%def name="gen_wr_asserts(name, is_ext, reg_w_path, wr_mask)">\
  % if is_ext:
<% wr_property = "ext_P" %>\
  % else:
<% wr_property = "P" %>\
  % endif
  % if not r.ishomog:
<% shift_index = lsb %>\
  % else:
<% shift_index = 0 %>\
  % endif
  % if field_access == "W1C":
  `ASSERT(${name}_w1c_A, w1c_${wr_property}(${reg_offset}, ${reg_w_path}, ${reg_wen}, 'h${wr_mask}, ${shift_index}), clk_i, !rst_ni || disable_sva)
  % elif field_access in {"RW", "WO", "W0C"}:
  `ASSERT(${name}_wr_A, wr_${wr_property}(${reg_offset}, ${reg_w_path}, ${reg_wen}, 'h${wr_mask}, ${shift_index}), clk_i, !rst_ni || disable_sva)
  % endif
</%def>\
<%def name="gen_rd_asserts(name, is_ext, reg_r_path, mask)">\
  % if is_ext:
<% rd_property = "rd_ext_P" %>\
  % else:
<% rd_property = "rd_P" %>\
  % endif
  % if not r.ishomog:
<% shift_index = lsb %>\
  % else:
<% shift_index = 0 %>\
  % endif
  % if sw_rdaccess == "NONE" and field_access == "W1C":
  `ASSERT(${name}_rd_A, ${rd_property}(${reg_offset}, 0, 'h${mask}, ${shift_index}), clk_i, !rst_ni || disable_sva)
  % elif field_access in {"RW", "W0C", "W1C"}:
  `ASSERT(${name}_rd_A, ${rd_property}(${reg_offset}, ${reg_r_path}, 'h${mask}, ${shift_index}), clk_i, !rst_ni || disable_sva)
  % endif
</%def>\
<%def name="declare_fpv_var(name, width, l_index)">\
  % if mreg_has_q_list[l_index]:
  logic [${width}:0] ${name}_q_fpv;
  % endif
  % if mreg_has_d_list[l_index]:
  logic [${width}:0] ${name}_d_fpv;
  % endif
</%def>\
<%def name="assign_fpv_var(fpv_name, dut_path, width, l_index)">\
  % if mreg_has_q_list[l_index]:
    assign ${fpv_name}_q_fpv[((s+1)*${width}-1):s*${width}] = reg2hw.${dut_path}.q;
  % endif
  % if mreg_has_d_list[l_index]:
    assign ${fpv_name}_d_fpv[((s+1)*${width}-1):s*${width}] = hw2reg.${dut_path}.d;
  % endif
</%def>\
</%def>\
${construct_classes(block)}
`undef REGWEN_PATH
`endif
`endif
endmodule
