hw/ip/nmi_gen/rtl/nmi_gen_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: module nmi_gen_reg_top (
   8:   input clk_i,
   9:   input rst_ni,
  10: 
  11:   // Below Regster interface can be changed
  12:   input  tlul_pkg::tl_h2d_t tl_i,
  13:   output tlul_pkg::tl_d2h_t tl_o,
  14:   // To HW
  15:   output nmi_gen_reg_pkg::nmi_gen_reg2hw_t reg2hw, // Write
  16:   input  nmi_gen_reg_pkg::nmi_gen_hw2reg_t hw2reg, // Read
  17: 
  18:   // Config
  19:   input devmode_i // If 1, explicit error return for unmapped register access
  20: );
  21: 
  22:   import nmi_gen_reg_pkg::* ;
  23: 
  24:   localparam int AW = 4;
  25:   localparam int DW = 32;
  26:   localparam int DBW = DW/8;                    // Byte Width
  27: 
  28:   // register signals
  29:   logic           reg_we;
  30:   logic           reg_re;
  31:   logic [AW-1:0]  reg_addr;
  32:   logic [DW-1:0]  reg_wdata;
  33:   logic [DBW-1:0] reg_be;
  34:   logic [DW-1:0]  reg_rdata;
  35:   logic           reg_error;
  36: 
  37:   logic          addrmiss, wr_err;
  38: 
  39:   logic [DW-1:0] reg_rdata_next;
  40: 
  41:   tlul_pkg::tl_h2d_t tl_reg_h2d;
  42:   tlul_pkg::tl_d2h_t tl_reg_d2h;
  43: 
  44:   assign tl_reg_h2d = tl_i;
  45:   assign tl_o       = tl_reg_d2h;
  46: 
  47:   tlul_adapter_reg #(
  48:     .RegAw(AW),
  49:     .RegDw(DW)
  50:   ) u_reg_if (
  51:     .clk_i,
  52:     .rst_ni,
  53: 
  54:     .tl_i (tl_reg_h2d),
  55:     .tl_o (tl_reg_d2h),
  56: 
  57:     .we_o    (reg_we),
  58:     .re_o    (reg_re),
  59:     .addr_o  (reg_addr),
  60:     .wdata_o (reg_wdata),
  61:     .be_o    (reg_be),
  62:     .rdata_i (reg_rdata),
  63:     .error_i (reg_error)
  64:   );
  65: 
  66:   assign reg_rdata = reg_rdata_next ;
  67:   assign reg_error = (devmode_i & addrmiss) | wr_err ;
  68: 
  69:   // Define SW related signals
  70:   // Format: __{wd|we|qs}
  71:   //        or _{wd|we|qs} if field == 1 or 0
  72:   logic intr_state_esc0_qs;
  73:   logic intr_state_esc0_wd;
  74:   logic intr_state_esc0_we;
  75:   logic intr_state_esc1_qs;
  76:   logic intr_state_esc1_wd;
  77:   logic intr_state_esc1_we;
  78:   logic intr_state_esc2_qs;
  79:   logic intr_state_esc2_wd;
  80:   logic intr_state_esc2_we;
  81:   logic intr_state_esc3_qs;
  82:   logic intr_state_esc3_wd;
  83:   logic intr_state_esc3_we;
  84:   logic intr_enable_esc0_qs;
  85:   logic intr_enable_esc0_wd;
  86:   logic intr_enable_esc0_we;
  87:   logic intr_enable_esc1_qs;
  88:   logic intr_enable_esc1_wd;
  89:   logic intr_enable_esc1_we;
  90:   logic intr_enable_esc2_qs;
  91:   logic intr_enable_esc2_wd;
  92:   logic intr_enable_esc2_we;
  93:   logic intr_enable_esc3_qs;
  94:   logic intr_enable_esc3_wd;
  95:   logic intr_enable_esc3_we;
  96:   logic intr_test_esc0_wd;
  97:   logic intr_test_esc0_we;
  98:   logic intr_test_esc1_wd;
  99:   logic intr_test_esc1_we;
 100:   logic intr_test_esc2_wd;
 101:   logic intr_test_esc2_we;
 102:   logic intr_test_esc3_wd;
 103:   logic intr_test_esc3_we;
 104: 
 105:   // Register instances
 106:   // R[intr_state]: V(False)
 107: 
 108:   //   F[esc0]: 0:0
 109:   prim_subreg #(
 110:     .DW      (1),
 111:     .SWACCESS("W1C"),
 112:     .RESVAL  (1'h0)
 113:   ) u_intr_state_esc0 (
 114:     .clk_i   (clk_i    ),
 115:     .rst_ni  (rst_ni  ),
 116: 
 117:     // from register interface
 118:     .we     (intr_state_esc0_we),
 119:     .wd     (intr_state_esc0_wd),
 120: 
 121:     // from internal hardware
 122:     .de     (hw2reg.intr_state.esc0.de),
 123:     .d      (hw2reg.intr_state.esc0.d ),
 124: 
 125:     // to internal hardware
 126:     .qe     (),
 127:     .q      (reg2hw.intr_state.esc0.q ),
 128: 
 129:     // to register interface (read)
 130:     .qs     (intr_state_esc0_qs)
 131:   );
 132: 
 133: 
 134:   //   F[esc1]: 1:1
 135:   prim_subreg #(
 136:     .DW      (1),
 137:     .SWACCESS("W1C"),
 138:     .RESVAL  (1'h0)
 139:   ) u_intr_state_esc1 (
 140:     .clk_i   (clk_i    ),
 141:     .rst_ni  (rst_ni  ),
 142: 
 143:     // from register interface
 144:     .we     (intr_state_esc1_we),
 145:     .wd     (intr_state_esc1_wd),
 146: 
 147:     // from internal hardware
 148:     .de     (hw2reg.intr_state.esc1.de),
 149:     .d      (hw2reg.intr_state.esc1.d ),
 150: 
 151:     // to internal hardware
 152:     .qe     (),
 153:     .q      (reg2hw.intr_state.esc1.q ),
 154: 
 155:     // to register interface (read)
 156:     .qs     (intr_state_esc1_qs)
 157:   );
 158: 
 159: 
 160:   //   F[esc2]: 2:2
 161:   prim_subreg #(
 162:     .DW      (1),
 163:     .SWACCESS("W1C"),
 164:     .RESVAL  (1'h0)
 165:   ) u_intr_state_esc2 (
 166:     .clk_i   (clk_i    ),
 167:     .rst_ni  (rst_ni  ),
 168: 
 169:     // from register interface
 170:     .we     (intr_state_esc2_we),
 171:     .wd     (intr_state_esc2_wd),
 172: 
 173:     // from internal hardware
 174:     .de     (hw2reg.intr_state.esc2.de),
 175:     .d      (hw2reg.intr_state.esc2.d ),
 176: 
 177:     // to internal hardware
 178:     .qe     (),
 179:     .q      (reg2hw.intr_state.esc2.q ),
 180: 
 181:     // to register interface (read)
 182:     .qs     (intr_state_esc2_qs)
 183:   );
 184: 
 185: 
 186:   //   F[esc3]: 3:3
 187:   prim_subreg #(
 188:     .DW      (1),
 189:     .SWACCESS("W1C"),
 190:     .RESVAL  (1'h0)
 191:   ) u_intr_state_esc3 (
 192:     .clk_i   (clk_i    ),
 193:     .rst_ni  (rst_ni  ),
 194: 
 195:     // from register interface
 196:     .we     (intr_state_esc3_we),
 197:     .wd     (intr_state_esc3_wd),
 198: 
 199:     // from internal hardware
 200:     .de     (hw2reg.intr_state.esc3.de),
 201:     .d      (hw2reg.intr_state.esc3.d ),
 202: 
 203:     // to internal hardware
 204:     .qe     (),
 205:     .q      (reg2hw.intr_state.esc3.q ),
 206: 
 207:     // to register interface (read)
 208:     .qs     (intr_state_esc3_qs)
 209:   );
 210: 
 211: 
 212:   // R[intr_enable]: V(False)
 213: 
 214:   //   F[esc0]: 0:0
 215:   prim_subreg #(
 216:     .DW      (1),
 217:     .SWACCESS("RW"),
 218:     .RESVAL  (1'h0)
 219:   ) u_intr_enable_esc0 (
 220:     .clk_i   (clk_i    ),
 221:     .rst_ni  (rst_ni  ),
 222: 
 223:     // from register interface
 224:     .we     (intr_enable_esc0_we),
 225:     .wd     (intr_enable_esc0_wd),
 226: 
 227:     // from internal hardware
 228:     .de     (1'b0),
 229:     .d      ('0  ),
 230: 
 231:     // to internal hardware
 232:     .qe     (),
 233:     .q      (reg2hw.intr_enable.esc0.q ),
 234: 
 235:     // to register interface (read)
 236:     .qs     (intr_enable_esc0_qs)
 237:   );
 238: 
 239: 
 240:   //   F[esc1]: 1:1
 241:   prim_subreg #(
 242:     .DW      (1),
 243:     .SWACCESS("RW"),
 244:     .RESVAL  (1'h0)
 245:   ) u_intr_enable_esc1 (
 246:     .clk_i   (clk_i    ),
 247:     .rst_ni  (rst_ni  ),
 248: 
 249:     // from register interface
 250:     .we     (intr_enable_esc1_we),
 251:     .wd     (intr_enable_esc1_wd),
 252: 
 253:     // from internal hardware
 254:     .de     (1'b0),
 255:     .d      ('0  ),
 256: 
 257:     // to internal hardware
 258:     .qe     (),
 259:     .q      (reg2hw.intr_enable.esc1.q ),
 260: 
 261:     // to register interface (read)
 262:     .qs     (intr_enable_esc1_qs)
 263:   );
 264: 
 265: 
 266:   //   F[esc2]: 2:2
 267:   prim_subreg #(
 268:     .DW      (1),
 269:     .SWACCESS("RW"),
 270:     .RESVAL  (1'h0)
 271:   ) u_intr_enable_esc2 (
 272:     .clk_i   (clk_i    ),
 273:     .rst_ni  (rst_ni  ),
 274: 
 275:     // from register interface
 276:     .we     (intr_enable_esc2_we),
 277:     .wd     (intr_enable_esc2_wd),
 278: 
 279:     // from internal hardware
 280:     .de     (1'b0),
 281:     .d      ('0  ),
 282: 
 283:     // to internal hardware
 284:     .qe     (),
 285:     .q      (reg2hw.intr_enable.esc2.q ),
 286: 
 287:     // to register interface (read)
 288:     .qs     (intr_enable_esc2_qs)
 289:   );
 290: 
 291: 
 292:   //   F[esc3]: 3:3
 293:   prim_subreg #(
 294:     .DW      (1),
 295:     .SWACCESS("RW"),
 296:     .RESVAL  (1'h0)
 297:   ) u_intr_enable_esc3 (
 298:     .clk_i   (clk_i    ),
 299:     .rst_ni  (rst_ni  ),
 300: 
 301:     // from register interface
 302:     .we     (intr_enable_esc3_we),
 303:     .wd     (intr_enable_esc3_wd),
 304: 
 305:     // from internal hardware
 306:     .de     (1'b0),
 307:     .d      ('0  ),
 308: 
 309:     // to internal hardware
 310:     .qe     (),
 311:     .q      (reg2hw.intr_enable.esc3.q ),
 312: 
 313:     // to register interface (read)
 314:     .qs     (intr_enable_esc3_qs)
 315:   );
 316: 
 317: 
 318:   // R[intr_test]: V(True)
 319: 
 320:   //   F[esc0]: 0:0
 321:   prim_subreg_ext #(
 322:     .DW    (1)
 323:   ) u_intr_test_esc0 (
 324:     .re     (1'b0),
 325:     .we     (intr_test_esc0_we),
 326:     .wd     (intr_test_esc0_wd),
 327:     .d      ('0),
 328:     .qre    (),
 329:     .qe     (reg2hw.intr_test.esc0.qe),
 330:     .q      (reg2hw.intr_test.esc0.q ),
 331:     .qs     ()
 332:   );
 333: 
 334: 
 335:   //   F[esc1]: 1:1
 336:   prim_subreg_ext #(
 337:     .DW    (1)
 338:   ) u_intr_test_esc1 (
 339:     .re     (1'b0),
 340:     .we     (intr_test_esc1_we),
 341:     .wd     (intr_test_esc1_wd),
 342:     .d      ('0),
 343:     .qre    (),
 344:     .qe     (reg2hw.intr_test.esc1.qe),
 345:     .q      (reg2hw.intr_test.esc1.q ),
 346:     .qs     ()
 347:   );
 348: 
 349: 
 350:   //   F[esc2]: 2:2
 351:   prim_subreg_ext #(
 352:     .DW    (1)
 353:   ) u_intr_test_esc2 (
 354:     .re     (1'b0),
 355:     .we     (intr_test_esc2_we),
 356:     .wd     (intr_test_esc2_wd),
 357:     .d      ('0),
 358:     .qre    (),
 359:     .qe     (reg2hw.intr_test.esc2.qe),
 360:     .q      (reg2hw.intr_test.esc2.q ),
 361:     .qs     ()
 362:   );
 363: 
 364: 
 365:   //   F[esc3]: 3:3
 366:   prim_subreg_ext #(
 367:     .DW    (1)
 368:   ) u_intr_test_esc3 (
 369:     .re     (1'b0),
 370:     .we     (intr_test_esc3_we),
 371:     .wd     (intr_test_esc3_wd),
 372:     .d      ('0),
 373:     .qre    (),
 374:     .qe     (reg2hw.intr_test.esc3.qe),
 375:     .q      (reg2hw.intr_test.esc3.q ),
 376:     .qs     ()
 377:   );
 378: 
 379: 
 380: 
 381: 
 382:   logic [2:0] addr_hit;
 383:   always_comb begin
 384:     addr_hit = '0;
 385:     addr_hit[0] = (reg_addr == NMI_GEN_INTR_STATE_OFFSET);
 386:     addr_hit[1] = (reg_addr == NMI_GEN_INTR_ENABLE_OFFSET);
 387:     addr_hit[2] = (reg_addr == NMI_GEN_INTR_TEST_OFFSET);
 388:   end
 389: 
 390:   assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
 391: 
 392:   // Check sub-word write is permitted
 393:   always_comb begin
 394:     wr_err = 1'b0;
 395:     if (addr_hit[0] && reg_we && (NMI_GEN_PERMIT[0] != (NMI_GEN_PERMIT[0] & reg_be))) wr_err = 1'b1 ;
 396:     if (addr_hit[1] && reg_we && (NMI_GEN_PERMIT[1] != (NMI_GEN_PERMIT[1] & reg_be))) wr_err = 1'b1 ;
 397:     if (addr_hit[2] && reg_we && (NMI_GEN_PERMIT[2] != (NMI_GEN_PERMIT[2] & reg_be))) wr_err = 1'b1 ;
 398:   end
 399: 
 400:   assign intr_state_esc0_we = addr_hit[0] & reg_we & ~wr_err;
 401:   assign intr_state_esc0_wd = reg_wdata[0];
 402: 
 403:   assign intr_state_esc1_we = addr_hit[0] & reg_we & ~wr_err;
 404:   assign intr_state_esc1_wd = reg_wdata[1];
 405: 
 406:   assign intr_state_esc2_we = addr_hit[0] & reg_we & ~wr_err;
 407:   assign intr_state_esc2_wd = reg_wdata[2];
 408: 
 409:   assign intr_state_esc3_we = addr_hit[0] & reg_we & ~wr_err;
 410:   assign intr_state_esc3_wd = reg_wdata[3];
 411: 
 412:   assign intr_enable_esc0_we = addr_hit[1] & reg_we & ~wr_err;
 413:   assign intr_enable_esc0_wd = reg_wdata[0];
 414: 
 415:   assign intr_enable_esc1_we = addr_hit[1] & reg_we & ~wr_err;
 416:   assign intr_enable_esc1_wd = reg_wdata[1];
 417: 
 418:   assign intr_enable_esc2_we = addr_hit[1] & reg_we & ~wr_err;
 419:   assign intr_enable_esc2_wd = reg_wdata[2];
 420: 
 421:   assign intr_enable_esc3_we = addr_hit[1] & reg_we & ~wr_err;
 422:   assign intr_enable_esc3_wd = reg_wdata[3];
 423: 
 424:   assign intr_test_esc0_we = addr_hit[2] & reg_we & ~wr_err;
 425:   assign intr_test_esc0_wd = reg_wdata[0];
 426: 
 427:   assign intr_test_esc1_we = addr_hit[2] & reg_we & ~wr_err;
 428:   assign intr_test_esc1_wd = reg_wdata[1];
 429: 
 430:   assign intr_test_esc2_we = addr_hit[2] & reg_we & ~wr_err;
 431:   assign intr_test_esc2_wd = reg_wdata[2];
 432: 
 433:   assign intr_test_esc3_we = addr_hit[2] & reg_we & ~wr_err;
 434:   assign intr_test_esc3_wd = reg_wdata[3];
 435: 
 436:   // Read data return
 437:   always_comb begin
 438:     reg_rdata_next = '0;
 439:     unique case (1'b1)
 440:       addr_hit[0]: begin
 441:         reg_rdata_next[0] = intr_state_esc0_qs;
 442:         reg_rdata_next[1] = intr_state_esc1_qs;
 443:         reg_rdata_next[2] = intr_state_esc2_qs;
 444:         reg_rdata_next[3] = intr_state_esc3_qs;
 445:       end
 446: 
 447:       addr_hit[1]: begin
 448:         reg_rdata_next[0] = intr_enable_esc0_qs;
 449:         reg_rdata_next[1] = intr_enable_esc1_qs;
 450:         reg_rdata_next[2] = intr_enable_esc2_qs;
 451:         reg_rdata_next[3] = intr_enable_esc3_qs;
 452:       end
 453: 
 454:       addr_hit[2]: begin
 455:         reg_rdata_next[0] = '0;
 456:         reg_rdata_next[1] = '0;
 457:         reg_rdata_next[2] = '0;
 458:         reg_rdata_next[3] = '0;
 459:       end
 460: 
 461:       default: begin
 462:         reg_rdata_next = '1;
 463:       end
 464:     endcase
 465:   end
 466: 
 467:   // Assertions for Register Interface
 468:   `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
 469:   `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
 470: 
 471:   `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid, clk_i, !rst_ni)
 472: 
 473:   `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
 474: 
 475:   // this is formulated as an assumption such that the FPV testbenches do disprove this
 476:   // property by mistake
 477:   `ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.parity_en == 1'b0, clk_i, !rst_ni)
 478: 
 479: endmodule
 480: