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_tdu.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-2020. See LICENSE for details
2
/// @file       
3
/// @brief      Trigger Debug Unit (TDU)
4
///
5
 
6
//------------------------------------------------------------------------------
7
 //
8
 // Functionality:
9
 // - Provides read/write interface for TDU CSRs
10
 // - Provides triggers functionality:
11
 //   - Supports triggers either in both Debug and M modes or in Debug mode only
12
 //   - Supports virtual address matching (load, store, exec) triggers
13
 //   - Supports instruction count triggers
14
 //   - Supports the following actions on trigger firing:
15
 //     - Breakpoint exception raising
16
 //     - Debug Mode entering
17
 //   - Supports triggers chaining
18
 //
19
 // Structure:
20
 // - CSR read/write i/f
21
 // - TDU CSRs:
22
 //   - TSELECT
23
 //   - TDATA1/MCONTROL/ICOUNT
24
 //   - TDATA2
25
 //   - TINFO
26
 // - TDU <-> EXU i/f
27
 // - TDU <-> LSU i/f
28
 // - TDU <-> HDU i/f
29
//------------------------------------------------------------------------------
30
 
31
`include "scr1_arch_description.svh"
32
 
33
`ifdef SCR1_TDU_EN
34
`include "scr1_riscv_isa_decoding.svh"
35
`include "scr1_tdu.svh"
36
 
37
module scr1_pipe_tdu (
38
    // Common signals
39
    input  logic                                            rst_n,                      // TDU reset
40
    input  logic                                            clk,                        // TDU clock
41
    input  logic                                            clk_en,                     // TDU clock enable
42
    input  logic                                            tdu_dsbl_i,                 // TDU Disable
43
 
44
    // TDU <-> CSR interface
45
    input  logic                                            csr2tdu_req_i,              // CSR-TDU i/f request
46
    input  type_scr1_csr_cmd_sel_e                          csr2tdu_cmd_i,              // CSR-TDU i/f command
47
    input  logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]             csr2tdu_addr_i,             // CSR-TDU i/f address
48
    input  logic [SCR1_TDU_DATA_W-1:0]                      csr2tdu_wdata_i,            // CSR-TDU i/f write data
49
    output logic [SCR1_TDU_DATA_W-1:0]                      tdu2csr_rdata_o,            // CSR-TDU i/f read data
50
    output type_scr1_csr_resp_e                             tdu2csr_resp_o,             // CSR-TDU i/f response
51
 
52
    // TDU <-> EXU interface
53
    input  type_scr1_brkm_instr_mon_s                       exu2tdu_imon_i,             // Instruction stream monitoring
54
    output logic [SCR1_TDU_ALLTRIG_NUM-1 : 0]               tdu2exu_ibrkpt_match_o,     // Instruction BP match
55
    output logic                                            tdu2exu_ibrkpt_exc_req_o,   // Instruction BP exception request
56
    input  logic [SCR1_TDU_ALLTRIG_NUM-1 : 0]               exu2tdu_bp_retire_i,        // Map of BPs being retired
57
 
58
    // TDU <-> LSU interface
59
`ifndef SCR1_TDU_EN
60
    output logic                                            tdu2lsu_brk_en_o,           // TDU-LSU Breakpoint enable
61
`endif // SCR1_TDU_EN
62
    output logic                                            tdu2lsu_ibrkpt_exc_req_o,   // TDU-LSU Instruction BP exception request
63
    input  type_scr1_brkm_lsu_mon_s                         lsu2tdu_dmon_i,             // TDU-LSU Data address stream monitoring
64
    output logic [SCR1_TDU_MTRIG_NUM-1 : 0]                 tdu2lsu_dbrkpt_match_o,     // TDU-LSU Data BP match
65
    output logic                                            tdu2lsu_dbrkpt_exc_req_o,   // TDU-LSU Data BP exception request
66
 
67
    // TDU <-> HDU interface
68
    output logic                                            tdu2hdu_dmode_req_o         // Debug Mode redirection request
69
);
70
 
71
//------------------------------------------------------------------------------
72
// Local parameters declaration
73
//------------------------------------------------------------------------------
74
 
75
localparam int unsigned MTRIG_NUM   = SCR1_TDU_MTRIG_NUM;
76
localparam int unsigned ALLTRIG_NUM = SCR1_TDU_ALLTRIG_NUM;
77
localparam int unsigned ALLTRIG_W   = $clog2(ALLTRIG_NUM+1);
78
 
79
//------------------------------------------------------------------------------
80
// Local signals declaration
81
//------------------------------------------------------------------------------
82
 
83
// TDU CSRs read/write i/f signals
84
//------------------------------------------------------------------------------
85
 
86
// Write signals
87
logic                                           csr_wr_req;
88
logic [SCR1_TDU_DATA_W-1:0]                     csr_wr_data;
89
 
90
// Register select
91
logic                                           csr_addr_tselect;
92
logic [MTRIG_NUM-1:0]                           csr_addr_mcontrol;
93
logic [MTRIG_NUM-1:0]                           csr_addr_tdata2;
94
`ifdef SCR1_TDU_ICOUNT_EN
95
logic                                           csr_addr_icount;
96
`endif // SCR1_TDU_ICOUNT_EN
97
 
98
// TDU CSRs
99
//------------------------------------------------------------------------------
100
 
101
// TSELECT register
102
logic                                           csr_tselect_upd;
103
logic [ALLTRIG_W-1:0]                           csr_tselect_ff;
104
 
105
// MCONTROL register
106
logic [MTRIG_NUM-1:0]                           csr_mcontrol_wr_req;
107
logic [MTRIG_NUM-1:0]                           csr_mcontrol_clk_en;
108
logic [MTRIG_NUM-1:0]                           csr_mcontrol_upd;
109
 
110
logic [MTRIG_NUM-1:0]                           csr_mcontrol_dmode_ff;
111
logic [MTRIG_NUM-1:0]                           csr_mcontrol_dmode_next;
112
logic [MTRIG_NUM-1:0]                           csr_mcontrol_m_ff;
113
logic [MTRIG_NUM-1:0]                           csr_mcontrol_m_next;
114
logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_ff;
115
logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_next;
116
logic [MTRIG_NUM-1:0]                           csr_mcontrol_load_ff;
117
logic [MTRIG_NUM-1:0]                           csr_mcontrol_load_next;
118
logic [MTRIG_NUM-1:0]                           csr_mcontrol_store_ff;
119
logic [MTRIG_NUM-1:0]                           csr_mcontrol_store_next;
120
logic [MTRIG_NUM-1:0]                           csr_mcontrol_action_ff;
121
logic [MTRIG_NUM-1:0]                           csr_mcontrol_action_next;
122
logic [MTRIG_NUM-1:0]                           csr_mcontrol_hit_ff;
123
logic [MTRIG_NUM-1:0]                           csr_mcontrol_hit_next;
124
 
125
logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_hit;
126
logic [MTRIG_NUM-1:0]                           csr_mcontrol_ldst_hit;
127
 
128
// ICOUNT register
129
`ifdef SCR1_TDU_ICOUNT_EN
130
logic                                           csr_icount_wr_req;
131
logic                                           csr_icount_clk_en;
132
logic                                           csr_icount_upd;
133
 
134
logic                                           csr_icount_dmode_ff;
135
logic                                           csr_icount_dmode_next;
136
logic                                           csr_icount_m_ff;
137
logic                                           csr_icount_m_next;
138
logic                                           csr_icount_action_ff;
139
logic                                           csr_icount_action_next;
140
logic                                           csr_icount_hit_ff;
141
logic                                           csr_icount_hit_next;
142
logic [SCR1_TDU_ICOUNT_COUNT_HI-SCR1_TDU_ICOUNT_COUNT_LO:0]
143
                                                csr_icount_count_ff;
144
logic [SCR1_TDU_ICOUNT_COUNT_HI-SCR1_TDU_ICOUNT_COUNT_LO:0]
145
                                                csr_icount_count_next;
146
logic                                           csr_icount_skip_ff;
147
logic                                           csr_icount_skip_next;
148
 
149
logic                                           csr_icount_decr_en;
150
logic                                           csr_icount_count_decr;
151
logic                                           csr_icount_skip_dsbl;
152
logic                                           csr_icount_hit;
153
`endif // SCR1_TDU_ICOUNT_EN
154
 
155
// TDATA2 register
156
logic [MTRIG_NUM-1:0]                           csr_tdata2_upd;
157
logic [MTRIG_NUM-1:0]                           csr_tdata2_ff [SCR1_TDU_DATA_W-1:0];
158
 
159
//------------------------------------------------------------------------------
160
// CSR read/write interface
161
//------------------------------------------------------------------------------
162
 
163
// Read logic
164
//------------------------------------------------------------------------------
165
 
166
assign tdu2csr_resp_o = csr2tdu_req_i ? SCR1_CSR_RESP_OK : SCR1_CSR_RESP_ER;
167
integer i;
168
always_comb begin
169
    i = 0; // yosys latch warning fix
170
    tdu2csr_rdata_o = '0;
171
    if (csr2tdu_req_i) begin
172
        case (csr2tdu_addr_i)
173
            SCR1_CSR_ADDR_TDU_OFFS_TSELECT: begin
174
                tdu2csr_rdata_o = {'0, csr_tselect_ff};
175
            end
176
            SCR1_CSR_ADDR_TDU_OFFS_TDATA2 : begin
177
                for(i = 0; i < MTRIG_NUM; i=i+1) begin // cp.4
178
                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
179
                        tdu2csr_rdata_o = csr_tdata2_ff[i];
180
                    end
181
                end
182
            end
183
            SCR1_CSR_ADDR_TDU_OFFS_TDATA1 : begin
184
                for(i = 0; i < MTRIG_NUM; i=i+1) begin // cp.4
185
                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
186
                        tdu2csr_rdata_o[SCR1_TDU_TDATA1_TYPE_HI:
187
                                       SCR1_TDU_TDATA1_TYPE_LO]      = SCR1_TDU_MCONTROL_TYPE_VAL;
188
                        tdu2csr_rdata_o[SCR1_TDU_TDATA1_DMODE]       = csr_mcontrol_dmode_ff[i];
189
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_MASKMAX_HI:
190
                                       SCR1_TDU_MCONTROL_MASKMAX_LO] = SCR1_TDU_MCONTROL_MASKMAX_VAL;
191
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_HIT]       = csr_mcontrol_hit_ff[i];
192
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_SELECT]    = SCR1_TDU_MCONTROL_SELECT_VAL;
193
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_TIMING]    = SCR1_TDU_MCONTROL_TIMING_VAL;
194
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_ACTION_HI:
195
                                       SCR1_TDU_MCONTROL_ACTION_LO]  = {5'b0, csr_mcontrol_action_ff[i]};
196
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_CHAIN]     = 1'b0;
197
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_MATCH_HI:
198
                                       SCR1_TDU_MCONTROL_MATCH_LO]   = 4'b0;
199
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_M]         = csr_mcontrol_m_ff[i];
200
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_RESERVEDA] = SCR1_TDU_MCONTROL_RESERVEDA_VAL;
201
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_S]         = 1'b0;
202
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_U]         = 1'b0;
203
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_EXECUTE]   = csr_mcontrol_exec_ff [i];
204
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_STORE]     = csr_mcontrol_store_ff[i];
205
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_LOAD]      = csr_mcontrol_load_ff [i];
206
                    end
207
                end
208
`ifdef SCR1_TDU_ICOUNT_EN
209
                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
210
                    tdu2csr_rdata_o[SCR1_TDU_TDATA1_TYPE_HI:
211
                                   SCR1_TDU_TDATA1_TYPE_LO]    = SCR1_TDU_ICOUNT_TYPE_VAL;
212
                    tdu2csr_rdata_o[SCR1_TDU_TDATA1_DMODE]     = csr_icount_dmode_ff;
213
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_HIT]       = csr_icount_hit_ff;
214
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_COUNT_HI:
215
                                   SCR1_TDU_ICOUNT_COUNT_LO]   = csr_icount_count_ff;
216
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_U]         = 1'b0;
217
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_S]         = 1'b0;
218
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_M]         = csr_icount_m_ff;
219
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_ACTION_HI:
220
                                   SCR1_TDU_ICOUNT_ACTION_LO]  = {5'b0, csr_icount_action_ff};
221
                end
222
`endif // SCR1_TDU_ICOUNT_EN
223
            end
224
            SCR1_CSR_ADDR_TDU_OFFS_TINFO : begin
225
                for(i = 0; i < MTRIG_NUM; i=i+1) begin // cp.4
226
                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
227
                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_TYPE_VAL] = 1'b1;
228
                    end
229
                end
230
`ifdef SCR1_TDU_ICOUNT_EN
231
                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
232
                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_TYPE_VAL] = 1'b1;
233
                end
234
`endif // SCR1_TDU_ICOUNT_EN
235
            end
236
            default : begin
237
            end
238
        endcase
239
    end
240
end
241
 
242
// Write logic
243
//------------------------------------------------------------------------------
244
 
245
always_comb begin
246
    csr_wr_req  = 1'b0;
247
    csr_wr_data = '0;
248
 
249
    case (csr2tdu_cmd_i)
250
        SCR1_CSR_CMD_WRITE: begin
251
            csr_wr_req  = 1'b1;
252
            csr_wr_data = csr2tdu_wdata_i;
253
        end
254
        SCR1_CSR_CMD_SET  : begin
255
            csr_wr_req  = |csr2tdu_wdata_i;
256
            csr_wr_data = tdu2csr_rdata_o | csr2tdu_wdata_i;
257
        end
258
        SCR1_CSR_CMD_CLEAR: begin
259
            csr_wr_req  = |csr2tdu_wdata_i;
260
            csr_wr_data = tdu2csr_rdata_o & ~csr2tdu_wdata_i;
261
        end
262
        default : begin
263
        end
264
    endcase
265
end
266
 
267
// Register selection
268
//------------------------------------------------------------------------------
269
integer k;
270
always_comb begin
271
    k = 0; // yosys latch warning fix
272
    csr_addr_tselect  = 1'b0;
273
    csr_addr_tdata2   = '0;
274
    csr_addr_mcontrol = '0;
275
`ifdef SCR1_TDU_ICOUNT_EN
276
    csr_addr_icount   = '0;
277
`endif // SCR1_TDU_ICOUNT_EN
278
 
279
    if (csr2tdu_req_i) begin
280
        case (csr2tdu_addr_i)
281
            SCR1_CSR_ADDR_TDU_OFFS_TSELECT: begin
282
                csr_addr_tselect = 1'b1;
283
            end
284
            SCR1_CSR_ADDR_TDU_OFFS_TDATA1 : begin
285
                for(k = 0; k < MTRIG_NUM; k=k+1) begin
286
                    if(csr_tselect_ff == ALLTRIG_W'(k)) begin
287
                        csr_addr_mcontrol[k] = 1'b1;
288
                    end
289
                end
290
`ifdef SCR1_TDU_ICOUNT_EN
291
                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
292
                    csr_addr_icount = 1'b1;
293
                end
294
`endif // SCR1_TDU_ICOUNT_EN
295
            end
296
            SCR1_CSR_ADDR_TDU_OFFS_TDATA2 : begin
297
                for(k = 0; k < MTRIG_NUM; k=k+1) begin // cp.4
298
                    if(csr_tselect_ff == ALLTRIG_W'(k) ) begin
299
                        csr_addr_tdata2[k] = 1'b1;
300
                    end
301
                end
302
            end
303
            default : begin
304
            end
305
        endcase
306
    end
307
end
308
 
309
//------------------------------------------------------------------------------
310
// TDU CSRs
311
//------------------------------------------------------------------------------
312
//
313
 // TDU CSRs consist of the following registers:
314
 // - TSELECT
315
 // - TDATA1/MCONTROL/ICOUNT (depending on the type field value)
316
 // - TDATA2
317
//
318
 
319
// TSELECT register
320
//------------------------------------------------------------------------------
321
// Determines which trigger is accessible through the other trigger registers
322
 
323
assign csr_tselect_upd = clk_en & csr_addr_tselect & csr_wr_req
324
                       & (csr_wr_data[ALLTRIG_W-1:0] < ALLTRIG_W'(ALLTRIG_NUM));
325
 
326
always_ff @(negedge rst_n, posedge clk) begin
327
    if(~rst_n) begin
328
        csr_tselect_ff <= '0;
329
    end else if(csr_tselect_upd) begin
330
        csr_tselect_ff <= csr_wr_data[ALLTRIG_W-1:0];
331
    end
332
end
333
 
334
`ifdef SCR1_TDU_ICOUNT_EN
335
// ICOUNT register
336
//------------------------------------------------------------------------------
337
// Provides a trigger that fires when the certain number of instructions has retired
338
// Is intended to be used as a single step trigger (in this case count must be 1)
339
 
340
assign csr_icount_wr_req = csr_addr_icount & csr_wr_req;
341
assign csr_icount_clk_en = clk_en & (csr_icount_wr_req | csr_icount_m_ff);
342
assign csr_icount_upd    = ~csr_icount_dmode_ff
343
                         ? csr_icount_wr_req
344
                         : tdu_dsbl_i & csr_icount_wr_req;
345
 
346
always_ff @(negedge rst_n, posedge clk) begin
347
    if(~rst_n) begin
348
        csr_icount_dmode_ff  <= 1'b0;
349
        csr_icount_m_ff      <= 1'b0;
350
        csr_icount_action_ff <= 1'b0;
351
        csr_icount_hit_ff    <= 1'b0;
352
        csr_icount_count_ff  <= '0;
353
        csr_icount_skip_ff   <= 1'b0;
354
    end else if (csr_icount_clk_en) begin
355
        csr_icount_dmode_ff  <= csr_icount_dmode_next;
356
        csr_icount_m_ff      <= csr_icount_m_next;
357
        csr_icount_action_ff <= csr_icount_action_next;
358
        csr_icount_hit_ff    <= csr_icount_hit_next;
359
        csr_icount_count_ff  <= csr_icount_count_next;
360
        csr_icount_skip_ff   <= csr_icount_skip_next;
361
    end
362
end
363
 
364
assign csr_icount_decr_en    = (~tdu_dsbl_i & csr_icount_m_ff)
365
                             ? exu2tdu_imon_i.vd & (csr_icount_count_ff != 14'b0)
366
                             : 1'b0;
367
assign csr_icount_count_decr = exu2tdu_imon_i.req & csr_icount_decr_en & ~csr_icount_skip_ff;
368
assign csr_icount_skip_dsbl  = exu2tdu_imon_i.req & csr_icount_decr_en & csr_icount_skip_ff;
369
 
370
always_comb begin
371
    if (csr_icount_upd) begin
372
        csr_icount_dmode_next  = csr_wr_data[SCR1_TDU_TDATA1_DMODE];
373
        csr_icount_m_next      = csr_wr_data[SCR1_TDU_ICOUNT_M];
374
        csr_icount_action_next = (csr_wr_data[SCR1_TDU_ICOUNT_ACTION_HI
375
                                             :SCR1_TDU_ICOUNT_ACTION_LO] == 'b1);
376
        csr_icount_hit_next    = csr_wr_data[SCR1_TDU_ICOUNT_HIT];
377
        csr_icount_count_next  = csr_wr_data[SCR1_TDU_ICOUNT_COUNT_HI:SCR1_TDU_ICOUNT_COUNT_LO];
378
    end else begin
379
        csr_icount_dmode_next  = csr_icount_dmode_ff;
380
        csr_icount_m_next      = csr_icount_m_ff;
381
        csr_icount_action_next = csr_icount_action_ff;
382
        csr_icount_hit_next    = exu2tdu_bp_retire_i[ALLTRIG_NUM - 1'b1]
383
                               ? 1'b1
384
                               : csr_icount_hit_ff;
385
        csr_icount_count_next  = csr_icount_count_decr
386
                               ? csr_icount_count_ff - 1'b1
387
                               : csr_icount_count_ff;
388
    end
389
end
390
 
391
assign csr_icount_skip_next = csr_icount_wr_req    ? csr_wr_data[SCR1_TDU_ICOUNT_M]
392
                            : csr_icount_skip_dsbl ? 1'b0
393
                                                   : csr_icount_skip_ff;
394
`endif // SCR1_TDU_ICOUNT_EN
395
 
396
// MCONTROL registers
397
//------------------------------------------------------------------------------
398
// Provides a trigger that fires on the virtual address (stored in TDATA2) match
399
// (load, store, exec options supported). Triggers chaining supported
400
 
401
genvar trig;
402
generate
403
for (trig = 0; $unsigned(trig) < MTRIG_NUM; trig=trig+1) begin : gblock_mtrig
404
 
405
assign csr_mcontrol_wr_req[trig] = csr_addr_mcontrol[trig] & csr_wr_req;
406
assign csr_mcontrol_clk_en[trig] = clk_en
407
                                 & (csr_mcontrol_wr_req[trig] | csr_mcontrol_m_ff[trig]);
408
assign csr_mcontrol_upd   [trig] = ~csr_mcontrol_dmode_ff[trig]
409
                                 ? csr_mcontrol_wr_req[trig]
410
                                 : tdu_dsbl_i & csr_mcontrol_wr_req[trig];
411
 
412
always_ff @(negedge rst_n, posedge clk) begin
413
    if(~rst_n) begin
414
        csr_mcontrol_dmode_ff [trig] <= 1'b0;
415
        csr_mcontrol_m_ff     [trig] <= 1'b0;
416
        csr_mcontrol_exec_ff  [trig] <= 1'b0;
417
        csr_mcontrol_load_ff  [trig] <= 1'b0;
418
        csr_mcontrol_store_ff [trig] <= 1'b0;
419
        csr_mcontrol_action_ff[trig] <= 1'b0;
420
        csr_mcontrol_hit_ff   [trig] <= 1'b0;
421
    end else if(csr_mcontrol_clk_en[trig]) begin
422
        csr_mcontrol_dmode_ff [trig] <= csr_mcontrol_dmode_next[trig];
423
        csr_mcontrol_m_ff     [trig] <= csr_mcontrol_m_next[trig];
424
        csr_mcontrol_exec_ff  [trig] <= csr_mcontrol_exec_next[trig];
425
        csr_mcontrol_load_ff  [trig] <= csr_mcontrol_load_next[trig];
426
        csr_mcontrol_store_ff [trig] <= csr_mcontrol_store_next[trig];
427
        csr_mcontrol_action_ff[trig] <= csr_mcontrol_action_next[trig];
428
        csr_mcontrol_hit_ff   [trig] <= csr_mcontrol_hit_next[trig];
429
    end
430
end
431
 
432
always_comb begin
433
    if (csr_mcontrol_upd[trig]) begin
434
        csr_mcontrol_dmode_next [trig] = csr_wr_data[SCR1_TDU_TDATA1_DMODE];
435
        csr_mcontrol_m_next     [trig] = csr_wr_data[SCR1_TDU_MCONTROL_M];
436
        csr_mcontrol_exec_next  [trig] = csr_wr_data[SCR1_TDU_MCONTROL_EXECUTE];
437
        csr_mcontrol_load_next  [trig] = csr_wr_data[SCR1_TDU_MCONTROL_LOAD];
438
        csr_mcontrol_store_next [trig] = csr_wr_data[SCR1_TDU_MCONTROL_STORE];
439
        csr_mcontrol_action_next[trig] = (csr_wr_data[SCR1_TDU_MCONTROL_ACTION_HI
440
                                                     :SCR1_TDU_MCONTROL_ACTION_LO] == 'b1);
441
        csr_mcontrol_hit_next   [trig] = csr_wr_data[SCR1_TDU_MCONTROL_HIT];
442
    end else begin
443
        csr_mcontrol_dmode_next [trig] = csr_mcontrol_dmode_ff [trig];
444
        csr_mcontrol_m_next     [trig] = csr_mcontrol_m_ff     [trig];
445
        csr_mcontrol_exec_next  [trig] = csr_mcontrol_exec_ff  [trig];
446
        csr_mcontrol_load_next  [trig] = csr_mcontrol_load_ff  [trig];
447
        csr_mcontrol_store_next [trig] = csr_mcontrol_store_ff [trig];
448
        csr_mcontrol_action_next[trig] = csr_mcontrol_action_ff[trig];
449
        csr_mcontrol_hit_next   [trig] = exu2tdu_bp_retire_i[trig]
450
                                       ? 1'b1
451
                                       : csr_mcontrol_hit_ff[trig];
452
    end
453
end
454
 
455
// TDATA2 register
456
//------------------------------------------------------------------------------
457
 
458
assign csr_tdata2_upd[trig] = ~csr_mcontrol_dmode_ff[trig]
459
                            ? clk_en & csr_addr_tdata2[trig] & csr_wr_req
460
                            : clk_en & csr_addr_tdata2[trig] & csr_wr_req & tdu_dsbl_i;
461
 
462
always_ff @(posedge clk) begin
463
    if (csr_tdata2_upd[trig]) begin
464
        csr_tdata2_ff[trig] <= csr_wr_data;
465
    end
466
end
467
 
468
end
469
endgenerate // gblock_mtrig
470
 
471
//------------------------------------------------------------------------------
472
// TDU <-> EXU interface
473
//------------------------------------------------------------------------------
474
 
475
assign csr_icount_hit = ~tdu_dsbl_i & csr_icount_m_ff
476
                      ? exu2tdu_imon_i.vd & (csr_icount_count_ff == 14'b1) & ~csr_icount_skip_ff
477
                      : 1'b0;
478
 
479
`ifndef SCR1_TDU_ICOUNT_EN
480
assign tdu2exu_ibrkpt_match_o   = csr_mcontrol_exec_hit;
481
assign tdu2exu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit;
482
`else
483
assign tdu2exu_ibrkpt_match_o   = {csr_icount_hit, csr_mcontrol_exec_hit};
484
assign tdu2exu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit | csr_icount_hit;
485
`endif // SCR1_TDU_ICOUNT_EN
486
 
487
//------------------------------------------------------------------------------
488
// TDU <-> LSU interface
489
//------------------------------------------------------------------------------
490
 
491
// Breakpoint logic
492
//------------------------------------------------------------------------------
493
 
494
generate
495
for (trig = 0; $unsigned(trig) < MTRIG_NUM; trig=trig+1) begin : gblock_break_trig
496
assign csr_mcontrol_exec_hit[trig] = ~tdu_dsbl_i
497
                                   & csr_mcontrol_m_ff[trig]
498
                                   & csr_mcontrol_exec_ff[trig]
499
                                   & exu2tdu_imon_i.vd
500
                                   & exu2tdu_imon_i.addr == csr_tdata2_ff[trig];
501
end
502
endgenerate
503
 
504
`ifndef SCR1_TDU_ICOUNT_EN
505
assign tdu2lsu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit;
506
`else
507
assign tdu2lsu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit | csr_icount_hit;
508
`endif // SCR1_TDU_ICOUNT_EN
509
 
510
// Watchpoint logic
511
//------------------------------------------------------------------------------
512
 
513
generate
514
for( trig = 0; $unsigned(trig) < MTRIG_NUM; trig=trig+1 ) begin : gblock_watch_trig
515
assign csr_mcontrol_ldst_hit[trig] = ~tdu_dsbl_i
516
                                   & csr_mcontrol_m_ff[trig]
517
                                   & lsu2tdu_dmon_i.vd
518
                                   & ( (csr_mcontrol_load_ff [trig] & lsu2tdu_dmon_i.load)
519
                                     | (csr_mcontrol_store_ff[trig] & lsu2tdu_dmon_i.store))
520
                                   & lsu2tdu_dmon_i.addr == csr_tdata2_ff[trig];
521
end
522
endgenerate
523
 
524
assign tdu2lsu_dbrkpt_match_o   = csr_mcontrol_ldst_hit;
525
assign tdu2lsu_dbrkpt_exc_req_o = |csr_mcontrol_ldst_hit;
526
 
527
`ifndef SCR1_TDU_EN
528
assign tdu2lsu_brk_en_o = |csr_mcontrol_m_ff | csr_icount_m_ff;
529
`endif // SCR1_TDU_EN
530
 
531
//------------------------------------------------------------------------------
532
// TDU <-> HDU interface
533
//------------------------------------------------------------------------------
534
integer j;
535
always_comb begin
536
    tdu2hdu_dmode_req_o = 1'b0;
537
 
538
    for(j = 0; j < MTRIG_NUM; j=j+1) begin
539
        tdu2hdu_dmode_req_o |= (csr_mcontrol_action_ff[j] & exu2tdu_bp_retire_i[j]);
540
    end
541
`ifdef SCR1_TDU_ICOUNT_EN
542
    tdu2hdu_dmode_req_o |= (csr_icount_action_ff & exu2tdu_bp_retire_i[ALLTRIG_NUM-1]);
543
`endif // SCR1_TDU_ICOUNT_EN
544
end
545
 
546
`ifdef SCR1_TRGT_SIMULATION
547
//------------------------------------------------------------------------------
548
// Assertion
549
//------------------------------------------------------------------------------
550
 
551
SVA_TDU_X_CONTROL : assert property (
552
    @(negedge clk) disable iff (~rst_n)
553
    !$isunknown({clk_en, tdu_dsbl_i, csr2tdu_req_i,
554
                 exu2tdu_imon_i.vd, lsu2tdu_dmon_i.vd, exu2tdu_bp_retire_i})
555
    ) else $error("TDU Error: control signals is X - %0b", {clk_en,
556
    tdu_dsbl_i, csr2tdu_req_i, exu2tdu_imon_i.vd, lsu2tdu_dmon_i.vd, exu2tdu_bp_retire_i});
557
 
558
SVA_DM_X_CLK_EN : assert property (
559
    @(negedge clk) disable iff (~rst_n)
560
    !$isunknown(clk_en)
561
    ) else $error("TDU Error: clk_en control signals is X");
562
 
563
SVA_DM_X_DSBL : assert property (
564
    @(negedge clk) disable iff (~rst_n)
565
    !$isunknown(tdu_dsbl_i)
566
    ) else $error("TDU Error: tdu_dsbl_i control signals is X");
567
 
568
SVA_DM_X_CSR2TDU_REQ : assert property (
569
    @(negedge clk) disable iff (~rst_n)
570
    !$isunknown(csr2tdu_req_i)
571
    ) else $error("TDU Error: csr2tdu_req_i control signals is X");
572
 
573
SVA_DM_X_I_MON_VD : assert property (
574
    @(negedge clk) disable iff (~rst_n)
575
    !$isunknown(exu2tdu_imon_i.vd)
576
    ) else $error("TDU Error: exu2tdu_imon_i.vd control signals is X");
577
 
578
SVA_DM_X_D_MON_VD : assert property (
579
    @(negedge clk) disable iff (~rst_n)
580
    !$isunknown(lsu2tdu_dmon_i.vd)
581
    ) else $error("TDU Error: lsu2tdu_dmon_i.vd control signals is X");
582
 
583
SVA_DM_X_BP_RETIRE : assert property (
584
    @(negedge clk) disable iff (~rst_n)
585
    !$isunknown(exu2tdu_bp_retire_i)
586
    ) else $error("TDU Error: exu2tdu_bp_retire_i control signals is X");
587
 
588
SVA_TDU_X_CSR : assert property (
589
    @(negedge clk) disable iff (~rst_n)
590
    csr2tdu_req_i |-> !$isunknown({csr2tdu_cmd_i,csr2tdu_addr_i})
591
    ) else $error("TDU Error: csr is X");
592
 
593
SVA_TDU_XW_CSR : assert property (
594
    @(negedge clk) disable iff (~rst_n)
595
    (csr2tdu_req_i & csr_wr_req) |-> !$isunknown(csr2tdu_wdata_i)
596
    ) else $error("TDU Error: csr wdata is X ");
597
 
598
SVA_TDU_X_IMON : assert property (
599
    @(negedge clk) disable iff (~rst_n)
600
    exu2tdu_imon_i.vd |-> !$isunknown({exu2tdu_imon_i.req,exu2tdu_imon_i.addr})
601
    ) else $error("TDU Error: imonitor is X");
602
 
603
SVA_TDU_X_DMON : assert property (
604
    @(negedge clk) disable iff (~rst_n)
605
    lsu2tdu_dmon_i.vd |-> !$isunknown({lsu2tdu_dmon_i})
606
    ) else $error("TDU Error: dmonitor is X");
607
 
608
`endif // SCR1_TRGT_SIMULATION
609
 
610
endmodule : scr1_pipe_tdu
611
 
612
`endif // SCR1_TDU_EN

powered by: WebSVN 2.1.0

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