return Case(self.output_state, c)
+class CSR:
+ def __init__(self, comb, sync, dc, register_rs1):
+ self.comb = comb
+ self.sync = sync
+ self.number = Signal(12, name="csr_number")
+ self.input_value = Signal(32, name="csr_input_value")
+ self.reads = Signal(name="csr_reads")
+ self.writes = Signal(name="csr_writes")
+ self.op_is_valid = Signal(name="csr_op_is_valid")
+
+ self.comb += self.number.eq(dc.immediate)
+ self.comb += self.input_value.eq(Mux(dc.funct3[2],
+ dc.rs1,
+ register_rs1))
+ self.comb += self.reads.eq(dc.funct3[1] | (dc.rd != 0))
+ self.comb += self.writes.eq(~dc.funct3[1] | (dc.rs1 != 0))
+
+ self.comb += self.get_csr_op_is_valid()
+
+ def get_csr_op_is_valid(self):
+ """ determines if a CSR is valid
+ """
+ c = {}
+ # invalid csrs
+ for f in [csr_ustatus, csr_fflags, csr_frm, csr_fcsr,
+ csr_uie, csr_utvec, csr_uscratch, csr_uepc,
+ csr_ucause, csr_utval, csr_uip, csr_sstatus,
+ csr_sedeleg, csr_sideleg, csr_sie, csr_stvec,
+ csr_scounteren, csr_sscratch, csr_sepc, csr_scause,
+ csr_stval, csr_sip, csr_satp, csr_medeleg,
+ csr_mideleg, csr_dcsr, csr_dpc, csr_dscratch]:
+ c[f] = self.op_is_valid.eq(0)
+
+ # not-writeable -> ok
+ for f in [csr_cycle, csr_time, csr_instret, csr_cycleh,
+ csr_timeh, csr_instreth, csr_mvendorid, csr_marchid,
+ csr_mimpid, csr_mhartid]:
+ c[f] = self.op_is_valid.eq(~self.writes)
+
+ # valid csrs
+ for f in [csr_misa, csr_mstatus, csr_mie, csr_mtvec,
+ csr_mscratch, csr_mepc, csr_mcause, csr_mip]:
+ c[f] = self.op_is_valid.eq(1)
+
+ # not implemented / default
+ for f in [csr_mcounteren, csr_mtval, csr_mcycle, csr_minstret,
+ csr_mcycleh, csr_minstreth, "default"]:
+ c[f] = self.op_is_valid.eq(0)
+
+ return Case(self.number, c)
+
class CPU(Module):
"""
s.append(i)
return s
- def get_csr_op_is_valid(self, csr_op_is_valid, csr_number,
- csr_reads, csr_writes):
- """ determines if a CSR is valid
- """
- c = {}
- # invalid csrs
- for f in [csr_ustatus, csr_fflags, csr_frm, csr_fcsr,
- csr_uie, csr_utvec, csr_uscratch, csr_uepc,
- csr_ucause, csr_utval, csr_uip, csr_sstatus,
- csr_sedeleg, csr_sideleg, csr_sie, csr_stvec,
- csr_scounteren, csr_sscratch, csr_sepc, csr_scause,
- csr_stval, csr_sip, csr_satp, csr_medeleg,
- csr_mideleg, csr_dcsr, csr_dpc, csr_dscratch]:
- c[f] = csr_op_is_valid.eq(0)
-
- # not-writeable -> ok
- for f in [csr_cycle, csr_time, csr_instret, csr_cycleh,
- csr_timeh, csr_instreth, csr_mvendorid, csr_marchid,
- csr_mimpid, csr_mhartid]:
- c[f] = csr_op_is_valid.eq(~csr_writes)
-
- # valid csrs
- for f in [csr_misa, csr_mstatus, csr_mie, csr_mtvec,
- csr_mscratch, csr_mepc, csr_mcause, csr_mip]:
- c[f] = csr_op_is_valid.eq(1)
-
- # not implemented / default
- for f in [csr_mcounteren, csr_mtval, csr_mcycle, csr_minstret,
- csr_mcycleh, csr_minstreth, "default"]:
- c[f] = csr_op_is_valid.eq(0)
-
- return Case(csr_number, c)
-
- def main_block(self, mi, m, mstatus, ft, dc, load_store_misaligned,
+ def main_block(self, csr, mi, m, mstatus, ft, dc, load_store_misaligned,
loaded_value, alu_result,
- lui_auipc_result, fetch_output_pc):
+ lui_auipc_result):
c = {}
c[FOS.empty] = []
c[FOS.trap] = self.handle_trap(m, mstatus, ft, dc,
load_store_misaligned)
- c[FOS.valid] = self.handle_valid(mi, m, mstatus, ft, dc,
+ c[FOS.valid] = self.handle_valid(csr, mi, m, mstatus, ft, dc,
load_store_misaligned,
loaded_value,
alu_result,
- lui_auipc_result,
- fetch_output_pc)
+ lui_auipc_result)
return Case(ft.output_state, c)
- def handle_valid(self, mi, m, mstatus, ft, dc, load_store_misaligned,
+ def handle_valid(self, csr, mi, m, mstatus, ft, dc, load_store_misaligned,
loaded_value, alu_result,
- lui_auipc_result, fetch_output_pc):
+ lui_auipc_result):
# fetch action ack trap
i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap),
self.handle_trap(m, mstatus, ft, dc,
# jal/jalr
i = i.Elif((dc.act & (DA.jal | DA.jalr)) != 0,
- self.write_register(dc.rd, fetch_output_pc + 4)
+ self.write_register(dc.rd, ft.output_pc + 4)
+ )
+
+ i = i.Elif((dc.act & DA.csr) != 0,
+ self.handle_csr(dc, csr)
)
# fence, store, branch
return i
+ def handle_csr(self, dc, csr):
+ return []
+
"""
else if((decode_action & `decode_action_csr) != 0) begin:csr
reg [31:0] csr_output_value;
mip = MIP(self.comb, self.sync)
- csr_op_is_valid = Signal()
+ # CSR decoding
+ csr = CSR(self.comb, self.sync, dc, register_rs1)
self.comb += ft.get_fetch_action(dc, load_store_misaligned, mi,
branch_taken, misaligned_jump_target,
- csr_op_is_valid)
-
- #self.comb += self.handle_trap(m, mstatus, ft, dc, load_store_misaligned)
- # CSR decoding
- csr_number = Signal(12)
- csr_input_value = Signal(32)
- csr_reads = Signal()
- csr_writes = Signal()
-
- self.comb += csr_number.eq(dc.immediate)
- self.comb += csr_input_value.eq(Mux(dc.funct3[2],
- dc.rs1,
- register_rs1))
- self.comb += csr_reads.eq(dc.funct3[1] | (dc.rd != 0))
- self.comb += csr_writes.eq(~dc.funct3[1] | (dc.rs1 != 0))
-
- self.comb += self.get_csr_op_is_valid(csr_op_is_valid, csr_number,
- csr_reads, csr_writes)
+ csr.op_is_valid)
# TODO
cycle_counter = Signal(64); # TODO: implement cycle_counter
instret_counter = Signal(64); # TODO: implement instret_counter
self.sync += If(~self.reset,
- self.main_block(mi, m, mstatus, ft, dc,
+ self.main_block(csr, mi, m, mstatus, ft, dc,
load_store_misaligned,
loaded_value,
alu_result,
- lui_auipc_result,
- fetch_output_pc)
+ lui_auipc_result)
)
if __name__ == "__main__":