add handle_trap
[rv32.git] / cpu.v
1 /*
2 * Copyright 2018 Jacob Lifshay
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 */
23 `timescale 1ns / 1ps
24 `include "riscv.vh"
25 `include "cpu.vh"
26
27 module cpu(
28 input clk,
29 input reset,
30 output tty_write,
31 output [7:0] tty_write_data,
32 input tty_write_busy,
33 input switch_2,
34 input switch_3,
35 output led_1,
36 output led_3
37 );
38
39 parameter ram_size = 'h8000;
40 parameter ram_start = 32'h1_0000;
41 parameter reset_vector = ram_start;
42 parameter mtvec = ram_start + 'h40;
43
44 reg [31:0] registers[31:1];
45
46 wire [31:2] memory_interface_fetch_address;
47 wire [31:0] memory_interface_fetch_data;
48 wire memory_interface_fetch_valid;
49 wire [31:2] memory_interface_rw_address;
50 wire [3:0] memory_interface_rw_byte_mask;
51 wire memory_interface_rw_read_not_write;
52 wire memory_interface_rw_active;
53 wire [31:0] memory_interface_rw_data_in;
54 wire [31:0] memory_interface_rw_data_out;
55 wire memory_interface_rw_address_valid;
56 wire memory_interface_rw_wait;
57
58 cpu_memory_interface #(
59 .ram_size(ram_size),
60 .ram_start(ram_start)
61 ) memory_interface(
62 .clk(clk),
63 .reset(reset),
64 .fetch_address(memory_interface_fetch_address),
65 .fetch_data(memory_interface_fetch_data),
66 .fetch_valid(memory_interface_fetch_valid),
67 .rw_address(memory_interface_rw_address),
68 .rw_byte_mask(memory_interface_rw_byte_mask),
69 .rw_read_not_write(memory_interface_rw_read_not_write),
70 .rw_active(memory_interface_rw_active),
71 .rw_data_in(memory_interface_rw_data_in),
72 .rw_data_out(memory_interface_rw_data_out),
73 .rw_address_valid(memory_interface_rw_address_valid),
74 .rw_wait(memory_interface_rw_wait),
75 .tty_write(tty_write),
76 .tty_write_data(tty_write_data),
77 .tty_write_busy(tty_write_busy),
78 .switch_2(switch_2),
79 .switch_3(switch_3),
80 .led_1(led_1),
81 .led_3(led_3)
82 );
83
84 wire `fetch_action fetch_action;
85 wire [31:0] fetch_target_pc;
86 wire [31:0] fetch_output_pc;
87 wire [31:0] fetch_output_instruction;
88 wire `fetch_output_state fetch_output_state;
89
90 cpu_fetch_stage #(
91 .reset_vector(reset_vector),
92 .mtvec(mtvec)
93 ) fetch_stage(
94 .clk(clk),
95 .reset(reset),
96 .memory_interface_fetch_address(memory_interface_fetch_address),
97 .memory_interface_fetch_data(memory_interface_fetch_data),
98 .memory_interface_fetch_valid(memory_interface_fetch_valid),
99 .fetch_action(fetch_action),
100 .target_pc(fetch_target_pc),
101 .output_pc(fetch_output_pc),
102 .output_instruction(fetch_output_instruction),
103 .output_state(fetch_output_state)
104 );
105
106 wire [6:0] decoder_funct7;
107 wire [2:0] decoder_funct3;
108 wire [4:0] decoder_rd;
109 wire [4:0] decoder_rs1;
110 wire [4:0] decoder_rs2;
111 wire [31:0] decoder_immediate;
112 wire [6:0] decoder_opcode;
113 wire `decode_action decode_action;
114
115 cpu_decoder decoder(
116 .instruction(fetch_output_instruction),
117 .funct7(decoder_funct7),
118 .funct3(decoder_funct3),
119 .rd(decoder_rd),
120 .rs1(decoder_rs1),
121 .rs2(decoder_rs2),
122 .immediate(decoder_immediate),
123 .opcode(decoder_opcode),
124 .decode_action(decode_action));
125
126 wire [31:0] register_rs1 = (decoder_rs1 == 0) ? 0 : registers[decoder_rs1];
127 wire [31:0] register_rs2 = (decoder_rs2 == 0) ? 0 : registers[decoder_rs2];
128
129 wire [31:0] load_store_address = decoder_immediate + register_rs1;
130
131 wire [1:0] load_store_address_low_2 = decoder_immediate[1:0] + register_rs1[1:0];
132
133 function get_load_store_misaligned(
134 input [2:0] funct3,
135 input [1:0] load_store_address_low_2
136 );
137 begin
138 case(funct3[1:0])
139 `funct3_sb:
140 get_load_store_misaligned = 0;
141 `funct3_sh:
142 get_load_store_misaligned = load_store_address_low_2[0] != 0;
143 `funct3_sw:
144 get_load_store_misaligned = load_store_address_low_2[1:0] != 0;
145 default:
146 get_load_store_misaligned = 1'bX;
147 endcase
148 end
149 endfunction
150
151 wire load_store_misaligned = get_load_store_misaligned(decoder_funct3, load_store_address_low_2);
152
153 assign memory_interface_rw_address = load_store_address[31:2];
154
155 wire [3:0] unshifted_load_store_byte_mask = {decoder_funct3[1] ? 2'b11 : 2'b00, (decoder_funct3[1] | decoder_funct3[0]) ? 1'b1 : 1'b0, 1'b1};
156
157 assign memory_interface_rw_byte_mask = unshifted_load_store_byte_mask << load_store_address_low_2;
158
159 assign memory_interface_rw_data_in[31:24] = load_store_address_low_2[1]
160 ? (load_store_address_low_2[0] ? register_rs2[7:0] : register_rs2[15:8])
161 : (load_store_address_low_2[0] ? register_rs2[23:16] : register_rs2[31:24]);
162 assign memory_interface_rw_data_in[23:16] = load_store_address_low_2[1] ? register_rs2[7:0] : register_rs2[23:16];
163 assign memory_interface_rw_data_in[15:8] = load_store_address_low_2[0] ? register_rs2[7:0] : register_rs2[15:8];
164 assign memory_interface_rw_data_in[7:0] = register_rs2[7:0];
165
166 wire [31:0] unmasked_loaded_value;
167
168 assign unmasked_loaded_value[7:0] = load_store_address_low_2[1]
169 ? (load_store_address_low_2[0] ? memory_interface_rw_data_out[31:24] : memory_interface_rw_data_out[23:16])
170 : (load_store_address_low_2[0] ? memory_interface_rw_data_out[15:8] : memory_interface_rw_data_out[7:0]);
171 assign unmasked_loaded_value[15:8] = load_store_address_low_2[1] ? memory_interface_rw_data_out[31:24] : memory_interface_rw_data_out[15:8];
172 assign unmasked_loaded_value[31:16] = memory_interface_rw_data_out[31:16];
173
174 wire [31:0] loaded_value;
175
176 assign loaded_value[7:0] = unmasked_loaded_value[7:0];
177 assign loaded_value[15:8] = decoder_funct3[1:0] == 0 ? ({8{~decoder_funct3[2] & unmasked_loaded_value[7]}}) : unmasked_loaded_value[15:8];
178 assign loaded_value[31:16] = decoder_funct3[1] == 0 ? ({16{~decoder_funct3[2] & (decoder_funct3[0] ? unmasked_loaded_value[15] : unmasked_loaded_value[7])}}) : unmasked_loaded_value[31:16];
179
180 assign memory_interface_rw_active = ~reset
181 & (fetch_output_state == `fetch_output_state_valid)
182 & ~load_store_misaligned
183 & ((decode_action & (`decode_action_load | `decode_action_store)) != 0);
184
185 assign memory_interface_rw_read_not_write = ~decoder_opcode[5];
186
187 wire [31:0] alu_a = register_rs1;
188 wire [31:0] alu_b = decoder_opcode[5] ? register_rs2 : decoder_immediate;
189 wire [31:0] alu_result;
190
191 cpu_alu alu(
192 .funct7(decoder_funct7),
193 .funct3(decoder_funct3),
194 .opcode(decoder_opcode),
195 .a(alu_a),
196 .b(alu_b),
197 .result(alu_result)
198 );
199
200 wire [31:0] lui_auipc_result = decoder_opcode[5] ? decoder_immediate : decoder_immediate + fetch_output_pc;
201
202 assign fetch_target_pc[31:1] = ((decoder_opcode != `opcode_jalr ? fetch_output_pc[31:1] : register_rs1[31:1]) + decoder_immediate[31:1]);
203 assign fetch_target_pc[0] = 0;
204
205 wire misaligned_jump_target = fetch_target_pc[1];
206
207 wire [31:0] branch_arg_a = {register_rs1[31] ^ ~decoder_funct3[1], register_rs1[30:0]};
208 wire [31:0] branch_arg_b = {register_rs2[31] ^ ~decoder_funct3[1], register_rs2[30:0]};
209
210 wire branch_taken = decoder_funct3[0] ^ (decoder_funct3[2] ? branch_arg_a < branch_arg_b : branch_arg_a == branch_arg_b);
211
212 reg [31:0] mcause = 0;
213 reg [31:0] mepc = 32'hXXXXXXXX;
214 reg [31:0] mscratch = 32'hXXXXXXXX;
215
216 reg mstatus_mpie = 1'bX;
217 reg mstatus_mie = 0;
218 parameter mstatus_mprv = 0;
219 parameter mstatus_tsr = 0;
220 parameter mstatus_tw = 0;
221 parameter mstatus_tvm = 0;
222 parameter mstatus_mxr = 0;
223 parameter mstatus_sum = 0;
224 parameter mstatus_xs = 0;
225 parameter mstatus_fs = 0;
226 parameter mstatus_mpp = 2'b11;
227 parameter mstatus_spp = 0;
228 parameter mstatus_spie = 0;
229 parameter mstatus_upie = 0;
230 parameter mstatus_sie = 0;
231 parameter mstatus_uie = 0;
232
233 reg mie_meie = 1'bX;
234 reg mie_mtie = 1'bX;
235 reg mie_msie = 1'bX;
236 parameter mie_seie = 0;
237 parameter mie_ueie = 0;
238 parameter mie_stie = 0;
239 parameter mie_utie = 0;
240 parameter mie_ssie = 0;
241 parameter mie_usie = 0;
242
243 task reset_to_initial;
244 begin
245 mcause = 0;
246 mepc = 32'hXXXXXXXX;
247 mscratch = 32'hXXXXXXXX;
248 mstatus_mie = 0;
249 mstatus_mpie = 1'bX;
250 mie_meie = 1'bX;
251 mie_mtie = 1'bX;
252 mie_msie = 1'bX;
253 registers['h01] <= 32'hXXXXXXXX;
254 registers['h02] <= 32'hXXXXXXXX;
255 registers['h03] <= 32'hXXXXXXXX;
256 registers['h04] <= 32'hXXXXXXXX;
257 registers['h05] <= 32'hXXXXXXXX;
258 registers['h06] <= 32'hXXXXXXXX;
259 registers['h07] <= 32'hXXXXXXXX;
260 registers['h08] <= 32'hXXXXXXXX;
261 registers['h09] <= 32'hXXXXXXXX;
262 registers['h0A] <= 32'hXXXXXXXX;
263 registers['h0B] <= 32'hXXXXXXXX;
264 registers['h0C] <= 32'hXXXXXXXX;
265 registers['h0D] <= 32'hXXXXXXXX;
266 registers['h0E] <= 32'hXXXXXXXX;
267 registers['h0F] <= 32'hXXXXXXXX;
268 registers['h10] <= 32'hXXXXXXXX;
269 registers['h11] <= 32'hXXXXXXXX;
270 registers['h12] <= 32'hXXXXXXXX;
271 registers['h13] <= 32'hXXXXXXXX;
272 registers['h14] <= 32'hXXXXXXXX;
273 registers['h15] <= 32'hXXXXXXXX;
274 registers['h16] <= 32'hXXXXXXXX;
275 registers['h17] <= 32'hXXXXXXXX;
276 registers['h18] <= 32'hXXXXXXXX;
277 registers['h19] <= 32'hXXXXXXXX;
278 registers['h1A] <= 32'hXXXXXXXX;
279 registers['h1B] <= 32'hXXXXXXXX;
280 registers['h1C] <= 32'hXXXXXXXX;
281 registers['h1D] <= 32'hXXXXXXXX;
282 registers['h1E] <= 32'hXXXXXXXX;
283 registers['h1F] <= 32'hXXXXXXXX;
284 end
285 endtask
286
287 task write_register(input [4:0] register_number, input [31:0] value);
288 begin
289 if(register_number != 0)
290 registers[register_number] <= value;
291 end
292 endtask
293
294 function [31:0] evaluate_csr_funct3_operation(input [2:0] funct3, input [31:0] previous_value, input [31:0] written_value);
295 begin
296 case(funct3)
297 `funct3_csrrw, `funct3_csrrwi:
298 evaluate_csr_funct3_operation = written_value;
299 `funct3_csrrs, `funct3_csrrsi:
300 evaluate_csr_funct3_operation = written_value | previous_value;
301 `funct3_csrrc, `funct3_csrrci:
302 evaluate_csr_funct3_operation = ~written_value & previous_value;
303 default:
304 evaluate_csr_funct3_operation = 32'hXXXXXXXX;
305 endcase
306 end
307 endfunction
308
309 parameter misa_a = 1'b0;
310 parameter misa_b = 1'b0;
311 parameter misa_c = 1'b0;
312 parameter misa_d = 1'b0;
313 parameter misa_e = 1'b0;
314 parameter misa_f = 1'b0;
315 parameter misa_g = 1'b0;
316 parameter misa_h = 1'b0;
317 parameter misa_i = 1'b1;
318 parameter misa_j = 1'b0;
319 parameter misa_k = 1'b0;
320 parameter misa_l = 1'b0;
321 parameter misa_m = 1'b0;
322 parameter misa_n = 1'b0;
323 parameter misa_o = 1'b0;
324 parameter misa_p = 1'b0;
325 parameter misa_q = 1'b0;
326 parameter misa_r = 1'b0;
327 parameter misa_s = 1'b0;
328 parameter misa_t = 1'b0;
329 parameter misa_u = 1'b0;
330 parameter misa_v = 1'b0;
331 parameter misa_w = 1'b0;
332 parameter misa_x = 1'b0;
333 parameter misa_y = 1'b0;
334 parameter misa_z = 1'b0;
335 parameter misa = {
336 2'b01,
337 4'b0,
338 misa_z,
339 misa_y,
340 misa_x,
341 misa_w,
342 misa_v,
343 misa_u,
344 misa_t,
345 misa_s,
346 misa_r,
347 misa_q,
348 misa_p,
349 misa_o,
350 misa_n,
351 misa_m,
352 misa_l,
353 misa_k,
354 misa_j,
355 misa_i,
356 misa_h,
357 misa_g,
358 misa_f,
359 misa_e,
360 misa_d,
361 misa_c,
362 misa_b,
363 misa_a};
364
365 parameter mvendorid = 32'b0;
366 parameter marchid = 32'b0;
367 parameter mimpid = 32'b0;
368 parameter mhartid = 32'b0;
369
370 function [31:0] make_mstatus(input mstatus_tsr,
371 input mstatus_tw,
372 input mstatus_tvm,
373 input mstatus_mxr,
374 input mstatus_sum,
375 input mstatus_mprv,
376 input [1:0] mstatus_xs,
377 input [1:0] mstatus_fs,
378 input [1:0] mstatus_mpp,
379 input mstatus_spp,
380 input mstatus_mpie,
381 input mstatus_spie,
382 input mstatus_upie,
383 input mstatus_mie,
384 input mstatus_sie,
385 input mstatus_uie);
386 begin
387 make_mstatus = {(mstatus_xs == 2'b11) | (mstatus_fs == 2'b11),
388 8'b0,
389 mstatus_tsr,
390 mstatus_tw,
391 mstatus_tvm,
392 mstatus_mxr,
393 mstatus_sum,
394 mstatus_mprv,
395 mstatus_xs,
396 mstatus_fs,
397 mstatus_mpp,
398 2'b0,
399 mstatus_spp,
400 mstatus_mpie,
401 1'b0,
402 mstatus_spie,
403 mstatus_upie,
404 mstatus_mie,
405 1'b0,
406 mstatus_sie,
407 mstatus_uie};
408 end
409 endfunction
410
411 wire mip_meip = 0; // TODO: implement external interrupts
412 parameter mip_seip = 0;
413 parameter mip_ueip = 0;
414 wire mip_mtip = 0; // TODO: implement timer interrupts
415 parameter mip_stip = 0;
416 parameter mip_utip = 0;
417 parameter mip_msip = 0;
418 parameter mip_ssip = 0;
419 parameter mip_usip = 0;
420
421 wire csr_op_is_valid;
422
423 function `fetch_action get_fetch_action(
424 input `fetch_output_state fetch_output_state,
425 input `decode_action decode_action,
426 input load_store_misaligned,
427 input memory_interface_rw_address_valid,
428 input memory_interface_rw_wait,
429 input branch_taken,
430 input misaligned_jump_target,
431 input csr_op_is_valid
432 );
433 begin
434 case(fetch_output_state)
435 `fetch_output_state_empty:
436 get_fetch_action = `fetch_action_default;
437 `fetch_output_state_trap:
438 get_fetch_action = `fetch_action_ack_trap;
439 `fetch_output_state_valid: begin
440 if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
441 get_fetch_action = `fetch_action_error_trap;
442 end
443 else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
444 get_fetch_action = `fetch_action_noerror_trap;
445 end
446 else if((decode_action & (`decode_action_load | `decode_action_store)) != 0) begin
447 if(load_store_misaligned | ~memory_interface_rw_address_valid) begin
448 get_fetch_action = `fetch_action_error_trap;
449 end
450 else if(memory_interface_rw_wait) begin
451 get_fetch_action = `fetch_action_wait;
452 end
453 else begin
454 get_fetch_action = `fetch_action_default;
455 end
456 end
457 else if((decode_action & `decode_action_fence_i) != 0) begin
458 get_fetch_action = `fetch_action_fence;
459 end
460 else if((decode_action & `decode_action_branch) != 0) begin
461 if(branch_taken) begin
462 if(misaligned_jump_target) begin
463 get_fetch_action = `fetch_action_error_trap;
464 end
465 else begin
466 get_fetch_action = `fetch_action_jump;
467 end
468 end
469 else
470 begin
471 get_fetch_action = `fetch_action_default;
472 end
473 end
474 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
475 if(misaligned_jump_target) begin
476 get_fetch_action = `fetch_action_error_trap;
477 end
478 else begin
479 get_fetch_action = `fetch_action_jump;
480 end
481 end
482 else if((decode_action & `decode_action_csr) != 0) begin
483 if(csr_op_is_valid)
484 get_fetch_action = `fetch_action_default;
485 else
486 get_fetch_action = `fetch_action_error_trap;
487 end
488 else begin
489 get_fetch_action = `fetch_action_default;
490 end
491 end
492 default:
493 get_fetch_action = 32'hXXXXXXXX;
494 endcase
495 end
496 endfunction
497
498 assign fetch_action = get_fetch_action(
499 fetch_output_state,
500 decode_action,
501 load_store_misaligned,
502 memory_interface_rw_address_valid,
503 memory_interface_rw_wait,
504 branch_taken,
505 misaligned_jump_target,
506 csr_op_is_valid
507 );
508
509 task handle_trap;
510 begin
511 mstatus_mpie = mstatus_mie;
512 mstatus_mie = 0;
513 mepc = (fetch_action == `fetch_action_noerror_trap) ? fetch_output_pc + 4 : fetch_output_pc;
514 if(fetch_action == `fetch_action_ack_trap) begin
515 mcause = `cause_instruction_access_fault;
516 end
517 else if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
518 mcause = `cause_illegal_instruction;
519 end
520 else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
521 mcause = decoder_immediate[0] ? `cause_machine_environment_call : `cause_breakpoint;
522 end
523 else if((decode_action & `decode_action_load) != 0) begin
524 if(load_store_misaligned)
525 mcause = `cause_load_address_misaligned;
526 else
527 mcause = `cause_load_access_fault;
528 end
529 else if((decode_action & `decode_action_store) != 0) begin
530 if(load_store_misaligned)
531 mcause = `cause_store_amo_address_misaligned;
532 else
533 mcause = `cause_store_amo_access_fault;
534 end
535 else if((decode_action & (`decode_action_branch | `decode_action_jal | `decode_action_jalr)) != 0) begin
536 mcause = `cause_instruction_address_misaligned;
537 end
538 else begin
539 mcause = `cause_illegal_instruction;
540 end
541 end
542 endtask
543
544 wire [11:0] csr_number = decoder_immediate;
545 wire [31:0] csr_input_value = decoder_funct3[2] ? decoder_rs1 : register_rs1;
546 wire csr_reads = decoder_funct3[1] | (decoder_rd != 0);
547 wire csr_writes = ~decoder_funct3[1] | (decoder_rs1 != 0);
548
549 function get_csr_op_is_valid(input [11:0] csr_number, input csr_reads, input csr_writes);
550 begin
551 case(csr_number)
552 `csr_ustatus,
553 `csr_fflags,
554 `csr_frm,
555 `csr_fcsr,
556 `csr_uie,
557 `csr_utvec,
558 `csr_uscratch,
559 `csr_uepc,
560 `csr_ucause,
561 `csr_utval,
562 `csr_uip,
563 `csr_sstatus,
564 `csr_sedeleg,
565 `csr_sideleg,
566 `csr_sie,
567 `csr_stvec,
568 `csr_scounteren,
569 `csr_sscratch,
570 `csr_sepc,
571 `csr_scause,
572 `csr_stval,
573 `csr_sip,
574 `csr_satp,
575 `csr_medeleg,
576 `csr_mideleg,
577 `csr_dcsr,
578 `csr_dpc,
579 `csr_dscratch:
580 get_csr_op_is_valid = 0;
581 `csr_cycle,
582 `csr_time,
583 `csr_instret,
584 `csr_cycleh,
585 `csr_timeh,
586 `csr_instreth,
587 `csr_mvendorid,
588 `csr_marchid,
589 `csr_mimpid,
590 `csr_mhartid:
591 get_csr_op_is_valid = ~csr_writes;
592 `csr_misa,
593 `csr_mstatus,
594 `csr_mie,
595 `csr_mtvec,
596 `csr_mscratch,
597 `csr_mepc,
598 `csr_mcause,
599 `csr_mip:
600 get_csr_op_is_valid = 1;
601 `csr_mcounteren,
602 `csr_mtval,
603 `csr_mcycle,
604 `csr_minstret,
605 `csr_mcycleh,
606 `csr_minstreth:
607 // TODO: CSRs not implemented yet
608 get_csr_op_is_valid = 0;
609 endcase
610 end
611 endfunction
612
613 assign csr_op_is_valid = get_csr_op_is_valid(csr_number, csr_reads, csr_writes);
614
615 wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter
616 wire [63:0] time_counter = 0; // TODO: implement time_counter
617 wire [63:0] instret_counter = 0; // TODO: implement instret_counter
618
619 always @(posedge clk) begin:main_block
620 if(reset) begin
621 reset_to_initial();
622 disable main_block;
623 end
624 case(fetch_output_state)
625 `fetch_output_state_empty: begin
626 end
627 `fetch_output_state_trap: begin
628 handle_trap();
629 end
630 `fetch_output_state_valid: begin:valid
631 if((fetch_action == `fetch_action_error_trap) | (fetch_action == `fetch_action_noerror_trap)) begin
632 handle_trap();
633 end
634 else if((decode_action & `decode_action_load) != 0) begin
635 if(~memory_interface_rw_wait)
636 write_register(decoder_rd, loaded_value);
637 end
638 else if((decode_action & `decode_action_op_op_imm) != 0) begin
639 write_register(decoder_rd, alu_result);
640 end
641 else if((decode_action & `decode_action_lui_auipc) != 0) begin
642 write_register(decoder_rd, lui_auipc_result);
643 end
644 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
645 write_register(decoder_rd, fetch_output_pc + 4);
646 end
647 else if((decode_action & `decode_action_csr) != 0) begin:csr
648 reg [31:0] csr_output_value;
649 reg [31:0] csr_written_value;
650 csr_output_value = 32'hXXXXXXXX;
651 csr_written_value = 32'hXXXXXXXX;
652 case(csr_number)
653 `csr_cycle: begin
654 csr_output_value = cycle_counter[31:0];
655 end
656 `csr_time: begin
657 csr_output_value = time_counter[31:0];
658 end
659 `csr_instret: begin
660 csr_output_value = instret_counter[31:0];
661 end
662 `csr_cycleh: begin
663 csr_output_value = cycle_counter[63:32];
664 end
665 `csr_timeh: begin
666 csr_output_value = time_counter[63:32];
667 end
668 `csr_instreth: begin
669 csr_output_value = instret_counter[63:32];
670 end
671 `csr_mvendorid: begin
672 csr_output_value = mvendorid;
673 end
674 `csr_marchid: begin
675 csr_output_value = marchid;
676 end
677 `csr_mimpid: begin
678 csr_output_value = mimpid;
679 end
680 `csr_mhartid: begin
681 csr_output_value = mhartid;
682 end
683 `csr_misa: begin
684 csr_output_value = misa;
685 end
686 `csr_mstatus: begin
687 csr_output_value = make_mstatus(mstatus_tsr,
688 mstatus_tw,
689 mstatus_tvm,
690 mstatus_mxr,
691 mstatus_sum,
692 mstatus_mprv,
693 mstatus_xs,
694 mstatus_fs,
695 mstatus_mpp,
696 mstatus_spp,
697 mstatus_mpie,
698 mstatus_spie,
699 mstatus_upie,
700 mstatus_mie,
701 mstatus_sie,
702 mstatus_uie);
703 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
704 if(csr_writes) begin
705 mstatus_mpie = csr_written_value[7];
706 mstatus_mie = csr_written_value[3];
707 end
708 end
709 `csr_mie: begin
710 csr_output_value = 0;
711 csr_output_value[11] = mie_meie;
712 csr_output_value[9] = mie_seie;
713 csr_output_value[8] = mie_ueie;
714 csr_output_value[7] = mie_mtie;
715 csr_output_value[5] = mie_stie;
716 csr_output_value[4] = mie_utie;
717 csr_output_value[3] = mie_msie;
718 csr_output_value[1] = mie_ssie;
719 csr_output_value[0] = mie_usie;
720 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
721 if(csr_writes) begin
722 mie_meie = csr_written_value[11];
723 mie_mtie = csr_written_value[7];
724 mie_msie = csr_written_value[3];
725 end
726 end
727 `csr_mtvec: begin
728 csr_output_value = mtvec;
729 end
730 `csr_mscratch: begin
731 csr_output_value = mscratch;
732 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
733 if(csr_writes)
734 mscratch = csr_written_value;
735 end
736 `csr_mepc: begin
737 csr_output_value = mepc;
738 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
739 if(csr_writes)
740 mepc = csr_written_value;
741 end
742 `csr_mcause: begin
743 csr_output_value = mcause;
744 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
745 if(csr_writes)
746 mcause = csr_written_value;
747 end
748 `csr_mip: begin
749 csr_output_value = 0;
750 csr_output_value[11] = mip_meip;
751 csr_output_value[9] = mip_seip;
752 csr_output_value[8] = mip_ueip;
753 csr_output_value[7] = mip_mtip;
754 csr_output_value[5] = mip_stip;
755 csr_output_value[4] = mip_utip;
756 csr_output_value[3] = mip_msip;
757 csr_output_value[1] = mip_ssip;
758 csr_output_value[0] = mip_usip;
759 end
760 endcase
761 if(csr_reads)
762 write_register(decoder_rd, csr_output_value);
763 end
764 else if((decode_action & (`decode_action_fence | `decode_action_fence_i | `decode_action_store | `decode_action_branch)) != 0) begin
765 // do nothing
766 end
767 end
768 endcase
769 end
770
771 endmodule