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
.seie
= Signal(name
="mie_seie")
111 self
.ueie
= Signal(name
="mie_ueie")
112 self
.stie
= Signal(name
="mie_stie")
113 self
.utie
= Signal(name
="mie_utie")
114 self
.ssie
= Signal(name
="mie_ssie")
115 self
.usie
= Signal(name
="mie_usie")
118 if n
in ['make', 'comb', 'sync'] or n
.startswith("_"):
120 self
.comb
+= getattr(self
, n
).eq(0x0)
122 self
.sync
+= self
.meie
.eq(0)
123 self
.sync
+= self
.mtie
.eq(0)
124 self
.sync
+= self
.msie
.eq(0)
127 return Cat( self
.usie
, self
.ssie
, 0, self
.msie
,
128 self
.utie
, self
.stie
, 0, self
.mtie
,
129 self
.ueie
, self
.seie
, 0, self
.meie
, )
133 def __init__(self
, comb
, sync
):
136 self
.meip
= Signal(name
="mip_meip") # TODO: implement ext interrupts
137 self
.seip
= Signal(name
="mip_seip")
138 self
.ueip
= Signal(name
="mip_uiep")
139 self
.mtip
= Signal(name
="mip_mtip") # TODO: implement timer interrupts
140 self
.stip
= Signal(name
="mip_stip")
141 self
.msip
= Signal(name
="mip_stip")
142 self
.utip
= Signal(name
="mip_utip")
143 self
.ssip
= Signal(name
="mip_ssip")
144 self
.usip
= Signal(name
="mip_usip")
147 if n
in ['make', 'comb', 'sync'] or n
.startswith("_"):
149 self
.comb
+= getattr(self
, n
).eq(0x0)
152 return Cat( self
.usip
, self
.ssip
, 0, self
.msip
,
153 self
.utip
, self
.stip
, 0, self
.mtip
,
154 self
.ueip
, self
.seip
, 0, self
.meip
, )
158 def __init__(self
, comb
, sync
):
161 self
.mcause
= Signal(32)
162 self
.mepc
= Signal(32)
163 self
.mscratch
= Signal(32)
164 self
.sync
+= self
.mcause
.eq(0)
165 self
.sync
+= self
.mepc
.eq(0) # 32'hXXXXXXXX;
166 self
.sync
+= self
.mscratch
.eq(0) # 32'hXXXXXXXX;
170 def __init__(self
, comb
, sync
):
173 self
.misa
= Signal(32)
175 for l
in list(string
.ascii_lowercase
):
176 value
= 1 if l
== 'i' else 0
177 cl
.append(Constant(value
))
178 cl
.append(Constant(0, 4))
179 cl
.append(Constant(0b01, 2))
180 self
.comb
+= self
.misa
.eq(Cat(cl
))
184 def __init__(self
, comb
, sync
):
187 self
.action
= Signal(fetch_action
, name
="fetch_action")
188 self
.target_pc
= Signal(32, name
="fetch_target_pc")
189 self
.output_pc
= Signal(32, name
="fetch_output_pc")
190 self
.output_instruction
= Signal(32, name
="fetch_ouutput_instruction")
191 self
.output_state
= Signal(fetch_output_state
,name
="fetch_output_state")
194 def __init__(self
, comb
, sync
, dc
, register_rs1
):
197 self
.number
= Signal(12, name
="csr_number")
198 self
.input_value
= Signal(32, name
="csr_input_value")
199 self
.reads
= Signal(name
="csr_reads")
200 self
.writes
= Signal(name
="csr_writes")
201 self
.op_is_valid
= Signal(name
="csr_op_is_valid")
203 self
.comb
+= self
.number
.eq(dc
.immediate
)
204 self
.comb
+= self
.input_value
.eq(Mux(dc
.funct3
[2],
207 self
.comb
+= self
.reads
.eq(dc
.funct3
[1] |
(dc
.rd
!= 0))
208 self
.comb
+= self
.writes
.eq(~dc
.funct3
[1] |
(dc
.rs1
!= 0))
210 self
.comb
+= self
.get_csr_op_is_valid()
212 def get_csr_op_is_valid(self
):
213 """ determines if a CSR is valid
217 for f
in [csr_ustatus
, csr_fflags
, csr_frm
, csr_fcsr
,
218 csr_uie
, csr_utvec
, csr_uscratch
, csr_uepc
,
219 csr_ucause
, csr_utval
, csr_uip
, csr_sstatus
,
220 csr_sedeleg
, csr_sideleg
, csr_sie
, csr_stvec
,
221 csr_scounteren
, csr_sscratch
, csr_sepc
, csr_scause
,
222 csr_stval
, csr_sip
, csr_satp
, csr_medeleg
,
223 csr_mideleg
, csr_dcsr
, csr_dpc
, csr_dscratch
]:
224 c
[f
] = self
.op_is_valid
.eq(0)
226 # not-writeable -> ok
227 for f
in [csr_cycle
, csr_time
, csr_instret
, csr_cycleh
,
228 csr_timeh
, csr_instreth
, csr_mvendorid
, csr_marchid
,
229 csr_mimpid
, csr_mhartid
]:
230 c
[f
] = self
.op_is_valid
.eq(~self
.writes
)
233 for f
in [csr_misa
, csr_mstatus
, csr_mie
, csr_mtvec
,
234 csr_mscratch
, csr_mepc
, csr_mcause
, csr_mip
]:
235 c
[f
] = self
.op_is_valid
.eq(1)
237 # not implemented / default
238 for f
in [csr_mcounteren
, csr_mtval
, csr_mcycle
, csr_minstret
,
239 csr_mcycleh
, csr_minstreth
, "default"]:
240 c
[f
] = self
.op_is_valid
.eq(0)
242 return Case(self
.number
, c
)
244 def evaluate_csr_funct3_op(self
, funct3
, previous
, written
):
245 c
= { "default": written
.eq(Constant(0, 32))}
246 for f
in [F3
.csrrw
, F3
.csrrwi
]:
247 c
[f
] = written
.eq(self
.input_value
)
248 for f
in [F3
.csrrs
, F3
.csrrsi
]:
249 c
[f
] = written
.eq(self
.input_value | previous
)
250 for f
in [F3
.csrrc
, F3
.csrrci
]:
251 c
[f
] = written
.eq(~self
.input_value
& previous
)
252 return Case(funct3
, c
)
256 def __init__(self
, comb
):
259 self
.cycle_counter
= Signal(64); # TODO: implement cycle_counter
260 self
.time_counter
= Signal(64); # TODO: implement time_counter
261 self
.instret_counter
= Signal(64); # TODO: implement instret_counter
263 self
.mvendorid
= Signal(32)
264 self
.marchid
= Signal(32)
265 self
.mimpid
= Signal(32)
266 self
.mhartid
= Signal(32)
267 self
.comb
+= self
.mvendorid
.eq(Constant(0, 32))
268 self
.comb
+= self
.marchid
.eq(Constant(0, 32))
269 self
.comb
+= self
.mimpid
.eq(Constant(0, 32))
270 self
.comb
+= self
.mhartid
.eq(Constant(0, 32))
273 def __init__(self
, comb
, sync
):
277 self
.ra_en
= Signal(reset
=1, name
="regfile_ra_en") # TODO: ondemand en
278 self
.rs1
= Signal(32, name
="regfile_rs1")
279 self
.rs_a
= Signal(5, name
="regfile_rs_a")
281 self
.rb_en
= Signal(reset
=1, name
="regfile_rb_en") # TODO: ondemand en
282 self
.rs2
= Signal(32, name
="regfile_rs2")
283 self
.rs_b
= Signal(5, name
="regfile_rs_b")
285 self
.w_en
= Signal(name
="regfile_w_en")
286 self
.wval
= Signal(32, name
="regfile_wval")
287 self
.rd
= Signal(32, name
="regfile_rd")
293 def get_lsbm(self
, dc
):
294 return Cat(Constant(1),
295 Mux((dc
.funct3
[1] | dc
.funct3
[0]),
296 Constant(1), Constant(0)),
298 Constant(0b11, 2), Constant(0, 2)))
300 # XXX this happens to get done by various self.sync actions
301 #def reset_to_initial(self, m, mstatus, mie, registers):
302 # return [m.mcause.eq(0),
305 def handle_trap(self
, m
, ms
, ft
, dc
, load_store_misaligned
):
306 s
= [ms
.mpie
.eq(ms
.mie
),
308 m
.mepc
.eq(Mux(ft
.action
== FA
.noerror_trap
,
312 # fetch action ack trap
313 i
= If(ft
.action
== FA
.ack_trap
,
314 m
.mcause
.eq(cause_instruction_access_fault
)
318 i
= i
.Elif((dc
.act
& DA
.trap_ecall_ebreak
) != 0,
319 m
.mcause
.eq(Mux(dc
.immediate
[0],
320 cause_machine_environment_call
,
325 i
= i
.Elif((dc
.act
& DA
.load
) != 0,
326 If(load_store_misaligned
,
327 m
.mcause
.eq(cause_load_address_misaligned
)
329 m
.mcause
.eq(cause_load_access_fault
)
334 i
= i
.Elif((dc
.act
& DA
.store
) != 0,
335 If(load_store_misaligned
,
336 m
.mcause
.eq(cause_store_amo_address_misaligned
)
338 m
.mcause
.eq(cause_store_amo_access_fault
)
342 # jal/jalr -> misaligned=error, otherwise jump
343 i
= i
.Elif((dc
.act
& (DA
.jal | DA
.jalr | DA
.branch
)) != 0,
344 m
.mcause
.eq(cause_instruction_address_misaligned
)
347 # defaults to illegal instruction
348 i
= i
.Else(m
.mcause
.eq(cause_illegal_instruction
))
353 def main_block(self
, mtvec
, mip
, minfo
, misa
, csr
, mi
, m
, mstatus
, mie
,
355 load_store_misaligned
,
356 loaded_value
, alu_result
,
360 c
[FOS
.trap
] = self
.handle_trap(m
, mstatus
, ft
, dc
,
361 load_store_misaligned
)
362 c
[FOS
.valid
] = self
.handle_valid(mtvec
, mip
, minfo
, misa
, csr
, mi
, m
,
363 mstatus
, mie
, ft
, dc
,
364 load_store_misaligned
,
368 return Case(ft
.output_state
, c
)
370 def write_register(self
, rd
, val
):
371 return [self
.regs
.rd
.eq(rd
),
372 self
.regs
.wval
.eq(val
),
376 def handle_valid(self
, mtvec
, mip
, minfo
, misa
, csr
, mi
, m
, mstatus
, mie
,
378 load_store_misaligned
,
379 loaded_value
, alu_result
,
381 # fetch action ack trap
382 i
= If((ft
.action
== FA
.ack_trap
) |
(ft
.action
== FA
.noerror_trap
),
383 [self
.handle_trap(m
, mstatus
, ft
, dc
,
384 load_store_misaligned
),
385 self
.regs
.w_en
.eq(0) # no writing to registers
390 i
= i
.Elif((dc
.act
& DA
.load
) != 0,
392 self
.write_register(dc
.rd
, loaded_value
)
397 i
= i
.Elif((dc
.act
& DA
.op_op_imm
) != 0,
398 self
.write_register(dc
.rd
, alu_result
)
402 i
= i
.Elif((dc
.act
& DA
.lui_auipc
) != 0,
403 self
.write_register(dc
.rd
, lui_auipc_result
)
407 i
= i
.Elif((dc
.act
& (DA
.jal | DA
.jalr
)) != 0,
408 self
.write_register(dc
.rd
, ft
.output_pc
+ 4)
411 i
= i
.Elif((dc
.act
& DA
.csr
) != 0,
412 self
.handle_csr(mtvec
, mip
, minfo
, misa
, mstatus
, mie
, m
,
416 # fence, store, branch
417 i
= i
.Elif((dc
.act
& (DA
.fence | DA
.fence_i |
418 DA
.store | DA
.branch
)) != 0,
420 self
.regs
.w_en
.eq(0) # no writing to registers
425 def handle_csr(self
, mtvec
, mip
, minfo
, misa
, mstatus
, mie
, m
, dc
, csr
):
426 csr_output_value
= Signal(32)
427 csr_written_value
= Signal(32)
431 c
[csr_cycle
] = csr_output_value
.eq(minfo
.cycle_counter
[0:32])
432 c
[csr_cycleh
] = csr_output_value
.eq(minfo
.cycle_counter
[32:64])
434 c
[csr_time
] = csr_output_value
.eq(minfo
.time_counter
[0:32])
435 c
[csr_timeh
] = csr_output_value
.eq(minfo
.time_counter
[32:64])
437 c
[csr_instret
] = csr_output_value
.eq(minfo
.instret_counter
[0:32])
438 c
[csr_instreth
] = csr_output_value
.eq(minfo
.instret_counter
[32:64])
439 # mvendorid/march/mimpl/mhart
440 c
[csr_mvendorid
] = csr_output_value
.eq(minfo
.mvendorid
)
441 c
[csr_marchid
] = csr_output_value
.eq(minfo
.marchid
)
442 c
[csr_mimpid
] = csr_output_value
.eq(minfo
.mimpid
)
443 c
[csr_mhartid
] = csr_output_value
.eq(minfo
.mhartid
)
445 c
[csr_misa
] = csr_output_value
.eq(misa
.misa
)
448 csr_output_value
.eq(mstatus
.make()),
449 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
451 mstatus
.mpie
.eq(csr_written_value
[7]),
452 mstatus
.mie
.eq(csr_written_value
[3])
456 csr_output_value
.eq(mie
.make()),
457 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
459 mie
.meie
.eq(csr_written_value
[11]),
460 mie
.mtie
.eq(csr_written_value
[7]),
461 mie
.msie
.eq(csr_written_value
[3]),
464 c
[csr_mtvec
] = csr_output_value
.eq(mtvec
)
467 csr_output_value
.eq(m
.mscratch
),
468 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
471 m
.mscratch
.eq(csr_written_value
),
476 csr_output_value
.eq(m
.mepc
),
477 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
480 m
.mepc
.eq(csr_written_value
),
486 csr_output_value
.eq(m
.mcause
),
487 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
490 m
.mcause
.eq(csr_written_value
),
496 csr_output_value
.eq(mip
.make()),
497 csr
.evaluate_csr_funct3_op(dc
.funct3
, csr_output_value
,
501 return [Case(csr
.number
, c
),
503 self
.write_register(dc
.rd
, csr_output_value
)
507 Module
.__init
__(self
)
508 self
.clk
= ClockSignal()
509 self
.reset
= ResetSignal()
510 self
.tty_write
= Signal()
511 self
.tty_write_data
= Signal(8)
512 self
.tty_write_busy
= Signal()
513 self
.switch_2
= Signal()
514 self
.switch_3
= Signal()
515 self
.led_1
= Signal()
516 self
.led_3
= Signal()
518 ram_size
= Constant(0x8000)
519 ram_start
= Constant(0x10000, 32)
520 reset_vector
= Signal(32)
523 reset_vector
.eq(ram_start
)
524 mtvec
.eq(ram_start
+ 0x40)
526 self
.regs
= Regs(self
.comb
, self
.sync
)
528 rf
= Instance("RegFile", name
="regfile",
529 i_ra_en
= self
.regs
.ra_en
,
530 i_rb_en
= self
.regs
.rb_en
,
531 i_w_en
= self
.regs
.w_en
,
532 o_read_a
= self
.regs
.rs1
,
533 o_read_b
= self
.regs
.rs2
,
534 i_writeval
= self
.regs
.wval
,
535 i_rs_a
= self
.regs
.rs_a
,
536 i_rs_b
= self
.regs
.rs_b
,
541 mi
= MemoryInterface()
543 mii
= Instance("cpu_memory_interface", name
="memory_instance",
544 p_ram_size
= ram_size
,
545 p_ram_start
= ram_start
,
548 i_fetch_address
= mi
.fetch_address
,
549 o_fetch_data
= mi
.fetch_data
,
550 o_fetch_valid
= mi
.fetch_valid
,
551 i_rw_address
= mi
.rw_address
,
552 i_rw_byte_mask
= mi
.rw_byte_mask
,
553 i_rw_read_not_write
= mi
.rw_read_not_write
,
554 i_rw_active
= mi
.rw_active
,
555 i_rw_data_in
= mi
.rw_data_in
,
556 o_rw_data_out
= mi
.rw_data_out
,
557 o_rw_address_valid
= mi
.rw_address_valid
,
558 o_rw_wait
= mi
.rw_wait
,
559 o_tty_write
= self
.tty_write
,
560 o_tty_write_data
= self
.tty_write_data
,
561 i_tty_write_busy
= self
.tty_write_busy
,
562 i_switch_2
= self
.switch_2
,
563 i_switch_3
= self
.switch_3
,
564 o_led_1
= self
.led_1
,
569 ft
= Fetch(self
.comb
, self
.sync
)
571 fs
= Instance("CPUFetchStage", name
="fetch_stage",
574 o_memory_interface_fetch_address
= mi
.fetch_address
,
575 i_memory_interface_fetch_data
= mi
.fetch_data
,
576 i_memory_interface_fetch_valid
= mi
.fetch_valid
,
577 i_fetch_action
= ft
.action
,
578 i_target_pc
= ft
.target_pc
,
579 o_output_pc
= ft
.output_pc
,
580 o_output_instruction
= ft
.output_instruction
,
581 o_output_state
= ft
.output_state
,
582 i_reset_vector
= reset_vector
,
589 cd
= Instance("CPUDecoder", name
="decoder",
590 i_instruction
= ft
.output_instruction
,
591 o_funct7
= dc
.funct7
,
592 o_funct3
= dc
.funct3
,
596 o_immediate
= dc
.immediate
,
597 o_opcode
= dc
.opcode
,
598 o_decode_action
= dc
.act
602 self
.comb
+= self
.regs
.rs_a
.eq(dc
.rs1
)
603 self
.comb
+= self
.regs
.rs_b
.eq(dc
.rs2
)
605 load_store_address
= Signal(32)
606 load_store_address_low_2
= Signal(2)
607 load_store_misaligned
= Signal()
608 unmasked_loaded_value
= Signal(32)
609 loaded_value
= Signal(32)
611 lsc
= Instance("CPULoadStoreCalc", name
="cpu_loadstore_calc",
612 i_dc_immediate
= dc
.immediate
,
613 i_dc_funct3
= dc
.funct3
,
614 i_rs1
= self
.regs
.rs1
,
615 i_rs2
= self
.regs
.rs2
,
616 i_rw_data_in
= mi
.rw_data_in
,
617 i_rw_data_out
= mi
.rw_data_out
,
618 o_load_store_address
= load_store_address
,
619 o_load_store_address_low_2
= load_store_address_low_2
,
620 o_load_store_misaligned
= load_store_misaligned
,
621 o_loaded_value
= loaded_value
)
625 # XXX rwaddr not 31:2 any more
626 self
.comb
+= mi
.rw_address
.eq(load_store_address
[2:])
628 unshifted_load_store_byte_mask
= Signal(4)
630 self
.comb
+= unshifted_load_store_byte_mask
.eq(self
.get_lsbm(dc
))
632 # XXX yuck. this will cause migen simulation to fail
633 # (however conversion to verilog works)
634 self
.comb
+= mi
.rw_byte_mask
.eq(
635 _Operator("<<", [unshifted_load_store_byte_mask
,
636 load_store_address_low_2
]))
638 self
.comb
+= mi
.rw_active
.eq(~self
.reset
639 & (ft
.output_state
== FOS
.valid
)
640 & ~load_store_misaligned
641 & ((dc
.act
& (DA
.load | DA
.store
)) != 0))
643 self
.comb
+= mi
.rw_read_not_write
.eq(~dc
.opcode
[5])
648 alu_result
= Signal(32)
650 self
.comb
+= alu_a
.eq(self
.regs
.rs1
)
651 self
.comb
+= alu_b
.eq(Mux(dc
.opcode
[5],
655 ali
= Instance("cpu_alu", name
="alu",
656 i_funct7
= dc
.funct7
,
657 i_funct3
= dc
.funct3
,
658 i_opcode
= dc
.opcode
,
661 o_result
= alu_result
665 lui_auipc_result
= Signal(32)
666 self
.comb
+= lui_auipc_result
.eq(Mux(dc
.opcode
[5],
668 dc
.immediate
+ ft
.output_pc
))
670 self
.comb
+= ft
.target_pc
.eq(Cat(0,
671 Mux(dc
.opcode
!= OP
.jalr
,
673 self
.regs
.rs1
[1:32] + dc
.immediate
[1:32])))
675 misaligned_jump_target
= Signal()
676 self
.comb
+= misaligned_jump_target
.eq(ft
.target_pc
[1])
678 branch_arg_a
= Signal(32)
679 branch_arg_b
= Signal(32)
680 self
.comb
+= branch_arg_a
.eq(Cat( self
.regs
.rs1
[0:31],
681 self
.regs
.rs1
[31] ^ ~dc
.funct3
[1]))
682 self
.comb
+= branch_arg_b
.eq(Cat( self
.regs
.rs2
[0:31],
683 self
.regs
.rs2
[31] ^ ~dc
.funct3
[1]))
685 branch_taken
= Signal()
686 self
.comb
+= branch_taken
.eq(dc
.funct3
[0] ^
688 branch_arg_a
< branch_arg_b
,
689 branch_arg_a
== branch_arg_b
))
691 m
= M(self
.comb
, self
.sync
)
692 mstatus
= MStatus(self
.comb
, self
.sync
)
693 mie
= MIE(self
.comb
, self
.sync
)
694 misa
= Misa(self
.comb
, self
.sync
)
695 mip
= MIP(self
.comb
, self
.sync
)
698 csr
= CSR(self
.comb
, self
.sync
, dc
, self
.regs
.rs1
)
700 fi
= Instance("CPUFetchAction", name
="cpu_fetch_action",
701 o_fetch_action
= ft
.action
,
702 i_output_state
= ft
.output_state
,
704 i_load_store_misaligned
= load_store_misaligned
,
705 i_mi_rw_wait
= mi
.rw_wait
,
706 i_mi_rw_address_valid
= mi
.rw_address_valid
,
707 i_branch_taken
= branch_taken
,
708 i_misaligned_jump_target
= misaligned_jump_target
,
709 i_csr_op_is_valid
= csr
.op_is_valid
)
713 minfo
= MInfo(self
.comb
)
715 self
.sync
+= If(~self
.reset
,
716 self
.main_block(mtvec
, mip
, minfo
, misa
, csr
, mi
, m
,
717 mstatus
, mie
, ft
, dc
,
718 load_store_misaligned
,
724 if __name__
== "__main__":
726 print(verilog
.convert(example
,
729 example
.tty_write_data
,
730 example
.tty_write_busy
,