From 3cea524b956ff52f3118b83f2b71031cd86730b9 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 26 Nov 2018 04:10:18 +0000 Subject: [PATCH] add handle_main --- cpu.py | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 185 insertions(+), 4 deletions(-) diff --git a/cpu.py b/cpu.py index eabe9d8..d654989 100644 --- a/cpu.py +++ b/cpu.py @@ -361,6 +361,182 @@ class CPU(Module): return Case(csr_number, c) + def main_block(self, mi, m, mstatus, ft, dc, load_store_misaligned, + loaded_value, alu_result, + lui_auipc_result, fetch_output_pc): + 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, + load_store_misaligned, + loaded_value, + alu_result, + lui_auipc_result, + fetch_output_pc) + return Case(ft.output_state, c) + + def handle_valid(self, mi, m, mstatus, ft, dc, load_store_misaligned, + loaded_value, alu_result, + lui_auipc_result, fetch_output_pc): + # fetch action ack trap + i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap), + self.handle_trap(m, mstatus, ft, dc, + load_store_misaligned) + ) + + # load + i = i.Elif((dc.act & DA.load) != 0, + If(~mi.rw_wait, + self.write_register(dc.rd, loaded_value) + ) + ) + + # op or op_immediate + i = i.Elif((dc.act & DA.op_op_imm) != 0, + self.write_register(dc.rd, alu_result) + ) + + # lui or auipc + i = i.Elif((dc.act & DA.lui_auipc) != 0, + self.write_register(dc.rd, lui_auipc_result) + ) + + # jal/jalr + i = i.Elif((dc.act & (DA.jal | DA.jalr)) != 0, + self.write_register(dc.rd, fetch_output_pc + 4) + ) + + # fence, store, branch + i = i.Elif((dc.act & (DA.fence | DA.fence_i | + DA.store | DA.branch)) != 0, + # do nothing + ) + + return i + + """ + else if((decode_action & `decode_action_csr) != 0) begin:csr + reg [31:0] csr_output_value; + reg [31:0] csr_written_value; + csr_output_value = 32'hXXXXXXXX; + csr_written_value = 32'hXXXXXXXX; + case(csr_number) + `csr_cycle: begin + csr_output_value = cycle_counter[31:0]; + end + `csr_time: begin + csr_output_value = time_counter[31:0]; + end + `csr_instret: begin + csr_output_value = instret_counter[31:0]; + end + `csr_cycleh: begin + csr_output_value = cycle_counter[63:32]; + end + `csr_timeh: begin + csr_output_value = time_counter[63:32]; + end + `csr_instreth: begin + csr_output_value = instret_counter[63:32]; + end + `csr_mvendorid: begin + csr_output_value = mvendorid; + end + `csr_marchid: begin + csr_output_value = marchid; + end + `csr_mimpid: begin + csr_output_value = mimpid; + end + `csr_mhartid: begin + csr_output_value = mhartid; + end + `csr_misa: begin + csr_output_value = misa; + end + `csr_mstatus: begin + csr_output_value = make_mstatus(mstatus_tsr, + mstatus_tw, + mstatus_tvm, + mstatus_mxr, + mstatus_sum, + mstatus_mprv, + mstatus_xs, + mstatus_fs, + mstatus_mpp, + mstatus_spp, + mstatus_mpie, + mstatus_spie, + mstatus_upie, + mstatus_mie, + mstatus_sie, + mstatus_uie); + csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value); + if(csr_writes) begin + mstatus_mpie = csr_written_value[7]; + mstatus_mie = csr_written_value[3]; + end + end + `csr_mie: begin + csr_output_value = 0; + csr_output_value[11] = mie_meie; + csr_output_value[9] = mie_seie; + csr_output_value[8] = mie_ueie; + csr_output_value[7] = mie_mtie; + csr_output_value[5] = mie_stie; + csr_output_value[4] = mie_utie; + csr_output_value[3] = mie_msie; + csr_output_value[1] = mie_ssie; + csr_output_value[0] = mie_usie; + csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value); + if(csr_writes) begin + mie_meie = csr_written_value[11]; + mie_mtie = csr_written_value[7]; + mie_msie = csr_written_value[3]; + end + end + `csr_mtvec: begin + csr_output_value = mtvec; + end + `csr_mscratch: begin + csr_output_value = mscratch; + csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value); + if(csr_writes) + mscratch = csr_written_value; + end + `csr_mepc: begin + csr_output_value = mepc; + csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value); + if(csr_writes) + mepc = csr_written_value; + end + `csr_mcause: begin + csr_output_value = mcause; + csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value); + if(csr_writes) + mcause = csr_written_value; + end + `csr_mip: begin + csr_output_value = 0; + csr_output_value[11] = mip_meip; + csr_output_value[9] = mip_seip; + csr_output_value[8] = mip_ueip; + csr_output_value[7] = mip_mtip; + csr_output_value[5] = mip_stip; + csr_output_value[4] = mip_utip; + csr_output_value[3] = mip_msip; + csr_output_value[1] = mip_ssip; + csr_output_value[0] = mip_usip; + end + endcase + if(csr_reads) + write_register(decoder_rd, csr_output_value); + end + end + endcase + end + """ def __init__(self): self.clk = ClockSignal() self.reset = ResetSignal() @@ -627,6 +803,15 @@ class CPU(Module): time_counter = Signal(64); # TODO: implement time_counter instret_counter = Signal(64); # TODO: implement instret_counter + self.sync += If(~self.reset, + self.main_block(mi, m, mstatus, ft, dc, + load_store_misaligned, + loaded_value, + alu_result, + lui_auipc_result, + fetch_output_pc) + ) + if __name__ == "__main__": example = CPU() print(verilog.convert(example, @@ -642,10 +827,6 @@ if __name__ == "__main__": """ - 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 - always @(posedge clk) begin:main_block if(reset) begin reset_to_initial(); -- 2.30.2