add more logic and mstatus
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 25 Nov 2018 08:17:02 +0000 (08:17 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 25 Nov 2018 08:17:02 +0000 (08:17 +0000)
cpu.py

diff --git a/cpu.py b/cpu.py
index ae24ce42c81e2afada7088adc7ac43e30864ab8d..3bce542fd7778b1298d8c4645dd09349a40cf203 100644 (file)
--- a/cpu.py
+++ b/cpu.py
@@ -57,6 +57,32 @@ class Decoder:
     opcode = Signal(7, name="decoder_opcode")
     act = Signal(decode_action, name="decoder_action")
 
+class MStatus:
+    def __init__(self, comb):
+        self.comb = comb
+        self.mpie = Signal(name="mstatus_mpie")
+        self.mie = Signal(name="mstatus_mie")
+        self.mprv = Signal(name="mstatus_mprv")
+        self.tsr = Signal(name="mstatus_tsr")
+        self.tw = Signal(name="mstatus_tw")
+        self.tvm = Signal(name="mstatus_tvm")
+        self.mxr = Signal(name="mstatus_mxr")
+        self._sum = Signal(name="mstatus_sum")
+        self.xs = Signal(name="mstatus_xs")
+        self.fs = Signal(name="mstatus_fs")
+        self.mpp = Signal(2, name="mstatus_mpp")
+        self.spp = Signal(name="mstatus_spp")
+        self.spie = Signal(name="mstatus_spie")
+        self.upie = Signal(name="mstatus_upie")
+        self.sie = Signal(name="mstatus_sie")
+        self.uie = Signal(name="mstatus_uie")
+
+        for n in dir(self):
+            if n in ['mpp', 'comb'] or n.startswith("_"):
+                continue
+            self.comb += getattr(self, n).eq(0x0)
+        self.comb += self.mpp.eq(0b11)
+
 
 class CPU(Module):
     """
@@ -279,6 +305,36 @@ class CPU(Module):
                                              dc.immediate,
                                              dc.immediate + fetch_output_pc))
 
+        self.comb += fetch_target_pc.eq(Cat(0,
+                    Mux(dc.opcode != OP.jalr,
+                                fetch_output_pc[1:32],
+                                register_rs1[1:32] + dc.immediate[1:32])))
+
+        misaligned_jump_target = Signal()
+        self.comb += misaligned_jump_target.eq(fetch_target_pc[1])
+
+        branch_arg_a = Signal(32)
+        branch_arg_b = Signal(32)
+        self.comb += branch_arg_a.eq(Cat( register_rs1[0:31],
+                                          register_rs1[31] ^ ~dc.funct3[1]))
+        self.comb += branch_arg_b.eq(Cat( register_rs2[0:31],
+                                          register_rs2[31] ^ ~dc.funct3[1]))
+
+        branch_taken = Signal()
+        self.comb += branch_taken.eq(dc.funct3[0] ^
+                                     Mux(dc.funct3[2],
+                                         branch_arg_a < branch_arg_b,
+                                         branch_arg_a == branch_arg_b))
+
+        mcause = Signal(32)
+        mepc = Signal(32)
+        mscratch = Signal(32)
+        self.comb += mcause.eq(0)
+        self.comb += mepc.eq(0) # 32'hXXXXXXXX;
+        self.comb += mscratch.eq(0) # 32'hXXXXXXXX;
+
+        mstatus = MStatus(self.comb)
+
 if __name__ == "__main__":
     example = CPU()
     print(verilog.convert(example,
@@ -294,39 +350,6 @@ if __name__ == "__main__":
 
 """
 
-    wire [31:0] lui_auipc_result = decoder_opcode[5] ? decoder_immediate : decoder_immediate + fetch_output_pc;
-
-    assign fetch_target_pc[31:1] = ((decoder_opcode != `opcode_jalr ? fetch_output_pc[31:1] : register_rs1[31:1]) + decoder_immediate[31:1]);
-    assign fetch_target_pc[0] = 0;
-
-    wire misaligned_jump_target = fetch_target_pc[1];
-
-    wire [31:0] branch_arg_a = {register_rs1[31] ^ ~decoder_funct3[1], register_rs1[30:0]};
-    wire [31:0] branch_arg_b = {register_rs2[31] ^ ~decoder_funct3[1], register_rs2[30:0]};
-
-    wire branch_taken = decoder_funct3[0] ^ (decoder_funct3[2] ? branch_arg_a < branch_arg_b : branch_arg_a == branch_arg_b);
-
-    reg [31:0] mcause = 0;
-    reg [31:0] mepc = 32'hXXXXXXXX;
-    reg [31:0] mscratch = 32'hXXXXXXXX;
-
-    reg mstatus_mpie = 1'bX;
-    reg mstatus_mie = 0;
-    parameter mstatus_mprv = 0;
-    parameter mstatus_tsr = 0;
-    parameter mstatus_tw = 0;
-    parameter mstatus_tvm = 0;
-    parameter mstatus_mxr = 0;
-    parameter mstatus_sum = 0;
-    parameter mstatus_xs = 0;
-    parameter mstatus_fs = 0;
-    parameter mstatus_mpp = 2'b11;
-    parameter mstatus_spp = 0;
-    parameter mstatus_spie = 0;
-    parameter mstatus_upie = 0;
-    parameter mstatus_sie = 0;
-    parameter mstatus_uie = 0;
-
     reg mie_meie = 1'bX;
     reg mie_mtie = 1'bX;
     reg mie_msie = 1'bX;