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