blob: c9cf0c5ef27fbdc2439abe5efe899ef663bbdc8a [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001// Copyright lowRISC contributors.
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4//
5// Register Package auto-generated by `reggen` containing data structure
6
Eunchan Kim51461cd2019-09-18 14:00:49 -07007<%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -07008 num_regs = block.get_n_regs_flat()
Eunchan Kim51461cd2019-09-18 14:00:49 -07009 max_regs_char = len("{}".format(num_regs-1))
10%>\
lowRISC Contributors802543a2019-08-31 12:12:56 +010011package ${block.name}_reg_pkg;
Eunchan Kimc4873f32019-09-25 12:46:12 -070012% if len(block.params) != 0:
13
14 // Param list
15% endif
Eunchan Kimb9931902019-09-26 14:16:40 -070016% for param in [p for p in block.params if p["local"] == "true"]:
Eunchan Kimc4873f32019-09-25 12:46:12 -070017 localparam ${param["type"]} ${param["name"]} = ${param["default"]};
18% endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +010019
Michael Schaffnera2c51d92019-09-27 16:38:24 -070020% if block.contains_multiregs():
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070021/////////////////////////////////////////////////////////////////////
22// Typedefs for multiregs
23/////////////////////////////////////////////////////////////////////
Michael Schaffnera2c51d92019-09-27 16:38:24 -070024
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070025% for r in block.regs:
Michael Schaffnera2c51d92019-09-27 16:38:24 -070026 ## in this case we have a homogeneous multireg, with only one replicated field
27 % if r.is_multi_reg() and r.get_n_bits(["q"]) and r.ishomog:
lowRISC Contributors802543a2019-08-31 12:12:56 +010028typedef struct packed {
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070029 logic [${r.get_field_flat(0).get_n_bits()-1}:0] q;
30 % if r.get_field_flat(0).hwqe:
31 logic qe;
32 % endif
33 % if r.get_field_flat(0).hwre:
34 logic re;
35 % endif
36} ${block.name + "_reg2hw_" + r.name + "_mreg_t"};
Michael Schaffnera2c51d92019-09-27 16:38:24 -070037 ## in this case we have an inhomogeneous multireg, with several different fields per register
38 % elif r.is_multi_reg() and r.get_n_bits(["q"]) and not r.ishomog:
39typedef struct packed {
40 % for f in r.get_reg_flat(0).fields:
41 struct packed {
42 logic [${f.get_n_bits()-1}:0] q;
43 % if f.hwqe:
44 logic qe;
45 % endif
46 % if f.hwre:
47 logic re;
48 % endif
49 } ${f.get_basename()};
50 %endfor
51} ${block.name + "_reg2hw_" + r.name + "_mreg_t"};
52 %endif
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070053% endfor
54
Michael Schaffnera2c51d92019-09-27 16:38:24 -070055% for r in block.regs:
56 ## in this case we have a homogeneous multireg, with only one replicated field
57 % if r.is_multi_reg() and r.get_n_bits(["d"]) and r.ishomog:
58typedef struct packed {
59 logic [${r.get_field_flat(0).get_n_bits(["d"])-1}:0] d;
60 % if not r.get_reg_flat(0).hwext:
61 logic de;
62 % endif
63} ${block.name + "_hw2reg_" + r.name + "_mreg_t"};
64 ## in this case we have an inhomogeneous multireg, with several different fields per register
65 % elif r.is_multi_reg() and r.get_n_bits(["d"]) and not r.ishomog:
66typedef struct packed {
67 % for f in r.get_reg_flat(0).fields:
68 struct packed {
69 logic [${f.get_n_bits(["d"])-1}:0] d;
70 % if not r.hwext:
71 logic de;
72 % endif
73 } ${f.get_basename()};
74 %endfor
75} ${block.name + "_hw2reg_" + r.name + "_mreg_t"};
76 % endif
77% endfor
78
79% endif
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070080/////////////////////////////////////////////////////////////////////
81// Register to internal design logic
82/////////////////////////////////////////////////////////////////////
lowRISC Contributors802543a2019-08-31 12:12:56 +010083<%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070084nbits = block.get_n_bits(["q","qe","re"]) - 1
lowRISC Contributors802543a2019-08-31 12:12:56 +010085packbit = 0
86%>
Michael Schaffner9a92bea2019-09-30 18:13:14 -070087% if nbits > 0:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070088typedef struct packed {
lowRISC Contributors802543a2019-08-31 12:12:56 +010089% for r in block.regs:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070090 ######################## multiregister ###########################
91 % if r.is_multi_reg() and r.get_n_bits(["q"]):
92 <%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070093 array_dims = ""
Michael Schaffnerf9fe0052019-09-27 12:05:58 -070094 for d in r.get_nested_dims():
Michael Schaffner9a94b6c2019-09-25 16:17:35 -070095 array_dims += "[%d:0]" % (d-1)
96 %>${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"]) %>
97 ######################## register with single field ###########################
98 % elif len(r.fields) == 1 and r.get_n_bits(["q"]):
lowRISC Contributors802543a2019-08-31 12:12:56 +010099 ## Only one field, should use register name as it is
100 struct packed {
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700101 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() %>
lowRISC Contributors802543a2019-08-31 12:12:56 +0100102 % if r.fields[0].hwqe:
103 logic qe; // [${nbits - packbit}]<% packbit += 1 %>
104 % endif
105 % if r.fields[0].hwre:
106 logic re; // [${nbits - packbit}]<% packbit += 1 %>
107 % endif
108 } ${r.name};
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700109 ######################## register with multiple fields ###########################
110 % elif len(r.fields) >= 2 and r.get_n_bits(["q"]):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100111 struct packed {
112 % for f in r.fields:
113 % if f.hwaccess in [HwAccess.HRW, HwAccess.HRO]:
114 struct packed {
115 ## reg2hw signal based on HW type and virtual?
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700116 % if f.get_n_bits() > 1:
117 logic [${f.get_n_bits()-1}:0] q; // [${nbits - packbit}:${nbits - (packbit + f.get_n_bits() - 1)}]<% packbit += f.get_n_bits() %>
lowRISC Contributors802543a2019-08-31 12:12:56 +0100118 % else:
119 logic q; // [${nbits - packbit}]<% packbit += 1 %>
120 % endif
121 % if f.hwqe:
122 logic qe; // [${nbits - packbit}]<% packbit += 1 %>
123 % endif
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700124 % if f.hwre:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100125 logic re; // [${nbits - packbit}]<% packbit += 1 %>
126 % endif
127 } ${f.name};
128 % endif
129 % endfor
130 } ${r.name};
131 % endif
132% endfor
133} ${block.name}_reg2hw_t;
Michael Schaffner9a92bea2019-09-30 18:13:14 -0700134% endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100135
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700136/////////////////////////////////////////////////////////////////////
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700137// Internal design logic to register
138/////////////////////////////////////////////////////////////////////
lowRISC Contributors802543a2019-08-31 12:12:56 +0100139<%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700140nbits = block.get_n_bits(["d","de"]) - 1
lowRISC Contributors802543a2019-08-31 12:12:56 +0100141packbit = 0
142%>
Michael Schaffner9a92bea2019-09-30 18:13:14 -0700143% if nbits > 0:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700144typedef struct packed {
lowRISC Contributors802543a2019-08-31 12:12:56 +0100145% for r in block.regs:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700146 ######################## multiregister ###########################
147 % if r.is_multi_reg() and r.get_n_bits(["d"]):
148 <%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700149 array_dims = ""
Michael Schaffnerf9fe0052019-09-27 12:05:58 -0700150 for d in r.get_nested_dims():
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700151 array_dims += "[%d:0]" % (d-1)
152 %>${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"]) %>
153 ######################## register with single field ###########################
154 % elif len(r.fields) == 1 and r.get_n_bits(["d"]):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100155 ## Only one field, should use register name as it is
156 struct packed {
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700157 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") %>
lowRISC Contributors802543a2019-08-31 12:12:56 +0100158 % if r.hwext == 0:
159 logic de; // [${nbits - packbit}]<% packbit += 1 %>
160 % endif
161 } ${r.name};
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700162 ######################## register with multiple fields ###########################
163 % elif len(r.fields) >= 2 and r.get_n_bits(["d"]):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100164 struct packed {
165 % for f in r.fields:
166 % if f.hwaccess in [HwAccess.HRW, HwAccess.HWO]:
167 struct packed {
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700168 ## reg2hw signal based on HW type and virtual?
169 % if f.get_n_bits("d") > 1:
170 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") %>
lowRISC Contributors802543a2019-08-31 12:12:56 +0100171 % else:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700172 logic d; // [${nbits - packbit}]<% packbit += 1 %>
lowRISC Contributors802543a2019-08-31 12:12:56 +0100173 % endif
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700174 % if not r.hwext:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100175 logic de; // [${nbits - packbit}]<% packbit += 1 %>
176 % endif
177 } ${f.name};
178 % endif
179 % endfor
180 } ${r.name};
181 % endif
182% endfor
183} ${block.name}_hw2reg_t;
Michael Schaffner9a92bea2019-09-30 18:13:14 -0700184% endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100185
186 // Register Address
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700187% for r in block.get_regs_flat():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100188 parameter ${block.name.upper()}_${r.name.upper()}_OFFSET = ${block.addr_width}'h ${"%x" % r.offset};
189% endfor
190
191% if len(block.wins) > 0:
192 // Window parameter
193% endif
194% for i,w in enumerate(block.wins):
195 parameter ${block.name.upper()}_${w.name.upper()}_OFFSET = ${block.addr_width}'h ${"%x" % w.base_addr};
196 parameter ${block.name.upper()}_${w.name.upper()}_SIZE = ${block.addr_width}'h ${"%x" % (w.limit_addr - w.base_addr)};
197% endfor
198
Eunchan Kim51461cd2019-09-18 14:00:49 -0700199 // Register Index
200 typedef enum int {
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700201% for r in block.get_regs_flat():
Eunchan Kim51461cd2019-09-18 14:00:49 -0700202 ${block.name.upper()}_${r.name.upper()}${"" if loop.last else ","}
203% endfor
204 } ${block.name}_id_e;
205
206 // Register width information to check illegal writes
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700207 localparam logic [3:0] ${block.name.upper()}_PERMIT [${block.get_n_regs_flat()}] = '{
208% for i,r in enumerate(block.get_regs_flat()):
Eunchan Kim51461cd2019-09-18 14:00:49 -0700209<% index_str = "{}".format(i).rjust(max_regs_char) %>\
210 % if r.width > 16:
Eunchan Kimbc5d5142019-09-19 14:54:06 -0700211 4'b 1111${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
Eunchan Kim51461cd2019-09-18 14:00:49 -0700212 % elif r.width > 8:
Eunchan Kimbc5d5142019-09-19 14:54:06 -0700213 4'b 0011${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
Eunchan Kim51461cd2019-09-18 14:00:49 -0700214 % else:
Eunchan Kimbc5d5142019-09-19 14:54:06 -0700215 4'b 0001${" " if i == num_regs-1 else ","} // index[${index_str}] ${block.name.upper()}_${r.name.upper()}
Eunchan Kim51461cd2019-09-18 14:00:49 -0700216 % endif
217% endfor
218 };
lowRISC Contributors802543a2019-08-31 12:12:56 +0100219endpackage
Eunchan Kim51461cd2019-09-18 14:00:49 -0700220