OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [core/] [pipeline/] [scr1_pipe_hdu.sv] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
2
/// @file       
3
/// @brief      HART Debug Unit (HDU)
4
///
5
 
6
//------------------------------------------------------------------------------
7
 //
8
 //
9
 // Functionality:
10
 // - Controls HART state (RUN, Debug RUN, Debug HALTED)
11
 // - Setups Debug Mode execution
12
 // - Provides status information about Debug Mode execution
13
 // - Provides Program Buffer functionality (a few instructions execution while
14
 //   in Debug Mode)
15
 // - Provides access to Debug CSRs
16
 //
17
 // Structure:
18
 // - Debug state FSM
19
 // - HART Control logic
20
 // - HART Status logic
21
 // - Program Buffer
22
 // - Debug CSRs
23
 // - HDU <-> DM interface
24
 // - HDU <-> EXU interface
25
 // - HDU <-> IFU interface
26
 // - HDU <-> CSR interface
27
 // - HDU <-> TDU interface
28
 //
29
//------------------------------------------------------------------------------
30
 
31
`include "scr1_arch_description.svh"
32
 
33
`ifdef SCR1_DBG_EN
34
`include "scr1_arch_types.svh"
35
`include "scr1_riscv_isa_decoding.svh"
36
`include "scr1_hdu.svh"
37
 
38
module scr1_pipe_hdu #(parameter HART_PBUF_INSTR_REGOUT_EN = 1'b1) (
39
    // Common signals
40
    input  logic                                        rst_n,                      // HDU reset
41
    input  logic                                        clk,                        // HDU clock
42
    input  logic                                        clk_en,                     // HDU clock enable
43
`ifdef SCR1_CLKCTRL_EN
44
    input   logic                                       clk_pipe_en,                // Pipeline clock enable
45
`endif // SCR1_CLKCTRL_EN
46
    input  logic                                        pipe2hdu_rdc_qlfy_i,        // Pipeline RDC qualifier
47
 
48
    // HDU <-> CSR i/f
49
    input  logic                                        csr2hdu_req_i,              // CSR i/f request
50
    input  type_scr1_csr_cmd_sel_e                      csr2hdu_cmd_i,              // CSR i/f command
51
    input  logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0]     csr2hdu_addr_i,             // CSR i/f address
52
    input  logic [`SCR1_XLEN-1:0]                       csr2hdu_wdata_i,            // CSR i/f write data
53
    output type_scr1_csr_resp_e                         hdu2csr_resp_o,             // CSR i/f response
54
    output logic [`SCR1_XLEN-1:0]                       hdu2csr_rdata_o,            // CSR i/f read data
55
 
56
    // HDU <-> DM i/f
57
    // HART Run Control i/f
58
    input  logic                                        dm2hdu_cmd_req_i,           // DM-HART Command request
59
    input  type_scr1_hdu_dbgstates_e                    dm2hdu_cmd_i,               // DM-HART Command
60
    output logic                                        hdu2dm_cmd_resp_o,          // DM-HART Command response
61
    output logic                                        hdu2dm_cmd_rcode_o,         // DM-HART Command return code: 0 - Ok; 1 - Error
62
    output logic                                        hdu2dm_hart_event_o,        // DM-HART Event: 1 if HART debug state changed
63
    output type_scr1_hdu_hartstatus_s                   hdu2dm_hart_status_o,       // DM-HART Status
64
 
65
    // Program Buffer i/f
66
    output logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]         hdu2dm_pbuf_addr_o,         // Program Buffer address - so far request only for 1 instruction
67
    input  logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]        dm2hdu_pbuf_instr_i,        // Program Buffer instruction
68
 
69
    // HART Abstract Data regs i/f
70
    output logic                                        hdu2dm_dreg_req_o,          // Abstract Data Register request
71
    output logic                                        hdu2dm_dreg_wr_o,           // Abstract Data Register write
72
    output logic [`SCR1_XLEN-1:0]                       hdu2dm_dreg_wdata_o,        // Abstract Data Register write data
73
    input  logic                                        dm2hdu_dreg_resp_i,         // Abstract Data Register response
74
    input  logic                                        dm2hdu_dreg_fail_i,         // Abstract Data Register fail
75
    input  logic [`SCR1_XLEN-1:0]                       dm2hdu_dreg_rdata_i,        // Abstract Data Register read data
76
 
77
`ifdef SCR1_TDU_EN
78
    // HDU <-> TDU interface
79
    output  logic                                       hdu2tdu_hwbrk_dsbl_o,       // Disables BRKM
80
    input   logic                                       tdu2hdu_dmode_req_i,        // Trigger Module requests transition to debug mode
81
    input   logic                                       exu2hdu_ibrkpt_hw_i,        // Hardware breakpoint on current instruction
82
`endif // SCR1_TDU_EN
83
 
84
    // HART Run Status
85
    input   logic                                       pipe2hdu_exu_busy_i,        // EXU busy
86
    input   logic                                       pipe2hdu_instret_i,         // Instruction retired (with or without exception)
87
    input   logic                                       pipe2hdu_init_pc_i,         // Reset exit
88
 
89
    // HART Halt Status
90
    input   logic                                       pipe2hdu_exu_exc_req_i,     // Exception request
91
    input   logic                                       pipe2hdu_brkpt_i,           // Software Breakpoint (EBREAK)
92
 
93
    // HDU <-> EXU i/f
94
    // HART Run Control
95
    output  logic                                       hdu2exu_pbuf_fetch_o,       // Fetch instruction from Program Buffer
96
    output  logic                                       hdu2exu_no_commit_o,        // Forbid instruction commitment
97
    output  logic                                       hdu2exu_irq_dsbl_o,         // Disable IRQ
98
    output  logic                                       hdu2exu_pc_advmt_dsbl_o,    // Forbid PC advancement
99
    output  logic                                       hdu2exu_dmode_sstep_en_o,   // Enable single-step
100
 
101
    // HART state
102
    output  logic                                       hdu2exu_dbg_halted_o,       // Debug halted state
103
    output  logic                                       hdu2exu_dbg_run2halt_o,     // Transition to debug halted state
104
    output  logic                                       hdu2exu_dbg_halt2run_o,     // Transition to run state
105
    output  logic                                       hdu2exu_dbg_run_start_o,    // First cycle of run state
106
 
107
    // PC interface
108
    input  logic [`SCR1_XLEN-1:0]                       pipe2hdu_pc_curr_i,         // Current PC
109
    output logic [`SCR1_XLEN-1:0]                       hdu2exu_dbg_new_pc_o,       // New PC for resume
110
 
111
    // HDU <-> IFU i/f
112
    // Program Buffer Instruction interface
113
    input   logic                                       ifu2hdu_pbuf_instr_rdy_i,   // Program Buffer Instruction i/f ready
114
    output  logic                                       hdu2ifu_pbuf_instr_vd_o,    // Program Buffer Instruction valid
115
    output  logic                                       hdu2ifu_pbuf_instr_err_o,   // Program Buffer Instruction i/f error
116
    output  logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]       hdu2ifu_pbuf_instr_o        // Program Buffer Instruction itself
117
);
118
 
119
//------------------------------------------------------------------------------
120
// Local Parameters
121
//------------------------------------------------------------------------------
122
 
123
localparam int unsigned SCR1_HDU_TIMEOUT       = 64;       // must be power of 2
124
localparam int unsigned SCR1_HDU_TIMEOUT_WIDTH = $clog2(SCR1_HDU_TIMEOUT);
125
 
126
//------------------------------------------------------------------------------
127
// Local Signals
128
//------------------------------------------------------------------------------
129
 
130
// Debug FSM
131
//------------------------------------------------------------------------------
132
 
133
// FSM control signals
134
logic                                               dm_dhalt_req;
135
logic                                               dm_run_req;
136
 
137
logic                                               dm_cmd_run;
138
logic                                               dm_cmd_dhalted;
139
logic                                               dm_cmd_drun;
140
 
141
// Debug state FSM signals
142
type_scr1_hdu_dbgstates_e                           dbg_state;
143
type_scr1_hdu_dbgstates_e                           dbg_state_next;
144
logic                                               dbg_state_dhalted;
145
logic                                               dbg_state_drun;
146
logic                                               dbg_state_run;
147
logic                                               dbg_state_reset;
148
 
149
// FSM transition, update and event registers
150
logic                                               dfsm_trans;
151
logic                                               dfsm_trans_next;
152
logic                                               dfsm_update;
153
logic                                               dfsm_update_next;
154
logic                                               dfsm_event;
155
logic                                               dfsm_event_next;
156
 
157
// HART Control signals
158
//------------------------------------------------------------------------------
159
 
160
logic                                               hart_resume_req;
161
logic                                               hart_halt_req;
162
logic                                               hart_cmd_req;
163
 
164
// HART Run Control register
165
logic                                               hart_runctrl_upd;
166
logic                                               hart_runctrl_clr;
167
type_scr1_hdu_runctrl_s                             hart_runctrl;
168
 
169
// HART halt request timeout counter signals
170
logic [SCR1_HDU_TIMEOUT_WIDTH-1:0]                  halt_req_timeout_cnt;
171
logic [SCR1_HDU_TIMEOUT_WIDTH-1:0]                  halt_req_timeout_cnt_next;
172
logic                                               halt_req_timeout_cnt_en;
173
logic                                               halt_req_timeout_flag;
174
 
175
// HART Status signals
176
//------------------------------------------------------------------------------
177
 
178
type_scr1_hdu_haltstatus_s                          hart_haltstatus;
179
type_scr1_hdu_haltcause_e                           hart_haltcause;
180
 
181
logic                                               hart_halt_pnd;
182
logic                                               hart_halt_ack;
183
 
184
// Debug mode cause decoder signals
185
logic                                               dmode_cause_sstep;
186
logic                                               dmode_cause_except;
187
logic                                               dmode_cause_ebreak;
188
logic                                               dmode_cause_any;
189
`ifdef SCR1_TDU_EN
190
logic                                               dmode_cause_tmreq;
191
`endif // SCR1_TDU_EN
192
 
193
// Program Buffer FSM
194
//------------------------------------------------------------------------------
195
 
196
// PBUF FSM control signals
197
logic                                               ifu_handshake_done;
198
logic                                               pbuf_exc_inj_req;
199
logic                                               pbuf_exc_inj_end;
200
logic                                               pbuf_start_fetch;
201
 
202
// PBUF FSM signals
203
type_scr1_hdu_pbufstates_e                          pbuf_fsm_curr;
204
type_scr1_hdu_pbufstates_e                          pbuf_fsm_next;
205
logic                                               pbuf_fsm_idle;
206
logic                                               pbuf_fsm_fetch;
207
logic                                               pbuf_fsm_excinj;
208
 
209
// PBUF address signals
210
logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]                pbuf_addr_ff;
211
logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]                pbuf_addr_next;
212
logic                                               pbuf_addr_end;
213
logic                                               pbuf_addr_next_vd;
214
 
215
logic                                               pbuf_instr_wait_latching;
216
 
217
// Debugs CSRs
218
//------------------------------------------------------------------------------
219
 
220
// CSRs write/read interface signals
221
logic                                               csr_upd_on_halt;
222
logic                                               csr_wr;
223
logic [`SCR1_XLEN-1:0]                              csr_wr_data;
224
logic [`SCR1_XLEN-1:0]                              csr_rd_data;
225
 
226
// Debug Control and Status register (DCSR)
227
logic                                               csr_dcsr_sel;
228
logic                                               csr_dcsr_wr;
229
type_scr1_hdu_dcsr_s                                csr_dcsr_in;
230
type_scr1_hdu_dcsr_s                                csr_dcsr_out;
231
logic                                               csr_dcsr_ebreakm;
232
logic                                               csr_dcsr_stepie;
233
logic                                               csr_dcsr_step;
234
logic [SCR1_HDU_DCSR_CAUSE_BIT_L-
235
       SCR1_HDU_DCSR_CAUSE_BIT_R:0]                 csr_dcsr_cause;
236
 
237
// Debug Program Counter register (DPC)
238
logic                                               csr_dpc_sel;
239
logic                                               csr_dpc_wr;
240
logic [`SCR1_XLEN-1:0]                              csr_dpc_ff;
241
logic [`SCR1_XLEN-1:0]                              csr_dpc_next;
242
logic [`SCR1_XLEN-1:0]                              csr_dpc_out;
243
 
244
// Debug Scratch register 0 (DSCRATCH0)
245
logic                                               csr_addr_dscratch0;
246
logic                                               csr_dscratch0_sel;
247
logic                                               csr_dscratch0_wr;
248
logic [`SCR1_XLEN-1:0]                              csr_dscratch0_out;
249
type_scr1_csr_resp_e                                csr_dscratch0_resp;
250
 
251
//------------------------------------------------------------------------------
252
// Debug state FSM logic
253
//------------------------------------------------------------------------------
254
//
255
 // Debug state FSM logic consists of the following functional units:
256
 // - FSM control logic
257
 // - Debug state FSM
258
 // - FSM transition, update and event registers
259
//
260
 
261
// FSM control logic
262
//------------------------------------------------------------------------------
263
 
264
assign dm_cmd_dhalted = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_DHALTED);
265
assign dm_cmd_run     = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_RUN);
266
assign dm_cmd_drun    = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_DRUN);
267
 
268
assign dm_dhalt_req   = dm2hdu_cmd_req_i & dm_cmd_dhalted;
269
assign dm_run_req     = dm2hdu_cmd_req_i & (dm_cmd_run | dm_cmd_drun);
270
 
271
// Debug state FSM
272
//------------------------------------------------------------------------------
273
 
274
always_ff @(negedge rst_n, posedge clk) begin
275
    if (~rst_n) begin
276
        dbg_state <= SCR1_HDU_DBGSTATE_RESET;
277
    end else begin
278
        dbg_state <= dbg_state_next;
279
    end
280
end
281
 
282
always_comb begin
283
    if (~pipe2hdu_rdc_qlfy_i) begin
284
        dbg_state_next = SCR1_HDU_DBGSTATE_RESET;
285
    end else begin
286
        case (dbg_state)
287
            SCR1_HDU_DBGSTATE_RESET: begin
288
                dbg_state_next = ~pipe2hdu_init_pc_i ? SCR1_HDU_DBGSTATE_RESET
289
                               : dm_dhalt_req        ? SCR1_HDU_DBGSTATE_DHALTED
290
                                                     : SCR1_HDU_DBGSTATE_RUN;
291
            end
292
            SCR1_HDU_DBGSTATE_RUN: begin
293
                dbg_state_next = dfsm_update         ? SCR1_HDU_DBGSTATE_DHALTED
294
                                                     : SCR1_HDU_DBGSTATE_RUN;
295
            end
296
            SCR1_HDU_DBGSTATE_DHALTED: begin
297
                dbg_state_next = ~dfsm_update        ? SCR1_HDU_DBGSTATE_DHALTED
298
                               : dm_cmd_drun         ? SCR1_HDU_DBGSTATE_DRUN
299
                                                     : SCR1_HDU_DBGSTATE_RUN;
300
            end
301
            SCR1_HDU_DBGSTATE_DRUN: begin
302
                dbg_state_next = dfsm_update         ? SCR1_HDU_DBGSTATE_DHALTED
303
                                                     : SCR1_HDU_DBGSTATE_DRUN;
304
            end
305
            default: begin
306
`ifdef SCR1_XPROP_EN
307
                dbg_state_next = SCR1_HDU_DBGSTATE_XXX;
308
`else // SCR1_XPROP_EN
309
                dbg_state_next = dbg_state;
310
`endif // SCR1_XPROP_EN
311
            end
312
        endcase
313
    end
314
end
315
 
316
assign dbg_state_dhalted = (dbg_state == SCR1_HDU_DBGSTATE_DHALTED);
317
assign dbg_state_drun    = (dbg_state == SCR1_HDU_DBGSTATE_DRUN);
318
assign dbg_state_run     = (dbg_state == SCR1_HDU_DBGSTATE_RUN);
319
assign dbg_state_reset   = (dbg_state == SCR1_HDU_DBGSTATE_RESET);
320
 
321
// FSM transition, update and event registers
322
//------------------------------------------------------------------------------
323
 
324
always_ff @(negedge rst_n, posedge clk) begin
325
    if (~rst_n) begin
326
        dfsm_trans  <= 1'b0;
327
        dfsm_update <= 1'b0;
328
        dfsm_event  <= 1'b0;
329
    end else begin
330
        dfsm_trans  <= dfsm_trans_next;
331
        dfsm_update <= dfsm_update_next;
332
        dfsm_event  <= dfsm_event_next;
333
    end
334
end
335
 
336
always_comb begin
337
    dfsm_trans_next  = 1'b0;
338
    dfsm_update_next = 1'b0;
339
    dfsm_event_next  = 1'b0;
340
 
341
    if (~pipe2hdu_rdc_qlfy_i) begin
342
        dfsm_trans_next  = 1'b0;
343
        dfsm_update_next = 1'b0;
344
        dfsm_event_next  = 1'b1;
345
    end else begin
346
        case (dbg_state)
347
            SCR1_HDU_DBGSTATE_RESET: begin
348
                dfsm_trans_next  = 1'b0;
349
                dfsm_update_next = 1'b0;
350
                dfsm_event_next  = pipe2hdu_init_pc_i & ~dm2hdu_cmd_req_i;
351
            end
352
 
353
            SCR1_HDU_DBGSTATE_RUN,
354
            SCR1_HDU_DBGSTATE_DRUN: begin
355
                dfsm_trans_next  = ~dfsm_update ? hart_halt_pnd : dfsm_trans;
356
                dfsm_update_next = ~dfsm_update & hart_halt_ack;
357
                dfsm_event_next  = dfsm_update;
358
            end
359
 
360
            SCR1_HDU_DBGSTATE_DHALTED: begin
361
                dfsm_trans_next  = ~dfsm_update ? ~dfsm_trans & dm_run_req
362
                                                : dfsm_trans;
363
                dfsm_update_next = ~dfsm_update & dfsm_trans;
364
                dfsm_event_next  = dfsm_update;
365
            end
366
 
367
            default : begin
368
                dfsm_trans_next  = 'X;
369
                dfsm_update_next = 'X;
370
                dfsm_event_next  = 'X;
371
            end
372
        endcase
373
    end
374
end
375
 
376
//------------------------------------------------------------------------------
377
// HART Control logic
378
//------------------------------------------------------------------------------
379
//
380
 // HART Control logic consists of the following functional units:
381
 // - Control signals
382
 // - HART Run Control register
383
 // - HART Halt Request Time-Out counter
384
//
385
 
386
// Control logic
387
always_comb begin
388
    hart_cmd_req = 1'b0;
389
 
390
    if (~pipe2hdu_rdc_qlfy_i) begin
391
        hart_cmd_req = 1'b0;
392
    end else begin
393
        case (dbg_state)
394
            SCR1_HDU_DBGSTATE_RESET  : hart_cmd_req = dm2hdu_cmd_req_i;
395
            SCR1_HDU_DBGSTATE_DHALTED: hart_cmd_req = (dfsm_update | dfsm_trans);
396
            SCR1_HDU_DBGSTATE_RUN,
397
            SCR1_HDU_DBGSTATE_DRUN   : hart_cmd_req = ~dfsm_update & dfsm_trans;
398
            default                  : hart_cmd_req = 'X;
399
        endcase
400
    end
401
end
402
 
403
assign hart_halt_req   = dm_cmd_dhalted & hart_cmd_req;
404
assign hart_resume_req = (dm_cmd_run | dm_cmd_drun) & hart_cmd_req;
405
 
406
// HART Run Control register
407
//------------------------------------------------------------------------------
408
 
409
assign hart_runctrl_clr = (dbg_state_run | dbg_state_drun)
410
                        & (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED);
411
assign hart_runctrl_upd = dbg_state_dhalted & dfsm_trans_next;
412
 
413
always_ff @(negedge rst_n, posedge clk) begin
414
    if (~rst_n) begin
415
        hart_runctrl.irq_dsbl      <= 1'b0;
416
        hart_runctrl.fetch_src     <= SCR1_HDU_FETCH_SRC_NORMAL;
417
        hart_runctrl.pc_advmt_dsbl <= 1'b0;
418
        hart_runctrl.hwbrkpt_dsbl  <= 1'b0;
419
        hart_runctrl.redirect      <= '0;
420
    end else if(clk_en) begin
421
        if (hart_runctrl_clr) begin
422
            hart_runctrl           <= '0;
423
        end else begin
424
            if (hart_runctrl_upd) begin
425
                if (~dm_cmd_drun) begin
426
                    // Case : resume to RUN state
427
                    hart_runctrl.irq_dsbl        <= csr_dcsr_step ? ~csr_dcsr_stepie : 1'b0;
428
                    hart_runctrl.fetch_src       <= SCR1_HDU_FETCH_SRC_NORMAL;
429
                    hart_runctrl.pc_advmt_dsbl   <= 1'b0;
430
                    hart_runctrl.hwbrkpt_dsbl    <= 1'b0;
431
                    hart_runctrl.redirect.sstep  <= csr_dcsr_step;
432
                    hart_runctrl.redirect.ebreak <= csr_dcsr_ebreakm;
433
                end else begin
434
                    // Case : resume to DRUN state
435
                    hart_runctrl.irq_dsbl        <= 1'b1;
436
                    hart_runctrl.fetch_src       <= SCR1_HDU_FETCH_SRC_PBUF;
437
                    hart_runctrl.pc_advmt_dsbl   <= 1'b1;
438
                    hart_runctrl.hwbrkpt_dsbl    <= 1'b1;
439
                    hart_runctrl.redirect.sstep  <= 1'b0;
440
                    hart_runctrl.redirect.ebreak <= 1'b1;
441
                end
442
            end
443
        end
444
    end
445
end
446
 
447
// HART Halt Request Time-Out counter
448
//------------------------------------------------------------------------------
449
// HART goes into halt state only if the halt request is present for timeout period
450
// of time
451
 
452
assign halt_req_timeout_cnt_en = hdu2exu_dbg_halt2run_o
453
                               | (hart_halt_req & ~hdu2exu_dbg_run2halt_o);
454
 
455
always_ff @(posedge clk, negedge rst_n) begin
456
    if (~rst_n) begin
457
        halt_req_timeout_cnt <= '1;
458
    end else if (halt_req_timeout_cnt_en) begin
459
        halt_req_timeout_cnt <= halt_req_timeout_cnt_next;
460
    end
461
end
462
 
463
assign halt_req_timeout_cnt_next = hdu2exu_dbg_halt2run_o                    ? '1
464
                                 : (hart_halt_req & ~hdu2exu_dbg_run2halt_o) ? halt_req_timeout_cnt - 1'b1
465
                                                                             : halt_req_timeout_cnt;
466
 
467
assign halt_req_timeout_flag = ~|halt_req_timeout_cnt;
468
 
469
//------------------------------------------------------------------------------
470
// HART Status logic
471
//------------------------------------------------------------------------------
472
//
473
 // HART Status logic consists of the following functional units:
474
 // - Debug mode cause decoder
475
 // - Hart halt status cause encoder
476
 // - Hart halt status register
477
//
478
 
479
// Debug mode cause decoder
480
//------------------------------------------------------------------------------
481
 
482
assign dmode_cause_sstep  = hart_runctrl.redirect.sstep & pipe2hdu_instret_i;
483
assign dmode_cause_except = dbg_state_drun & pipe2hdu_exu_exc_req_i
484
                          & ~pipe2hdu_brkpt_i
485
`ifdef SCR1_TDU_EN
486
                          & ~exu2hdu_ibrkpt_hw_i
487
`endif // SCR1_TDU_EN
488
                          ;
489
assign dmode_cause_ebreak = hart_runctrl.redirect.ebreak & pipe2hdu_brkpt_i;
490
`ifdef SCR1_TDU_EN
491
assign dmode_cause_tmreq  = tdu2hdu_dmode_req_i & exu2hdu_ibrkpt_hw_i;
492
`endif // SCR1_TDU_EN
493
 
494
assign dmode_cause_any = dmode_cause_sstep | dmode_cause_ebreak | dmode_cause_except
495
                       | hart_halt_req
496
`ifdef SCR1_TDU_EN
497
                       | dmode_cause_tmreq
498
`endif // SCR1_TDU_EN
499
                       ;
500
 
501
// HART halt cause encoder
502
//------------------------------------------------------------------------------
503
 
504
always_comb begin
505
    case (1'b1)
506
`ifdef SCR1_TDU_EN
507
        dmode_cause_tmreq   : hart_haltcause = SCR1_HDU_HALTCAUSE_TMREQ;
508
`endif // SCR1_TDU_EN
509
        dmode_cause_ebreak  : hart_haltcause = SCR1_HDU_HALTCAUSE_EBREAK;
510
        hart_halt_req       : hart_haltcause = SCR1_HDU_HALTCAUSE_DMREQ;
511
        dmode_cause_sstep   : hart_haltcause = SCR1_HDU_HALTCAUSE_SSTEP;
512
        default             : hart_haltcause = SCR1_HDU_HALTCAUSE_NONE;
513
    endcase
514
end
515
 
516
// HART halt status register
517
//------------------------------------------------------------------------------
518
 
519
always_ff @(posedge clk, negedge rst_n) begin
520
    if (~rst_n) begin
521
        hart_haltstatus        <= '0;
522
    end else if (hart_halt_ack) begin
523
        hart_haltstatus.except <= dmode_cause_except;
524
        hart_haltstatus.cause  <= hart_haltcause;
525
    end
526
end
527
 
528
assign hart_halt_pnd = (dfsm_trans | dm_dhalt_req) & ~hart_halt_ack;
529
assign hart_halt_ack = ~hdu2exu_dbg_halted_o
530
                     & (halt_req_timeout_flag | (~pipe2hdu_exu_busy_i & dmode_cause_any));
531
 
532
//------------------------------------------------------------------------------
533
// Program Buffer (PBUF) logic
534
//------------------------------------------------------------------------------
535
//
536
 // Program Buffer allows to execute small programs in debug mode
537
//
538
 
539
// To terminate Program Buffer execution exception should be raised. There are 2
540
// cases:
541
// - One of PBUF instructions raise an exception
542
// - No PBUF instruction raise an exception before the last PBUF instruction has
543
// been issued. In this case FSM goes into EXCINJECT state and an "Instruction
544
// fetch access fault" exception is injected
545
 
546
// PBUF FSM
547
//------------------------------------------------------------------------------
548
 
549
assign ifu_handshake_done = hdu2ifu_pbuf_instr_vd_o & ifu2hdu_pbuf_instr_rdy_i;
550
assign pbuf_addr_end      = (pbuf_addr_ff == (SCR1_HDU_PBUF_ADDR_SPAN-1));
551
 
552
assign pbuf_start_fetch = dbg_state_dhalted      & (dbg_state_next == SCR1_HDU_DBGSTATE_DRUN);
553
assign pbuf_exc_inj_req = ifu_handshake_done     & pbuf_addr_end;
554
assign pbuf_exc_inj_end = pipe2hdu_exu_exc_req_i | ifu_handshake_done;
555
 
556
always_ff @(negedge rst_n, posedge clk) begin
557
    if (~rst_n) begin
558
        pbuf_fsm_curr <= SCR1_HDU_PBUFSTATE_IDLE;
559
    end else if(clk_en) begin
560
        pbuf_fsm_curr <= pbuf_fsm_next;
561
    end
562
end
563
 
564
always_comb begin
565
    case (pbuf_fsm_curr)
566
        SCR1_HDU_PBUFSTATE_IDLE: begin
567
            pbuf_fsm_next = pbuf_start_fetch       ? SCR1_HDU_PBUFSTATE_FETCH
568
                                                   : SCR1_HDU_PBUFSTATE_IDLE;
569
        end
570
        SCR1_HDU_PBUFSTATE_FETCH: begin
571
            pbuf_fsm_next = pipe2hdu_exu_exc_req_i ? SCR1_HDU_PBUFSTATE_WAIT4END
572
                          : pbuf_exc_inj_req       ? SCR1_HDU_PBUFSTATE_EXCINJECT
573
                                                   : SCR1_HDU_PBUFSTATE_FETCH;
574
        end
575
        SCR1_HDU_PBUFSTATE_EXCINJECT: begin
576
            pbuf_fsm_next = pbuf_exc_inj_end       ? SCR1_HDU_PBUFSTATE_WAIT4END
577
                                                   : SCR1_HDU_PBUFSTATE_EXCINJECT;
578
        end
579
        SCR1_HDU_PBUFSTATE_WAIT4END: begin
580
            pbuf_fsm_next = hdu2exu_dbg_halted_o   ? SCR1_HDU_PBUFSTATE_IDLE
581
                                                   : SCR1_HDU_PBUFSTATE_WAIT4END;
582
        end
583
    endcase
584
end
585
 
586
assign pbuf_fsm_idle   = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_IDLE);
587
assign pbuf_fsm_fetch  = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_FETCH);
588
assign pbuf_fsm_excinj = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_EXCINJECT);
589
 
590
// Program Buffer address register
591
//------------------------------------------------------------------------------
592
 
593
assign pbuf_addr_next_vd = pbuf_fsm_fetch          & ifu_handshake_done
594
                         & ~pipe2hdu_exu_exc_req_i & ~pbuf_addr_end;
595
 
596
always_ff @(negedge rst_n, posedge clk) begin
597
    if (~rst_n) begin
598
        pbuf_addr_ff <= '0;
599
    end else if(clk_en) begin
600
        pbuf_addr_ff <= pbuf_addr_next;
601
    end
602
end
603
 
604
assign pbuf_addr_next = pbuf_fsm_idle     ? '0
605
                      : pbuf_addr_next_vd ? pbuf_addr_ff + 1'b1
606
                                          : pbuf_addr_ff;
607
 
608
// Pass instruction from debug program buffer to cpu pipeline with two options:
609
// - through register, better for frequency
610
// - through wires, better for area
611
generate if (HART_PBUF_INSTR_REGOUT_EN) begin
612
    always_ff @(posedge clk, negedge rst_n) begin
613
        if (~rst_n) begin
614
            pbuf_instr_wait_latching <= 1'b0;
615
        end else begin
616
            pbuf_instr_wait_latching <= ifu_handshake_done;
617
        end
618
    end
619
end else begin
620
    assign pbuf_instr_wait_latching = 1'b0;
621
end endgenerate
622
 
623
//------------------------------------------------------------------------------
624
// Debug CSRs
625
//------------------------------------------------------------------------------
626
 
627
assign csr_upd_on_halt = (dbg_state_reset | dbg_state_run)
628
                       & (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED);
629
 
630
// CSRs select logic
631
//------------------------------------------------------------------------------
632
 
633
always_comb begin : csr_if_regsel
634
    csr_dcsr_sel        = 1'b0;
635
    csr_dpc_sel         = 1'b0;
636
    csr_dscratch0_sel   = 1'b0;
637
    //csr_dscratch1_sel   = 1'b0;
638
 
639
    if (csr2hdu_req_i) begin
640
        case (csr2hdu_addr_i)
641
            SCR1_HDU_DBGCSR_OFFS_DCSR     : csr_dcsr_sel      = 1'b1;
642
            SCR1_HDU_DBGCSR_OFFS_DPC      : csr_dpc_sel       = 1'b1;
643
            SCR1_HDU_DBGCSR_OFFS_DSCRATCH0: csr_dscratch0_sel = 1'b1;
644
            default : begin
645
                                            csr_dcsr_sel      = 1'bX;
646
                                            csr_dpc_sel       = 1'bX;
647
                                            csr_dscratch0_sel = 1'bX;
648
            end
649
        endcase
650
    end
651
end : csr_if_regsel
652
 
653
// CSRs read interface
654
//------------------------------------------------------------------------------
655
 
656
assign csr_rd_data = csr_dcsr_out | csr_dpc_out | csr_dscratch0_out;
657
 
658
// CSRs write interface
659
//------------------------------------------------------------------------------
660
 
661
assign csr_wr = csr2hdu_req_i;
662
 
663
always_comb begin : csr_if_write
664
    csr_wr_data     = '0;
665
 
666
    if (csr2hdu_req_i) begin
667
        case (csr2hdu_cmd_i)
668
            SCR1_CSR_CMD_WRITE : csr_wr_data = csr2hdu_wdata_i;
669
            SCR1_CSR_CMD_SET   : csr_wr_data = csr_rd_data | csr2hdu_wdata_i;
670
            SCR1_CSR_CMD_CLEAR : csr_wr_data = csr_rd_data & (~csr2hdu_wdata_i);
671
            default            : csr_wr_data = 'X;
672
        endcase
673
    end
674
end : csr_if_write
675
 
676
// Debug Control and Status register
677
//------------------------------------------------------------------------------
678
// Setups the HART behaviour in Debug Mode and holds Debug status information
679
 
680
always_comb begin
681
    csr_dcsr_in                 = csr_wr_data;
682
    csr_dcsr_wr                 = csr_wr & csr_dcsr_sel;
683
 
684
    csr_dcsr_out                = '0;
685
    if (csr_dcsr_sel) begin
686
        csr_dcsr_out.xdebugver  = SCR1_HDU_DEBUGCSR_DCSR_XDEBUGVER;
687
        csr_dcsr_out.ebreakm    = csr_dcsr_ebreakm;
688
        csr_dcsr_out.stepie     = csr_dcsr_stepie;
689
        csr_dcsr_out.step       = csr_dcsr_step;
690
        csr_dcsr_out.prv        = 2'b11;
691
        csr_dcsr_out.cause      = csr_dcsr_cause;
692
    end
693
end
694
 
695
always_ff @(negedge rst_n, posedge clk) begin
696
    if (~rst_n) begin
697
        csr_dcsr_ebreakm        <= 1'b0;
698
        csr_dcsr_stepie         <= 1'b0;
699
        csr_dcsr_step           <= 1'b0;
700
    end else if(clk_en) begin
701
        if (csr_dcsr_wr) begin
702
            csr_dcsr_ebreakm    <= csr_dcsr_in.ebreakm;
703
            csr_dcsr_stepie     <= csr_dcsr_in.stepie;
704
            csr_dcsr_step       <= csr_dcsr_in.step;
705
        end
706
    end
707
end
708
 
709
always_ff @(negedge rst_n, posedge clk) begin
710
    if (~rst_n) begin
711
        csr_dcsr_cause <= 1'b0;
712
    end else if(clk_en) begin
713
        if(csr_upd_on_halt) begin
714
            csr_dcsr_cause <= hart_haltstatus.cause;
715
        end
716
    end
717
end
718
 
719
// Debug PC register
720
//------------------------------------------------------------------------------
721
// Saves the virtual address of the next instruction to be executed when Debug
722
// Mode is entered. Could be changed by debugger
723
 
724
assign csr_dpc_wr   = csr_wr & csr_dpc_sel;
725
 
726
always_ff @(posedge clk, negedge rst_n) begin
727
    if (~rst_n) begin
728
        csr_dpc_ff <= '0;
729
    end else if(clk_en) begin
730
        csr_dpc_ff <= csr_dpc_next;
731
    end
732
end
733
 
734
assign csr_dpc_next = csr_upd_on_halt ? pipe2hdu_pc_curr_i
735
                    : csr_dpc_wr      ? csr_wr_data
736
                                      : csr_dpc_ff;
737
assign csr_dpc_out  = csr_dpc_sel     ? csr_dpc_ff : '0;
738
 
739
// Debug Scratch 0 register
740
//------------------------------------------------------------------------------
741
 
742
assign csr_dscratch0_resp = (~dm2hdu_dreg_resp_i | dm2hdu_dreg_fail_i)
743
                          ? SCR1_CSR_RESP_ER
744
                          : SCR1_CSR_RESP_OK;
745
assign csr_dscratch0_out  = csr_dscratch0_sel ? dm2hdu_dreg_rdata_i : '0;
746
 
747
//------------------------------------------------------------------------------
748
// HDU <-> DM interface
749
//------------------------------------------------------------------------------
750
 
751
assign hdu2dm_hart_event_o = dfsm_event;
752
 
753
// HART status
754
always_comb begin
755
    hdu2dm_hart_status_o           = '0;
756
    hdu2dm_hart_status_o.dbg_state = dbg_state;
757
    hdu2dm_hart_status_o.except    = dbg_state_dhalted & hart_haltstatus.except;
758
    hdu2dm_hart_status_o.ebreak    = dbg_state_dhalted & (hart_haltstatus.cause == SCR1_HDU_HALTCAUSE_EBREAK);
759
end
760
 
761
assign hdu2dm_cmd_rcode_o = dbg_state_reset
762
                          ? ~pipe2hdu_rdc_qlfy_i | ~pipe2hdu_init_pc_i | ~dm2hdu_cmd_req_i
763
                          : ~pipe2hdu_rdc_qlfy_i | ~dfsm_update;
764
 
765
always_comb begin
766
    hdu2dm_cmd_resp_o   = 1'b0;
767
 
768
    case (dbg_state)
769
        SCR1_HDU_DBGSTATE_RESET: begin
770
            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i & pipe2hdu_init_pc_i & dm2hdu_cmd_req_i;
771
        end
772
 
773
        SCR1_HDU_DBGSTATE_RUN: begin
774
            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i & dfsm_update & dm2hdu_cmd_req_i;
775
        end
776
 
777
        SCR1_HDU_DBGSTATE_DHALTED: begin
778
            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i ? dfsm_update : dm2hdu_cmd_req_i;
779
        end
780
 
781
        SCR1_HDU_DBGSTATE_DRUN: begin
782
            hdu2dm_cmd_resp_o  = (~pipe2hdu_rdc_qlfy_i | dfsm_update) & dm2hdu_cmd_req_i;
783
        end
784
 
785
        default: begin
786
            hdu2dm_cmd_resp_o  = 'X;
787
        end
788
    endcase
789
end
790
 
791
assign hdu2dm_pbuf_addr_o  = pbuf_addr_ff;
792
assign hdu2dm_dreg_req_o   = csr_dscratch0_sel;
793
assign hdu2dm_dreg_wr_o    = csr_wr & csr_dscratch0_sel;
794
assign hdu2dm_dreg_wdata_o = csr_wr_data;
795
 
796
//------------------------------------------------------------------------------
797
// HDU <-> EXU interface
798
//------------------------------------------------------------------------------
799
 
800
assign hdu2exu_dbg_halted_o    = (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED)
801
                               | (~pipe2hdu_rdc_qlfy_i & ~dbg_state_run);
802
assign hdu2exu_dbg_run_start_o = dbg_state_dhalted & pipe2hdu_rdc_qlfy_i & dfsm_update;
803
assign hdu2exu_dbg_halt2run_o  = hdu2exu_dbg_halted_o & hart_resume_req
804
`ifdef SCR1_CLKCTRL_EN
805
                               & clk_pipe_en
806
`endif // SCR1_CLKCTRL_EN
807
                               ;
808
assign hdu2exu_dbg_run2halt_o  = hart_halt_ack;
809
 
810
assign hdu2exu_pbuf_fetch_o    = hart_runctrl.fetch_src;
811
assign hdu2exu_irq_dsbl_o      = hart_runctrl.irq_dsbl;
812
assign hdu2exu_pc_advmt_dsbl_o = hart_runctrl.pc_advmt_dsbl;
813
// No change in arch. state if dmode caused by breakpoint
814
assign hdu2exu_no_commit_o     = dmode_cause_ebreak
815
`ifdef SCR1_TDU_EN
816
                               | dmode_cause_tmreq
817
`endif // SCR1_TDU_EN
818
                               ;
819
assign hdu2exu_dmode_sstep_en_o = hart_runctrl.redirect.sstep;
820
assign hdu2exu_dbg_new_pc_o     = csr_dpc_ff;
821
 
822
//------------------------------------------------------------------------------
823
// HDU <-> IFU interface
824
//------------------------------------------------------------------------------
825
 
826
assign hdu2ifu_pbuf_instr_vd_o  = (pbuf_fsm_fetch | pbuf_fsm_excinj)
827
                                & ~pbuf_instr_wait_latching;
828
assign hdu2ifu_pbuf_instr_err_o = pbuf_fsm_excinj;
829
 
830
generate if (HART_PBUF_INSTR_REGOUT_EN) begin
831
    always_ff @(posedge clk) begin
832
        hdu2ifu_pbuf_instr_o <= dm2hdu_pbuf_instr_i;
833
    end
834
end else begin
835
    assign hdu2ifu_pbuf_instr_o = dm2hdu_pbuf_instr_i;
836
end endgenerate
837
 
838
//------------------------------------------------------------------------------
839
// HDU <-> CSR interface
840
//------------------------------------------------------------------------------
841
 
842
assign csr_addr_dscratch0 = (csr2hdu_addr_i == SCR1_HDU_DBGCSR_OFFS_DSCRATCH0);
843
 
844
assign hdu2csr_resp_o  = ~dbg_state_drun    ? SCR1_CSR_RESP_ER
845
                       : csr_addr_dscratch0 ? csr_dscratch0_resp
846
                       : csr2hdu_req_i      ? SCR1_CSR_RESP_OK
847
                                            : SCR1_CSR_RESP_ER;
848
assign hdu2csr_rdata_o = csr_rd_data;
849
 
850
`ifdef SCR1_TDU_EN
851
//------------------------------------------------------------------------------
852
// HDU <-> TDU interface
853
//------------------------------------------------------------------------------
854
 
855
assign hdu2tdu_hwbrk_dsbl_o = hart_runctrl.hwbrkpt_dsbl;
856
`endif // SCR1_TDU_EN
857
 
858
`ifdef SCR1_TRGT_SIMULATION
859
//-------------------------------------------------------------------------------
860
// Assertion
861
//-------------------------------------------------------------------------------
862
 
863
SVA_HDU_XCHECK_COMMON :
864
    assert property (
865
        @(negedge clk) disable iff (~rst_n)
866
        !$isunknown( {rst_n,clk,clk_en,csr2hdu_req_i,pipe2hdu_rdc_qlfy_i} )
867
    )
868
    else $error("HDU Error: common signals are in X state");
869
 
870
SVA_HDU_XCHECK_CSR_INTF :
871
    assert property (
872
        @(negedge clk) disable iff (~rst_n)
873
        csr2hdu_req_i |-> !$isunknown( {csr2hdu_cmd_i,csr2hdu_addr_i,csr2hdu_wdata_i} )
874
    )
875
    else $error("HDU Error: CSR i/f is in X state");
876
 
877
SVA_HDU_XCHECK_DM_INTF :
878
    assert property (
879
        @(negedge clk) disable iff (~rst_n)
880
        !$isunknown( {dm2hdu_cmd_req_i,dm2hdu_cmd_i,dm2hdu_dreg_resp_i,
881
        dm2hdu_dreg_fail_i} )
882
    )
883
    else $error("HDU Error: DM i/f is in X state");
884
 
885
SVA_HDU_XCHECK_TDU_INTF :
886
    assert property (
887
        @(negedge clk) disable iff (~rst_n)
888
        !$isunknown( {tdu2hdu_dmode_req_i,exu2hdu_ibrkpt_hw_i} )
889
    )
890
    else $error("HDU Error: TDU i/f is in X state");
891
 
892
SVA_HDU_XCHECK_HART_INTF :
893
    assert property (
894
        @(negedge clk) disable iff (~rst_n)
895
        !$isunknown( {pipe2hdu_exu_busy_i,pipe2hdu_instret_i,pipe2hdu_init_pc_i,pipe2hdu_exu_exc_req_i,pipe2hdu_brkpt_i,
896
        pipe2hdu_pc_curr_i,ifu2hdu_pbuf_instr_rdy_i} )
897
    )
898
    else $error("HDU Error: HART i/f is in X state");
899
 
900
`endif // SCR1_TRGT_SIMULATION
901
 
902
endmodule : scr1_pipe_hdu
903
 
904
`endif // SCR1_DBG_EN

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.