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: