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 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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