hw/ip/rv_dm/rtl/rv_dm.sv Cov: 99%

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