blob: 0c43c4e0b653fbcb537455520f3730caed21b559 [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
package ${block.name}_reg_pkg;
// Register to internal design logic
typedef struct packed {
<%
# directly mirrors below (avoided optimizations to ensure a match)
# have to do as a python block to avoid inserting blank lines
# compute number of bits because packed structs are declared msb first
packbit = 0
for r in block.regs:
if len(r.fields) == 1 and r.fields[0].hwaccess in [HwAccess.HRW, HwAccess.HRO]:
packbit += 1 + r.fields[0].msb - r.fields[0].lsb
if r.fields[0].hwqe:
packbit += 1
if r.fields[0].hwre:
packbit += 1
elif len(r.fields) >= 2 and len([f for f in r.fields if f.hwaccess in [HwAccess.HRW, HwAccess.HRO]]):
for f in r.fields:
if f.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
if f.msb != f.lsb:
packbit += 1 + f.msb - f.lsb
else:
packbit += 1
if r.hwqe:
packbit += 1
if r.fields[0].hwre:
packbit += 1
nbits = packbit - 1
packbit = 0
%>
% for r in block.regs:
% if len(r.fields) == 1 and r.fields[0].hwaccess in [HwAccess.HRW, HwAccess.HRO]:
## Only one field, should use register name as it is
struct packed {
logic [${r.fields[0].msb - r.fields[0].lsb}:0] q; // [${nbits - packbit}:${nbits - (packbit + r.fields[0].msb - r.fields[0].lsb)}]<% packbit += 1 + r.fields[0].msb - r.fields[0].lsb %>
% 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};
% elif len(r.fields) >= 2 and len([f for f in r.fields if f.hwaccess in [HwAccess.HRW, HwAccess.HRO]]):
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.msb != f.lsb:
logic [${f.msb - f.lsb}:0] q; // [${nbits - packbit}:${nbits - (packbit + f.msb - f.lsb)}]<% packbit += 1 + f.msb - f.lsb %>
% else:
logic q; // [${nbits - packbit}]<% packbit += 1 %>
% endif
% if f.hwqe:
logic qe; // [${nbits - packbit}]<% packbit += 1 %>
% endif
% if r.fields[0].hwre:
logic re; // [${nbits - packbit}]<% packbit += 1 %>
% endif
} ${f.name};
% endif
% endfor
} ${r.name};
% endif
% endfor
} ${block.name}_reg2hw_t;
// Internal design logic to register
typedef struct packed {
<%
packbit = 0
for r in block.regs:
if len(r.fields) == 1 and r.fields[0].hwaccess in [HwAccess.HRW, HwAccess.HWO]:
packbit += 1 + r.fields[0].msb - r.fields[0].lsb
if r.hwext == 0:
packbit += 1
elif len(r.fields) >= 2 and len([f for f in r.fields if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]]):
for f in r.fields:
if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
if f.msb != f.lsb:
packbit += 1 + f.msb - f.lsb
else:
packbit += 1
if r.hwext == 0:
packbit += 1
nbits = packbit - 1
packbit = 0
%>
% for r in block.regs:
% if len(r.fields) == 1 and r.fields[0].hwaccess in [HwAccess.HRW, HwAccess.HWO]:
## Only one field, should use register name as it is
struct packed {
logic [${r.fields[0].msb - r.fields[0].lsb}:0] d; // [${nbits - packbit}:${nbits - (packbit + r.fields[0].msb - r.fields[0].lsb)}]<% packbit += 1 + r.fields[0].msb - r.fields[0].lsb %>
% if r.hwext == 0:
logic de; // [${nbits - packbit}]<% packbit += 1 %>
% endif
} ${r.name};
% elif len(r.fields) >= 2 and len([f for f in r.fields if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]]):
struct packed {
% for f in r.fields:
% if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
struct packed {
% if f.msb != f.lsb:
logic [${f.msb - f.lsb}:0] d; // [${nbits - packbit}:${nbits - (packbit + f.msb - f.lsb)}]<% packbit += 1 + f.msb - f.lsb %>
% else:
logic d; // [${nbits - packbit}]<% packbit += 1 %>
% endif
% if r.hwext == 0:
logic de; // [${nbits - packbit}]<% packbit += 1 %>
% endif
} ${f.name};
% endif
% endfor
} ${r.name};
% endif
% endfor
} ${block.name}_hw2reg_t;
// Register Address
% for r in block.regs:
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
## typedef enum int {
## % for r in block.regs:
## % if loop.last:
## ${block.name.upper()}_${r.name.upper()}
## % else:
## ${block.name.upper()}_${r.name.upper()},
## % endif
## % endfor
## } ${block.name}_reg_e;
endpackage