X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=cpu.py;h=c8dafdeb3a10938d0a4d0c34270a07b1e0132b5b;hb=e103247b196ca128bfbf4b4c6c0d68e63e64b98b;hp=e0a6881c9248769e328e73ed1498ec4cf0bd49e3;hpb=80df153847f312aab82be5c970305223619c3da5;p=rv32.git diff --git a/cpu.py b/cpu.py index e0a6881..c8dafde 100644 --- a/cpu.py +++ b/cpu.py @@ -328,42 +328,38 @@ class CPU(Module): s.append(i) return s - """ - task handle_trap; - begin - mstatus_mpie = mstatus_mie; - mstatus_mie = 0; - mepc = (fetch_action == `fetch_action_noerror_trap) ? fetch_output_pc + 4 : fetch_output_pc; - if(fetch_action == `fetch_action_ack_trap) begin - mcause = `cause_instruction_access_fault; - end - else if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin - mcause = `cause_illegal_instruction; - end - else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin - mcause = decoder_immediate[0] ? `cause_machine_environment_call : `cause_breakpoint; - end - else if((decode_action & `decode_action_load) != 0) begin - if(load_store_misaligned) - mcause = `cause_load_address_misaligned; - else - mcause = `cause_load_access_fault; - end - else if((decode_action & `decode_action_store) != 0) begin - if(load_store_misaligned) - mcause = `cause_store_amo_address_misaligned; - else - mcause = `cause_store_amo_access_fault; - end - else if((decode_action & (`decode_action_branch | `decode_action_jal | `decode_action_jalr)) != 0) begin - mcause = `cause_instruction_address_misaligned; - end - else begin - mcause = `cause_illegal_instruction; - end - end - endtask - """ + 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 __init__(self): self.clk = ClockSignal() @@ -610,6 +606,21 @@ class CPU(Module): 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) if __name__ == "__main__": example = CPU() @@ -626,77 +637,6 @@ if __name__ == "__main__": """ - wire [11:0] csr_number = decoder_immediate; - wire [31:0] csr_input_value = decoder_funct3[2] ? decoder_rs1 : register_rs1; - wire csr_reads = decoder_funct3[1] | (decoder_rd != 0); - wire csr_writes = ~decoder_funct3[1] | (decoder_rs1 != 0); - - function get_csr_op_is_valid(input [11:0] csr_number, input csr_reads, input csr_writes); - begin - case(csr_number) - `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: - get_csr_op_is_valid = 0; - `csr_cycle, - `csr_time, - `csr_instret, - `csr_cycleh, - `csr_timeh, - `csr_instreth, - `csr_mvendorid, - `csr_marchid, - `csr_mimpid, - `csr_mhartid: - get_csr_op_is_valid = ~csr_writes; - `csr_misa, - `csr_mstatus, - `csr_mie, - `csr_mtvec, - `csr_mscratch, - `csr_mepc, - `csr_mcause, - `csr_mip: - get_csr_op_is_valid = 1; - `csr_mcounteren, - `csr_mtval, - `csr_mcycle, - `csr_minstret, - `csr_mcycleh, - `csr_minstreth: - // TODO: CSRs not implemented yet - get_csr_op_is_valid = 0; - endcase - end - endfunction - - assign csr_op_is_valid = get_csr_op_is_valid(csr_number, csr_reads, csr_writes); - wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter wire [63:0] time_counter = 0; // TODO: implement time_counter wire [63:0] instret_counter = 0; // TODO: implement instret_counter