// 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
<% 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::*; (
  input clk_i,
  input rst_ni,

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

  parameter int DWidth = 32;
  // mask register to convert byte to bit
  logic [DWidth-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
  mask = block.addr_width
%>\
  // declare common read and write sequences
  sequence device_wr_S(logic [${addr_msb}:0] addr);
    h2d.a_address == addr && h2d.a_opcode inside {PutFullData, PutPartialData} &&
        h2d.a_valid && h2d.d_ready && !d2h.d_valid;
  endsequence

  // this sequence is used for reg_field which has access w1c or w0c
  // it returns true if the `index` bit of a_data matches `exp_bit`
  // this sequence is under assumption - w1c/w0c will only use one bit per field
  sequence device_wc_S(logic [${addr_msb}:0] addr, bit exp_bit, int index);
    h2d.a_address == addr && h2d.a_opcode inside {PutFullData, PutPartialData} && h2d.a_valid &&
        h2d.d_ready && !d2h.d_valid && ((h2d.a_data[index] & a_mask_bit[index]) == exp_bit);
  endsequence

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

  // declare common read and write properties
  property wr_P(bit [${addr_msb}:0] addr, bit [DWidth-1:0] act_data, bit regen,
                bit [DWidth-1:0] mask);
    logic [DWidth-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 == 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 [DWidth-1:0] act_data, bit regen,
                    bit [DWidth-1:0] mask);
    logic [DWidth-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) == exp_data || !regen);
  endproperty

  // For W1C or W0C, first scenario: write 1(W1C) or 0(W0C) that clears the value
  property wc0_P(bit [${addr_msb}:0] addr, bit act_data, bit regen, int index, bit clear_bit);
    logic [DWidth-1:0] id;
    (device_wc_S(addr, clear_bit, index), id = h2d.a_source) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || act_data == 1'b0 || !regen);
  endproperty

  // For W1C or W0C, second scenario: write 0(W1C) or 1(W0C) that won't clear the value
  property wc1_P(bit [${addr_msb}:0] addr, bit act_data, bit regen, int index, bit clear_bit);
    logic [DWidth-1:0] id;
    (device_wc_S(addr, !clear_bit, index), id = h2d.a_source) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || $stable(act_data) || !regen);
  endproperty

  property rd_P(bit [${addr_msb}:0] addr, bit [DWidth-1:0] act_data);
    logic [DWidth-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 == exp_data);
  endproperty

  property rd_ext_P(bit [${addr_msb}:0] addr, bit [DWidth-1:0] act_data);
    logic [DWidth-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 == exp_data);
  endproperty

  // read a WO register, always return 0
  property r_wo_P(bit [${addr_msb}:0] addr);
    logic [DWidth-1:0] id;
    (device_rd_S(addr), id = h2d.a_source) ##1
        first_match(##[0:$] (d2h.d_valid && d2h.d_source == id)) |->
        (d2h.d_error || d2h.d_data == 0);
  endproperty

  property wr_regen_stable_P(bit regen, bit [DWidth-1:0] exp_data);
    (!regen && $stable(regen)) |-> $stable(exp_data);
  endproperty

// for all the regsters, declare assertion
% for r in block.regs:
<%
  i = -1
  msb = -1
  lsb = 0
%>\
  % for reg_flat in r.get_regs_flat():
<%
  reg_name = reg_flat.name
  reg_width = block.addr_width
  reg_offset =  str(reg_width) + "'h" + "%x" % reg_flat.offset
  reg_msb = reg_flat.width - 1
  regwen = reg_flat.regwen
  reg_access = set()
  reg_wr_mask = 0
  hw_access = reg_flat.fields[0].hwaccess
%>\
    % if regwen:
<%
    reg_wen = "i_"+ block.name + ".i_reg_top."+ regwen + "_qs"
%>\
    % else:
<%
    reg_wen = "1"
%>\
    % endif
    % if r.is_multi_reg():
<%
      r_multi_name = r.name
      f = reg_flat.fields[0]
      r_multi_width = f.msb - f.lsb + 1
      r_multi_depth = r.get_n_fields_flat()
      r_multi_msb = r_multi_width * r_multi_depth -1
      i += 1
      lsb = i * (msb - lsb + 1)
      msb = lsb + reg_msb
%>\
      % if reg_flat.get_n_bits(["q"]):
<%
      reg_r_path = r_multi_name + "_q_fpv[" + str(msb) + ":" + str(lsb) + "]"
      reg_w_path = r_multi_name + "_q_fpv[" + str(msb) + ":" + str(lsb) + "]"
%>\
      % endif
      % if reg_flat.get_n_bits(["d"]):
<%
      reg_r_path = r_multi_name + "_d_fpv[" + str(msb) + ":" + str(lsb) + "]"
%>\
      % endif
      % if (i == 0):

  // define local fpv variable for the multi_reg
        % if reg_flat.get_n_bits(["q"]):
  logic [${r_multi_msb}:0] ${r_multi_name}_q_fpv;
          % if reg_flat.get_n_bits(["qe"]):
<%
      qe = "i_" + block.name + ".reg2hw." + r_multi_name + "[s].qe"
%>\
          % else:
<%
      qe = 1
%>\
          % endif
          % if r_multi_width == 1:
  for (genvar s = 0; s <= ${r_multi_msb}; s++) begin : gen_${r_multi_name}_q
    assign ${r_multi_name}_q_fpv[s] = ${qe} ?
        i_${block.name}.reg2hw.${r_multi_name}[s].q : ${r_multi_name}_q_fpv[s];
          % else:
  for (genvar s = 0; s < ${r_multi_depth}; s++) begin : gen_${r_multi_name}_q
    assign ${r_multi_name}_q_fpv[((s+1)*${r_multi_width}-1):s*${r_multi_width}] = ${qe} ?
        i_${block.name}.reg2hw.${r_multi_name}[s].q : ${r_multi_name}_q_fpv[((s+1)*${r_multi_width}-1):s*${r_multi_width}];
          % endif
  end
        % endif
        % if reg_flat.get_n_bits(["d"]):
  logic [${r_multi_msb}:0] ${r_multi_name}_d_fpv;
          % if r_multi_width == 1:
  for (genvar s = 0; s <= ${r_multi_msb}; s++) begin : gen_${r_multi_name}_d
    assign ${r_multi_name}_d_fpv[s] = i_${block.name}.hw2reg.${r_multi_name}[s].d;
          % else:
  for (genvar s = 0; s <= ${r_multi_depth}-1; s++) begin : gen_${r_multi_name}_d
    assign ${r_multi_name}_d_fpv[((s+1)*${r_multi_width}-1):s*${r_multi_width}] = i_${block.name}.hw2reg.${r_multi_name}[s].d;
          % endif
  end
        % endif
      % endif
    % else :
<%
      reg_r_path = "i_" + block.name + ".hw2reg." + reg_name + ".d"
      reg_w_path = "i_" + block.name + ".reg2hw." + reg_name + ".q"
%>\
      % if hw_access == HwAccess.HRO or hw_access == HwAccess.NONE:
<%
      reg_r_path = "i_" + block.name + ".reg2hw." + reg_name + ".q"
%>\
      % endif
      % if reg_flat.get_n_bits(["q", "d"]) == 0:
<%
      reg_r_path = "i_" + block.name + ".i_reg_top." + reg_name + "_qs"
      reg_w_path = "i_" + block.name + ".i_reg_top." + reg_name + "_qs"
%>\
      % endif
    % endif
    % if reg_flat.hwext:
<%
      wr_prperty = "wr_ext_P"
      rd_prperty = "rd_ext_P"
%>\
    % else:
<%
      wr_prperty = "wr_P"
      rd_prperty = "rd_P"
%>\
    % endif
    % for f in reg_flat.get_fields_flat():
<%
        field_access = f.swaccess.name
        reg_access.add(field_access)
        reg_wr_mask |= ((1 << (f.msb-f.lsb + 1)) -1) << f.lsb
%>\
      % if field_access == "W0C":
  // assertions for W0C reg fields:
  `ASSERT(${f.name}_wc0_A, wc0_P(${reg_offset}, ${reg_w_path}, ${reg_wen}, ${f.lsb}, 0))
  `ASSERT(${f.name}_wc1_A, wc1_P(${reg_offset}, ${reg_w_path}, ${reg_wen}, ${f.lsb}, 0))
  `ASSERT(${f.name}_rd_A, ${rd_prperty}(${reg_offset}, ${reg_r_path}))
      % elif field_access == "W1C":
  // assertions for W1C reg fields:
  `ASSERT(${f.name}_wc0_A, wc0_P(${reg_offset}, ${reg_w_path}, ${reg_wen}, ${f.lsb}, 1))
  `ASSERT(${f.name}_wc1_A, wc1_P(${reg_offset}, ${reg_w_path}, ${reg_wen}, ${f.lsb}, 1))
  `ASSERT(${f.name}_rd_A, ${rd_prperty}(${reg_offset}, ${reg_r_path}))
      % endif
    % endfor
<%
      reg_wr_mask_h = format(reg_wr_mask, 'x')
%>\

    % if "RW" in reg_access:
  `ASSERT(${reg_name}_wr_A, ${wr_prperty}(${reg_offset}, ${reg_w_path}, ${reg_wen}, 'h${reg_wr_mask_h}))
  `ASSERT(${reg_name}_rd_A, ${rd_prperty}(${reg_offset}, ${reg_r_path}))
    % elif "WO" in reg_access:
  `ASSERT(${reg_name}_wr_A, ${wr_prperty}(${reg_offset}, ${reg_w_path}, ${reg_wen}, 'h${reg_wr_mask_h}))
  `ASSERT(${reg_name}_rd_A, r_wo_P(${reg_offset}))
    % elif "RO" in reg_access:
  `ASSERT(${reg_name}_rd_A, ${rd_prperty}(${reg_offset}, ${reg_r_path}))
    % endif
    % if regwen:
  `ASSERT(${reg_name}_stable_A, wr_regen_stable_P(${reg_wen}, ${reg_w_path}))
    % endif
  % endfor
% endfor
</%def>\
${construct_classes(block)}
endmodule
