3 * Copyright 2018 Jacob Lifshay
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:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
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
31 from migen
.fhdl
import verilog
32 from migen
.fhdl
.structure
import _Operator
34 from riscvdefs
import *
37 class MemoryInterface
:
38 fetch_address
= Signal(32, name
="memory_interface_fetch_address") # XXX [2:]
39 fetch_data
= Signal(32, name
="memory_interface_fetch_data")
40 fetch_valid
= Signal(name
="memory_interface_fetch_valid")
41 rw_address
= Signal(32, name
="memory_interface_rw_address") # XXX [2:]
42 rw_byte_mask
= Signal(4, name
="memory_interface_rw_byte_mask")
43 rw_read_not_write
= Signal(name
="memory_interface_rw_read_not_write")
44 rw_active
= Signal(name
="memory_interface_rw_active")
45 rw_data_in
= Signal(32, name
="memory_interface_rw_data_in")
46 rw_data_out
= Signal(32, name
="memory_interface_rw_data_out")
47 rw_address_valid
= Signal(name
="memory_interface_rw_address_valid")
48 rw_wait
= Signal(name
="memory_interface_rw_wait")
52 funct7
= Signal(7, name
="decoder_funct7")
53 funct3
= Signal(3, name
="decoder_funct3")
54 rd
= Signal(5, name
="decoder_rd")
55 rs1
= Signal(5, name
="decoder_rs1")
56 rs2
= Signal(5, name
="decoder_rs2")
57 immediate
= Signal(32, name
="decoder_immediate")
58 opcode
= Signal(7, name
="decoder_opcode")
59 act
= Signal(decode_action
, name
="decoder_action")
62 def __init__(self
, comb
, sync
):
65 self
.mpie
= Signal(name
="mstatus_mpie")
66 self
.mie
= Signal(name
="mstatus_mie")
67 self
.mprv
= Signal(name
="mstatus_mprv")
68 self
.tsr
= Signal(name
="mstatus_tsr")
69 self
.tw
= Signal(name
="mstatus_tw")
70 self
.tvm
= Signal(name
="mstatus_tvm")
71 self
.mxr
= Signal(name
="mstatus_mxr")
72 self
._sum
= Signal(name
="mstatus_sum")
73 self
.xs
= Signal(name
="mstatus_xs")
74 self
.fs
= Signal(name
="mstatus_fs")
75 self
.mpp
= Signal(2, name
="mstatus_mpp")
76 self
.spp
= Signal(name
="mstatus_spp")
77 self
.spie
= Signal(name
="mstatus_spie")
78 self
.upie
= Signal(name
="mstatus_upie")
79 self
.sie
= Signal(name
="mstatus_sie")
80 self
.uie
= Signal(name
="mstatus_uie")
83 if n
in ['make', 'mpp', 'comb', 'sync'] or n
.startswith("_"):
85 self
.comb
+= getattr(self
, n
).eq(0x0)
86 self
.comb
+= self
.mpp
.eq(0b11)
88 self
.sync
+= self
.mie
.eq(0)
89 self
.sync
+= self
.mpie
.eq(0)
93 self
.uie
, self
.sie
, Constant(0), self
.mie
,
94 self
.upie
, self
.spie
, Constant(0), self
.mpie
,
95 self
.spp
, Constant(0, 2), self
.mpp
,
96 self
.fs
, self
.xs
, self
.mprv
, self
._sum
,
97 self
.mxr
, self
.tvm
, self
.tw
, self
.tsr
,
99 (self
.xs
== Constant(0b11, 2)) |
(self
.fs
== Constant(0b11, 2))
104 def __init__(self
, comb
, sync
):
107 self
.meie
= Signal(name
="mie_meie")
108 self
.mtie
= Signal(name
="mie_mtie")
109 self
.msie
= Signal(name
="mie_msie")
110 self
.ueie
= Signal(name
="mie_ueie")
111 self
.stie
= Signal(name
="mie_stie")
112 self
.utie
= Signal(name
="mie_utie")
113 self
.ssie
= Signal(name
="mie_ssie")
114 self
.usie
= Signal(name
="mie_usie")
117 if n
in ['make', 'comb', 'sync'] or n
.startswith("_"):
119 self
.comb
+= getattr(self
, n
).eq(0x0)
121 self
.sync
+= self
.meie
.eq(0)
122 self
.sync
+= self
.mtie
.eq(0)
123 self
.sync
+= self
.msie
.eq(0)
126 def __init__(self
, comb
, sync
):
129 self
.meip
= Signal(name
="mip_meip") # TODO: implement ext interrupts
130 self
.seip
= Signal(name
="mip_seip")
131 self
.ueip
= Signal(name
="mip_uiep")
132 self
.mtip
= Signal(name
="mip_mtip") # TODO: implement timer interrupts
133 self
.stip
= Signal(name
="mip_stip")
134 self
.msip
= Signal(name
="mip_stip")
135 self
.utip
= Signal(name
="mip_utip")
136 self
.ssip
= Signal(name
="mip_ssip")
137 self
.usip
= Signal(name
="mip_usip")
140 if n
in ['comb', 'sync'] or n
.startswith("_"):
142 self
.comb
+= getattr(self
, n
).eq(0x0)
146 def __init__(self
, comb
, sync
):
149 self
.mcause
= Signal(32)
150 self
.mepc
= Signal(32)
151 self
.mscratch
= Signal(32)
152 self
.sync
+= self
.mcause
.eq(0)
153 self
.sync
+= self
.mepc
.eq(0) # 32'hXXXXXXXX;
154 self
.sync
+= self
.mscratch
.eq(0) # 32'hXXXXXXXX;
158 def __init__(self
, comb
, sync
):
161 self
.misa
= Signal(32)
163 for l
in list(string
.ascii_lowercase
):
164 value
= 1 if l
== 'i' else 0
165 cl
.append(Constant(value
))
166 cl
.append(Constant(0, 4))
167 cl
.append(Constant(0b01, 2))
168 self
.comb
+= self
.misa
.eq(Cat(cl
))
175 def get_ls_misaligned(self
, ls
, funct3
, load_store_address_low_2
):
176 return Case(funct3
[:2],
177 { F3
.sb
: ls
.eq(Constant(0)),
178 F3
.sh
: ls
.eq(load_store_address_low_2
[0] != 0),
179 F3
.sw
: ls
.eq(load_store_address_low_2
[0:2] != Constant(0, 2)),
180 "default": ls
.eq(Constant(1))
183 def get_lsbm(self
, dc
):
184 return Cat(Constant(1),
185 Mux((dc
.funct3
[1] | dc
.funct3
[0]),
186 Constant(1), Constant(0)),
188 Constant(0b11, 2), Constant(0, 2)))
190 # XXX this happens to get done by various self.sync actions
191 #def reset_to_initial(self, m, mstatus, mie, registers):
192 # return [m.mcause.eq(0),
195 def write_register(self
, register_number
, value
):
196 return If(register_number
!= 0,
197 self
.registers
[register_number
].eq(value
)
200 def evaluate_csr_funct3_op(self
, funct3
, previous_value
, written_value
):
201 c
= { "default": Constant(0, 32)}
202 for f
in [F3
.csrrw
, F3
.csrrwi
]: c
[f
] = written_value
203 for f
in [F3
.csrrs
, F3
.csrrsi
]: c
[f
] = written_value | previous_value
204 for f
in [F3
.csrrc
, F3
.csrrci
]: c
[f
] = ~written_value
& previous_value
205 return Case(funct3
, c
)
208 def get_fetch_action(self, fetch_output_state,
209 input `decode_action decode_action,
210 input load_store_misaligned,
211 input memory_interface_rw_address_valid,
212 input memory_interface_rw_wait,
214 input misaligned_jump_target,
215 input csr_op_is_valid
218 case(fetch_output_state)
219 `fetch_output_state_empty:
220 get_fetch_action = `fetch_action_default;
221 `fetch_output_state_trap:
222 get_fetch_action = `fetch_action_ack_trap;
223 `fetch_output_state_valid: begin
224 if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
225 get_fetch_action = `fetch_action_error_trap;
227 else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
228 get_fetch_action = `fetch_action_noerror_trap;
230 else if((decode_action & (`decode_action_load | `decode_action_store)) != 0) begin
231 if(load_store_misaligned | ~memory_interface_rw_address_valid) begin
232 get_fetch_action = `fetch_action_error_trap;
234 else if(memory_interface_rw_wait) begin
235 get_fetch_action = `fetch_action_wait;
238 get_fetch_action = `fetch_action_default;
241 else if((decode_action & `decode_action_fence_i) != 0) begin
242 get_fetch_action = `fetch_action_fence;
244 else if((decode_action & `decode_action_branch) != 0) begin
245 if(branch_taken) begin
246 if(misaligned_jump_target) begin
247 get_fetch_action = `fetch_action_error_trap;
250 get_fetch_action = `fetch_action_jump;
255 get_fetch_action = `fetch_action_default;
258 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
259 if(misaligned_jump_target) begin
260 get_fetch_action = `fetch_action_error_trap;
263 get_fetch_action = `fetch_action_jump;
266 else if((decode_action & `decode_action_csr) != 0) begin
268 get_fetch_action = `fetch_action_default;
270 get_fetch_action = `fetch_action_error_trap;
273 get_fetch_action = `fetch_action_default;
277 get_fetch_action = 32'hXXXXXXXX;
284 self
.clk
= ClockSignal()
285 self
.reset
= ResetSignal()
286 self
.tty_write
= Signal()
287 self
.tty_write_data
= Signal(8)
288 self
.tty_write_busy
= Signal()
289 self
.switch_2
= Signal()
290 self
.switch_3
= Signal()
291 self
.led_1
= Signal()
292 self
.led_3
= Signal()
294 ram_size
= Constant(0x8000)
295 ram_start
= Constant(0x10000, 32)
296 reset_vector
= Signal(32)
299 reset_vector
.eq(ram_start
)
300 mtvec
.eq(ram_start
+ 0x40)
304 r
= Signal(32, name
="register%d" % i
)
306 self
.sync
+= r
.eq(Constant(0, 32))
307 self
.registers
= Array(l
)
309 mi
= MemoryInterface()
311 mii
= Instance("cpu_memory_interface", name
="memory_instance",
312 p_ram_size
= ram_size
,
313 p_ram_start
= ram_start
,
316 i_fetch_address
= mi
.fetch_address
,
317 o_fetch_data
= mi
.fetch_data
,
318 o_fetch_valid
= mi
.fetch_valid
,
319 i_rw_address
= mi
.rw_address
,
320 i_rw_byte_mask
= mi
.rw_byte_mask
,
321 i_rw_read_not_write
= mi
.rw_read_not_write
,
322 i_rw_active
= mi
.rw_active
,
323 i_rw_data_in
= mi
.rw_data_in
,
324 o_rw_data_out
= mi
.rw_data_out
,
325 o_rw_address_valid
= mi
.rw_address_valid
,
326 o_rw_wait
= mi
.rw_wait
,
327 o_tty_write
= self
.tty_write
,
328 o_tty_write_data
= self
.tty_write_data
,
329 i_tty_write_busy
= self
.tty_write_busy
,
330 i_switch_2
= self
.switch_2
,
331 i_switch_3
= self
.switch_3
,
332 o_led_1
= self
.led_1
,
337 fetch_act
= Signal(fetch_action
)
338 fetch_target_pc
= Signal(32)
339 fetch_output_pc
= Signal(32)
340 fetch_output_instruction
= Signal(32)
341 fetch_output_st
= Signal(fetch_output_state
)
343 fs
= Instance("CPUFetchStage", name
="fetch_stage",
346 o_memory_interface_fetch_address
= mi
.fetch_address
,
347 i_memory_interface_fetch_data
= mi
.fetch_data
,
348 i_memory_interface_fetch_valid
= mi
.fetch_valid
,
349 i_fetch_action
= fetch_act
,
350 i_target_pc
= fetch_target_pc
,
351 o_output_pc
= fetch_output_pc
,
352 o_output_instruction
= fetch_output_instruction
,
353 o_output_state
= fetch_output_st
,
354 i_reset_vector
= reset_vector
,
361 cd
= Instance("CPUDecoder", name
="decoder",
362 i_instruction
= fetch_output_instruction
,
363 o_funct7
= dc
.funct7
,
364 o_funct3
= dc
.funct3
,
368 o_immediate
= dc
.immediate
,
369 o_opcode
= dc
.opcode
,
370 o_decode_action
= dc
.act
374 register_rs1
= Signal(32)
375 register_rs2
= Signal(32)
376 self
.comb
+= If(dc
.rs1
== 0,
379 register_rs1
.eq(self
.registers
[dc
.rs1
-1]))
380 self
.comb
+= If(dc
.rs2
== 0,
383 register_rs2
.eq(self
.registers
[dc
.rs2
-1]))
385 load_store_address
= Signal(32)
386 load_store_address_low_2
= Signal(2)
388 self
.comb
+= load_store_address
.eq(dc
.immediate
+ register_rs1
)
389 self
.comb
+= load_store_address_low_2
.eq(
390 dc
.immediate
[:2] + register_rs1
[:2])
392 load_store_misaligned
= Signal()
394 lsa
= self
.get_ls_misaligned(load_store_misaligned
, dc
.funct3
,
395 load_store_address_low_2
)
398 # XXX rwaddr not 31:2 any more
399 self
.comb
+= mi
.rw_address
.eq(load_store_address
[2:])
401 unshifted_load_store_byte_mask
= Signal(4)
403 self
.comb
+= unshifted_load_store_byte_mask
.eq(self
.get_lsbm(dc
))
405 # XXX yuck. this will cause migen simulation to fail
406 # (however conversion to verilog works)
407 self
.comb
+= mi
.rw_byte_mask
.eq(
408 _Operator("<<", [unshifted_load_store_byte_mask
,
409 load_store_address_low_2
]))
412 b3
= Mux(load_store_address_low_2
[1],
413 Mux(load_store_address_low_2
[0], register_rs2
[0:8],
415 Mux(load_store_address_low_2
[0], register_rs2
[16:24],
416 register_rs2
[24:32]))
417 b2
= Mux(load_store_address_low_2
[1], register_rs2
[0:8],
419 b1
= Mux(load_store_address_low_2
[0], register_rs2
[0:8],
421 b0
= register_rs2
[0:8]
423 self
.comb
+= mi
.rw_data_in
.eq(Cat(b0
, b1
, b2
, b3
))
426 unmasked_loaded_value
= Signal(32)
428 b0
= Mux(load_store_address_low_2
[1],
429 Mux(load_store_address_low_2
[0], mi
.rw_data_out
[24:32],
430 mi
.rw_data_out
[16:24]),
431 Mux(load_store_address_low_2
[0], mi
.rw_data_out
[15:8],
432 mi
.rw_data_out
[0:8]))
433 b1
= Mux(load_store_address_low_2
[1], mi
.rw_data_out
[24:31],
434 mi
.rw_data_out
[8:16])
435 b23
= mi
.rw_data_out
[16:32]
437 self
.comb
+= unmasked_loaded_value
.eq(Cat(b0
, b1
, b23
))
440 loaded_value
= Signal(32)
442 b0
= unmasked_loaded_value
[0:8]
443 b1
= Mux(dc
.funct3
[0:2] == 0,
444 Replicate(~dc
.funct3
[2] & unmasked_loaded_value
[7], 8),
445 unmasked_loaded_value
[8:16])
446 b2
= Mux(dc
.funct3
[1] == 0,
447 Replicate(~dc
.funct3
[2] &
448 Mux(dc
.funct3
[0], unmasked_loaded_value
[15],
449 unmasked_loaded_value
[7]),
451 unmasked_loaded_value
[16:32])
453 self
.comb
+= loaded_value
.eq(Cat(b0
, b1
, b2
))
455 self
.comb
+= mi
.rw_active
.eq(~self
.reset
456 & (fetch_output_st
== fetch_output_state_valid
)
457 & ~load_store_misaligned
458 & ((dc
.act
& (DA
.load | DA
.store
)) != 0))
460 self
.comb
+= mi
.rw_read_not_write
.eq(~dc
.opcode
[5])
465 alu_result
= Signal(32)
467 self
.comb
+= alu_a
.eq(register_rs1
)
468 self
.comb
+= alu_b
.eq(Mux(dc
.opcode
[5],
472 ali
= Instance("cpu_alu", name
="alu",
473 i_funct7
= dc
.funct7
,
474 i_funct3
= dc
.funct3
,
475 i_opcode
= dc
.opcode
,
478 o_result
= alu_result
482 lui_auipc_result
= Signal(32)
483 self
.comb
+= lui_auipc_result
.eq(Mux(dc
.opcode
[5],
485 dc
.immediate
+ fetch_output_pc
))
487 self
.comb
+= fetch_target_pc
.eq(Cat(0,
488 Mux(dc
.opcode
!= OP
.jalr
,
489 fetch_output_pc
[1:32],
490 register_rs1
[1:32] + dc
.immediate
[1:32])))
492 misaligned_jump_target
= Signal()
493 self
.comb
+= misaligned_jump_target
.eq(fetch_target_pc
[1])
495 branch_arg_a
= Signal(32)
496 branch_arg_b
= Signal(32)
497 self
.comb
+= branch_arg_a
.eq(Cat( register_rs1
[0:31],
498 register_rs1
[31] ^ ~dc
.funct3
[1]))
499 self
.comb
+= branch_arg_b
.eq(Cat( register_rs2
[0:31],
500 register_rs2
[31] ^ ~dc
.funct3
[1]))
502 branch_taken
= Signal()
503 self
.comb
+= branch_taken
.eq(dc
.funct3
[0] ^
505 branch_arg_a
< branch_arg_b
,
506 branch_arg_a
== branch_arg_b
))
508 m
= M(self
.comb
, self
.sync
)
509 mstatus
= MStatus(self
.comb
, self
.sync
)
510 mie
= MIE(self
.comb
, self
.sync
)
512 misa
= Misa(self
.comb
, self
.sync
)
514 mvendorid
= Signal(32)
518 self
.comb
+= mvendorid
.eq(Constant(0, 32))
519 self
.comb
+= marchid
.eq(Constant(0, 32))
520 self
.comb
+= mimpid
.eq(Constant(0, 32))
521 self
.comb
+= mhartid
.eq(Constant(0, 32))
523 mip
= MIP(self
.comb
, self
.sync
)
525 csr_op_is_valid
= Signal()
527 if __name__
== "__main__":
529 print(verilog
.convert(example
,
532 example
.tty_write_data
,
533 example
.tty_write_busy
,
542 function `fetch_action get_fetch_action(
543 input `fetch_output_state fetch_output_state,
544 input `decode_action decode_action,
545 input load_store_misaligned,
546 input memory_interface_rw_address_valid,
547 input memory_interface_rw_wait,
549 input misaligned_jump_target,
550 input csr_op_is_valid
553 case(fetch_output_state)
554 `fetch_output_state_empty:
555 get_fetch_action = `fetch_action_default;
556 `fetch_output_state_trap:
557 get_fetch_action = `fetch_action_ack_trap;
558 `fetch_output_state_valid: begin
559 if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
560 get_fetch_action = `fetch_action_error_trap;
562 else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
563 get_fetch_action = `fetch_action_noerror_trap;
565 else if((decode_action & (`decode_action_load | `decode_action_store)) != 0) begin
566 if(load_store_misaligned | ~memory_interface_rw_address_valid) begin
567 get_fetch_action = `fetch_action_error_trap;
569 else if(memory_interface_rw_wait) begin
570 get_fetch_action = `fetch_action_wait;
573 get_fetch_action = `fetch_action_default;
576 else if((decode_action & `decode_action_fence_i) != 0) begin
577 get_fetch_action = `fetch_action_fence;
579 else if((decode_action & `decode_action_branch) != 0) begin
580 if(branch_taken) begin
581 if(misaligned_jump_target) begin
582 get_fetch_action = `fetch_action_error_trap;
585 get_fetch_action = `fetch_action_jump;
590 get_fetch_action = `fetch_action_default;
593 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
594 if(misaligned_jump_target) begin
595 get_fetch_action = `fetch_action_error_trap;
598 get_fetch_action = `fetch_action_jump;
601 else if((decode_action & `decode_action_csr) != 0) begin
603 get_fetch_action = `fetch_action_default;
605 get_fetch_action = `fetch_action_error_trap;
608 get_fetch_action = `fetch_action_default;
612 get_fetch_action = 32'hXXXXXXXX;
617 assign fetch_action = get_fetch_action(
620 load_store_misaligned,
621 memory_interface_rw_address_valid,
622 memory_interface_rw_wait,
624 misaligned_jump_target,
630 mstatus_mpie = mstatus_mie;
632 mepc = (fetch_action == `fetch_action_noerror_trap) ? fetch_output_pc + 4 : fetch_output_pc;
633 if(fetch_action == `fetch_action_ack_trap) begin
634 mcause = `cause_instruction_access_fault;
636 else if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
637 mcause = `cause_illegal_instruction;
639 else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
640 mcause = decoder_immediate[0] ? `cause_machine_environment_call : `cause_breakpoint;
642 else if((decode_action & `decode_action_load) != 0) begin
643 if(load_store_misaligned)
644 mcause = `cause_load_address_misaligned;
646 mcause = `cause_load_access_fault;
648 else if((decode_action & `decode_action_store) != 0) begin
649 if(load_store_misaligned)
650 mcause = `cause_store_amo_address_misaligned;
652 mcause = `cause_store_amo_access_fault;
654 else if((decode_action & (`decode_action_branch | `decode_action_jal | `decode_action_jalr)) != 0) begin
655 mcause = `cause_instruction_address_misaligned;
658 mcause = `cause_illegal_instruction;
663 wire [11:0] csr_number = decoder_immediate;
664 wire [31:0] csr_input_value = decoder_funct3[2] ? decoder_rs1 : register_rs1;
665 wire csr_reads = decoder_funct3[1] | (decoder_rd != 0);
666 wire csr_writes = ~decoder_funct3[1] | (decoder_rs1 != 0);
668 function get_csr_op_is_valid(input [11:0] csr_number, input csr_reads, input csr_writes);
699 get_csr_op_is_valid = 0;
710 get_csr_op_is_valid = ~csr_writes;
719 get_csr_op_is_valid = 1;
726 // TODO: CSRs not implemented yet
727 get_csr_op_is_valid = 0;
732 assign csr_op_is_valid = get_csr_op_is_valid(csr_number, csr_reads, csr_writes);
734 wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter
735 wire [63:0] time_counter = 0; // TODO: implement time_counter
736 wire [63:0] instret_counter = 0; // TODO: implement instret_counter
738 always @(posedge clk) begin:main_block
743 case(fetch_output_state)
744 `fetch_output_state_empty: begin
746 `fetch_output_state_trap: begin
749 `fetch_output_state_valid: begin:valid
750 if((fetch_action == `fetch_action_error_trap) | (fetch_action == `fetch_action_noerror_trap)) begin
753 else if((decode_action & `decode_action_load) != 0) begin
754 if(~memory_interface_rw_wait)
755 write_register(decoder_rd, loaded_value);
757 else if((decode_action & `decode_action_op_op_imm) != 0) begin
758 write_register(decoder_rd, alu_result);
760 else if((decode_action & `decode_action_lui_auipc) != 0) begin
761 write_register(decoder_rd, lui_auipc_result);
763 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
764 write_register(decoder_rd, fetch_output_pc + 4);
766 else if((decode_action & `decode_action_csr) != 0) begin:csr
767 reg [31:0] csr_output_value;
768 reg [31:0] csr_written_value;
769 csr_output_value = 32'hXXXXXXXX;
770 csr_written_value = 32'hXXXXXXXX;
773 csr_output_value = cycle_counter[31:0];
776 csr_output_value = time_counter[31:0];
779 csr_output_value = instret_counter[31:0];
782 csr_output_value = cycle_counter[63:32];
785 csr_output_value = time_counter[63:32];
788 csr_output_value = instret_counter[63:32];
790 `csr_mvendorid: begin
791 csr_output_value = mvendorid;
794 csr_output_value = marchid;
797 csr_output_value = mimpid;
800 csr_output_value = mhartid;
803 csr_output_value = misa;
806 csr_output_value = make_mstatus(mstatus_tsr,
822 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
824 mstatus_mpie = csr_written_value[7];
825 mstatus_mie = csr_written_value[3];
829 csr_output_value = 0;
830 csr_output_value[11] = mie_meie;
831 csr_output_value[9] = mie_seie;
832 csr_output_value[8] = mie_ueie;
833 csr_output_value[7] = mie_mtie;
834 csr_output_value[5] = mie_stie;
835 csr_output_value[4] = mie_utie;
836 csr_output_value[3] = mie_msie;
837 csr_output_value[1] = mie_ssie;
838 csr_output_value[0] = mie_usie;
839 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
841 mie_meie = csr_written_value[11];
842 mie_mtie = csr_written_value[7];
843 mie_msie = csr_written_value[3];
847 csr_output_value = mtvec;
850 csr_output_value = mscratch;
851 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
853 mscratch = csr_written_value;
856 csr_output_value = mepc;
857 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
859 mepc = csr_written_value;
862 csr_output_value = mcause;
863 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
865 mcause = csr_written_value;
868 csr_output_value = 0;
869 csr_output_value[11] = mip_meip;
870 csr_output_value[9] = mip_seip;
871 csr_output_value[8] = mip_ueip;
872 csr_output_value[7] = mip_mtip;
873 csr_output_value[5] = mip_stip;
874 csr_output_value[4] = mip_utip;
875 csr_output_value[3] = mip_msip;
876 csr_output_value[1] = mip_ssip;
877 csr_output_value[0] = mip_usip;
881 write_register(decoder_rd, csr_output_value);
883 else if((decode_action & (`decode_action_fence | `decode_action_fence_i | `decode_action_store | `decode_action_branch)) != 0) begin