blob: 8f5bd95cf9fe63fbf25bb9ec24f44076eb20e021 [file] [log] [blame]
// 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