// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Register Package auto-generated by `reggen` containing data structure

<%
  num_regs = block.get_n_regs_flat()
  max_regs_char = len("{}".format(num_regs-1))
%>\
package ${block.name}_reg_pkg;
% if len(block.params) != 0:

  // Param list
% endif
% for param in [p for p in block.params if p["local"] == "true"]:
  localparam ${param["type"]} ${param["name"]} = ${param["default"]};
% endfor

% if block.contains_multiregs():
/////////////////////////////////////////////////////////////////////
// Typedefs for multiregs
/////////////////////////////////////////////////////////////////////

% for r in block.regs:
  ## in this case we have a homogeneous multireg, with only one replicated field
  % if r.is_multi_reg() and r.get_n_bits(["q"]) and r.ishomog:
typedef struct packed {
  logic [${r.get_field_flat(0).get_n_bits()-1}:0] q;
  % if r.get_field_flat(0).hwqe:
  logic qe;
  % endif
  % if r.get_field_flat(0).hwre:
  logic re;
  % endif
} ${block.name + "_reg2hw_" + r.name + "_mreg_t"};
  ## in this case we have an inhomogeneous multireg, with several different fields per register
  % elif r.is_multi_reg() and r.get_n_bits(["q"]) and not r.ishomog:
typedef struct packed {
    % for f in r.get_reg_flat(0).fields:
  struct packed {
    logic [${f.get_n_bits()-1}:0] q;
      % if f.hwqe:
    logic qe;
      % endif
      % if f.hwre:
    logic re;
      % endif
  } ${f.get_basename()};
    %endfor
} ${block.name + "_reg2hw_" + r.name + "_mreg_t"};
  %endif
% endfor

% for r in block.regs:
 ## in this case we have a homogeneous multireg, with only one replicated field
  % if r.is_multi_reg() and r.get_n_bits(["d"]) and r.ishomog:
typedef struct packed {
  logic [${r.get_field_flat(0).get_n_bits(["d"])-1}:0] d;
    % if not r.get_reg_flat(0).hwext:
  logic de;
    % endif
} ${block.name + "_hw2reg_" + r.name + "_mreg_t"};
  ## in this case we have an inhomogeneous multireg, with several different fields per register
  % elif r.is_multi_reg() and r.get_n_bits(["d"]) and not r.ishomog:
typedef struct packed {
    % for f in r.get_reg_flat(0).fields:
  struct packed {
    logic [${f.get_n_bits(["d"])-1}:0] d;
      % if not r.hwext:
    logic de;
      % endif
  } ${f.get_basename()};
    %endfor
} ${block.name + "_hw2reg_" + r.name + "_mreg_t"};
  % endif
% endfor

% endif
/////////////////////////////////////////////////////////////////////
// Register to internal design logic
/////////////////////////////////////////////////////////////////////
<%
nbits = block.get_n_bits(["q","qe","re"]) - 1
packbit = 0
%>
% if nbits > 0:
typedef struct packed {
% for r in block.regs:
  ######################## multiregister ###########################
  % if r.is_multi_reg() and r.get_n_bits(["q"]):
  <%
  array_dims = ""
  for d in r.get_nested_dims():
    array_dims += "[%d:0]" % (d-1)
  %>${block.name + "_reg2hw_" + r.name + "_mreg_t"} ${array_dims} ${r.name}; // [${nbits - packbit}:${nbits - (packbit + r.get_n_bits(["q", "qe", "re"]) - 1)}]<% packbit += r.get_n_bits(["q", "qe", "re"]) %>
  ######################## register with single field ###########################
  % elif len(r.fields) == 1 and r.get_n_bits(["q"]):
    ## Only one field, should use register name as it is
  struct packed {
    logic [${r.fields[0].get_n_bits()-1}:0] q; // [${nbits - packbit}:${nbits - (packbit + r.fields[0].get_n_bits() - 1)}]<% packbit += r.fields[0].get_n_bits() %>
    % if r.fields[0].hwqe:
    logic qe; // [${nbits - packbit}]<% packbit += 1 %>
    % endif
    % if r.fields[0].hwre:
    logic re; // [${nbits - packbit}]<% packbit += 1 %>
    % endif
  } ${r.name};
  ######################## register with multiple fields ###########################
  % elif len(r.fields) >= 2 and r.get_n_bits(["q"]):
  struct packed {
    % for f in r.fields:
      % if f.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
    struct packed {
      ## reg2hw signal based on HW type and virtual?
      % if f.get_n_bits() > 1:
      logic [${f.get_n_bits()-1}:0] q; // [${nbits - packbit}:${nbits - (packbit + f.get_n_bits() - 1)}]<% packbit += f.get_n_bits() %>
      % else:
      logic q; // [${nbits - packbit}]<% packbit += 1 %>
      % endif
      % if f.hwqe:
      logic qe; // [${nbits - packbit}]<% packbit += 1 %>
      % endif
      % if f.hwre:
      logic re; // [${nbits - packbit}]<% packbit += 1 %>
      % endif
    } ${f.name};
      % endif
    % endfor
  } ${r.name};
  % endif
% endfor
} ${block.name}_reg2hw_t;
% endif

/////////////////////////////////////////////////////////////////////
// Internal design logic to register
/////////////////////////////////////////////////////////////////////
<%
nbits = block.get_n_bits(["d","de"]) - 1
packbit = 0
%>
% if nbits > 0:
typedef struct packed {
% for r in block.regs:
  ######################## multiregister ###########################
  % if r.is_multi_reg() and r.get_n_bits(["d"]):
  <%
  array_dims = ""
  for d in r.get_nested_dims():
    array_dims += "[%d:0]" % (d-1)
  %>${block.name + "_hw2reg_" + r.name + "_mreg_t"} ${array_dims} ${r.name}; // [${nbits - packbit}:${nbits - (packbit + r.get_n_bits(["d", "de"]) - 1)}]<% packbit += r.get_n_bits(["d", "de"]) %>
  ######################## register with single field ###########################
  % elif len(r.fields) == 1 and r.get_n_bits(["d"]):
    ## Only one field, should use register name as it is
  struct packed {
    logic [${r.fields[0].get_n_bits("d")-1}:0] d; // [${nbits - packbit}:${nbits - (packbit + r.fields[0].get_n_bits("d") - 1)}]<% packbit += r.fields[0].get_n_bits("d") %>
    % if r.hwext == 0:
    logic de; // [${nbits - packbit}]<% packbit += 1 %>
    % endif
  } ${r.name};
  ######################## register with multiple fields ###########################
  % elif len(r.fields) >= 2 and r.get_n_bits(["d"]):
  struct packed {
    % for f in r.fields:
      % if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
    struct packed {
      ## reg2hw signal based on HW type and virtual?
      % if f.get_n_bits("d") > 1:
      logic [${f.get_n_bits("d")-1}:0] d; // [${nbits - packbit}:${nbits - (packbit + f.get_n_bits("d") - 1)}]<% packbit += f.get_n_bits("d") %>
      % else:
      logic d; // [${nbits - packbit}]<% packbit += 1 %>
      % endif
      % if not r.hwext:
      logic de; // [${nbits - packbit}]<% packbit += 1 %>
      % endif
    } ${f.name};
      % endif
    % endfor
  } ${r.name};
  % endif
% endfor
} ${block.name}_hw2reg_t;
% endif

  // Register Address
% for r in block.get_regs_flat():
  parameter ${block.name.upper()}_${r.name.upper()}_OFFSET = ${block.addr_width}'h ${"%x" % r.offset};
% endfor

% if len(block.wins) > 0:
  // Window parameter
% endif
% for i,w in enumerate(block.wins):
  parameter ${block.name.upper()}_${w.name.upper()}_OFFSET = ${block.addr_width}'h ${"%x" % w.base_addr};
  parameter ${block.name.upper()}_${w.name.upper()}_SIZE   = ${block.addr_width}'h ${"%x" % (w.limit_addr - w.base_addr)};
% endfor

  // Register Index
  typedef enum int {
% for r in block.get_regs_flat():
    ${block.name.upper()}_${r.name.upper()}${"" if loop.last else ","}
% endfor
  } ${block.name}_id_e;

  // Register width information to check illegal writes
  localparam logic [3:0] ${block.name.upper()}_PERMIT [${block.get_n_regs_flat()}] = '{
% for i,r in enumerate(block.get_regs_flat()):
<% index_str = "{}".format(i).rjust(max_regs_char) %>\
  % if r.width > 24:
    4'b 1111${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
  % elif r.width > 16:
    4'b 0111${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
  % elif r.width > 8:
    4'b 0011${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
  % else:
    4'b 0001${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
  % endif
% endfor
  };
endpackage

