@@ -51,13 +51,13 @@ SC_MODULE(plic) {
51
51
bool async_reset_;
52
52
53
53
struct plic_context_type {
54
- sc_uint<4 > priority_th;
55
- sc_bv<1024 > ie; // interrupt enable per context
56
- sc_bv<(4 * 1024 )> ip_prio; // interrupt pending priority per context
57
- sc_uint<16 > prio_mask; // pending interrupts priorites
58
- sc_uint<4 > sel_prio; // the most available priority
59
- sc_uint<10 > irq_idx; // currently selected most prio irq
60
- sc_uint<10 > irq_prio; // currently selected prio level
54
+ sc_signal< sc_uint<4 > > priority_th;
55
+ sc_signal< sc_bv<1024 >> ie; // interrupt enable per context
56
+ sc_signal< sc_bv<(4 * 1024 )>> ip_prio; // interrupt pending priority per context
57
+ sc_signal< sc_uint<16 >> prio_mask; // pending interrupts priorites
58
+ sc_signal< sc_uint<4 >> sel_prio; // the most available priority
59
+ sc_signal< sc_uint<10 >> irq_idx; // currently selected most prio irq
60
+ sc_signal< sc_uint<10 >> irq_prio; // currently selected prio level
61
61
};
62
62
63
63
@@ -141,6 +141,15 @@ plic<ctxmax, irqmax>::plic(sc_module_name name,
141
141
sensitive << r.src_priority ;
142
142
sensitive << r.pending ;
143
143
sensitive << r.ip ;
144
+ for (int i = 0 ; i < ctxmax; i++) {
145
+ sensitive << r.ctx [i].priority_th ;
146
+ sensitive << r.ctx [i].ie ;
147
+ sensitive << r.ctx [i].ip_prio ;
148
+ sensitive << r.ctx [i].prio_mask ;
149
+ sensitive << r.ctx [i].sel_prio ;
150
+ sensitive << r.ctx [i].irq_idx ;
151
+ sensitive << r.ctx [i].irq_prio ;
152
+ }
144
153
sensitive << r.rdata ;
145
154
146
155
SC_METHOD (registers);
@@ -196,7 +205,13 @@ void plic<ctxmax, irqmax>::comb() {
196
205
sc_uint<CFG_SYSBUS_DATA_BITS> vrdata;
197
206
sc_uint<10 > vb_irq_idx[ctxmax]; // Currently selected most prio irq
198
207
sc_uint<10 > vb_irq_prio[ctxmax]; // Currently selected prio level
199
- plic_context_type vb_ctx[ctxmax];
208
+ sc_uint<4 > vb_ctx_priority_th[ctxmax];
209
+ sc_bv<1024 > vb_ctx_ie[ctxmax];
210
+ sc_bv<(4 * 1024 )> vb_ctx_ip_prio[ctxmax];
211
+ sc_uint<16 > vb_ctx_prio_mask[ctxmax];
212
+ sc_uint<4 > vb_ctx_sel_prio[ctxmax];
213
+ sc_uint<10 > vb_ctx_irq_idx[ctxmax];
214
+ sc_uint<10 > vb_ctx_irq_prio[ctxmax];
200
215
sc_bv<(4 * 1024 )> vb_src_priority;
201
216
sc_bv<1024 > vb_pending;
202
217
sc_uint<ctxmax> vb_ip;
@@ -210,13 +225,25 @@ void plic<ctxmax, irqmax>::comb() {
210
225
vb_irq_prio[i] = 0 ;
211
226
}
212
227
for (int i = 0 ; i < ctxmax; i++) {
213
- vb_ctx[i].priority_th = 0 ;
214
- vb_ctx[i].ie = 0 ;
215
- vb_ctx[i].ip_prio = 0 ;
216
- vb_ctx[i].prio_mask = 0 ;
217
- vb_ctx[i].sel_prio = 0 ;
218
- vb_ctx[i].irq_idx = 0 ;
219
- vb_ctx[i].irq_prio = 0 ;
228
+ vb_ctx_priority_th[i] = 0 ;
229
+ }
230
+ for (int i = 0 ; i < ctxmax; i++) {
231
+ vb_ctx_ie[i] = 0 ;
232
+ }
233
+ for (int i = 0 ; i < ctxmax; i++) {
234
+ vb_ctx_ip_prio[i] = 0 ;
235
+ }
236
+ for (int i = 0 ; i < ctxmax; i++) {
237
+ vb_ctx_prio_mask[i] = 0 ;
238
+ }
239
+ for (int i = 0 ; i < ctxmax; i++) {
240
+ vb_ctx_sel_prio[i] = 0 ;
241
+ }
242
+ for (int i = 0 ; i < ctxmax; i++) {
243
+ vb_ctx_irq_idx[i] = 0 ;
244
+ }
245
+ for (int i = 0 ; i < ctxmax; i++) {
246
+ vb_ctx_irq_prio[i] = 0 ;
220
247
}
221
248
vb_src_priority = 0 ;
222
249
vb_pending = 0 ;
@@ -243,10 +270,10 @@ void plic<ctxmax, irqmax>::comb() {
243
270
vb_src_priority = r.src_priority ;
244
271
vb_pending = r.pending ;
245
272
for (int i = 0 ; i < ctxmax; i++) {
246
- vb_ctx [i]. priority_th = r.ctx [i].priority_th ;
247
- vb_ctx [i]. ie = r.ctx [i].ie ;
248
- vb_ctx [i]. irq_idx = r.ctx [i].irq_idx ;
249
- vb_ctx [i]. irq_prio = r.ctx [i].irq_prio ;
273
+ vb_ctx_priority_th [i] = r.ctx [i].priority_th ;
274
+ vb_ctx_ie [i] = r.ctx [i].ie ;
275
+ vb_ctx_irq_idx [i] = r.ctx [i].irq_idx ;
276
+ vb_ctx_irq_prio [i] = r.ctx [i].irq_prio ;
250
277
}
251
278
252
279
for (int i = 1 ; i < irqmax; i++) {
@@ -258,28 +285,28 @@ void plic<ctxmax, irqmax>::comb() {
258
285
for (int n = 0 ; n < ctxmax; n++) {
259
286
for (int i = 0 ; i < irqmax; i++) {
260
287
if ((r.pending .read ()[i] == 1 )
261
- && (r.ctx [n].ie [i] == 1 )
262
- && (r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i)).to_int () > r.ctx [n].priority_th )) {
263
- vb_ctx [n]. ip_prio ((4 * i) + 4 - 1 , (4 * i)) = r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i));
264
- vb_ctx [n]. prio_mask [r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i)).to_int ()] = 1 ;
288
+ && (r.ctx [n].ie . read () [i] == 1 )
289
+ && (r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i)).to_int () > r.ctx [n].priority_th . read () )) {
290
+ vb_ctx_ip_prio [n]((4 * i) + 4 - 1 , (4 * i)) = r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i));
291
+ vb_ctx_prio_mask [n][r.src_priority .read ()((4 * i) + 4 - 1 , (4 * i)).to_int ()] = 1 ;
265
292
}
266
293
}
267
294
}
268
295
269
296
// Select max priority in each context
270
297
for (int n = 0 ; n < ctxmax; n++) {
271
298
for (int i = 0 ; i < 16 ; i++) {
272
- if (r.ctx [n].prio_mask [i] == 1 ) {
273
- vb_ctx [n]. sel_prio = i;
299
+ if (r.ctx [n].prio_mask . read () [i] == 1 ) {
300
+ vb_ctx_sel_prio [n] = i;
274
301
}
275
302
}
276
303
}
277
304
278
305
// Select max priority in each context
279
306
for (int n = 0 ; n < ctxmax; n++) {
280
307
for (int i = 0 ; i < irqmax; i++) {
281
- if (r.ctx [n].sel_prio .or_reduce ()
282
- && (r.ctx [n].ip_prio ((4 * i) + 4 - 1 , (4 * i)) == r.ctx [n].sel_prio )) {
308
+ if (r.ctx [n].sel_prio .read (). or_reduce ()
309
+ && (r.ctx [n].ip_prio . read () ((4 * i) + 4 - 1 , (4 * i)) == r.ctx [n].sel_prio )) {
283
310
// Most prio irq and prio level
284
311
vb_irq_idx[n] = i;
285
312
vb_irq_prio[n] = r.ctx [n].sel_prio ;
@@ -288,8 +315,8 @@ void plic<ctxmax, irqmax>::comb() {
288
315
}
289
316
290
317
for (int n = 0 ; n < ctxmax; n++) {
291
- vb_ctx [n]. irq_idx = vb_irq_idx[n];
292
- vb_ctx [n]. irq_prio = vb_irq_prio[n];
318
+ vb_ctx_irq_idx [n] = vb_irq_idx[n];
319
+ vb_ctx_irq_prio [n] = vb_irq_prio[n];
293
320
vb_ip[n] = vb_irq_idx[n].or_reduce ();
294
321
}
295
322
@@ -327,13 +354,13 @@ void plic<ctxmax, irqmax>::comb() {
327
354
&& (wb_req_addr.read ()(11 , 7 ) < ctxmax)) {
328
355
// First 32 context of 15867 support only
329
356
// 0x002000,0x002080,...,0x200000
330
- vrdata = r.ctx [wb_req_addr.read ()(11 , 7 )].ie ((64 * wb_req_addr.read ()(6 , 3 )) + 64 - 1 , (64 * wb_req_addr.read ()(6 , 3 ))).to_uint64 ();
357
+ vrdata = r.ctx [wb_req_addr.read ()(11 , 7 )].ie . read () ((64 * wb_req_addr.read ()(6 , 3 )) + 64 - 1 , (64 * wb_req_addr.read ()(6 , 3 ))).to_uint64 ();
331
358
if ((w_req_valid.read () == 1 ) && (w_req_write.read () == 1 )) {
332
359
if (wb_req_wstrb.read ()(3 , 0 ).or_reduce () == 1 ) {
333
- vb_ctx [wb_req_addr.read ()(11 , 7 )]. ie ((64 * wb_req_addr.read ()(6 , 3 )) + 32 - 1 , (64 * wb_req_addr.read ()(6 , 3 ))) = wb_req_wdata.read ()(31 , 0 );
360
+ vb_ctx_ie [wb_req_addr.read ()(11 , 7 )]((64 * wb_req_addr.read ()(6 , 3 )) + 32 - 1 , (64 * wb_req_addr.read ()(6 , 3 ))) = wb_req_wdata.read ()(31 , 0 );
334
361
}
335
362
if (wb_req_wstrb.read ()(7 , 4 ).or_reduce () == 1 ) {
336
- vb_ctx [wb_req_addr.read ()(11 , 7 )]. ie (((64 * wb_req_addr.read ()(6 , 3 )) + 32 ) + 32 - 1 , ((64 * wb_req_addr.read ()(6 , 3 )) + 32 )) = wb_req_wdata.read ()(63 , 32 );
363
+ vb_ctx_ie [wb_req_addr.read ()(11 , 7 )](((64 * wb_req_addr.read ()(6 , 3 )) + 32 ) + 32 - 1 , ((64 * wb_req_addr.read ()(6 , 3 )) + 32 )) = wb_req_wdata.read ()(63 , 32 );
337
364
}
338
365
}
339
366
} else if ((wb_req_addr.read ()(21 , 12 ) >= 0x200 ) && (wb_req_addr.read ()(20 , 12 ) < ctxmax)) {
@@ -344,15 +371,15 @@ void plic<ctxmax, irqmax>::comb() {
344
371
vrdata (41 , 32 ) = r.ctx [rctx_idx].irq_idx ;
345
372
// claim/ complete. Reading clears pending bit
346
373
if (r.ip .read ()[rctx_idx] == 1 ) {
347
- vb_pending[r.ctx [rctx_idx].irq_idx ] = 0 ;
374
+ vb_pending[r.ctx [rctx_idx].irq_idx . read () ] = 0 ;
348
375
}
349
376
if ((w_req_valid.read () == 1 ) && (w_req_write.read () == 1 )) {
350
377
if (wb_req_wstrb.read ()(3 , 0 ).or_reduce () == 1 ) {
351
- vb_ctx [rctx_idx]. priority_th = wb_req_wdata.read ()(3 , 0 );
378
+ vb_ctx_priority_th [rctx_idx] = wb_req_wdata.read ()(3 , 0 );
352
379
}
353
380
if (wb_req_wstrb.read ()(7 , 4 ).or_reduce () == 1 ) {
354
381
// claim/ complete. Reading clears pedning bit
355
- vb_ctx [rctx_idx]. irq_idx = 0 ;
382
+ vb_ctx_irq_idx [rctx_idx] = 0 ;
356
383
}
357
384
}
358
385
} else {
@@ -365,13 +392,13 @@ void plic<ctxmax, irqmax>::comb() {
365
392
v.pending = vb_pending;
366
393
v.ip = vb_ip;
367
394
for (int n = 0 ; n < ctxmax; n++) {
368
- v.ctx [n].priority_th = vb_ctx [n]. priority_th ;
369
- v.ctx [n].ie = vb_ctx [n]. ie ;
370
- v.ctx [n].ip_prio = vb_ctx [n]. ip_prio ;
371
- v.ctx [n].prio_mask = vb_ctx [n]. prio_mask ;
372
- v.ctx [n].sel_prio = vb_ctx [n]. sel_prio ;
373
- v.ctx [n].irq_idx = vb_ctx [n]. irq_idx ;
374
- v.ctx [n].irq_prio = vb_ctx [n]. irq_prio ;
395
+ v.ctx [n].priority_th = vb_ctx_priority_th [n];
396
+ v.ctx [n].ie = vb_ctx_ie [n];
397
+ v.ctx [n].ip_prio = vb_ctx_ip_prio [n];
398
+ v.ctx [n].prio_mask = vb_ctx_prio_mask [n];
399
+ v.ctx [n].sel_prio = vb_ctx_sel_prio [n];
400
+ v.ctx [n].irq_idx = vb_ctx_irq_idx [n];
401
+ v.ctx [n].irq_prio = vb_ctx_irq_prio [n];
375
402
}
376
403
377
404
if (!async_reset_ && i_nrst.read () == 0 ) {
0 commit comments