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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [riverlib/] [core/] [execute.cpp] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      CPU Instruction Execution stage.
6
 */
7
 
8
#include "execute.h"
9
#include "riscv-isa.h"
10
 
11
namespace debugger {
12
 
13
InstrExecute::InstrExecute(sc_module_name name_)  : sc_module(name_) {
14
    SC_METHOD(comb);
15
    sensitive << i_nrst;
16
    sensitive << i_pipeline_hold;
17
    sensitive << i_d_valid;
18
    sensitive << i_d_pc;
19
    sensitive << i_d_instr;
20
    sensitive << i_wb_done;
21
    sensitive << i_memop_load;
22
    sensitive << i_memop_store;
23
    sensitive << i_memop_sign_ext;
24
    sensitive << i_memop_size;
25
    sensitive << i_unsigned_op;
26
    sensitive << i_rv32;;
27
    sensitive << i_isa_type;
28
    sensitive << i_ivec;
29
    sensitive << i_rdata1;
30
    sensitive << i_rdata2;
31
    sensitive << i_csr_rdata;
32
    sensitive << i_ext_irq;
33
    sensitive << i_ie;
34
    sensitive << i_mtvec;
35
    sensitive << i_mode;
36
    sensitive << i_break_mode;
37
    sensitive << i_unsup_exception;
38
    sensitive << i_dport_npc_write;
39
    sensitive << i_dport_npc;
40
    sensitive << r.d_valid;
41
    sensitive << r.npc;
42
    sensitive << r.hazard_depth;
43
    sensitive << r.hazard_addr0;
44
    sensitive << r.hazard_addr1;
45
    sensitive << r.res_val;
46
    sensitive << r.memop_load;
47
    sensitive << r.memop_store;
48
    sensitive << w_hazard_detected;
49
    sensitive << r.multi_ena[Multi_MUL];
50
    sensitive << r.multi_ena[Multi_DIV];
51
    sensitive << r.multi_res_addr;
52
    sensitive << r.multiclock_ena;
53
    sensitive << r.trap_ena;
54
    sensitive << r.breakpoint;
55
    sensitive << wb_arith_res.arr[Multi_MUL];
56
    sensitive << wb_arith_res.arr[Multi_DIV];
57
    sensitive << w_arith_valid[Multi_MUL];
58
    sensitive << w_arith_valid[Multi_DIV];
59
    sensitive << wb_sll;
60
    sensitive << wb_sllw;
61
    sensitive << wb_srl;
62
    sensitive << wb_srlw;
63
    sensitive << wb_sra;
64
    sensitive << wb_sraw;
65
 
66
    SC_METHOD(registers);
67
    sensitive << i_clk.pos();
68
 
69
    mul0 = new IntMul("mul0");
70
    mul0->i_clk(i_clk);
71
    mul0->i_nrst(i_nrst);
72
    mul0->i_ena(r.multi_ena[Multi_MUL]);
73
    mul0->i_unsigned(r.multi_unsigned);
74
    mul0->i_rv32(r.multi_rv32);
75
    mul0->i_high(r.multi_residual_high);
76
    mul0->i_a1(r.multi_a1);
77
    mul0->i_a2(r.multi_a2);
78
    mul0->o_res(wb_arith_res.arr[Multi_MUL]);
79
    mul0->o_valid(w_arith_valid[Multi_MUL]);
80
    mul0->o_busy(w_arith_busy[Multi_MUL]);
81
 
82
    div0 = new IntDiv("div0");
83
    div0->i_clk(i_clk);
84
    div0->i_nrst(i_nrst);
85
    div0->i_ena(r.multi_ena[Multi_DIV]);
86
    div0->i_unsigned(r.multi_unsigned);
87
    div0->i_residual(r.multi_residual_high);
88
    div0->i_rv32(r.multi_rv32);
89
    div0->i_a1(r.multi_a1);
90
    div0->i_a2(r.multi_a2);
91
    div0->o_res(wb_arith_res.arr[Multi_DIV]);
92
    div0->o_valid(w_arith_valid[Multi_DIV]);
93
    div0->o_busy(w_arith_busy[Multi_DIV]);
94
 
95
    sh0 = new Shifter("sh0");
96
    sh0->i_a1(wb_shifter_a1);
97
    sh0->i_a2(wb_shifter_a2);
98
    sh0->o_sll(wb_sll);
99
    sh0->o_sllw(wb_sllw);
100
    sh0->o_srl(wb_srl);
101
    sh0->o_sra(wb_sra);
102
    sh0->o_srlw(wb_srlw);
103
    sh0->o_sraw(wb_sraw);
104
};
105
 
106
InstrExecute::~InstrExecute() {
107
    delete mul0;
108
    delete div0;
109
    delete sh0;
110
}
111
 
112
void InstrExecute::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
113
    if (o_vcd) {
114
        sc_trace(o_vcd, i_ext_irq, "/top/proc0/exec0/i_ext_irq");
115
        sc_trace(o_vcd, i_pipeline_hold, "/top/proc0/exec0/i_pipeline_hold");
116
        sc_trace(o_vcd, i_d_valid, "/top/proc0/exec0/i_d_valid");
117
        sc_trace(o_vcd, i_d_pc, "/top/proc0/exec0/i_d_pc");
118
        sc_trace(o_vcd, i_d_instr, "/top/proc0/exec0/i_d_instr");
119
        sc_trace(o_vcd, i_wb_done, "/top/proc0/exec0/i_wb_done");
120
        sc_trace(o_vcd, i_rdata1, "/top/proc0/exec0/i_rdata1");
121
        sc_trace(o_vcd, i_rdata2, "/top/proc0/exec0/i_rdata2");
122
        sc_trace(o_vcd, o_valid, "/top/proc0/exec0/o_valid");
123
        sc_trace(o_vcd, o_npc, "/top/proc0/exec0/o_npc");
124
        sc_trace(o_vcd, o_pc, "/top/proc0/exec0/o_pc");
125
        sc_trace(o_vcd, o_radr1, "/top/proc0/exec0/o_radr1");
126
        sc_trace(o_vcd, o_radr2, "/top/proc0/exec0/o_radr2");
127
        sc_trace(o_vcd, o_res_addr, "/top/proc0/exec0/o_res_addr");
128
        sc_trace(o_vcd, o_res_data, "/top/proc0/exec0/o_res_data");
129
        sc_trace(o_vcd, o_memop_addr, "/top/proc0/exec0/o_memop_addr");
130
        sc_trace(o_vcd, o_memop_load, "/top/proc0/exec0/o_memop_load");
131
        sc_trace(o_vcd, o_memop_store, "/top/proc0/exec0/o_memop_store");
132
        sc_trace(o_vcd, o_memop_size, "/top/proc0/exec0/o_memop_size");
133
        sc_trace(o_vcd, o_csr_addr, "/top/proc0/exec0/o_csr_addr");
134
        sc_trace(o_vcd, o_csr_wena, "/top/proc0/exec0/o_csr_wena");
135
        sc_trace(o_vcd, i_csr_rdata, "/top/proc0/exec0/i_csr_rdata");
136
        sc_trace(o_vcd, o_csr_wdata, "/top/proc0/exec0/o_csr_wdata");
137
        sc_trace(o_vcd, o_pipeline_hold, "/top/proc0/exec0/o_pipeline_hold");
138
        sc_trace(o_vcd, o_breakpoint, "/top/proc0/exec0/o_breakpoint");
139
        sc_trace(o_vcd, o_call, "/top/proc0/exec0/o_call");
140
        sc_trace(o_vcd, o_ret, "/top/proc0/exec0/o_ret");
141
 
142
        sc_trace(o_vcd, w_hazard_detected, "/top/proc0/exec0/w_hazard_detected");
143
        sc_trace(o_vcd, r.hazard_depth, "/top/proc0/exec0/r_hazard_depth");
144
        sc_trace(o_vcd, r.hazard_addr0, "/top/proc0/exec0/r_hazard_addr0");
145
        sc_trace(o_vcd, r.hazard_addr1, "/top/proc0/exec0/r_hazard_addr1");
146
        sc_trace(o_vcd, r.multiclock_ena, "/top/proc0/exec0/r_multiclock_ena");
147
        sc_trace(o_vcd, r.multi_ena[Multi_MUL], "/top/proc0/exec0/r_multi_ena(0)");
148
        sc_trace(o_vcd, wb_arith_res.arr[Multi_MUL], "/top/proc0/exec0/wb_arith_res(0)");
149
        sc_trace(o_vcd, r.multi_ena[Multi_DIV], "/top/proc0/exec0/r_multi_ena(1)");
150
        sc_trace(o_vcd, wb_arith_res.arr[Multi_DIV], "/top/proc0/exec0/wb_arith_res(1)");
151
        sc_trace(o_vcd, r.multi_res_addr, "/top/proc0/exec0/r_multi_res_addr");
152
        sc_trace(o_vcd, r.multi_a1, "/top/proc0/exec0/multi_a1");
153
        sc_trace(o_vcd, r.multi_a2, "/top/proc0/exec0/multi_a2");
154
 
155
        sc_trace(o_vcd, w_interrupt, "/top/proc0/exec0/w_interrupt");
156
        sc_trace(o_vcd, w_exception, "/top/proc0/exec0/w_exception");
157
        sc_trace(o_vcd, r.trap_ena, "/top/proc0/exec0/r_trap_ena");
158
        sc_trace(o_vcd, r.trap_pc, "/top/proc0/exec0/r_trap_pc");
159
        sc_trace(o_vcd, r.trap_code, "/top/proc0/exec0/r_trap_code");
160
        sc_trace(o_vcd, r.trap_code_waiting, "/top/proc0/exec0/r_trap_code_waiting");
161
        sc_trace(o_vcd, r.ext_irq_pulser, "/top/proc0/exec0/r_ext_irq_pulser");
162
    }
163
    mul0->generateVCD(i_vcd, o_vcd);
164
    div0->generateVCD(i_vcd, o_vcd);
165
}
166
 
167
void InstrExecute::comb() {
168
    sc_uint<5> wb_radr1;
169
    sc_uint<RISCV_ARCH> wb_rdata1;
170
    sc_uint<5> wb_radr2;
171
    sc_uint<RISCV_ARCH> wb_rdata2;
172
    bool w_xret;
173
    bool w_csr_wena;
174
    sc_uint<5> wb_res_addr;
175
    sc_uint<12> wb_csr_addr;
176
    sc_uint<RISCV_ARCH> wb_csr_wdata;
177
    sc_uint<RISCV_ARCH> wb_res;
178
    sc_uint<BUS_ADDR_WIDTH> wb_npc;
179
    sc_uint<RISCV_ARCH> wb_off;
180
    sc_uint<RISCV_ARCH> wb_mask_i31;    // Bits depending instr[31] bits
181
    sc_uint<RISCV_ARCH> wb_sum64;
182
    sc_uint<RISCV_ARCH> wb_sum32;
183
    sc_uint<RISCV_ARCH> wb_sub64;
184
    sc_uint<RISCV_ARCH> wb_sub32;
185
    sc_uint<RISCV_ARCH> wb_and64;
186
    sc_uint<RISCV_ARCH> wb_or64;
187
    sc_uint<RISCV_ARCH> wb_xor64;
188
    bool w_memop_load;
189
    bool w_memop_store;
190
    bool w_memop_sign_ext;
191
    sc_uint<2> wb_memop_size;
192
    sc_uint<BUS_ADDR_WIDTH> wb_memop_addr;
193
    sc_bv<Instr_Total> wv;
194
 
195
    bool w_pc_valid;
196
    bool w_d_acceptable;
197
    bool w_multi_valid;
198
    bool w_multi_ena;
199
    bool w_res_wena;
200
    bool w_pc_branch;
201
    bool w_hazard_lvl1;
202
    bool w_hazard_lvl2;
203
    bool w_d_valid;
204
    bool w_o_valid;
205
    bool w_o_pipeline_hold;
206
    bool w_less;
207
    bool w_gr_equal;
208
 
209
    wb_radr1 = 0;
210
    wb_radr2 = 0;
211
    w_xret = 0;
212
    w_csr_wena = 0;
213
    wb_res_addr = 0;
214
    wb_csr_addr = 0;
215
    wb_csr_wdata = 0;
216
    wb_res = 0;
217
    wb_off = 0;
218
    wb_rdata1 = 0;
219
    wb_rdata2 = 0;
220
    w_memop_load = 0;
221
    w_memop_store = 0;
222
    w_memop_sign_ext = 0;
223
    wb_memop_size = 0;
224
    wb_memop_addr = 0;
225
    wv = i_ivec.read();
226
 
227
    v = r;
228
    v.breakpoint = 0;
229
 
230
    wb_mask_i31 = 0;
231
    if (i_d_instr.read()[31]) {
232
        wb_mask_i31 = ~0ull;
233
    }
234
 
235
    w_pc_valid = 0;
236
    if (i_d_pc.read() == r.npc.read()) {
237
        w_pc_valid = 1;
238
    }
239
    w_d_acceptable = (!i_pipeline_hold) & i_d_valid
240
                          & w_pc_valid & (!r.multiclock_ena);
241
 
242
    v.ext_irq_pulser = i_ext_irq & i_ie;
243
    w_interrupt = 0;
244
    if (w_d_acceptable && (r.trap_code_waiting != 0)) {
245
        w_interrupt = 1;
246
    }
247
 
248
    if (i_isa_type.read()[ISA_R_type]) {
249
        wb_radr1 = i_d_instr.read().range(19, 15);
250
        wb_rdata1 = i_rdata1;
251
        wb_radr2 = i_d_instr.read().range(24, 20);
252
        wb_rdata2 = i_rdata2;
253
    } else if (i_isa_type.read()[ISA_I_type]) {
254
        wb_radr1 = i_d_instr.read().range(19, 15);
255
        wb_rdata1 = i_rdata1;
256
        wb_radr2 = 0;
257
        wb_rdata2 = (wb_mask_i31(63, 12), i_d_instr.read().range(31, 20));
258
    } else if (i_isa_type.read()[ISA_SB_type]) {
259
        wb_radr1 = i_d_instr.read().range(19, 15);
260
        wb_rdata1 = i_rdata1;
261
        wb_radr2 = i_d_instr.read().range(24, 20);
262
        wb_rdata2 = i_rdata2;
263
        wb_off(RISCV_ARCH-1, 12) = wb_mask_i31(RISCV_ARCH-1, 12);
264
        wb_off[12] = i_d_instr.read()[31];
265
        wb_off[11] = i_d_instr.read()[7];
266
        wb_off(10, 5) = i_d_instr.read()(30, 25);
267
        wb_off(4, 1) = i_d_instr.read()(11, 8);
268
        wb_off[0] = 0;
269
    } else if (i_isa_type.read()[ISA_UJ_type]) {
270
        wb_radr1 = 0;
271
        wb_rdata1 = i_d_pc;
272
        wb_radr2 = 0;
273
        wb_off(RISCV_ARCH-1, 20) = wb_mask_i31(RISCV_ARCH-1, 20);
274
        wb_off(19, 12) = i_d_instr.read()(19, 12);
275
        wb_off[11] = i_d_instr.read()[20];
276
        wb_off(10, 1) = i_d_instr.read()(30, 21);
277
        wb_off[0] = 0;
278
    } else if (i_isa_type.read()[ISA_U_type]) {
279
        wb_radr1 = 0;
280
        wb_rdata1 = i_d_pc;
281
        wb_radr2 = 0;
282
        wb_rdata2(31, 0) = i_d_instr.read().range(31, 12) << 12;
283
        wb_rdata2(RISCV_ARCH-1, 32) = wb_mask_i31(RISCV_ARCH-1, 32);
284
    } else if (i_isa_type.read()[ISA_S_type]) {
285
        wb_radr1 = i_d_instr.read().range(19, 15);
286
        wb_rdata1 = i_rdata1;
287
        wb_radr2 = i_d_instr.read().range(24, 20);
288
        wb_rdata2 = i_rdata2;
289
        wb_off(RISCV_ARCH-1, 12) = wb_mask_i31(RISCV_ARCH-1, 12);
290
        wb_off(11, 5) = i_d_instr.read()(31, 25);
291
        wb_off(4, 0) = i_d_instr.read()(11, 7);
292
    }
293
 
294
    // parallel ALU:
295
    wb_sum64 = wb_rdata1 + wb_rdata2;
296
    wb_sum32(31, 0) = wb_rdata1(31, 0) + wb_rdata2(31, 0);
297
    if (wb_sum32[31]) {
298
        wb_sum32(63, 32) = ~0;
299
    }
300
    wb_sub64 = wb_rdata1 - wb_rdata2;
301
    wb_sub32(31, 0) = wb_rdata1(31, 0) - wb_rdata2(31, 0);
302
    if (wb_sub32[31]) {
303
        wb_sub32(63, 32) = ~0;
304
    }
305
    wb_and64 = wb_rdata1 & wb_rdata2;
306
    wb_or64 = wb_rdata1 | wb_rdata2;
307
    wb_xor64 = wb_rdata1 ^ wb_rdata2;
308
 
309
    wb_shifter_a1 = wb_rdata1;
310
    wb_shifter_a2 = wb_rdata2(5, 0);
311
 
312
    w_multi_valid = w_arith_valid[Multi_MUL] | w_arith_valid[Multi_DIV];
313
 
314
    // Don't modify registers on conditional jumps:
315
    w_res_wena = !(wv[Instr_BEQ] | wv[Instr_BGE] | wv[Instr_BGEU]
316
               | wv[Instr_BLT] | wv[Instr_BLTU] | wv[Instr_BNE]
317
               | wv[Instr_SD] | wv[Instr_SW] | wv[Instr_SH] | wv[Instr_SB]
318
               | wv[Instr_MRET] | wv[Instr_URET]
319
               | wv[Instr_ECALL] | wv[Instr_EBREAK]).to_bool();
320
 
321
    if (w_multi_valid) {
322
        wb_res_addr = r.multi_res_addr;
323
        v.multiclock_ena = 0;
324
    } else if (w_res_wena) {
325
        wb_res_addr = i_d_instr.read().range(11, 7);
326
    } else {
327
        wb_res_addr = 0;
328
    }
329
    w_less = 0;
330
    w_gr_equal = 0;
331
    if (wb_rdata1 < wb_rdata2) {
332
        w_less = 1;
333
    }
334
    if (wb_rdata1 >= wb_rdata2) {
335
        w_gr_equal = 1;
336
    }
337
 
338
    // Relative Branch on some condition:
339
    w_pc_branch = 0;
340
    if ((wv[Instr_BEQ] & (wb_sub64 == 0))
341
        || (wv[Instr_BGE] & (wb_sub64[63] == 0))
342
        || (wv[Instr_BGEU] & (w_gr_equal))
343
        || (wv[Instr_BLT] & (wb_sub64[63] == 1))
344
        || (wv[Instr_BLTU] & (w_less))
345
        || (wv[Instr_BNE] & (wb_sub64 != 0))) {
346
        w_pc_branch = 1;
347
    }
348
 
349
    if (w_pc_branch) {
350
        wb_npc = i_d_pc.read() + wb_off(BUS_ADDR_WIDTH-1, 0);
351
    } else if (wv[Instr_JAL].to_bool()) {
352
        wb_res = i_d_pc.read() + 4;
353
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_off(BUS_ADDR_WIDTH-1, 0);
354
    } else if (wv[Instr_JALR].to_bool()) {
355
        wb_res = i_d_pc.read() + 4;
356
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
357
        wb_npc[0] = 0;
358
    } else if ((wv[Instr_MRET] | wv[Instr_URET]).to_bool()) {
359
        wb_res = i_d_pc.read() + 4;
360
        w_xret = i_d_valid;
361
        w_csr_wena = 0;
362
        if (wv[Instr_URET].to_bool()) {
363
            wb_csr_addr = CSR_uepc;
364
        } else {
365
            wb_csr_addr = CSR_mepc;
366
        }
367
        wb_npc = i_csr_rdata;
368
    } else {
369
        // Instr_HRET, Instr_SRET, Instr_FENCE, Instr_FENCE_I:
370
        wb_npc = i_d_pc.read() + 4;
371
    }
372
 
373
    if (i_memop_load) {
374
        wb_memop_addr =
375
            wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
376
    } else if (i_memop_store) {
377
        wb_memop_addr =
378
            wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_off(BUS_ADDR_WIDTH-1, 0);
379
    }
380
 
381
    v.memop_addr = 0;
382
    v.memop_load = 0;
383
    v.memop_store = 0;
384
    v.memop_sign_ext = 0;
385
    v.memop_size = 0;
386
    w_exception_store = 0;
387
    w_exception_load = 0;
388
    w_exception_xret = 0;
389
 
390
    if ((wv[Instr_LD] && wb_memop_addr(2, 0) != 0)
391
        || ((wv[Instr_LW] || wv[Instr_LWU]) && wb_memop_addr(1, 0) != 0)
392
        || ((wv[Instr_LH] || wv[Instr_LHU]) && wb_memop_addr[0] != 0)) {
393
        w_exception_load = !w_hazard_detected.read();
394
    }
395
    if ((wv[Instr_SD] && wb_memop_addr(2, 0) != 0)
396
        || (wv[Instr_SW] && wb_memop_addr(1, 0) != 0)
397
        || (wv[Instr_SH] && wb_memop_addr[0] != 0)) {
398
        w_exception_store = !w_hazard_detected.read();
399
    }
400
    if ((wv[Instr_MRET] && i_mode.read() != PRV_M)
401
        || (wv[Instr_URET] && i_mode.read() != PRV_U)) {
402
        w_exception_xret = 1;
403
    }
404
 
405
    w_exception = w_d_acceptable
406
        & (i_unsup_exception.read() || w_exception_load || w_exception_store
407
           || w_exception_xret || wv[Instr_ECALL] || wv[Instr_EBREAK]);
408
 
409
    /** Default number of cycles per instruction = 0 (1 clock per instr)
410
     *  If instruction is multicycle then modify this value.
411
     */
412
    v.multi_ena[Multi_MUL] = 0;
413
    v.multi_ena[Multi_DIV] = 0;
414
    v.multi_rv32 = i_rv32;
415
    v.multi_unsigned = i_unsigned_op;
416
    v.multi_residual_high = 0;
417
    v.multi_a1 = i_rdata1;
418
    v.multi_a2 = i_rdata2;
419
 
420
    w_multi_ena = (wv[Instr_MUL] | wv[Instr_MULW] | wv[Instr_DIV]
421
                    | wv[Instr_DIVU] | wv[Instr_DIVW] | wv[Instr_DIVUW]
422
                    | wv[Instr_REM] | wv[Instr_REMU] | wv[Instr_REMW]
423
                    | wv[Instr_REMUW]).to_bool();
424
    if (w_multi_ena & w_d_acceptable & !w_exception & !w_interrupt) {
425
        v.multiclock_ena = 1;
426
        v.multi_res_addr = wb_res_addr;
427
        v.multi_pc = i_d_pc;
428
        v.multi_instr = i_d_instr;
429
        v.multi_npc = wb_npc;
430
    }
431
 
432
    // ALU block selector:
433
    if (w_arith_valid[Multi_MUL]) {
434
        wb_res = wb_arith_res.arr[Multi_MUL];
435
    } else if (w_arith_valid[Multi_DIV]) {
436
        wb_res = wb_arith_res.arr[Multi_DIV];
437
    } else if (i_memop_load) {
438
        w_memop_load = !w_hazard_detected.read();
439
        w_memop_sign_ext = i_memop_sign_ext;
440
        wb_memop_size = i_memop_size;
441
    } else if (i_memop_store) {
442
        w_memop_store = !w_hazard_detected.read();
443
        wb_memop_size = i_memop_size;
444
        wb_res = wb_rdata2;
445
    } else if (wv[Instr_ADD] || wv[Instr_ADDI] || wv[Instr_AUIPC]) {
446
        wb_res = wb_sum64;
447
    } else if (wv[Instr_ADDW] || wv[Instr_ADDIW]) {
448
        wb_res = wb_sum32;
449
    } else if (wv[Instr_SUB]) {
450
        wb_res = wb_sub64;
451
    } else if (wv[Instr_SUBW]) {
452
        wb_res = wb_sub32;
453
    } else if (wv[Instr_SLL] || wv[Instr_SLLI]) {
454
        wb_res = wb_sll;
455
    } else if (wv[Instr_SLLW] || wv[Instr_SLLIW]) {
456
        wb_res = wb_sllw;
457
    } else if (wv[Instr_SRL] || wv[Instr_SRLI]) {
458
        wb_res = wb_srl;
459
    } else if (wv[Instr_SRLW] || wv[Instr_SRLIW]) {
460
        wb_res = wb_srlw;
461
    } else if (wv[Instr_SRA] || wv[Instr_SRAI]) {
462
        wb_res = wb_sra;
463
    } else if (wv[Instr_SRAW] || wv[Instr_SRAW] || wv[Instr_SRAIW]) {
464
        wb_res = wb_sraw;
465
    } else if (wv[Instr_AND] || wv[Instr_ANDI]) {
466
        wb_res = wb_and64;
467
    } else if (wv[Instr_OR] || wv[Instr_ORI]) {
468
        wb_res = wb_or64;
469
    } else if (wv[Instr_XOR] || wv[Instr_XORI]) {
470
        wb_res = wb_xor64;
471
    } else if (wv[Instr_SLT] || wv[Instr_SLTI]) {
472
        wb_res = wb_sub64[63];
473
    } else if (wv[Instr_SLTU] || wv[Instr_SLTIU]) {
474
        wb_res = w_less;
475
    } else if (wv[Instr_LUI]) {
476
        wb_res = wb_rdata2;
477
    } else if (wv[Instr_MUL] || wv[Instr_MULW]) {
478
        v.multi_ena[Multi_MUL] = w_d_acceptable & !w_exception & !w_interrupt;
479
    } else if (wv[Instr_DIV] || wv[Instr_DIVU]
480
            || wv[Instr_DIVW] || wv[Instr_DIVUW]) {
481
        v.multi_ena[Multi_DIV] = w_d_acceptable & !w_exception & !w_interrupt;
482
    } else if (wv[Instr_REM] || wv[Instr_REMU]
483
            || wv[Instr_REMW] || wv[Instr_REMUW]) {
484
        v.multi_ena[Multi_DIV] = w_d_acceptable & !w_exception & !w_interrupt;
485
        v.multi_residual_high = 1;
486
    } else if (wv[Instr_CSRRC]) {
487
        wb_res = i_csr_rdata;
488
        w_csr_wena = 1;
489
        wb_csr_addr = wb_rdata2.range(11, 0);
490
        wb_csr_wdata = i_csr_rdata.read() & ~i_rdata1.read();
491
    } else if (wv[Instr_CSRRCI]) {
492
        wb_res = i_csr_rdata;
493
        w_csr_wena = 1;
494
        wb_csr_addr = wb_rdata2.range(11, 0);
495
        wb_csr_wdata(RISCV_ARCH-1, 5) = i_csr_rdata.read()(RISCV_ARCH-1, 5);
496
        wb_csr_wdata(4, 0) = i_csr_rdata.read()(4, 0) & ~wb_radr1;  // zero-extending 5 to 64-bits
497
    } else if (wv[Instr_CSRRS]) {
498
        wb_res = i_csr_rdata;
499
        w_csr_wena = 1;
500
        wb_csr_addr = wb_rdata2.range(11, 0);
501
        wb_csr_wdata = i_csr_rdata.read() | i_rdata1.read();
502
    } else if (wv[Instr_CSRRSI]) {
503
        wb_res = i_csr_rdata;
504
        w_csr_wena = 1;
505
        wb_csr_addr = wb_rdata2.range(11, 0);
506
        wb_csr_wdata(RISCV_ARCH-1, 5) = i_csr_rdata.read()(RISCV_ARCH-1, 5);
507
        wb_csr_wdata(4, 0) = i_csr_rdata.read()(4, 0) | wb_radr1;  // zero-extending 5 to 64-bits
508
    } else if (wv[Instr_CSRRW]) {
509
        wb_res = i_csr_rdata;
510
        w_csr_wena = 1;
511
        wb_csr_addr = wb_rdata2.range(11, 0);
512
        wb_csr_wdata = i_rdata1;
513
    } else if (wv[Instr_CSRRWI]) {
514
        wb_res = i_csr_rdata;
515
        w_csr_wena = 1;
516
        wb_csr_addr = wb_rdata2.range(11, 0);
517
        wb_csr_wdata(RISCV_ARCH-1, 5) = 0;
518
        wb_csr_wdata(4, 0) = wb_radr1;  // zero-extending 5 to 64-bits
519
    }
520
 
521
    wb_exception_code = 0;
522
    if (i_ext_irq & i_ie & !r.ext_irq_pulser) { // Maskable traps (interrupts)
523
        v.trap_code_waiting[4] = 1;
524
        v.trap_code_waiting(3, 0) = INTERRUPT_MExternal;
525
    } else if (w_exception) {      // Unmaskable traps (exceptions)
526
        wb_exception_code[4] = 0;
527
        if (w_exception_load) {
528
            wb_exception_code(3, 0) = EXCEPTION_LoadMisalign;
529
        } else if (w_exception_store) {
530
            wb_exception_code(3, 0) = EXCEPTION_StoreMisalign;
531
        } else if (w_exception_xret) {
532
            wb_exception_code(3, 0) = EXCEPTION_InstrIllegal;
533
        } else if (wv[Instr_ECALL]) {
534
            if (i_mode.read() == PRV_M) {
535
                wb_exception_code(3, 0) = EXCEPTION_CallFromMmode;
536
            } else {
537
                wb_exception_code(3, 0) = EXCEPTION_CallFromUmode;
538
            }
539
        } else if (wv[Instr_EBREAK]) {
540
            v.breakpoint = 1;
541
            wb_exception_code(3, 0) = EXCEPTION_Breakpoint;
542
        } else {
543
            wb_exception_code(3, 0) = EXCEPTION_InstrIllegal;
544
        }
545
    } else if (w_interrupt) {
546
        v.trap_code_waiting = 0;
547
    }
548
 
549
    w_d_valid =
550
        (w_d_acceptable && !w_interrupt && !w_exception && !w_multi_ena)
551
        || w_multi_valid;
552
 
553
 
554
    v.trap_ena = 0;
555
    v.call = 0;
556
    v.ret = 0;
557
    if (i_dport_npc_write.read()) {
558
        v.npc = i_dport_npc.read();
559
    } else if (w_interrupt) {
560
        v.trap_ena = 1;
561
        v.trap_pc = i_d_pc;
562
        v.trap_code = r.trap_code_waiting;
563
        v.npc = i_mtvec;
564
    } else if (w_exception) {
565
        v.trap_ena = 1;
566
        v.trap_pc = i_d_pc;
567
        v.trap_code = wb_exception_code;
568
        if (wv[Instr_EBREAK] && i_break_mode.read() == 0) {
569
            v.npc = i_d_pc;
570
        } else {
571
            v.npc = i_mtvec;
572
        }
573
    } else if (w_d_valid) {
574
        if (w_multi_valid) {
575
            v.pc = r.multi_pc;
576
            v.instr = r.multi_instr;
577
            v.npc = r.multi_npc;;
578
            v.memop_load = 0;
579
            v.memop_sign_ext = 0;
580
            v.memop_store = 0;
581
            v.memop_size = 0;
582
            v.memop_addr = 0;
583
        } else {
584
            v.pc = i_d_pc;
585
            v.instr = i_d_instr;
586
            v.npc = wb_npc;
587
            v.memop_load = w_memop_load;
588
            v.memop_sign_ext = w_memop_sign_ext;
589
            v.memop_store = w_memop_store;
590
            v.memop_size = wb_memop_size;
591
            v.memop_addr = wb_memop_addr;
592
        }
593
        v.res_addr = wb_res_addr;
594
        v.res_val = wb_res;
595
 
596
        v.hazard_addr1 = r.hazard_addr0;
597
        v.hazard_addr0 = wb_res_addr;
598
 
599
        if (wv[Instr_JAL] && wb_res_addr == Reg_ra) {
600
            v.call = 1;
601
        }
602
        if (wv[Instr_JALR]) {
603
            if (wb_res_addr == Reg_ra) {
604
                v.call = 1;
605
            } else if (wb_rdata2 == 0 && wb_radr1 == Reg_ra) {
606
                v.ret = 1;
607
            }
608
        }
609
    }
610
 
611
    v.d_valid = w_d_valid;
612
 
613
    if (w_d_valid && !i_wb_done.read()) {
614
        v.hazard_depth = r.hazard_depth.read() + 1;
615
        v.hazard_addr0 = wb_res_addr;
616
    } else if (!w_d_valid && i_wb_done.read()) {
617
        v.hazard_depth = r.hazard_depth.read() - 1;
618
    }
619
    w_hazard_lvl1 = 0;
620
    if ((wb_radr1 != 0 && (wb_radr1 == r.hazard_addr0)) ||
621
        (wb_radr2 != 0 && (wb_radr2 == r.hazard_addr0))) {
622
        w_hazard_lvl1 = 1;
623
    }
624
    w_hazard_lvl2 = 0;
625
    if ((wb_radr1 != 0 && (wb_radr1 == r.hazard_addr1)) ||
626
        (wb_radr2 != 0 && (wb_radr2 == r.hazard_addr1))) {
627
        w_hazard_lvl2 = 1;
628
    }
629
 
630
    if (r.hazard_depth.read() == 1) {
631
        w_hazard_detected = w_hazard_lvl1;
632
    } else if (r.hazard_depth.read() == 2) {
633
        w_hazard_detected = w_hazard_lvl1 | w_hazard_lvl2;
634
    } else {
635
        w_hazard_detected = 0;
636
    }
637
 
638
    w_o_valid = r.d_valid.read();
639
    w_o_pipeline_hold = w_hazard_detected | r.multiclock_ena;
640
 
641
    if (!i_nrst.read()) {
642
        v.d_valid = false;
643
        v.pc = 0;
644
        v.npc = RESET_VECTOR;
645
        v.instr = 0;
646
        v.res_addr = 0;
647
        v.res_val = 0;
648
        v.memop_load = 0;
649
        v.memop_sign_ext = 0;
650
        v.memop_store = 0;
651
        v.memop_size = 0;
652
        v.memop_addr = 0;
653
        v.hazard_depth = 0;
654
        v.hazard_addr0 = 0;
655
        v.hazard_addr1 = 0;
656
 
657
        v.multiclock_ena = 0;
658
        v.multi_pc = 0;
659
        v.multi_instr = 0;
660
        v.multi_npc = 0;
661
        v.multi_res_addr = 0;
662
        v.multi_ena[Multi_MUL] = 0;
663
        v.multi_ena[Multi_DIV] = 0;
664
        v.multi_rv32 = 0;
665
        v.multi_unsigned = 0;
666
        v.multi_residual_high = 0;
667
        v.multi_a1 = 0;
668
        v.multi_a2 = 0;
669
 
670
        v.ext_irq_pulser = 0;
671
        v.trap_code_waiting = 0;
672
        v.trap_ena = 0;
673
        v.trap_code = 0;
674
        v.trap_pc = 0;
675
        v.call = 0;
676
        v.ret = 0;
677
    }
678
 
679
    o_radr1 = wb_radr1;
680
    o_radr2 = wb_radr2;
681
    o_res_addr = r.res_addr;
682
    o_res_data = r.res_val;
683
    o_pipeline_hold = w_o_pipeline_hold;
684
 
685
    o_xret = w_xret;
686
    o_csr_wena = w_csr_wena & w_pc_valid & !w_hazard_detected;
687
    o_csr_addr = wb_csr_addr;
688
    o_csr_wdata = wb_csr_wdata;
689
    o_trap_ena = r.trap_ena;
690
    o_trap_code = r.trap_code;
691
    o_trap_pc = r.trap_pc;
692
 
693
    o_memop_sign_ext = r.memop_sign_ext;
694
    o_memop_load = r.memop_load;
695
    o_memop_store = r.memop_store;
696
    o_memop_size = r.memop_size;
697
    o_memop_addr = r.memop_addr;
698
 
699
    o_valid = w_o_valid;
700
    o_pc = r.pc;
701
    o_npc = r.npc;
702
    o_instr = r.instr;
703
    o_breakpoint = r.breakpoint;
704
    o_call = r.call;
705
    o_ret = r.ret;
706
}
707
 
708
void InstrExecute::registers() {
709
    r = v;
710
}
711
 
712
}  // namespace debugger
713
 

powered by: WebSVN 2.1.0

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