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
))
172 def __init__(self
, comb
, sync
):
175 self
.action
= Signal(fetch_action
, name
="fetch_action")
176 self
.target_pc
= Signal(32, name
="fetch_target_pc")
177 self
.output_pc
= Signal(32, name
="fetch_output_pc")
178 self
.output_instruction
= Signal(32, name
="fetch_ouutput_instruction")
179 self
.output_state
= Signal(fetch_output_state
,name
="fetch_output_state")
181 def get_fetch_action(self
, dc
, load_store_misaligned
, mi
,
182 branch_taken
, misaligned_jump_target
,
185 c
["default"] = self
.action
.eq(FA
.default
) # XXX should be 32'XXXXXXXX?
186 c
[FOS
.empty
] = self
.action
.eq(FA
.default
)
187 c
[FOS
.trap
] = self
.action
.eq(FA
.ack_trap
)
189 # illegal instruction -> error trap
190 i
= If((dc
.act
& DA
.trap_illegal_instruction
) != 0,
191 self
.action
.eq(FA
.error_trap
)
194 # ecall / ebreak -> noerror trap
195 i
= i
.Elif((dc
.act
& DA
.trap_ecall_ebreak
) != 0,
196 self
.action
.eq(FA
.noerror_trap
))
198 # load/store: check alignment, check wait
199 i
= i
.Elif((dc
.act
& (DA
.load | DA
.store
)) != 0,
200 If((load_store_misaligned | ~mi
.rw_address_valid
),
201 self
.action
.eq(FA
.error_trap
) # misaligned or invalid addr
203 self
.action
.eq(FA
.wait
) # wait
205 self
.action
.eq(FA
.default
) # ok
210 i
= i
.Elif((dc
.act
& DA
.fence
) != 0,
211 self
.action
.eq(FA
.fence
))
213 # branch -> misaligned=error, otherwise jump
214 i
= i
.Elif((dc
.act
& DA
.branch
) != 0,
215 If(misaligned_jump_target
,
216 self
.action
.eq(FA
.error_trap
)
218 self
.action
.eq(FA
.jump
)
222 # jal/jalr -> misaligned=error, otherwise jump
223 i
= i
.Elif((dc
.act
& (DA
.jal | DA
.jalr
)) != 0,
224 If(misaligned_jump_target
,
225 self
.action
.eq(FA
.error_trap
)
227 self
.action
.eq(FA
.jump
)
231 # csr -> opvalid=ok, else error trap
232 i
= i
.Elif((dc
.act
& DA
.csr
) != 0,
234 self
.action
.eq(FA
.default
)
236 self
.action
.eq(FA
.error_trap
)
242 return Case(self
.output_state
, c
)
249 def get_ls_misaligned(self
, ls
, funct3
, load_store_address_low_2
):
250 """ returns whether a load/store is misaligned
252 return Case(funct3
[:2],
253 { F3
.sb
: ls
.eq(Constant(0)),
254 F3
.sh
: ls
.eq(load_store_address_low_2
[0] != 0),
255 F3
.sw
: ls
.eq(load_store_address_low_2
[0:2] != Constant(0, 2)),
256 "default": ls
.eq(Constant(1))
259 def get_lsbm(self
, dc
):
260 return Cat(Constant(1),
261 Mux((dc
.funct3
[1] | dc
.funct3
[0]),
262 Constant(1), Constant(0)),
264 Constant(0b11, 2), Constant(0, 2)))
266 # XXX this happens to get done by various self.sync actions
267 #def reset_to_initial(self, m, mstatus, mie, registers):
268 # return [m.mcause.eq(0),
271 def write_register(self
, register_number
, value
):
272 return If(register_number
!= 0,
273 self
.registers
[register_number
].eq(value
)
276 def evaluate_csr_funct3_op(self
, funct3
, previous_value
, written_value
):
277 c
= { "default": Constant(0, 32)}
278 for f
in [F3
.csrrw
, F3
.csrrwi
]: c
[f
] = written_value
279 for f
in [F3
.csrrs
, F3
.csrrsi
]: c
[f
] = written_value | previous_value
280 for f
in [F3
.csrrc
, F3
.csrrci
]: c
[f
] = ~written_value
& previous_value
281 return Case(funct3
, c
)
283 def handle_trap(self
, m
, ms
, ft
, dc
, load_store_misaligned
):
284 s
= [ms
.mpie
.eq(ms
.mie
),
286 m
.mepc
.eq(Mux(ft
.action
== FA
.noerror_trap
,
290 # fetch action ack trap
291 i
= If(ft
.action
== FA
.ack_trap
,
292 m
.mcause
.eq(cause_instruction_access_fault
)
296 i
= i
.Elif((dc
.act
& DA
.trap_ecall_ebreak
) != 0,
297 m
.mcause
.eq(Mux(dc
.immediate
[0],
298 cause_machine_environment_call
,
303 i
= i
.Elif((dc
.act
& DA
.load
) != 0,
304 If(load_store_misaligned
,
305 m
.mcause
.eq(cause_load_address_misaligned
)
307 m
.mcause
.eq(cause_load_access_fault
)
312 i
= i
.Elif((dc
.act
& DA
.store
) != 0,
313 If(load_store_misaligned
,
314 m
.mcause
.eq(cause_store_amo_address_misaligned
)
316 m
.mcause
.eq(cause_store_amo_access_fault
)
320 # jal/jalr -> misaligned=error, otherwise jump
321 i
= i
.Elif((dc
.act
& (DA
.jal | DA
.jalr | DA
.branch
)) != 0,
322 m
.mcause
.eq(cause_instruction_address_misaligned
)
325 # defaults to illegal instruction
326 i
= i
.Else(m
.mcause
.eq(cause_illegal_instruction
))
331 def get_csr_op_is_valid(self
, csr_op_is_valid
, csr_number
,
332 csr_reads
, csr_writes
):
333 """ determines if a CSR is valid
337 for f
in [csr_ustatus
, csr_fflags
, csr_frm
, csr_fcsr
,
338 csr_uie
, csr_utvec
, csr_uscratch
, csr_uepc
,
339 csr_ucause
, csr_utval
, csr_uip
, csr_sstatus
,
340 csr_sedeleg
, csr_sideleg
, csr_sie
, csr_stvec
,
341 csr_scounteren
, csr_sscratch
, csr_sepc
, csr_scause
,
342 csr_stval
, csr_sip
, csr_satp
, csr_medeleg
,
343 csr_mideleg
, csr_dcsr
, csr_dpc
, csr_dscratch
]:
344 c
[f
] = csr_op_is_valid
.eq(0)
346 # not-writeable -> ok
347 for f
in [csr_cycle
, csr_time
, csr_instret
, csr_cycleh
,
348 csr_timeh
, csr_instreth
, csr_mvendorid
, csr_marchid
,
349 csr_mimpid
, csr_mhartid
]:
350 c
[f
] = csr_op_is_valid
.eq(~csr_writes
)
353 for f
in [csr_misa
, csr_mstatus
, csr_mie
, csr_mtvec
,
354 csr_mscratch
, csr_mepc
, csr_mcause
, csr_mip
]:
355 c
[f
] = csr_op_is_valid
.eq(1)
357 # not implemented / default
358 for f
in [csr_mcounteren
, csr_mtval
, csr_mcycle
, csr_minstret
,
359 csr_mcycleh
, csr_minstreth
, "default"]:
360 c
[f
] = csr_op_is_valid
.eq(0)
362 return Case(csr_number
, c
)
364 def main_block(self
, mi
, m
, mstatus
, ft
, dc
, load_store_misaligned
,
365 loaded_value
, alu_result
,
366 lui_auipc_result
, fetch_output_pc
):
369 c
[FOS
.trap
] = self
.handle_trap(m
, mstatus
, ft
, dc
,
370 load_store_misaligned
)
371 c
[FOS
.valid
] = self
.handle_valid(mi
, m
, mstatus
, ft
, dc
,
372 load_store_misaligned
,
377 return Case(ft
.output_state
, c
)
379 def handle_valid(self
, mi
, m
, mstatus
, ft
, dc
, load_store_misaligned
,
380 loaded_value
, alu_result
,
381 lui_auipc_result
, fetch_output_pc
):
382 # fetch action ack trap
383 i
= If((ft
.action
== FA
.ack_trap
) |
(ft
.action
== FA
.noerror_trap
),
384 self
.handle_trap(m
, mstatus
, ft
, dc
,
385 load_store_misaligned
)
389 i
= i
.Elif((dc
.act
& DA
.load
) != 0,
391 self
.write_register(dc
.rd
, loaded_value
)
396 i
= i
.Elif((dc
.act
& DA
.op_op_imm
) != 0,
397 self
.write_register(dc
.rd
, alu_result
)
401 i
= i
.Elif((dc
.act
& DA
.lui_auipc
) != 0,
402 self
.write_register(dc
.rd
, lui_auipc_result
)
406 i
= i
.Elif((dc
.act
& (DA
.jal | DA
.jalr
)) != 0,
407 self
.write_register(dc
.rd
, fetch_output_pc
+ 4)
410 # fence, store, branch
411 i
= i
.Elif((dc
.act
& (DA
.fence | DA
.fence_i |
412 DA
.store | DA
.branch
)) != 0,
419 else if((decode_action & `decode_action_csr) != 0) begin:csr
420 reg [31:0] csr_output_value;
421 reg [31:0] csr_written_value;
422 csr_output_value = 32'hXXXXXXXX;
423 csr_written_value = 32'hXXXXXXXX;
426 csr_output_value = cycle_counter[31:0];
429 csr_output_value = time_counter[31:0];
432 csr_output_value = instret_counter[31:0];
435 csr_output_value = cycle_counter[63:32];
438 csr_output_value = time_counter[63:32];
441 csr_output_value = instret_counter[63:32];
443 `csr_mvendorid: begin
444 csr_output_value = mvendorid;
447 csr_output_value = marchid;
450 csr_output_value = mimpid;
453 csr_output_value = mhartid;
456 csr_output_value = misa;
459 csr_output_value = make_mstatus(mstatus_tsr,
475 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
477 mstatus_mpie = csr_written_value[7];
478 mstatus_mie = csr_written_value[3];
482 csr_output_value = 0;
483 csr_output_value[11] = mie_meie;
484 csr_output_value[9] = mie_seie;
485 csr_output_value[8] = mie_ueie;
486 csr_output_value[7] = mie_mtie;
487 csr_output_value[5] = mie_stie;
488 csr_output_value[4] = mie_utie;
489 csr_output_value[3] = mie_msie;
490 csr_output_value[1] = mie_ssie;
491 csr_output_value[0] = mie_usie;
492 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
494 mie_meie = csr_written_value[11];
495 mie_mtie = csr_written_value[7];
496 mie_msie = csr_written_value[3];
500 csr_output_value = mtvec;
503 csr_output_value = mscratch;
504 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
506 mscratch = csr_written_value;
509 csr_output_value = mepc;
510 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
512 mepc = csr_written_value;
515 csr_output_value = mcause;
516 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
518 mcause = csr_written_value;
521 csr_output_value = 0;
522 csr_output_value[11] = mip_meip;
523 csr_output_value[9] = mip_seip;
524 csr_output_value[8] = mip_ueip;
525 csr_output_value[7] = mip_mtip;
526 csr_output_value[5] = mip_stip;
527 csr_output_value[4] = mip_utip;
528 csr_output_value[3] = mip_msip;
529 csr_output_value[1] = mip_ssip;
530 csr_output_value[0] = mip_usip;
534 write_register(decoder_rd, csr_output_value);
541 self
.clk
= ClockSignal()
542 self
.reset
= ResetSignal()
543 self
.tty_write
= Signal()
544 self
.tty_write_data
= Signal(8)
545 self
.tty_write_busy
= Signal()
546 self
.switch_2
= Signal()
547 self
.switch_3
= Signal()
548 self
.led_1
= Signal()
549 self
.led_3
= Signal()
551 ram_size
= Constant(0x8000)
552 ram_start
= Constant(0x10000, 32)
553 reset_vector
= Signal(32)
556 reset_vector
.eq(ram_start
)
557 mtvec
.eq(ram_start
+ 0x40)
561 r
= Signal(32, name
="register%d" % i
)
563 self
.sync
+= r
.eq(Constant(0, 32))
564 self
.registers
= Array(l
)
566 mi
= MemoryInterface()
568 mii
= Instance("cpu_memory_interface", name
="memory_instance",
569 p_ram_size
= ram_size
,
570 p_ram_start
= ram_start
,
573 i_fetch_address
= mi
.fetch_address
,
574 o_fetch_data
= mi
.fetch_data
,
575 o_fetch_valid
= mi
.fetch_valid
,
576 i_rw_address
= mi
.rw_address
,
577 i_rw_byte_mask
= mi
.rw_byte_mask
,
578 i_rw_read_not_write
= mi
.rw_read_not_write
,
579 i_rw_active
= mi
.rw_active
,
580 i_rw_data_in
= mi
.rw_data_in
,
581 o_rw_data_out
= mi
.rw_data_out
,
582 o_rw_address_valid
= mi
.rw_address_valid
,
583 o_rw_wait
= mi
.rw_wait
,
584 o_tty_write
= self
.tty_write
,
585 o_tty_write_data
= self
.tty_write_data
,
586 i_tty_write_busy
= self
.tty_write_busy
,
587 i_switch_2
= self
.switch_2
,
588 i_switch_3
= self
.switch_3
,
589 o_led_1
= self
.led_1
,
594 ft
= Fetch(self
.comb
, self
.sync
)
596 fs
= Instance("CPUFetchStage", name
="fetch_stage",
599 o_memory_interface_fetch_address
= mi
.fetch_address
,
600 i_memory_interface_fetch_data
= mi
.fetch_data
,
601 i_memory_interface_fetch_valid
= mi
.fetch_valid
,
602 i_fetch_action
= ft
.action
,
603 i_target_pc
= ft
.target_pc
,
604 o_output_pc
= ft
.output_pc
,
605 o_output_instruction
= ft
.output_instruction
,
606 o_output_state
= ft
.output_state
,
607 i_reset_vector
= reset_vector
,
614 cd
= Instance("CPUDecoder", name
="decoder",
615 i_instruction
= ft
.output_instruction
,
616 o_funct7
= dc
.funct7
,
617 o_funct3
= dc
.funct3
,
621 o_immediate
= dc
.immediate
,
622 o_opcode
= dc
.opcode
,
623 o_decode_action
= dc
.act
627 register_rs1
= Signal(32)
628 register_rs2
= Signal(32)
629 self
.comb
+= If(dc
.rs1
== 0,
632 register_rs1
.eq(self
.registers
[dc
.rs1
-1]))
633 self
.comb
+= If(dc
.rs2
== 0,
636 register_rs2
.eq(self
.registers
[dc
.rs2
-1]))
638 load_store_address
= Signal(32)
639 load_store_address_low_2
= Signal(2)
641 self
.comb
+= load_store_address
.eq(dc
.immediate
+ register_rs1
)
642 self
.comb
+= load_store_address_low_2
.eq(
643 dc
.immediate
[:2] + register_rs1
[:2])
645 load_store_misaligned
= Signal()
647 lsa
= self
.get_ls_misaligned(load_store_misaligned
, dc
.funct3
,
648 load_store_address_low_2
)
651 # XXX rwaddr not 31:2 any more
652 self
.comb
+= mi
.rw_address
.eq(load_store_address
[2:])
654 unshifted_load_store_byte_mask
= Signal(4)
656 self
.comb
+= unshifted_load_store_byte_mask
.eq(self
.get_lsbm(dc
))
658 # XXX yuck. this will cause migen simulation to fail
659 # (however conversion to verilog works)
660 self
.comb
+= mi
.rw_byte_mask
.eq(
661 _Operator("<<", [unshifted_load_store_byte_mask
,
662 load_store_address_low_2
]))
665 b3
= Mux(load_store_address_low_2
[1],
666 Mux(load_store_address_low_2
[0], register_rs2
[0:8],
668 Mux(load_store_address_low_2
[0], register_rs2
[16:24],
669 register_rs2
[24:32]))
670 b2
= Mux(load_store_address_low_2
[1], register_rs2
[0:8],
672 b1
= Mux(load_store_address_low_2
[0], register_rs2
[0:8],
674 b0
= register_rs2
[0:8]
676 self
.comb
+= mi
.rw_data_in
.eq(Cat(b0
, b1
, b2
, b3
))
679 unmasked_loaded_value
= Signal(32)
681 b0
= Mux(load_store_address_low_2
[1],
682 Mux(load_store_address_low_2
[0], mi
.rw_data_out
[24:32],
683 mi
.rw_data_out
[16:24]),
684 Mux(load_store_address_low_2
[0], mi
.rw_data_out
[15:8],
685 mi
.rw_data_out
[0:8]))
686 b1
= Mux(load_store_address_low_2
[1], mi
.rw_data_out
[24:31],
687 mi
.rw_data_out
[8:16])
688 b23
= mi
.rw_data_out
[16:32]
690 self
.comb
+= unmasked_loaded_value
.eq(Cat(b0
, b1
, b23
))
693 loaded_value
= Signal(32)
695 b0
= unmasked_loaded_value
[0:8]
696 b1
= Mux(dc
.funct3
[0:2] == 0,
697 Replicate(~dc
.funct3
[2] & unmasked_loaded_value
[7], 8),
698 unmasked_loaded_value
[8:16])
699 b2
= Mux(dc
.funct3
[1] == 0,
700 Replicate(~dc
.funct3
[2] &
701 Mux(dc
.funct3
[0], unmasked_loaded_value
[15],
702 unmasked_loaded_value
[7]),
704 unmasked_loaded_value
[16:32])
706 self
.comb
+= loaded_value
.eq(Cat(b0
, b1
, b2
))
708 self
.comb
+= mi
.rw_active
.eq(~self
.reset
709 & (ft
.output_state
== FOS
.valid
)
710 & ~load_store_misaligned
711 & ((dc
.act
& (DA
.load | DA
.store
)) != 0))
713 self
.comb
+= mi
.rw_read_not_write
.eq(~dc
.opcode
[5])
718 alu_result
= Signal(32)
720 self
.comb
+= alu_a
.eq(register_rs1
)
721 self
.comb
+= alu_b
.eq(Mux(dc
.opcode
[5],
725 ali
= Instance("cpu_alu", name
="alu",
726 i_funct7
= dc
.funct7
,
727 i_funct3
= dc
.funct3
,
728 i_opcode
= dc
.opcode
,
731 o_result
= alu_result
735 lui_auipc_result
= Signal(32)
736 self
.comb
+= lui_auipc_result
.eq(Mux(dc
.opcode
[5],
738 dc
.immediate
+ ft
.output_pc
))
740 self
.comb
+= ft
.target_pc
.eq(Cat(0,
741 Mux(dc
.opcode
!= OP
.jalr
,
743 register_rs1
[1:32] + dc
.immediate
[1:32])))
745 misaligned_jump_target
= Signal()
746 self
.comb
+= misaligned_jump_target
.eq(ft
.target_pc
[1])
748 branch_arg_a
= Signal(32)
749 branch_arg_b
= Signal(32)
750 self
.comb
+= branch_arg_a
.eq(Cat( register_rs1
[0:31],
751 register_rs1
[31] ^ ~dc
.funct3
[1]))
752 self
.comb
+= branch_arg_b
.eq(Cat( register_rs2
[0:31],
753 register_rs2
[31] ^ ~dc
.funct3
[1]))
755 branch_taken
= Signal()
756 self
.comb
+= branch_taken
.eq(dc
.funct3
[0] ^
758 branch_arg_a
< branch_arg_b
,
759 branch_arg_a
== branch_arg_b
))
761 m
= M(self
.comb
, self
.sync
)
762 mstatus
= MStatus(self
.comb
, self
.sync
)
763 mie
= MIE(self
.comb
, self
.sync
)
765 misa
= Misa(self
.comb
, self
.sync
)
767 mvendorid
= Signal(32)
771 self
.comb
+= mvendorid
.eq(Constant(0, 32))
772 self
.comb
+= marchid
.eq(Constant(0, 32))
773 self
.comb
+= mimpid
.eq(Constant(0, 32))
774 self
.comb
+= mhartid
.eq(Constant(0, 32))
776 mip
= MIP(self
.comb
, self
.sync
)
778 csr_op_is_valid
= Signal()
780 self
.comb
+= ft
.get_fetch_action(dc
, load_store_misaligned
, mi
,
781 branch_taken
, misaligned_jump_target
,
784 #self.comb += self.handle_trap(m, mstatus, ft, dc, load_store_misaligned)
786 csr_number
= Signal(12)
787 csr_input_value
= Signal(32)
789 csr_writes
= Signal()
791 self
.comb
+= csr_number
.eq(dc
.immediate
)
792 self
.comb
+= csr_input_value
.eq(Mux(dc
.funct3
[2],
795 self
.comb
+= csr_reads
.eq(dc
.funct3
[1] |
(dc
.rd
!= 0))
796 self
.comb
+= csr_writes
.eq(~dc
.funct3
[1] |
(dc
.rs1
!= 0))
798 self
.comb
+= self
.get_csr_op_is_valid(csr_op_is_valid
, csr_number
,
799 csr_reads
, csr_writes
)
802 cycle_counter
= Signal(64); # TODO: implement cycle_counter
803 time_counter
= Signal(64); # TODO: implement time_counter
804 instret_counter
= Signal(64); # TODO: implement instret_counter
806 self
.sync
+= If(~self
.reset
,
807 self
.main_block(mi
, m
, mstatus
, ft
, dc
,
808 load_store_misaligned
,
815 if __name__
== "__main__":
817 print(verilog
.convert(example
,
820 example
.tty_write_data
,
821 example
.tty_write_busy
,
830 always @(posedge clk) begin:main_block
835 case(fetch_output_state)
836 `fetch_output_state_empty: begin
838 `fetch_output_state_trap: begin
841 `fetch_output_state_valid: begin:valid
842 if((fetch_action == `fetch_action_error_trap) | (fetch_action == `fetch_action_noerror_trap)) begin
845 else if((decode_action & `decode_action_load) != 0) begin
846 if(~memory_interface_rw_wait)
847 write_register(decoder_rd, loaded_value);
849 else if((decode_action & `decode_action_op_op_imm) != 0) begin
850 write_register(decoder_rd, alu_result);
852 else if((decode_action & `decode_action_lui_auipc) != 0) begin
853 write_register(decoder_rd, lui_auipc_result);
855 else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
856 write_register(decoder_rd, fetch_output_pc + 4);
858 else if((decode_action & `decode_action_csr) != 0) begin:csr
859 reg [31:0] csr_output_value;
860 reg [31:0] csr_written_value;
861 csr_output_value = 32'hXXXXXXXX;
862 csr_written_value = 32'hXXXXXXXX;
865 csr_output_value = cycle_counter[31:0];
868 csr_output_value = time_counter[31:0];
871 csr_output_value = instret_counter[31:0];
874 csr_output_value = cycle_counter[63:32];
877 csr_output_value = time_counter[63:32];
880 csr_output_value = instret_counter[63:32];
882 `csr_mvendorid: begin
883 csr_output_value = mvendorid;
886 csr_output_value = marchid;
889 csr_output_value = mimpid;
892 csr_output_value = mhartid;
895 csr_output_value = misa;
898 csr_output_value = make_mstatus(mstatus_tsr,
914 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
916 mstatus_mpie = csr_written_value[7];
917 mstatus_mie = csr_written_value[3];
921 csr_output_value = 0;
922 csr_output_value[11] = mie_meie;
923 csr_output_value[9] = mie_seie;
924 csr_output_value[8] = mie_ueie;
925 csr_output_value[7] = mie_mtie;
926 csr_output_value[5] = mie_stie;
927 csr_output_value[4] = mie_utie;
928 csr_output_value[3] = mie_msie;
929 csr_output_value[1] = mie_ssie;
930 csr_output_value[0] = mie_usie;
931 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
933 mie_meie = csr_written_value[11];
934 mie_mtie = csr_written_value[7];
935 mie_msie = csr_written_value[3];
939 csr_output_value = mtvec;
942 csr_output_value = mscratch;
943 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
945 mscratch = csr_written_value;
948 csr_output_value = mepc;
949 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
951 mepc = csr_written_value;
954 csr_output_value = mcause;
955 csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
957 mcause = csr_written_value;
960 csr_output_value = 0;
961 csr_output_value[11] = mip_meip;
962 csr_output_value[9] = mip_seip;
963 csr_output_value[8] = mip_ueip;
964 csr_output_value[7] = mip_mtip;
965 csr_output_value[5] = mip_stip;
966 csr_output_value[4] = mip_utip;
967 csr_output_value[3] = mip_msip;
968 csr_output_value[1] = mip_ssip;
969 csr_output_value[0] = mip_usip;
973 write_register(decoder_rd, csr_output_value);
975 else if((decode_action & (`decode_action_fence | `decode_action_fence_i | `decode_action_store | `decode_action_branch)) != 0) begin