../src/lowrisc_ip_rv_dm_0.1/rtl/rv_dm.sv Cov: 99.6%

   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: // Top-level debug module (DM)
   6: //
   7: // This module implements the RISC-V debug specification version 0.13,
   8: //
   9: // This toplevel wraps the PULP debug module available from
  10: // https://github.com/pulp-platform/riscv-dbg to match the needs of
  11: // the TL-UL-based lowRISC chip design.
  12: 
  13: `include "prim_assert.sv"
  14: 
  15: module rv_dm #(
  16:   parameter int                 NrHarts = 1,
  17:   parameter logic [31:0]        IdcodeValue = 32'h 0000_0001
  18: ) (
  19:   input  logic                  clk_i,       // clock
  20:   input  logic                  rst_ni,      // asynchronous reset active low, connect PoR
  21:                                              // here, not the system reset
  22:   input  logic                  testmode_i,
  23:   output logic                  ndmreset_o,  // non-debug module reset
  24:   output logic                  dmactive_o,  // debug module is active
  25:   output logic [NrHarts-1:0]    debug_req_o, // async debug request
  26:   input  logic [NrHarts-1:0]    unavailable_i, // communicate whether the hart is unavailable
  27:                                                // (e.g.: power down)
  28: 
  29:   // bus device with debug memory, for an execution based technique
  30:   input  tlul_pkg::tl_h2d_t tl_d_i,
  31:   output tlul_pkg::tl_d2h_t tl_d_o,
  32: 
  33:   // bus host, for system bus accesses
  34:   output tlul_pkg::tl_h2d_t  tl_h_o,
  35:   input  tlul_pkg::tl_d2h_t  tl_h_i,
  36: 
  37:   input  logic               tck_i,           // JTAG test clock pad
  38:   input  logic               tms_i,           // JTAG test mode select pad
  39:   input  logic               trst_ni,         // JTAG test reset pad
  40:   input  logic               td_i,            // JTAG test data input pad
  41:   output logic               td_o,            // JTAG test data output pad
  42:   output logic               tdo_oe_o         // Data out output enable
  43: );
  44: 
  45:   `ASSERT_INIT(paramCheckNrHarts, NrHarts > 0)
  46: 
  47:   // Currently only 32 bit busses are supported by our TL-UL IP
  48:   localparam int BusWidth = 32;
  49:   // all harts have contiguous IDs
  50:   localparam logic [NrHarts-1:0] SelectableHarts = {NrHarts{1'b1}};
  51: 
  52:   // Debug CSRs
  53:   dm::hartinfo_t [NrHarts-1:0]      hartinfo;
  54:   logic [NrHarts-1:0]               halted;
  55:   // logic [NrHarts-1:0]               running;
  56:   logic [NrHarts-1:0]               resumeack;
  57:   logic [NrHarts-1:0]               haltreq;
  58:   logic [NrHarts-1:0]               resumereq;
  59:   logic                             clear_resumeack;
  60:   logic                             cmd_valid;
  61:   dm::command_t                     cmd;
  62: 
  63:   logic                             cmderror_valid;
  64:   dm::cmderr_e                      cmderror;
  65:   logic                             cmdbusy;
  66:   logic [dm::ProgBufSize-1:0][31:0] progbuf;
  67:   logic [dm::DataCount-1:0][31:0]   data_csrs_mem;
  68:   logic [dm::DataCount-1:0][31:0]   data_mem_csrs;
  69:   logic                             data_valid;
  70:   logic [19:0]                      hartsel;
  71:   // System Bus Access Module
  72:   logic [BusWidth-1:0]              sbaddress_csrs_sba;
  73:   logic [BusWidth-1:0]              sbaddress_sba_csrs;
  74:   logic                             sbaddress_write_valid;
  75:   logic                             sbreadonaddr;
  76:   logic                             sbautoincrement;
  77:   logic [2:0]                       sbaccess;
  78:   logic                             sbreadondata;
  79:   logic [BusWidth-1:0]              sbdata_write;
  80:   logic                             sbdata_read_valid;
  81:   logic                             sbdata_write_valid;
  82:   logic [BusWidth-1:0]              sbdata_read;
  83:   logic                             sbdata_valid;
  84:   logic                             sbbusy;
  85:   logic                             sberror_valid;
  86:   logic [2:0]                       sberror;
  87: 
  88:   dm::dmi_req_t  dmi_req;
  89:   dm::dmi_resp_t dmi_rsp;
  90:   logic dmi_req_valid, dmi_req_ready;
  91:   logic dmi_rsp_valid, dmi_rsp_ready;
  92:   logic dmi_rst_n;
  93: 
  94:   // static debug hartinfo
  95:   localparam dm::hartinfo_t DebugHartInfo = '{
  96:     zero1:      '0,
  97:     nscratch:   2, // Debug module needs at least two scratch regs
  98:     zero0:      0,
  99:     dataaccess: 1'b1, // data registers are memory mapped in the debugger
 100:     datasize:   dm::DataCount,
 101:     dataaddr:   dm::DataAddr
 102:   };
 103:   for (genvar i = 0; i < NrHarts; i++) begin : gen_dm_hart_ctrl
 104:     assign hartinfo[i] = DebugHartInfo;
 105:   end
 106: 
 107:   dm_csrs #(
 108:     .NrHarts(NrHarts),
 109:     .BusWidth(BusWidth),
 110:     .SelectableHarts(SelectableHarts)
 111:   ) i_dm_csrs (
 112:     .clk_i                   ( clk_i                 ),
 113:     .rst_ni                  ( rst_ni                ),
 114:     .testmode_i              ( testmode_i            ),
 115:     .dmi_rst_ni              ( dmi_rst_n             ),
 116:     .dmi_req_valid_i         ( dmi_req_valid         ),
 117:     .dmi_req_ready_o         ( dmi_req_ready         ),
 118:     .dmi_req_i               ( dmi_req               ),
 119:     .dmi_resp_valid_o        ( dmi_rsp_valid         ),
 120:     .dmi_resp_ready_i        ( dmi_rsp_ready         ),
 121:     .dmi_resp_o              ( dmi_rsp               ),
 122:     .ndmreset_o              ( ndmreset_o            ),
 123:     .dmactive_o              ( dmactive_o            ),
 124:     .hartsel_o               ( hartsel               ),
 125:     .hartinfo_i              ( hartinfo              ),
 126:     .halted_i                ( halted                ),
 127:     .unavailable_i,
 128:     .resumeack_i             ( resumeack             ),
 129:     .haltreq_o               ( haltreq               ),
 130:     .resumereq_o             ( resumereq             ),
 131:     .clear_resumeack_o       ( clear_resumeack       ),
 132:     .cmd_valid_o             ( cmd_valid             ),
 133:     .cmd_o                   ( cmd                   ),
 134:     .cmderror_valid_i        ( cmderror_valid        ),
 135:     .cmderror_i              ( cmderror              ),
 136:     .cmdbusy_i               ( cmdbusy               ),
 137:     .progbuf_o               ( progbuf               ),
 138:     .data_i                  ( data_mem_csrs         ),
 139:     .data_valid_i            ( data_valid            ),
 140:     .data_o                  ( data_csrs_mem         ),
 141:     .sbaddress_o             ( sbaddress_csrs_sba    ),
 142:     .sbaddress_i             ( sbaddress_sba_csrs    ),
 143:     .sbaddress_write_valid_o ( sbaddress_write_valid ),
 144:     .sbreadonaddr_o          ( sbreadonaddr          ),
 145:     .sbautoincrement_o       ( sbautoincrement       ),
 146:     .sbaccess_o              ( sbaccess              ),
 147:     .sbreadondata_o          ( sbreadondata          ),
 148:     .sbdata_o                ( sbdata_write          ),
 149:     .sbdata_read_valid_o     ( sbdata_read_valid     ),
 150:     .sbdata_write_valid_o    ( sbdata_write_valid    ),
 151:     .sbdata_i                ( sbdata_read           ),
 152:     .sbdata_valid_i          ( sbdata_valid          ),
 153:     .sbbusy_i                ( sbbusy                ),
 154:     .sberror_valid_i         ( sberror_valid         ),
 155:     .sberror_i               ( sberror               )
 156:   );
 157: 
 158:   logic                   master_req;
 159:   logic   [BusWidth-1:0]  master_add;
 160:   logic                   master_we;
 161:   logic   [BusWidth-1:0]  master_wdata;
 162:   logic [BusWidth/8-1:0]  master_be;
 163:   logic                   master_gnt;
 164:   logic                   master_r_valid;
 165:   logic   [BusWidth-1:0]  master_r_rdata;
 166:   logic                   master_r_err;
 167: 
 168:   dm_sba #(
 169:     .BusWidth(BusWidth)
 170:   ) i_dm_sba (
 171:     .clk_i                   ( clk_i                 ),
 172:     .rst_ni                  ( rst_ni                ),
 173:     .master_req_o            ( master_req            ),
 174:     .master_add_o            ( master_add            ),
 175:     .master_we_o             ( master_we             ),
 176:     .master_wdata_o          ( master_wdata          ),
 177:     .master_be_o             ( master_be             ),
 178:     .master_gnt_i            ( master_gnt            ),
 179:     .master_r_valid_i        ( master_r_valid        ),
 180:     .master_r_rdata_i        ( master_r_rdata        ),
 181:     .dmactive_i              ( dmactive_o            ),
 182:     .sbaddress_i             ( sbaddress_csrs_sba    ),
 183:     .sbaddress_o             ( sbaddress_sba_csrs    ),
 184:     .sbaddress_write_valid_i ( sbaddress_write_valid ),
 185:     .sbreadonaddr_i          ( sbreadonaddr          ),
 186:     .sbautoincrement_i       ( sbautoincrement       ),
 187:     .sbaccess_i              ( sbaccess              ),
 188:     .sbreadondata_i          ( sbreadondata          ),
 189:     .sbdata_i                ( sbdata_write          ),
 190:     .sbdata_read_valid_i     ( sbdata_read_valid     ),
 191:     .sbdata_write_valid_i    ( sbdata_write_valid    ),
 192:     .sbdata_o                ( sbdata_read           ),
 193:     .sbdata_valid_o          ( sbdata_valid          ),
 194:     .sbbusy_o                ( sbbusy                ),
 195:     .sberror_valid_o         ( sberror_valid         ),
 196:     .sberror_o               ( sberror               )
 197:   );
 198: 
 199:   tlul_adapter_host #(
 200:     .MAX_REQS(1)
 201:   ) tl_adapter_host_sba (
 202:     .clk_i,
 203:     .rst_ni,
 204:     .req_i        (master_req),
 205:     .gnt_o        (master_gnt),
 206:     .addr_i       (master_add),
 207:     .we_i         (master_we),
 208:     .wdata_i      (master_wdata),
 209:     .be_i         (master_be),
 210:     .valid_o      (master_r_valid),
 211:     .rdata_o      (master_r_rdata),
 212:     .err_o        (master_r_err),
 213:     .tl_o         (tl_h_o),
 214:     .tl_i         (tl_h_i)
 215:   );
 216: 
 217:   // DBG doesn't handle error responses so raise assertion if we see one
 218:   `ASSERT(dbgNoErrorResponse, master_r_valid |-> !master_r_err)
 219: 
 220:   localparam int unsigned AddressWidthWords = BusWidth - $clog2(BusWidth/8);
 221: 
 222:   logic                         req;
 223:   logic                         we;
 224:   logic [BusWidth/8-1:0]        be;
 225:   logic   [BusWidth-1:0]        wdata;
 226:   logic   [BusWidth-1:0]        rdata;
 227:   logic                         rvalid;
 228: 
 229:   logic [BusWidth-1:0]          addr_b;
 230:   logic [AddressWidthWords-1:0] addr_w;
 231: 
 232:   // TODO: The tlul_adapter_sram give us a bitwise write mask currently,
 233:   // but dm_mem only supports byte write masks. Disable sub-word access in the
 234:   // adapter for now until we figure out a good strategy to deal with this.
 235:   assign be = {BusWidth/8{1'b1}};
 236: 
 237:   assign addr_b = {addr_w, {$clog2(BusWidth/8){1'b0}}};
 238: 
 239:   dm_mem #(
 240:     .NrHarts(NrHarts),
 241:     .BusWidth(BusWidth),
 242:     .SelectableHarts(SelectableHarts)
 243:   ) i_dm_mem (
 244:     .clk_i                   ( clk_i                 ),
 245:     .rst_ni                  ( rst_ni                ),
 246:     .debug_req_o             ( debug_req_o           ),
 247:     .hartsel_i               ( hartsel               ),
 248:     .haltreq_i               ( haltreq               ),
 249:     .resumereq_i             ( resumereq             ),
 250:     .clear_resumeack_i       ( clear_resumeack       ),
 251:     .halted_o                ( halted                ),
 252:     .resuming_o              ( resumeack             ),
 253:     .cmd_valid_i             ( cmd_valid             ),
 254:     .cmd_i                   ( cmd                   ),
 255:     .cmderror_valid_o        ( cmderror_valid        ),
 256:     .cmderror_o              ( cmderror              ),
 257:     .cmdbusy_o               ( cmdbusy               ),
 258:     .progbuf_i               ( progbuf               ),
 259:     .data_i                  ( data_csrs_mem         ),
 260:     .data_o                  ( data_mem_csrs         ),
 261:     .data_valid_o            ( data_valid            ),
 262:     .req_i                   ( req                   ),
 263:     .we_i                    ( we                    ),
 264:     .addr_i                  ( addr_b                ),
 265:     .wdata_i                 ( wdata                 ),
 266:     .be_i                    ( be                    ),
 267:     .rdata_o                 ( rdata                 )
 268:   );
 269: 
 270:   // Bound-in DPI module replaces the TAP
 271: `ifndef DMIDirectTAP
 272:   // JTAG TAP
 273:   dmi_jtag #(
 274:     .IdcodeValue    (IdcodeValue)
 275:   ) dap (
 276:     .clk_i            (clk_i),
 277:     .rst_ni           (rst_ni),
 278:     .testmode_i       (testmode_i),
 279: 
 280:     .dmi_rst_no       (dmi_rst_n),
 281:     .dmi_req_o        (dmi_req),
 282:     .dmi_req_valid_o  (dmi_req_valid),
 283:     .dmi_req_ready_i  (dmi_req_ready),
 284: 
 285:     .dmi_resp_i       (dmi_rsp      ),
 286:     .dmi_resp_ready_o (dmi_rsp_ready),
 287:     .dmi_resp_valid_i (dmi_rsp_valid),
 288: 
 289:     //JTAG
 290:     .tck_i,
 291:     .tms_i,
 292:     .trst_ni,
 293:     .td_i,
 294:     .td_o,
 295:     .tdo_oe_o
 296:   );
 297: `endif
 298: 
 299:   tlul_adapter_sram #(
 300:     .SramAw(AddressWidthWords),
 301:     .SramDw(BusWidth),
 302:     .Outstanding(1),
 303:     .ByteAccess(0)
 304:   ) tl_adapter_device_mem (
 305:     .clk_i,
 306:     .rst_ni,
 307: 
 308:     .req_o    (req),
 309:     .gnt_i    (1'b1),
 310:     .we_o     (we),
 311:     .addr_o   (addr_w),
 312:     .wdata_o  (wdata),
 313:     .wmask_o  (),
 314:     .rdata_i  (rdata),
 315:     .rvalid_i (rvalid),
 316:     .rerror_i (2'b00),
 317: 
 318:     .tl_o     (tl_d_o),
 319:     .tl_i     (tl_d_i)
 320:   );
 321: 
 322:   always_ff @(posedge clk_i or negedge rst_ni) begin
 323:     if (!rst_ni) begin
 324:       rvalid <= '0;
 325:     end else begin
 326:       rvalid <= req & ~we;
 327:     end
 328:   end
 329: 
 330: endmodule
 331: