blob: d925c74fa7e7ea6a563fce0382dc5a7f6693c25f [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 Top module auto-generated by `reggen`
6<%
Rupert Swarbrick200d8b42021-03-08 12:32:11 +00007 from reggen import gen_rtl
8 from reggen.access import HwAccess, SwRdAccess, SwWrAccess
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +00009 from reggen.lib import get_basename
Rupert Swarbrick4d645362021-02-08 17:17:05 +000010 from reggen.register import Register
11 from reggen.multi_register import MultiRegister
Rupert Swarbrickede94802021-02-08 09:16:50 +000012
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000013 num_wins = len(rb.windows)
lowRISC Contributors802543a2019-08-31 12:12:56 +010014 num_wins_width = ((num_wins+1).bit_length()) - 1
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000015 num_reg_dsp = 1 if rb.all_regs else 0
16 num_dsp = num_wins + num_reg_dsp
17 regs_flat = rb.flat_regs
Rupert Swarbrick1db6fcd2021-02-11 14:56:20 +000018 max_regs_char = len("{}".format(len(regs_flat) - 1))
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000019 addr_width = rb.get_addr_width()
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000020
21 lblock = block.name.lower()
22 ublock = lblock.upper()
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000023
24 u_mod_base = mod_base.upper()
25
26 reg2hw_t = gen_rtl.get_iface_tx_type(block, if_name, False)
27 hw2reg_t = gen_rtl.get_iface_tx_type(block, if_name, True)
28
29 # Calculate whether we're going to need an AW parameter. We use it if there
30 # are any registers (obviously). We also use it if there are any windows that
31 # don't start at zero and end at 1 << addr_width (see the "addr_checks"
32 # calculation below for where that comes from).
33 needs_aw = (bool(regs_flat) or
34 num_wins > 1 or
35 rb.windows and (
36 rb.windows[0].offset != 0 or
37 rb.windows[0].size_in_bytes != (1 << addr_width)))
38
lowRISC Contributors802543a2019-08-31 12:12:56 +010039%>
Greg Chadwickcf423082020-02-05 16:52:23 +000040`include "prim_assert.sv"
41
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000042module ${mod_name} (
lowRISC Contributors802543a2019-08-31 12:12:56 +010043 input clk_i,
44 input rst_ni,
45
lowRISC Contributors802543a2019-08-31 12:12:56 +010046 input tlul_pkg::tl_h2d_t tl_i,
47 output tlul_pkg::tl_d2h_t tl_o,
48% if num_wins != 0:
49
50 // Output port for window
51 output tlul_pkg::tl_h2d_t tl_win_o [${num_wins}],
52 input tlul_pkg::tl_d2h_t tl_win_i [${num_wins}],
53
54% endif
55 // To HW
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000056% if rb.get_n_bits(["q","qe","re"]):
57 output ${lblock}_reg_pkg::${reg2hw_t} reg2hw, // Write
Michael Schaffner9a92bea2019-09-30 18:13:14 -070058% endif
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000059% if rb.get_n_bits(["d","de"]):
60 input ${lblock}_reg_pkg::${hw2reg_t} hw2reg, // Read
Michael Schaffner9a92bea2019-09-30 18:13:14 -070061% endif
Eunchan Kimde88e3a2019-09-23 11:06:41 -070062
Timothy Chenaa6c1ed2021-03-01 16:20:11 -080063 // Integrity check errors
64 output logic intg_err_o,
65
Eunchan Kimde88e3a2019-09-23 11:06:41 -070066 // Config
67 input devmode_i // If 1, explicit error return for unmapped register access
lowRISC Contributors802543a2019-08-31 12:12:56 +010068);
69
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000070 import ${lblock}_reg_pkg::* ;
lowRISC Contributors802543a2019-08-31 12:12:56 +010071
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000072% if needs_aw:
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000073 localparam int AW = ${addr_width};
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000074% endif
75% if rb.all_regs:
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +000076 localparam int DW = ${block.regwidth};
Michael Schaffner1b5fa9f2020-01-17 17:43:42 -080077 localparam int DBW = DW/8; // Byte Width
lowRISC Contributors802543a2019-08-31 12:12:56 +010078
79 // register signals
Eunchan Kim819a4662019-09-04 21:44:36 -070080 logic reg_we;
81 logic reg_re;
82 logic [AW-1:0] reg_addr;
83 logic [DW-1:0] reg_wdata;
84 logic [DBW-1:0] reg_be;
85 logic [DW-1:0] reg_rdata;
86 logic reg_error;
lowRISC Contributors802543a2019-08-31 12:12:56 +010087
Eunchan Kim51461cd2019-09-18 14:00:49 -070088 logic addrmiss, wr_err;
lowRISC Contributors802543a2019-08-31 12:12:56 +010089
Eunchan Kim819a4662019-09-04 21:44:36 -070090 logic [DW-1:0] reg_rdata_next;
lowRISC Contributors802543a2019-08-31 12:12:56 +010091
92 tlul_pkg::tl_h2d_t tl_reg_h2d;
93 tlul_pkg::tl_d2h_t tl_reg_d2h;
Rupert Swarbrick200d8b42021-03-08 12:32:11 +000094% endif
lowRISC Contributors802543a2019-08-31 12:12:56 +010095
Timothy Chend12569f2021-02-12 15:28:12 -080096 // incoming payload check
Timothy Chenaa6c1ed2021-03-01 16:20:11 -080097 logic intg_err;
98 tlul_cmd_intg_chk u_chk (
Timothy Chend12569f2021-02-12 15:28:12 -080099 .tl_i,
Timothy Chen915df692021-03-05 13:16:36 -0800100 .err_o(intg_err)
Timothy Chend12569f2021-02-12 15:28:12 -0800101 );
102
Timothy Chen915df692021-03-05 13:16:36 -0800103 logic intg_err_q;
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800104 always_ff @(posedge clk_i or negedge rst_ni) begin
105 if (!rst_ni) begin
Timothy Chen915df692021-03-05 13:16:36 -0800106 intg_err_q <= '0;
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800107 end else if (intg_err) begin
Timothy Chen915df692021-03-05 13:16:36 -0800108 intg_err_q <= 1'b1;
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800109 end
110 end
111
Timothy Chen915df692021-03-05 13:16:36 -0800112 // integrity error output is permanent and should be used for alert generation
113 // register errors are transactional
114 assign intg_err_o = intg_err_q | intg_err;
115
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800116 // outgoing integrity generation
Timothy Chend12569f2021-02-12 15:28:12 -0800117 tlul_pkg::tl_d2h_t tl_o_pre;
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800118 tlul_rsp_intg_gen u_rsp_intg_gen (
Timothy Chend12569f2021-02-12 15:28:12 -0800119 .tl_i(tl_o_pre),
120 .tl_o
121 );
122
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000123% if num_dsp == 1:
124 ## Either no windows (and just registers) or no registers and only
125 ## one window.
126 % if num_wins == 0:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100127 assign tl_reg_h2d = tl_i;
Timothy Chend12569f2021-02-12 15:28:12 -0800128 assign tl_o_pre = tl_reg_d2h;
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000129 % else:
130 assign tl_win_o[0] = tl_i;
131 assign tl_o_pre = tl_win_i[0];
132 % endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100133% else:
134 tlul_pkg::tl_h2d_t tl_socket_h2d [${num_dsp}];
135 tlul_pkg::tl_d2h_t tl_socket_d2h [${num_dsp}];
136
137 logic [${num_wins_width}:0] reg_steer;
138
139 // socket_1n connection
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000140 % if rb.all_regs:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100141 assign tl_reg_h2d = tl_socket_h2d[${num_wins}];
142 assign tl_socket_d2h[${num_wins}] = tl_reg_d2h;
143
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000144 % endif
145 % for i,t in enumerate(rb.windows):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100146 assign tl_win_o[${i}] = tl_socket_h2d[${i}];
147 assign tl_socket_d2h[${i}] = tl_win_i[${i}];
148 % endfor
149
150 // Create Socket_1n
151 tlul_socket_1n #(
152 .N (${num_dsp}),
153 .HReqPass (1'b1),
154 .HRspPass (1'b1),
155 .DReqPass ({${num_dsp}{1'b1}}),
156 .DRspPass ({${num_dsp}{1'b1}}),
Eunchan Kim32dd11b2019-11-05 15:15:33 -0800157 .HReqDepth (4'h0),
158 .HRspDepth (4'h0),
159 .DReqDepth ({${num_dsp}{4'h0}}),
160 .DRspDepth ({${num_dsp}{4'h0}})
lowRISC Contributors802543a2019-08-31 12:12:56 +0100161 ) u_socket (
162 .clk_i,
163 .rst_ni,
164 .tl_h_i (tl_i),
Timothy Chend12569f2021-02-12 15:28:12 -0800165 .tl_h_o (tl_o_pre),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100166 .tl_d_o (tl_socket_h2d),
167 .tl_d_i (tl_socket_d2h),
Scott Johnson204d98d2020-07-17 12:06:05 -0700168 .dev_select_i (reg_steer)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100169 );
170
171 // Create steering logic
172 always_comb begin
173 reg_steer = ${num_dsp-1}; // Default set to register
174
175 // TODO: Can below codes be unique case () inside ?
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000176 % for i,w in enumerate(rb.windows):
Rupert Swarbrickbc2bc582021-02-09 13:30:37 +0000177<%
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000178 base_addr = w.offset
179 limit_addr = w.offset + w.size_in_bytes
180
181 hi_check = 'tl_i.a_address[AW-1:0] < {}'.format(limit_addr)
182 addr_checks = []
183 if base_addr > 0:
184 addr_checks.append('tl_i.a_address[AW-1:0] >= {}'.format(base_addr))
185 if limit_addr < 2**addr_width:
186 addr_checks.append('tl_i.a_address[AW-1:0] < {}'.format(limit_addr))
187
188 addr_test = ' && '.join(addr_checks)
Rupert Swarbrickbc2bc582021-02-09 13:30:37 +0000189%>\
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000190 % if addr_test:
191 if (${addr_test}) begin
lowRISC Contributors802543a2019-08-31 12:12:56 +0100192 % endif
193 reg_steer = ${i};
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000194 % if addr_test:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100195 end
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000196 % endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100197 % endfor
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800198 if (intg_err) begin
Timothy Chend12569f2021-02-12 15:28:12 -0800199 reg_steer = ${num_dsp-1};
200 end
lowRISC Contributors802543a2019-08-31 12:12:56 +0100201 end
202% endif
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000203% if rb.all_regs:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100204
Eunchan Kim819a4662019-09-04 21:44:36 -0700205 tlul_adapter_reg #(
206 .RegAw(AW),
207 .RegDw(DW)
208 ) u_reg_if (
209 .clk_i,
210 .rst_ni,
lowRISC Contributors802543a2019-08-31 12:12:56 +0100211
Eunchan Kim819a4662019-09-04 21:44:36 -0700212 .tl_i (tl_reg_h2d),
213 .tl_o (tl_reg_d2h),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100214
Eunchan Kim819a4662019-09-04 21:44:36 -0700215 .we_o (reg_we),
216 .re_o (reg_re),
217 .addr_o (reg_addr),
218 .wdata_o (reg_wdata),
219 .be_o (reg_be),
220 .rdata_i (reg_rdata),
221 .error_i (reg_error)
222 );
lowRISC Contributors802543a2019-08-31 12:12:56 +0100223
Eunchan Kim819a4662019-09-04 21:44:36 -0700224 assign reg_rdata = reg_rdata_next ;
Timothy Chenaa6c1ed2021-03-01 16:20:11 -0800225 assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100226
227 // Define SW related signals
228 // Format: <reg>_<field>_{wd|we|qs}
229 // or <reg>_{wd|we|qs} if field == 1 or 0
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700230 % for r in regs_flat:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100231 % if len(r.fields) == 1:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000232${sig_gen(r.fields[0], r.name.lower(), r.hwext, r.shadowed)}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100233 % else:
234 % for f in r.fields:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000235${sig_gen(f, r.name.lower() + "_" + f.name.lower(), r.hwext, r.shadowed)}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100236 % endfor
237 % endif
238 % endfor
239
240 // Register instances
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000241 % for r in rb.all_regs:
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700242 ######################## multiregister ###########################
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000243 % if isinstance(r, MultiRegister):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100244<%
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700245 k = 0
246%>
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000247 % for sr in r.regs:
248 // Subregister ${k} of Multireg ${r.reg.name.lower()}
249 // R[${sr.name.lower()}]: V(${str(sr.hwext)})
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700250 % if len(sr.fields) == 1:
251<%
252 f = sr.fields[0]
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000253 finst_name = sr.name.lower()
254 fsig_name = r.reg.name.lower() + "[%d]" % k
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700255 k = k + 1
lowRISC Contributors802543a2019-08-31 12:12:56 +0100256%>
Rupert Swarbrickede94802021-02-08 09:16:50 +0000257${finst_gen(f, finst_name, fsig_name, sr.hwext, sr.regwen, sr.shadowed)}
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700258 % else:
259 % for f in sr.fields:
260<%
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000261 finst_name = sr.name.lower() + "_" + f.name.lower()
262 if r.is_homogeneous():
263 fsig_name = r.reg.name.lower() + "[%d]" % k
Michael Schaffnera2c51d92019-09-27 16:38:24 -0700264 k = k + 1
265 else:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000266 fsig_name = r.reg.name.lower() + "[%d]" % k + "." + get_basename(f.name.lower())
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700267%>
Rupert Swarbrickede94802021-02-08 09:16:50 +0000268 // F[${f.name.lower()}]: ${f.bits.msb}:${f.bits.lsb}
269${finst_gen(f, finst_name, fsig_name, sr.hwext, sr.regwen, sr.shadowed)}
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700270 % endfor
Michael Schaffnera2c51d92019-09-27 16:38:24 -0700271<%
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000272 if not r.is_homogeneous():
Michael Schaffnera2c51d92019-09-27 16:38:24 -0700273 k += 1
274%>
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700275 % endif
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000276 ## for: mreg_flat
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700277 % endfor
278######################## register with single field ###########################
279 % elif len(r.fields) == 1:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000280 // R[${r.name.lower()}]: V(${str(r.hwext)})
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700281<%
282 f = r.fields[0]
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000283 finst_name = r.name.lower()
284 fsig_name = r.name.lower()
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700285%>
Rupert Swarbrickede94802021-02-08 09:16:50 +0000286${finst_gen(f, finst_name, fsig_name, r.hwext, r.regwen, r.shadowed)}
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700287######################## register with multiple fields ###########################
lowRISC Contributors802543a2019-08-31 12:12:56 +0100288 % else:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000289 // R[${r.name.lower()}]: V(${str(r.hwext)})
lowRISC Contributors802543a2019-08-31 12:12:56 +0100290 % for f in r.fields:
291<%
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000292 finst_name = r.name.lower() + "_" + f.name.lower()
293 fsig_name = r.name.lower() + "." + f.name.lower()
lowRISC Contributors802543a2019-08-31 12:12:56 +0100294%>
Rupert Swarbrickede94802021-02-08 09:16:50 +0000295 // F[${f.name.lower()}]: ${f.bits.msb}:${f.bits.lsb}
296${finst_gen(f, finst_name, fsig_name, r.hwext, r.regwen, r.shadowed)}
lowRISC Contributors802543a2019-08-31 12:12:56 +0100297 % endfor
298 % endif
299
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000300 ## for: rb.all_regs
lowRISC Contributors802543a2019-08-31 12:12:56 +0100301 % endfor
302
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700303
304 logic [${len(regs_flat)-1}:0] addr_hit;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100305 always_comb begin
306 addr_hit = '0;
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700307 % for i,r in enumerate(regs_flat):
Rupert Swarbrick269bb3d2021-02-23 15:41:56 +0000308 addr_hit[${"{}".format(i).rjust(max_regs_char)}] = (reg_addr == ${ublock}_${r.name.upper()}_OFFSET);
lowRISC Contributors802543a2019-08-31 12:12:56 +0100309 % endfor
310 end
311
Eunchan Kim244a1d52019-09-23 15:46:43 -0700312 assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100313
Eunchan Kim51461cd2019-09-18 14:00:49 -0700314 // Check sub-word write is permitted
315 always_comb begin
316 wr_err = 1'b0;
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700317 % for i,r in enumerate(regs_flat):
Eunchan Kim51461cd2019-09-18 14:00:49 -0700318<% index_str = "{}".format(i).rjust(max_regs_char) %>\
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000319 if (addr_hit[${index_str}] && reg_we && (${u_mod_base}_PERMIT[${index_str}] != (${u_mod_base}_PERMIT[${index_str}] & reg_be))) wr_err = 1'b1 ;
Eunchan Kim51461cd2019-09-18 14:00:49 -0700320 % endfor
321 end
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700322 % for i, r in enumerate(regs_flat):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100323 % if len(r.fields) == 1:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000324${we_gen(r.fields[0], r.name.lower(), r.hwext, r.shadowed, i)}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100325 % else:
326 % for f in r.fields:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000327${we_gen(f, r.name.lower() + "_" + f.name.lower(), r.hwext, r.shadowed, i)}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100328 % endfor
329 % endif
330 % endfor
331
332 // Read data return
lowRISC Contributors802543a2019-08-31 12:12:56 +0100333 always_comb begin
334 reg_rdata_next = '0;
335 unique case (1'b1)
Michael Schaffner9a94b6c2019-09-25 16:17:35 -0700336 % for i, r in enumerate(regs_flat):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100337 % if len(r.fields) == 1:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100338 addr_hit[${i}]: begin
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000339${rdata_gen(r.fields[0], r.name.lower())}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100340 end
341
342 % else:
343 addr_hit[${i}]: begin
344 % for f in r.fields:
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000345${rdata_gen(f, r.name.lower() + "_" + f.name.lower())}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100346 % endfor
347 end
348
349 % endif
350 % endfor
351 default: begin
352 reg_rdata_next = '1;
353 end
354 endcase
355 end
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000356% endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100357
Timothy Chenac6af872021-02-22 17:17:52 -0800358 // Unused signal tieoff
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000359% if rb.all_regs:
Timothy Chenac6af872021-02-22 17:17:52 -0800360
361 // wdata / byte enable are not always fully used
362 // add a blanket unused statement to handle lint waivers
363 logic unused_wdata;
364 logic unused_be;
365 assign unused_wdata = ^reg_wdata;
366 assign unused_be = ^reg_be;
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000367% else:
368 // devmode_i is not used if there are no registers
369 logic unused_devmode;
370 assign unused_devmode = ^devmode_i;
371% endif
372% if rb.all_regs:
Timothy Chenac6af872021-02-22 17:17:52 -0800373
lowRISC Contributors802543a2019-08-31 12:12:56 +0100374 // Assertions for Register Interface
Greg Chadwick46ede4b2020-01-14 12:46:39 +0000375 `ASSERT_PULSE(wePulse, reg_we)
376 `ASSERT_PULSE(rePulse, reg_re)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100377
Greg Chadwick46ede4b2020-01-14 12:46:39 +0000378 `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100379
Greg Chadwick46ede4b2020-01-14 12:46:39 +0000380 `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
lowRISC Contributors802543a2019-08-31 12:12:56 +0100381
Michael Schaffneree9e8db2019-10-22 17:49:51 -0700382 // this is formulated as an assumption such that the FPV testbenches do disprove this
383 // property by mistake
Timothy Chen27b0a642021-02-16 14:02:08 -0800384 //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100385
Rupert Swarbrick200d8b42021-03-08 12:32:11 +0000386% endif
lowRISC Contributors802543a2019-08-31 12:12:56 +0100387endmodule
Rupert Swarbrickede94802021-02-08 09:16:50 +0000388<%def name="str_bits_sv(bits)">\
389% if bits.msb != bits.lsb:
390${bits.msb}:${bits.lsb}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100391% else:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000392${bits.msb}\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100393% endif
394</%def>\
Rupert Swarbrickede94802021-02-08 09:16:50 +0000395<%def name="str_arr_sv(bits)">\
396% if bits.msb != bits.lsb:
397[${bits.msb-bits.lsb}:0] \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100398% endif
399</%def>\
Rupert Swarbrickede94802021-02-08 09:16:50 +0000400<%def name="sig_gen(field, sig_name, hwext, shadowed)">\
401 % if field.swaccess.allows_read():
402 logic ${str_arr_sv(field.bits)}${sig_name}_qs;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100403 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000404 % if field.swaccess.allows_write():
405 logic ${str_arr_sv(field.bits)}${sig_name}_wd;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100406 logic ${sig_name}_we;
407 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000408 % if (field.swaccess.allows_read() and hwext) or shadowed:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100409 logic ${sig_name}_re;
410 % endif
411</%def>\
Rupert Swarbrickede94802021-02-08 09:16:50 +0000412<%def name="finst_gen(field, finst_name, fsig_name, hwext, regwen, shadowed)">\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100413 % if hwext: ## if hwext, instantiate prim_subreg_ext
414 prim_subreg_ext #(
Rupert Swarbrickede94802021-02-08 09:16:50 +0000415 .DW (${field.bits.width()})
lowRISC Contributors802543a2019-08-31 12:12:56 +0100416 ) u_${finst_name} (
Rupert Swarbrickede94802021-02-08 09:16:50 +0000417 % if field.swaccess.allows_read():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100418 .re (${finst_name}_re),
419 % else:
420 .re (1'b0),
421 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000422 % if field.swaccess.allows_write():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100423 % if regwen:
424 // qualified with register enable
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000425 .we (${finst_name}_we & ${regwen.lower()}_qs),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100426 % else:
427 .we (${finst_name}_we),
428 % endif
429 .wd (${finst_name}_wd),
430 % else:
431 .we (1'b0),
432 .wd ('0),
433 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000434 % if field.hwaccess.allows_write():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100435 .d (hw2reg.${fsig_name}.d),
Rupert Swarbrickede94802021-02-08 09:16:50 +0000436 % else:
437 .d ('0),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100438 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000439 % if field.hwre or shadowed:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100440 .qre (reg2hw.${fsig_name}.re),
441 % else:
442 .qre (),
443 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000444 % if not field.hwaccess.allows_read():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100445 .qe (),
446 .q (),
447 % else:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000448 % if field.hwqe:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100449 .qe (reg2hw.${fsig_name}.qe),
450 % else:
451 .qe (),
452 % endif
453 .q (reg2hw.${fsig_name}.q ),
454 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000455 % if field.swaccess.allows_read():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100456 .qs (${finst_name}_qs)
457 % else:
458 .qs ()
459 % endif
460 );
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200461 % else: ## if not hwext, instantiate prim_subreg, prim_subreg_shadow or constant assign
Rupert Swarbrickede94802021-02-08 09:16:50 +0000462 % if ((not field.hwaccess.allows_read() and\
463 not field.hwaccess.allows_write() and\
464 field.swaccess.swrd() == SwRdAccess.RD and\
465 not field.swaccess.allows_write())):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100466 // constant-only read
Rupert Swarbrickede94802021-02-08 09:16:50 +0000467 assign ${finst_name}_qs = ${field.bits.width()}'h${"%x" % (field.resval or 0)};
lowRISC Contributors802543a2019-08-31 12:12:56 +0100468 % else: ## not hwext not constant
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200469 % if not shadowed:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100470 prim_subreg #(
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200471 % else:
472 prim_subreg_shadow #(
473 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000474 .DW (${field.bits.width()}),
475 .SWACCESS("${field.swaccess.value[1].name.upper()}"),
476 .RESVAL (${field.bits.width()}'h${"%x" % (field.resval or 0)})
lowRISC Contributors802543a2019-08-31 12:12:56 +0100477 ) u_${finst_name} (
478 .clk_i (clk_i ),
479 .rst_ni (rst_ni ),
480
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200481 % if shadowed:
482 .re (${finst_name}_re),
483 % endif
Rupert Swarbrickede94802021-02-08 09:16:50 +0000484 % if field.swaccess.allows_write(): ## non-RO types
lowRISC Contributors802543a2019-08-31 12:12:56 +0100485 % if regwen:
486 // from register interface (qualified with register enable)
Rupert Swarbrick4d645362021-02-08 17:17:05 +0000487 .we (${finst_name}_we & ${regwen.lower()}_qs),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100488 % else:
489 // from register interface
490 .we (${finst_name}_we),
491 % endif
492 .wd (${finst_name}_wd),
493 % else: ## RO types
494 .we (1'b0),
495 .wd ('0 ),
496 % endif
497
498 // from internal hardware
Rupert Swarbrickede94802021-02-08 09:16:50 +0000499 % if field.hwaccess.allows_write():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100500 .de (hw2reg.${fsig_name}.de),
501 .d (hw2reg.${fsig_name}.d ),
Rupert Swarbrickede94802021-02-08 09:16:50 +0000502 % else:
503 .de (1'b0),
504 .d ('0 ),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100505 % endif
506
507 // to internal hardware
Rupert Swarbrickede94802021-02-08 09:16:50 +0000508 % if not field.hwaccess.allows_read():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100509 .qe (),
510 .q (),
511 % else:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000512 % if field.hwqe:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100513 .qe (reg2hw.${fsig_name}.qe),
514 % else:
515 .qe (),
516 % endif
517 .q (reg2hw.${fsig_name}.q ),
518 % endif
519
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200520 % if not shadowed:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000521 % if field.swaccess.allows_read():
lowRISC Contributors802543a2019-08-31 12:12:56 +0100522 // to register interface (read)
523 .qs (${finst_name}_qs)
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200524 % else:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100525 .qs ()
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200526 % endif
527 % else:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000528 % if field.swaccess.allows_read():
Pirmin Vogelab9d1ca2020-05-25 14:52:55 +0200529 // to register interface (read)
530 .qs (${finst_name}_qs),
531 % else:
532 .qs (),
533 % endif
534
535 // Shadow register error conditions
536 .err_update (reg2hw.${fsig_name}.err_update ),
537 .err_storage (reg2hw.${fsig_name}.err_storage)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100538 % endif
539 );
540 % endif ## end non-constant prim_subreg
541 % endif
542</%def>\
Rupert Swarbrickede94802021-02-08 09:16:50 +0000543<%def name="we_gen(field, sig_name, hwext, shadowed, idx)">\
Rupert Swarbrick1032b472021-03-12 11:09:56 +0000544<%
545 needs_we = field.swaccess.allows_write()
546 needs_re = (field.swaccess.allows_read() and hwext) or shadowed
547 space = '\n' if needs_we or needs_re else ''
548%>\
549${space}\
550% if needs_we:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000551 % if field.swaccess.swrd() != SwRdAccess.RC:
Timothy Chena6f58292021-03-02 14:02:47 -0800552 assign ${sig_name}_we = addr_hit[${idx}] & reg_we & !reg_error;
Rupert Swarbrickede94802021-02-08 09:16:50 +0000553 assign ${sig_name}_wd = reg_wdata[${str_bits_sv(field.bits)}];
lowRISC Contributors802543a2019-08-31 12:12:56 +0100554 % else:
555 ## Generate WE based on read request, read should clear
Timothy Chena6f58292021-03-02 14:02:47 -0800556 assign ${sig_name}_we = addr_hit[${idx}] & reg_re & !reg_error;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100557 assign ${sig_name}_wd = '1;
558 % endif
559% endif
Rupert Swarbrick1032b472021-03-12 11:09:56 +0000560% if needs_re:
Timothy Chena6f58292021-03-02 14:02:47 -0800561 assign ${sig_name}_re = addr_hit[${idx}] & reg_re & !reg_error;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100562% endif
563</%def>\
Rupert Swarbrickede94802021-02-08 09:16:50 +0000564<%def name="rdata_gen(field, sig_name)">\
565% if field.swaccess.allows_read():
566 reg_rdata_next[${str_bits_sv(field.bits)}] = ${sig_name}_qs;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100567% else:
Rupert Swarbrickede94802021-02-08 09:16:50 +0000568 reg_rdata_next[${str_bits_sv(field.bits)}] = '0;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100569% endif
570</%def>\