| // 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 |
| |