../src/lowrisc_ip_rstmgr_0.1/rtl/rstmgr_reg_top.sv Cov: 100%
1: // 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:
7: `include "prim_assert.sv"
8:
9: module rstmgr_reg_top (
10: input clk_i,
11: input rst_ni,
12:
13: // Below Regster interface can be changed
14: input tlul_pkg::tl_h2d_t tl_i,
15: output tlul_pkg::tl_d2h_t tl_o,
16: // To HW
17: output rstmgr_reg_pkg::rstmgr_reg2hw_t reg2hw, // Write
18: input rstmgr_reg_pkg::rstmgr_hw2reg_t hw2reg, // Read
19:
20: // Config
21: input devmode_i // If 1, explicit error return for unmapped register access
22: );
23:
24: import rstmgr_reg_pkg::* ;
25:
26: localparam int AW = 5;
27: localparam int DW = 32;
28: localparam int DBW = DW/8; // Byte Width
29:
30: // register signals
31: logic reg_we;
32: logic reg_re;
33: logic [AW-1:0] reg_addr;
34: logic [DW-1:0] reg_wdata;
35: logic [DBW-1:0] reg_be;
36: logic [DW-1:0] reg_rdata;
37: logic reg_error;
38:
39: logic addrmiss, wr_err;
40:
41: logic [DW-1:0] reg_rdata_next;
42:
43: tlul_pkg::tl_h2d_t tl_reg_h2d;
44: tlul_pkg::tl_d2h_t tl_reg_d2h;
45:
46: assign tl_reg_h2d = tl_i;
47: assign tl_o = tl_reg_d2h;
48:
49: tlul_adapter_reg #(
50: .RegAw(AW),
51: .RegDw(DW)
52: ) u_reg_if (
53: .clk_i,
54: .rst_ni,
55:
56: .tl_i (tl_reg_h2d),
57: .tl_o (tl_reg_d2h),
58:
59: .we_o (reg_we),
60: .re_o (reg_re),
61: .addr_o (reg_addr),
62: .wdata_o (reg_wdata),
63: .be_o (reg_be),
64: .rdata_i (reg_rdata),
65: .error_i (reg_error)
66: );
67:
68: assign reg_rdata = reg_rdata_next ;
69: assign reg_error = (devmode_i & addrmiss) | wr_err ;
70:
71: // Define SW related signals
72: // Format: __{wd|we|qs}
73: // or _{wd|we|qs} if field == 1 or 0
74: logic [4:0] reset_info_qs;
75: logic [4:0] reset_info_wd;
76: logic reset_info_we;
77: logic reset_info_re;
78: logic spi_device_regen_qs;
79: logic spi_device_regen_wd;
80: logic spi_device_regen_we;
81: logic usb_regen_qs;
82: logic usb_regen_wd;
83: logic usb_regen_we;
84: logic rst_spi_device_n_qs;
85: logic rst_spi_device_n_wd;
86: logic rst_spi_device_n_we;
87: logic rst_usb_n_qs;
88: logic rst_usb_n_wd;
89: logic rst_usb_n_we;
90:
91: // Register instances
92: // R[reset_info]: V(True)
93:
94: prim_subreg_ext #(
95: .DW (5)
96: ) u_reset_info (
97: .re (reset_info_re),
98: .we (reset_info_we),
99: .wd (reset_info_wd),
100: .d (hw2reg.reset_info.d),
101: .qre (),
102: .qe (reg2hw.reset_info.qe),
103: .q (reg2hw.reset_info.q ),
104: .qs (reset_info_qs)
105: );
106:
107:
108: // R[spi_device_regen]: V(False)
109:
110: prim_subreg #(
111: .DW (1),
112: .SWACCESS("W1C"),
113: .RESVAL (1'h1)
114: ) u_spi_device_regen (
115: .clk_i (clk_i ),
116: .rst_ni (rst_ni ),
117:
118: // from register interface
119: .we (spi_device_regen_we),
120: .wd (spi_device_regen_wd),
121:
122: // from internal hardware
123: .de (1'b0),
124: .d ('0 ),
125:
126: // to internal hardware
127: .qe (),
128: .q (),
129:
130: // to register interface (read)
131: .qs (spi_device_regen_qs)
132: );
133:
134:
135: // R[usb_regen]: V(False)
136:
137: prim_subreg #(
138: .DW (1),
139: .SWACCESS("W1C"),
140: .RESVAL (1'h1)
141: ) u_usb_regen (
142: .clk_i (clk_i ),
143: .rst_ni (rst_ni ),
144:
145: // from register interface
146: .we (usb_regen_we),
147: .wd (usb_regen_wd),
148:
149: // from internal hardware
150: .de (1'b0),
151: .d ('0 ),
152:
153: // to internal hardware
154: .qe (),
155: .q (),
156:
157: // to register interface (read)
158: .qs (usb_regen_qs)
159: );
160:
161:
162: // R[rst_spi_device_n]: V(False)
163:
164: prim_subreg #(
165: .DW (1),
166: .SWACCESS("RW"),
167: .RESVAL (1'h1)
168: ) u_rst_spi_device_n (
169: .clk_i (clk_i ),
170: .rst_ni (rst_ni ),
171:
172: // from register interface (qualified with register enable)
173: .we (rst_spi_device_n_we & spi_device_regen_qs),
174: .wd (rst_spi_device_n_wd),
175:
176: // from internal hardware
177: .de (1'b0),
178: .d ('0 ),
179:
180: // to internal hardware
181: .qe (),
182: .q (reg2hw.rst_spi_device_n.q ),
183:
184: // to register interface (read)
185: .qs (rst_spi_device_n_qs)
186: );
187:
188:
189: // R[rst_usb_n]: V(False)
190:
191: prim_subreg #(
192: .DW (1),
193: .SWACCESS("RW"),
194: .RESVAL (1'h1)
195: ) u_rst_usb_n (
196: .clk_i (clk_i ),
197: .rst_ni (rst_ni ),
198:
199: // from register interface (qualified with register enable)
200: .we (rst_usb_n_we & usb_regen_qs),
201: .wd (rst_usb_n_wd),
202:
203: // from internal hardware
204: .de (1'b0),
205: .d ('0 ),
206:
207: // to internal hardware
208: .qe (),
209: .q (reg2hw.rst_usb_n.q ),
210:
211: // to register interface (read)
212: .qs (rst_usb_n_qs)
213: );
214:
215:
216:
217:
218: logic [4:0] addr_hit;
219: always_comb begin
220: addr_hit = '0;
221: addr_hit[0] = (reg_addr == RSTMGR_RESET_INFO_OFFSET);
222: addr_hit[1] = (reg_addr == RSTMGR_SPI_DEVICE_REGEN_OFFSET);
223: addr_hit[2] = (reg_addr == RSTMGR_USB_REGEN_OFFSET);
224: addr_hit[3] = (reg_addr == RSTMGR_RST_SPI_DEVICE_N_OFFSET);
225: addr_hit[4] = (reg_addr == RSTMGR_RST_USB_N_OFFSET);
226: end
227:
228: assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
229:
230: // Check sub-word write is permitted
231: always_comb begin
232: wr_err = 1'b0;
233: if (addr_hit[0] && reg_we && (RSTMGR_PERMIT[0] != (RSTMGR_PERMIT[0] & reg_be))) wr_err = 1'b1 ;
234: if (addr_hit[1] && reg_we && (RSTMGR_PERMIT[1] != (RSTMGR_PERMIT[1] & reg_be))) wr_err = 1'b1 ;
235: if (addr_hit[2] && reg_we && (RSTMGR_PERMIT[2] != (RSTMGR_PERMIT[2] & reg_be))) wr_err = 1'b1 ;
236: if (addr_hit[3] && reg_we && (RSTMGR_PERMIT[3] != (RSTMGR_PERMIT[3] & reg_be))) wr_err = 1'b1 ;
237: if (addr_hit[4] && reg_we && (RSTMGR_PERMIT[4] != (RSTMGR_PERMIT[4] & reg_be))) wr_err = 1'b1 ;
238: end
239:
240: assign reset_info_we = addr_hit[0] & reg_we & ~wr_err;
241: assign reset_info_wd = reg_wdata[4:0];
242: assign reset_info_re = addr_hit[0] && reg_re;
243:
244: assign spi_device_regen_we = addr_hit[1] & reg_we & ~wr_err;
245: assign spi_device_regen_wd = reg_wdata[0];
246:
247: assign usb_regen_we = addr_hit[2] & reg_we & ~wr_err;
248: assign usb_regen_wd = reg_wdata[0];
249:
250: assign rst_spi_device_n_we = addr_hit[3] & reg_we & ~wr_err;
251: assign rst_spi_device_n_wd = reg_wdata[0];
252:
253: assign rst_usb_n_we = addr_hit[4] & reg_we & ~wr_err;
254: assign rst_usb_n_wd = reg_wdata[0];
255:
256: // Read data return
257: always_comb begin
258: reg_rdata_next = '0;
259: unique case (1'b1)
260: addr_hit[0]: begin
261: reg_rdata_next[4:0] = reset_info_qs;
262: end
263:
264: addr_hit[1]: begin
265: reg_rdata_next[0] = spi_device_regen_qs;
266: end
267:
268: addr_hit[2]: begin
269: reg_rdata_next[0] = usb_regen_qs;
270: end
271:
272: addr_hit[3]: begin
273: reg_rdata_next[0] = rst_spi_device_n_qs;
274: end
275:
276: addr_hit[4]: begin
277: reg_rdata_next[0] = rst_usb_n_qs;
278: end
279:
280: default: begin
281: reg_rdata_next = '1;
282: end
283: endcase
284: end
285:
286: // Assertions for Register Interface
287: `ASSERT_PULSE(wePulse, reg_we)
288: `ASSERT_PULSE(rePulse, reg_re)
289:
290: `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
291:
292: `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
293:
294: // this is formulated as an assumption such that the FPV testbenches do disprove this
295: // property by mistake
296: `ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.parity_en == 1'b0)
297:
298: endmodule
299: