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

Subversion Repositories fwrisc

[/] [fwrisc/] [trunk/] [rtl/] [fwrisc.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mballance
/****************************************************************************
2
 * fwrisc.sv
3
 *
4
 * Copyright 2018 Matthew Ballance
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in
8
 * compliance with the License.  You may obtain a copy of
9
 * the License at
10
 *
11
 * http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in
14
 * writing, software distributed under the License is
15
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
16
 * CONDITIONS OF ANY KIND, either express or implied.  See
17
 * the License for the specific language governing
18
 * permissions and limitations under the License.
19
 ****************************************************************************/
20
`include "fwrisc_defines.vh"
21
 
22
 
23
/**
24
 * Module: fwrisc
25
 *
26
 * TODO: Add module documentation
27
 */
28
module fwrisc (
29
                input                   clock,
30
                input                   reset,
31
 
32
                output[31:0]    iaddr,
33
                input[31:0]             idata,
34
                output                  ivalid,
35
                input                   iready,
36
 
37
                output[31:0]    daddr,
38
                output[31:0]    dwdata,
39
                input[31:0]             drdata,
40
                output[3:0]             dstrb,
41
                output                  dwrite,
42
                output                  dvalid,
43
                input                   dready
44
                );
45
 
46
        reg[31:0]                       instr;
47
 
48
 
49
        reg[3:0]                        state;
50
        reg[31:2]                       pc;
51
        reg[4:0]                        shift_amt;
52
        wire[31:2]                      pc_plus4;
53
        reg[31:2]                       pc_next;
54
 
55
        assign pc_plus4 = (pc + 1'b1);
56
 
57
        assign iaddr = {pc, 2'b0};
58
        assign ivalid = (state == `FETCH && !reset);
59
 
60
        /****************************************************************
61
         * Instruction and Cycle counters
62
         ****************************************************************/
63
        reg [7:0]                       cycle_counter = 1;
64
        wire                            cycle_counter_ovf = cycle_counter[7];
65
        reg [7:0]                       instr_counter = 0;
66
        always @(posedge clock) begin
67
                if (reset || state == `CYCLE_COUNT_UPDATE_1) begin
68
                        cycle_counter <= 1;
69
                end else begin
70
                        cycle_counter <= cycle_counter + 1;
71
                end
72
        end
73
 
74
        always @(posedge clock) begin
75
                if (reset || state == `INSTR_COUNT_UPDATE_1) begin
76
                        instr_counter <= 0;
77
                end else if (state == `EXECUTE) begin
78
                        instr_counter <= instr_counter + 1;
79
                end
80
        end
81
 
82
        // ALU signals
83
        reg[31:0]                                       alu_op_a;
84
        reg[31:0]                                       alu_op_b;
85
        reg[2:0]                                        alu_op;
86
        wire[31:0]                                      alu_out;
87
        wire                                            alu_carry;
88
        wire                                            alu_eqz;
89
 
90
        always @(posedge clock) begin
91
                if (reset) begin
92
                        state <= `FETCH;
93
                        instr <= 0;
94
                        pc <= (32'h8000_0000 >> 2);
95
                end else begin
96
                        if (ivalid && iready) begin
97
                                instr <= idata;
98
                        end
99
 
100
                        case (state)
101
                                default /*`FETCH*/: begin
102
                                        if (ivalid && iready) begin
103
                                                state <= `DECODE;
104
                                                instr <= idata;
105
                                        end
106
                                end
107
 
108
                                `DECODE: begin
109
                                        // NOP: wait for decode to occur
110
                                        if (op_csr) begin
111
                                                state <= `CSR_1;
112
                                        end else if (op_shift) begin
113
                                                state <= `SHIFT_1;
114
                                        end else begin
115
                                                state <= `EXECUTE;
116
                                        end
117
                                end
118
 
119
                                `CSR_1: begin
120
                                        state <= `CSR_2;
121
                                end
122
 
123
                                `CSR_2: begin
124
                                        state <= `EXECUTE;
125
                                end
126
 
127
                                `EXECUTE: begin
128
                                        if (exception) begin
129
                                                // Exception Handling:
130
                                                // - Write the address to MTVAL in EXECUTE
131
                                                // - Write the cause to MTCAUSE in EXECEPTION_1
132
                                                // - Jump to FETCH to execute vector address
133
                                                state <= `EXCEPTION_1;
134
                                        end else if (op_ld) begin
135
                                                state <= `MEMR;
136
                                        end else if (op_st) begin
137
                                                state <= `MEMW;
138
                                        end else if (cycle_counter_ovf) begin
139
                                                pc <= pc_next;
140
                                                state <= `CYCLE_COUNT_UPDATE_1;
141
                                        end else begin
142
                                                pc <= pc_next;
143
                                                state <= `FETCH;
144
                                        end
145
                                end
146
 
147
                                `MEMW, `MEMR: begin
148
                                        if (dvalid && dready) begin
149
                                                pc <= pc_next;
150
                                                // Steal a few cycles to update the cycle counter
151
                                                if (cycle_counter[7]) begin
152
                                                        state <= `CYCLE_COUNT_UPDATE_1;
153
                                                end else begin
154
                                                        state <= `FETCH;
155
                                                end
156
                                        end
157
                                end
158
 
159
                                // Capture the fault address
160
                                `EXCEPTION_1: begin
161
                                        state <= `EXCEPTION_2;
162
                                end
163
 
164
                                // Capture the EPC
165
                                `EXCEPTION_2: begin
166
                                        // Contains MTVEC
167
                                        pc <= ra_rdata[31:2];
168
                                        state <= `FETCH;
169
                                end
170
 
171
                                // Latch the shift amount into the shift_amt register
172
                                `SHIFT_1: begin
173
                                        if (op_shift_reg) begin
174
                                                shift_amt <= (rb_rdata[4:0] - 1'b1);
175
                                                if (|rb_rdata[4:0]) begin
176
                                                        state <= `SHIFT_2;
177
                                                end else begin
178
                                                        state <= `EXECUTE;
179
                                                end
180
                                        end else begin
181
                                                shift_amt <= (rs2 - 1'b1);
182
                                                if (|rs2) begin
183
                                                        state <= `SHIFT_2;
184
                                                end else begin
185
                                                        state <= `EXECUTE;
186
                                                end
187
                                        end
188
                                end
189
 
190
                                `SHIFT_2: begin
191
                                        // Shift
192
                                        if (|shift_amt) begin
193
                                                shift_amt <= shift_amt - 1;
194
                                        end else begin
195
                                                state <= `EXECUTE;
196
                                        end
197
                                end
198
 
199
                                /**
200
                                 * Write the cycle count to CSR_tmp.
201
                                 * Setup a read of CSR_tmp and the counter CSR
202
                                 */
203
                                `CYCLE_COUNT_UPDATE_1: begin
204
                                        state <= `CYCLE_COUNT_UPDATE_2;
205
                                end
206
 
207
                                /**
208
                                 * Add CSR_tmp and the counter CSR
209
                                 */
210
                                `CYCLE_COUNT_UPDATE_2: begin
211
                                        state <= `INSTR_COUNT_UPDATE_1;
212
                                end
213
 
214
                                `INSTR_COUNT_UPDATE_1: begin
215
                                        state <= `FETCH;
216
                                end
217
 
218
                        endcase
219
                end
220
        end
221
 
222
 
223
        wire op_branch_ld_st_arith = (instr[3:0] == 4'b0011);
224
        wire op_fence     = (instr[3:0] == 4'b1111);
225
        wire op_ld        = (op_branch_ld_st_arith && instr[6:4] == 3'b000);
226
        wire op_arith_imm = (op_branch_ld_st_arith && instr[6:4] == 3'b001);
227
        wire op_shift_imm = (op_arith_imm && instr[13:12] == 2'b01);
228
        wire op_shift_reg = (op_arith_reg && instr[13:12] == 2'b01);
229
        wire op_shift     = (op_shift_imm || op_shift_reg);
230
        wire op_st        = (op_branch_ld_st_arith && instr[6:4] == 3'b010);
231
        wire op_ld_st     = (op_ld || op_st);
232
        wire op_arith_reg = (op_branch_ld_st_arith && instr[6:4] == 3'b011);
233
        wire op_branch    = (op_branch_ld_st_arith && instr[6:4] == 3'b110);
234
        wire op_jal       = (instr[6:0] == 7'b1101111);
235
        wire op_jalr      = (instr[6:0] == 7'b1100111);
236
        wire op_auipc     = (instr[6:0] == 7'b0010111);
237
        wire op_lui       = (instr[6:0] == 7'b0110111);
238
        wire op_sys       = (op_branch_ld_st_arith && instr[6:4] == 3'b111);
239
        wire op_sys_prv   = !(|instr[14:12]);
240
//      wire op_ecall     = (op_sys && op_sys_prv && instr[24:21] == 4'b0000);
241
        wire op_ecall     = (op_sys && op_sys_prv && !instr[28]);
242
        // Seems the compiler that Zephyr uses encodes eret as 0x10000073
243
//      wire op_eret      = (op_sys && op_sys_prv && instr[24:20] == 5'b00010);
244
        wire op_eret      = (op_sys && op_sys_prv && instr[28]);
245
 
246
        wire op_csr       = (op_sys && |instr[14:12]);
247
        wire op_csrr_cs   = (op_csr && instr[13]);
248
        wire op_csrrc     = (op_csr && instr[13:12] == 2'b11);
249
        wire op_csrrs     = (op_csr && instr[13:12] == 2'b10);
250
        wire [11:0]     csr   = instr[31:20];
251
        reg [5:0]       csr_addr;
252
 
253
        wire[5:0] CSR_MTVEC   = 6'h25;
254
        wire[5:0] CSR_MEPC    = 6'h29;
255
        wire[5:0] CSR_MCAUSE  = 6'h2A;
256
        wire[5:0] CSR_MTVAL   = 6'h2B;
257
        wire[5:0] CSR_MCYCLE  = 6'h36;
258
        wire[5:0] CSR_MINSTR  = 6'h37;
259
        wire[5:0] CSR_MCYCLEH = 6'h38;
260
        wire[5:0] CSR_MINSTRH = 6'h39;
261
        wire[5:0] CSR_tmp     = 6'h3F;
262
        // 0x300-0x306 => 0x20-0x26 (32-38)
263
        // 0x340-0x344 => 0x28-0x2C (40-44)
264
        // 0xF11-0xF14 => 0x31-0x34 (49-52)
265
        // 0xB00       => 0x36
266
        // 0xB02       => 0x37
267
        // 0xB80       => 0x38
268
        // 0xB82       => 0x39
269
        // CSR_tmp     => 0x3F (63)
270
        always @* begin
271
                case (csr[11:8])
272
                        4'h3: begin
273
                                if (csr[7:4] == 3'b0) begin
274
                                        csr_addr = {2'b10, csr[3:0]};
275
                                end else begin
276
                                        csr_addr = {3'b101, csr[2:0]};
277
                                end
278
                        end
279
                        4'hb: begin // counters
280
                                if (csr[7]) begin // 0xB8x
281
                                        csr_addr = {2'd3, 3'b100, csr[1]};
282
                                end else begin
283
                                        csr_addr = {2'd3, 3'b011, csr[1]};
284
                                end
285
                        end
286
                        default: begin // 4'hf
287
                                csr_addr = {2'b11, csr[3:0]};
288
                        end
289
                endcase
290
        end
291
 
292
        wire[31:0]      jal_off = (instr[31])?{{21{1'b1}}, instr[31], instr[19:12], instr[20], instr[30:21],1'b0}:
293
                                                                                        {{21{1'b0}}, instr[31], instr[19:12], instr[20], instr[30:21],1'b0};
294
        wire[31:0]      auipc_imm_31_12 = {instr[31:12], {12{1'b0}}};
295
        wire[31:0]      imm_11_0 = (instr[31])?{{22{1'b1}}, instr[31:20]}:{{22{1'b0}}, instr[31:20]};
296
        wire[31:0]      st_imm_11_0 = (instr[31])?
297
                {{22{1'b1}}, instr[31:25], instr[11:7]}:
298
                {{22{1'b0}}, instr[31:25], instr[11:7]};
299
 
300
        wire[31:0]      imm_lui = {instr[31:12], 12'h000};
301
        wire[31:0]              imm_branch = (instr[31])?
302
                {{19{1'b1}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0}:
303
                {{19{1'b0}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0};
304
        wire[31:0]              zero = 32'h00000000;
305
 
306
        // RS1, RS2, and RD are always in the same place
307
        wire[4:0]               rs1 = instr[19:15];
308
        wire[4:0]               rs2 = instr[24:20];
309
        wire[4:0]               rd  = instr[11:7];
310
 
311
 
312
        reg[5:0]                ra_raddr;
313
        reg[5:0]                rb_raddr;
314
        wire[31:0]              ra_rdata;
315
        wire[31:0]              rb_rdata;
316
        reg[5:0]                rd_waddr;
317
        reg[31:0]               rd_wdata;
318
        reg                             rd_wen;
319
 
320
 
321
        // Comparator signals
322
        wire[31:0]                                      comp_op_a = ra_rdata;
323
        reg[31:0]                                       comp_op_b;
324
        reg[1:0]                                        comp_op;
325
        wire                                            comp_out;
326
        wire                                            branch_cond;
327
 
328
        // Exception signals
329
        wire                                            exception;
330
        reg                                             misaligned_addr;
331
 
332
        fwrisc_comparator u_comp (
333
                .clock  (clock          ),
334
                .reset  (reset          ),
335
                .in_a   (comp_op_a  ),
336
                .in_b   (comp_op_b  ),
337
                .op     (comp_op    ),
338
                .out    (comp_out   ));
339
 
340
        always @* begin
341
                if (op_arith_imm) begin
342
                        comp_op_b = imm_11_0;
343
                end else begin
344
                        comp_op_b = rb_rdata;
345
                end
346
                if (op_arith_imm || op_arith_reg) begin
347
                        if (instr[14:12] == 3'b010) begin
348
                                comp_op = `COMPARE_LT;  // SLT, SLTI
349
                        end else begin
350
                                comp_op = `COMPARE_LTU; // SLTU, SLTUI
351
                        end
352
                end else begin
353
                        case (instr[14:13])
354
                                2'b00: comp_op = `COMPARE_EQ;  // BEQ, BNE
355
                                2'b10: comp_op = `COMPARE_LT;  // BLT, BGE
356
                                default: /*2'b11: */comp_op = `COMPARE_LTU; // BLTU BGEU
357
                        endcase
358
                end
359
        end
360
        assign branch_cond = (instr[12])?!comp_out:comp_out;
361
 
362
        /****************************************************************
363
         * Selection of ra_raddr, rb_raddr, and rd_waddr
364
         ****************************************************************/
365
        always @* begin
366
                case (state)
367
                        `DECODE: begin
368
                                if (op_csr) begin
369
                                        ra_raddr = rs1;
370
                                        if (op_csrrc) begin
371
                                                rb_raddr = csr_addr;
372
                                        end else begin
373
                                                rb_raddr = zero;
374
                                        end
375
                                        rd_waddr = 0;
376
                                end else if (op_eret) begin
377
                                        // ERET sets up
378
                                        ra_raddr = CSR_MEPC;
379
                                        rb_raddr = zero;
380
                                        rd_waddr = zero;
381
                                end else begin
382
                                        // Normal instructions setup read during DECODE
383
                                        ra_raddr = rs1;
384
                                        rb_raddr = rs2;
385
                                        rd_waddr = rd;
386
                                end
387
                        end
388
 
389
                        `CSR_1: begin
390
                                ra_raddr = csr_addr; // CSR
391
                                rb_raddr = zero;
392
                                rd_waddr = CSR_tmp; // write RS1 to CSR_tmp
393
                        end
394
 
395
                        `CSR_2: begin
396
                                ra_raddr = CSR_tmp;
397
                                if (op_csrrc || op_csrrs) begin
398
                                        rb_raddr = csr_addr;
399
                                end else begin
400
                                        rb_raddr = zero;
401
                                end
402
                                rd_waddr = rd;
403
                        end
404
 
405
                        `EXCEPTION_1: begin
406
                                ra_raddr = CSR_MTVEC;
407
                                rb_raddr = zero;
408
                                rd_waddr = CSR_MEPC;
409
                        end
410
 
411
                        `EXCEPTION_2: begin
412
                                ra_raddr = zero;
413
                                rb_raddr = zero;
414
                                rd_waddr = CSR_MCAUSE; // Need to write the cause
415
                        end
416
 
417
                        `SHIFT_1, `SHIFT_2: begin
418
                                // rs1 has been read as ra_rdata
419
                                // write to CSR_tmp
420
                                ra_raddr = CSR_tmp;
421
                                rb_raddr = zero;
422
                                rd_waddr = CSR_tmp;
423
                        end
424
 
425
                        `CYCLE_COUNT_UPDATE_1: begin
426
                                ra_raddr = CSR_tmp;    // Read CSR_tmp in the next cycle
427
                                rb_raddr = CSR_MCYCLE; // Read MCYCLE in the next cycle
428
                                rd_waddr = CSR_tmp;    // Write the current count to CSR_tmp
429
                        end
430
 
431
                        `CYCLE_COUNT_UPDATE_2: begin
432
                                ra_raddr = zero;  // Temp
433
                                rb_raddr = CSR_MINSTR;  // Setup a read for the next cycle
434
                                rd_waddr = CSR_MCYCLE; // Write back the new count
435
                        end
436
 
437
                        `INSTR_COUNT_UPDATE_1: begin
438
                                ra_raddr = zero;  // Temp
439
                                rb_raddr = zero;  // Temp
440
                                rd_waddr = CSR_MINSTR; // Write back the new count
441
                        end
442
 
443
                        default: /* EXECUTE, MEMR, MEMW */
444
                                if (exception) begin
445
                                        ra_raddr = 0; // Future: PC
446
                                        rb_raddr = 0;
447
                                        if (op_ecall) begin
448
                                                rd_waddr = zero; // Don't save an exception address on ECALL
449
                                        end else begin
450
                                                rd_waddr = CSR_MTVAL;
451
                                        end
452
                                end else if (op_csr) begin
453
                                        ra_raddr = 0;
454
                                        rb_raddr = 0;
455
                                        if (op_csrr_cs && |rs1 == 0) begin
456
                                                // CSRRC and CSRRS don't modify the CSR is RS1==0
457
                                                rd_waddr = zero;
458
                                        end else begin
459
                                                rd_waddr = csr_addr;
460
                                        end
461
                                end else if (op_shift) begin
462
                                        ra_raddr = CSR_tmp;
463
                                        rb_raddr = zero;
464
                                        rd_waddr = rd;
465
                                end else begin
466
                                        ra_raddr = rs1;
467
                                        rb_raddr = rs2;
468
                                        rd_waddr = rd;
469
                                end
470
                endcase
471
        end
472
 
473
        reg[31:0]                       read_data_wb;
474
        always @* begin
475
        case (instr[13:12])
476
                2'b00: begin // LB, LBU
477
                        case (alu_out[1:0])
478
                                2'b00: begin
479
                                        if (!instr[14] && drdata[7]) begin
480
                                                read_data_wb = {{24{1'b1}}, drdata[7:0]};
481
                                        end else begin
482
                                                read_data_wb = {{24{1'b0}}, drdata[7:0]};
483
                                        end
484
                                end
485
                                2'b01: begin
486
                                        if (!instr[14] && drdata[15]) begin
487
                                                read_data_wb = {{24{1'b1}}, drdata[15:8]};
488
                                        end else begin
489
                                                read_data_wb = {{24{1'b0}}, drdata[15:8]};
490
                                        end
491
                                end
492
                                2'b10: begin
493
                                        if (!instr[14] && drdata[23]) begin
494
                                                read_data_wb = {{24{1'b1}}, drdata[23:16]};
495
                                        end else begin
496
                                                read_data_wb = {{24{1'b0}}, drdata[23:16]};
497
                                        end
498
                                end
499
                                default: /*2'b11*/ begin
500
                                        if (!instr[14] && drdata[31]) begin
501
                                                read_data_wb = {{24{1'b1}}, drdata[31:24]};
502
                                        end else begin
503
                                                read_data_wb = {{24{1'b0}}, drdata[31:24]};
504
                                        end
505
                                end
506
                        endcase
507
                end
508
                2'b01: begin // LH, LHU
509
                        if (alu_out[1]) begin
510
                                if (!instr[14] && drdata[31]) begin
511
                                        read_data_wb = {{16{1'b1}}, drdata[31:16]};
512
                                end else begin
513
                                        read_data_wb = {{16{1'b0}}, drdata[31:16]};
514
                                end
515
                        end else begin
516
                                if (!instr[14] && drdata[15]) begin
517
                                        read_data_wb = {{16{1'b1}}, drdata[15:0]};
518
                                end else begin
519
                                        read_data_wb = {{16{1'b0}}, drdata[15:0]};
520
                                end
521
                        end
522
                end
523
                // LW and default
524
                default: read_data_wb = drdata;
525
        endcase
526
        end
527
 
528
        reg[3:0] exc_code;
529
        always @* begin
530
                if (op_ecall) begin
531
                        exc_code = (instr[20])?4'h3:4'hb;
532
                end else if (op_ld) begin
533
                        exc_code = 4'h4;
534
                end else if (op_st) begin
535
                        exc_code = 4'h6;
536
                end else begin
537
                        exc_code = 4'h0;
538
                end
539
 
540
        end
541
 
542
        // Selection of rd_wdata
543
        // 1+4+7+1+1+1+5 => 20 taps
544
        // {pc, 2'b0} (EXCEPTION_1)
545
        // MCAUSE (EXCEPTION_2)
546
        //
547
        always @* begin
548
                case (state)
549
 
550
                        `EXCEPTION_1:
551
                                rd_wdata = {pc, 2'b0}; // Exception PC
552
 
553
                        `EXCEPTION_2: begin
554
                                // Write the cause
555
                                rd_wdata = {{24{1'b0}}, exc_code};
556
//                              if (op_ecall) begin
557
//                                      // EBREAK, ECALL
558
//                                      rd_wdata = (instr[20])?32'h0000_0003:32'h0000_000b;
559
//                              end else if (op_ld) begin
560
//                                      rd_wdata = 32'h0000_0004; // misaligned load address
561
//                              end else if (op_st) begin
562
//                                      rd_wdata = 32'h0000_0006; // misaligned store address
563
//                              end else begin
564
//                                      rd_wdata = zero; // instruction address misaligned
565
//                              end
566
                        end
567
 
568
                        `MEMR: begin
569
                                rd_wdata = read_data_wb;
570
//                              case (instr[14:12])
571
//                                      3'b000,3'b100: begin // LB, LBU
572
//                                              case (alu_out[1:0])
573
//                                                      2'b00: rd_wdata = (!instr[14] && drdata[7])?{{24{1'b1}}, drdata[7:0]}:{{24{1'b0}}, drdata[7:0]};
574
//                                                      2'b01: rd_wdata = (!instr[14] && drdata[15])?{{24{1'b1}}, drdata[15:8]}:{{24{1'b0}}, drdata[15:8]};
575
//                                                      2'b10: rd_wdata = (!instr[14] && drdata[23])?{{24{1'b1}}, drdata[23:16]}:{{24{1'b0}}, drdata[23:16]};
576
//                                                      default: /*2'b11:*/ rd_wdata = (!instr[14] && drdata[31])?{{24{1'b1}}, drdata[31:24]}:{{24{1'b0}}, drdata[31:24]};
577
//                                              endcase
578
//                                      end
579
//                                      3'b001, 3'b101: begin // LH, LHU
580
//                                              if (alu_out[1]) begin
581
//                                                      rd_wdata = (!instr[14] & drdata[31])?{{16{1'b1}}, drdata[31:16]}:{{16{1'b0}}, drdata[31:16]};
582
//                                              end else begin
583
//                                                      rd_wdata = (!instr[14] & drdata[15])?{{16{1'b1}}, drdata[15:0]}:{{16{1'b0}}, drdata[15:0]};
584
//                                              end
585
//                                      end
586
//                                      // LW and default
587
//                                      default: rd_wdata = drdata;
588
//                              endcase
589
                        end
590
 
591
                        `CYCLE_COUNT_UPDATE_1: begin
592
                                rd_wdata = {24'b0, cycle_counter};
593
                        end
594
 
595
                        `CYCLE_COUNT_UPDATE_2: begin
596
                                rd_wdata = alu_out;
597
                        end
598
 
599
                        `SHIFT_1: begin
600
                                rd_wdata = ra_rdata;
601
                        end
602
 
603
                        default: /*EXECUTE: */ begin
604
                                if (exception) begin
605
                                        // Write badaddr
606
                                        if (instr[6:5] == 3'b11 /*op_jal || op_jalr || op_branch*/) begin
607
                                                rd_wdata = {alu_out[31:1], 1'b0};
608
                                        end else begin
609
                                                rd_wdata = alu_out;
610
                                        end
611
                                end else if (op_jal || op_jalr) begin
612
                                        rd_wdata = {pc_plus4, 2'b0};
613
                                end else if ((op_arith_imm || op_arith_reg) && instr[14:13] == 2'b01) begin
614
                                        // SLT, SLTU, SLTI, SLTUI
615
                                        rd_wdata = {{31{1'b0}}, comp_out};
616
                                end else begin
617
                                        rd_wdata = alu_out;
618
                                end
619
                        end
620
                endcase
621
        end
622
 
623
        /****************************************************************
624
         * Selection of wd_wen
625
         ****************************************************************/
626
        always @* begin
627
                case (state)
628
                        `FETCH, `DECODE:
629
                                rd_wen = 0; // TODO:
630
 
631
                        `EXECUTE:
632
                                rd_wen = ((!op_branch && !op_ld_st) || exception || op_shift) && |rd_waddr;
633
 
634
                        `MEMR:
635
                                rd_wen = (|rd_waddr && dready);
636
 
637
                        `MEMW:
638
                                rd_wen = 0;
639
 
640
                        default:
641
                                rd_wen = |rd_waddr;
642
 
643
                endcase
644
        end
645
 
646
        fwrisc_regfile u_regfile (
647
                .clock     (clock    ),
648
                .reset     (reset    ),
649
                .ra_raddr  (ra_raddr ),
650
                .ra_rdata  (ra_rdata ),
651
                .rb_raddr  (rb_raddr ),
652
                .rb_rdata  (rb_rdata ),
653
                .rd_waddr  (rd_waddr ),
654
                .rd_wdata  (rd_wdata ),
655
                .rd_wen    (rd_wen   ));
656
 
657
//      reg[31:0]               imm;
658
//      always @* begin
659
//              if (op_ui) begin
660
//                      imm_a = imm_lui;
661
//              end else if (op_auipc) begin
662
//                      imm_a = auipc_imm_31_12;
663
//              end else if (op_branch) begin
664
//
665
//      end
666
//
667
 
668
        always @* begin
669
 
670
                case (state)
671
                        `CSR_1: begin
672
                                if (instr[14]) begin
673
                                        alu_op_a = rs1;
674
                                end else begin
675
                                        alu_op_a = ra_rdata;
676
                                end
677
                        end
678
 
679
                        `CYCLE_COUNT_UPDATE_2: alu_op_a = ra_rdata;
680
 
681
                        `INSTR_COUNT_UPDATE_1: alu_op_a = {24'b0, instr_counter};
682
 
683
                        default: begin
684
                                if (op_lui) begin
685
                                        alu_op_a = imm_lui;
686
                                end else if (op_auipc) begin
687
                                        alu_op_a = auipc_imm_31_12;
688
                                end else if (op_jal) begin
689
                                        alu_op_a = jal_off;
690
                                end else if (op_branch) begin
691
                                        alu_op_a = imm_branch;
692
                                end else begin
693
                                        alu_op_a = ra_rdata;
694
                                end
695
                        end
696
                endcase
697
 
698
                case (state)
699
                        `CYCLE_COUNT_UPDATE_2, `INSTR_COUNT_UPDATE_1: begin
700
                                alu_op_b = rb_rdata;
701
                        end
702
 
703
                        default: begin
704
                                if (op_lui) begin
705
                                        alu_op_b = zero;
706
                                end else if (op_auipc || op_jal || op_branch) begin
707
                                        alu_op_b = {pc, 2'b0};
708
                                end else if (op_jalr || op_ld || (op_arith_imm && !op_shift)) begin
709
                                        alu_op_b = imm_11_0;
710
                                end else if (op_st) begin
711
                                        alu_op_b = st_imm_11_0;
712
                                end else begin
713
                                        alu_op_b = rb_rdata;
714
                                end
715
                        end
716
                endcase
717
 
718
                case (state)
719
                        `EXECUTE: begin
720
                                if (op_arith_imm || op_arith_reg) begin
721
                                        case (instr[14:12])
722
                                                3'b000: begin // ADDI, ADD, SUB
723
                                                        if (op_arith_reg) begin
724
                                                                alu_op = (instr[30])?`OP_SUB:`OP_ADD;
725
                                                        end else begin
726
                                                                alu_op = `OP_ADD;
727
                                                        end
728
                                                end
729
                                                3'b100: begin // XOR
730
                                                        alu_op = `OP_XOR;
731
                                                end
732
                                                3'b001, 3'b101, 3'b110: begin // SLL, SRA, SRL, OR
733
                                                        alu_op = `OP_OR;
734
                                                end
735
                                                default: /*3'b111: */begin // AND
736
                                                        alu_op = `OP_AND;
737
                                                end
738
                                        endcase
739
                                end else if (op_csrrc) begin
740
                                        alu_op = `OP_XOR;
741
                                end else if (op_sys) begin
742
                                        alu_op = `OP_OR;
743
                                end else begin
744
                                        alu_op = `OP_ADD;
745
                                end
746
                        end
747
 
748
                        `CYCLE_COUNT_UPDATE_2, `INSTR_COUNT_UPDATE_1:
749
                                alu_op = `OP_ADD;
750
 
751
                        `SHIFT_2:
752
                                alu_op = (instr[14])?
753
                                        (instr[30])?`OP_SRA:`OP_SRL:
754
                                        `OP_SLL;
755
 
756
                        `CSR_1: begin
757
                                if (op_csrrc) begin
758
                                        alu_op = `OP_AND;
759
                                end else begin
760
                                        alu_op = `OP_OR;
761
                                end
762
                        end
763
 
764
                        `MEMR, `MEMW: alu_op = `OP_ADD;
765
 
766
                        default: /* DECODE */
767
                                alu_op = `OP_OR;
768
                endcase
769
        end
770
 
771
        fwrisc_alu u_alu (
772
                .clock  (clock     ),
773
                .reset  (reset     ),
774
                .op_a   (alu_op_a  ),
775
                .op_b   (alu_op_b  ),
776
                .op     (alu_op    ),
777
                .out    (alu_out   ),
778
                .carry  (alu_carry ),
779
                .eqz    (alu_eqz   ));
780
 
781
        /****************************************************************
782
         * pc_next selection
783
         ****************************************************************/
784
        always @* begin : pc_next_sel
785
                if (op_jal || op_jalr || (op_branch && branch_cond)) begin
786
                        pc_next = alu_out[31:2];
787
                end else if (op_eret || exception) begin
788
                        pc_next = ra_rdata[31:2];
789
                end else begin
790
                        pc_next = pc_plus4;
791
                end
792
        end
793
 
794
        // Handle data-access control signals
795
        fwrisc_dbus_if u_dbus_if (
796
                .clock     (clock    ),
797
                .instr     (instr    ),
798
                .rb_rdata  (rb_rdata ),
799
                .alu_out   (alu_out  ),
800
                .state     (state    ),
801
                .daddr     (daddr    ),
802
                .dvalid    (dvalid   ),
803
                .dwrite    (dwrite   ),
804
                .dwdata    (dwdata   ),
805
                .dstrb     (dstrb    ),
806
                .dready    (dready   ));
807
 
808
 
809
        always @* begin
810
                if (op_st || op_ld) begin
811
                        case (instr[13:12])
812
                                2'b00: begin // SB
813
                                        misaligned_addr = 0;
814
                                end
815
                                2'b01: begin // SH
816
                                        misaligned_addr = op_ld_st && alu_out[0];
817
                                end
818
                                // SW and default
819
                                default: begin
820
                                        misaligned_addr = op_ld_st && |alu_out[1:0];
821
                                end
822
                        endcase
823
                end else if (op_jal || op_jalr || (op_branch && branch_cond)) begin
824
                        misaligned_addr = alu_out[1]; // the low-bit is always cleared on jump
825
                end else begin
826
                        misaligned_addr = 0;
827
                end
828
        end
829
 
830
        assign exception = (state == `EXECUTE && (op_ecall || misaligned_addr));
831
 
832
        /**
833
         * The tracer is used during simulation to inspect operation of the core
834
         */
835
        fwrisc_tracer u_tracer (
836
                .clock   (clock                         ),
837
                .reset   (reset                         ),
838
                .addr    ({pc, 2'b0}            ),
839
                .instr   (instr                         ),
840
                .ivalid  ((state == `EXECUTE)),
841
                .raddr   (rd_waddr                      ),
842
                .rdata   (rd_wdata                      ),
843
                .rwrite  (rd_wen                        ),
844
                .maddr   (daddr                         ),
845
                .mdata   ((dwrite)?dwdata:drdata),
846
                .mstrb   (dstrb                         ),
847
                .mwrite  (dwrite                        ),
848
                .mvalid  ((dvalid && dready))
849
                );
850
 
851
endmodule
852
 

powered by: WebSVN 2.1.0

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