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