add handle_main
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 26 Nov 2018 04:10:18 +0000 (04:10 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 26 Nov 2018 04:10:18 +0000 (04:10 +0000)
cpu.py

diff --git a/cpu.py b/cpu.py
index eabe9d85f2157e4ce02c2049e90a8535aaf37243..d654989e717a164d5b16368f975193ad9547be39 100644 (file)
--- 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();