more cpu logic
[rv32.git] / cpu.py
diff --git a/cpu.py b/cpu.py
index ed3c450096966525d936ccb813dcfe71df8c9a91..7dbf77d5b06fe7fd56535443a9bf990d450ced86 100644 (file)
--- a/cpu.py
+++ b/cpu.py
 
 from migen import *
 from migen.fhdl import verilog
+from migen.fhdl.structure import _Operator
 
 from riscvdefs import *
 from cpudefs import *
 
+class MemoryInterface:
+    fetch_address = Signal(32, name="memory_interface_fetch_address") # XXX [2:]
+    fetch_data = Signal(32, name="memory_interface_fetch_data")
+    fetch_valid = Signal(name="memory_interface_fetch_valid")
+    rw_address= Signal(32, name="memory_interface_rw_address") # XXX [2:]
+    rw_byte_mask = Signal(4, name="memory_interface_rw_byte_mask")
+    rw_read_not_write = Signal(name="memory_interface_rw_read_not_write")
+    rw_active = Signal(name="memory_interface_rw_active")
+    rw_data_in = Signal(32, name="memory_interface_rw_data_in")
+    rw_data_out = Signal(32, name="memory_interface_rw_data_out")
+    rw_address_valid = Signal(name="memory_interface_rw_address_valid")
+    rw_wait = Signal(name="memory_interface_rw_wait")
+
+
 class CPU(Module):
     """ 
     """
 
+    def get_ls_misaligned(self, ls, funct3, load_store_address_low_2):
+        return Case(funct3[:2],
+                { F3.sb: ls.eq(Constant(0)),
+                  F3.sh: ls.eq(load_store_address_low_2[0] != 0),
+                  F3.sw: ls.eq(load_store_address_low_2[0:2] != Constant(0, 2)),
+                  "default": ls.eq(Constant(1))
+                })
+
+    def get_lsbm(self, decoder_funct3):
+        return Cat(Constant(1),
+                   Mux((decoder_funct3[1] | decoder_funct3[0]),
+                       Constant(1), Constant(0)),
+                   Mux((decoder_funct3[1]),
+                       Constant(0b11, 2), Constant(0, 2)))
+
     def __init__(self):
         #self.clk = ClockSignal()
         #self.reset = ResetSignal()
@@ -60,37 +90,24 @@ class CPU(Module):
             l.append(Signal(32, name="register%d" % i))
         registers = Array(l)
 
-        #self.sync += self.registers[0].eq(0)
-        #self.sync += self.registers[1].eq(0)
-
-        memory_interface_fetch_address = Signal(32) # XXX [2:]
-        memory_interface_fetch_data = Signal(32)
-        memory_interface_fetch_valid = Signal()
-        memory_interface_rw_address= Signal(32) # XXX [2:]
-        memory_interface_rw_byte_mask = Signal(4)
-        memory_interface_rw_read_not_write = Signal()
-        memory_interface_rw_active = Signal()
-        memory_interface_rw_data_in = Signal(32)
-        memory_interface_rw_data_out = Signal(32)
-        memory_interface_rw_address_valid = Signal()
-        memory_interface_rw_wait = Signal()
-
-        mi = Instance("cpu_memory_interface", name="memory_instance",
+        mi = MemoryInterface()
+
+        mii = Instance("cpu_memory_interface", name="memory_instance",
                     p_ram_size = ram_size,
                     p_ram_start = ram_start,
                     i_clk=ClockSignal(),
                     i_rst=ResetSignal(),
-                    i_fetch_address = memory_interface_fetch_address,
-                    o_fetch_data = memory_interface_fetch_data,
-                    o_fetch_valid = memory_interface_fetch_valid,
-                    i_rw_address = memory_interface_rw_address,
-                    i_rw_byte_mask = memory_interface_rw_byte_mask,
-                    i_rw_read_not_write = memory_interface_rw_read_not_write,
-                    i_rw_active = memory_interface_rw_active,
-                    i_rw_data_in = memory_interface_rw_data_in,
-                    o_rw_data_out = memory_interface_rw_data_out,
-                    o_rw_address_valid = memory_interface_rw_address_valid,
-                    o_rw_wait = memory_interface_rw_wait,
+                    i_fetch_address = mi.fetch_address,
+                    o_fetch_data = mi.fetch_data,
+                    o_fetch_valid = mi.fetch_valid,
+                    i_rw_address = mi.rw_address,
+                    i_rw_byte_mask = mi.rw_byte_mask,
+                    i_rw_read_not_write = mi.rw_read_not_write,
+                    i_rw_active = mi.rw_active,
+                    i_rw_data_in = mi.rw_data_in,
+                    o_rw_data_out = mi.rw_data_out,
+                    o_rw_address_valid = mi.rw_address_valid,
+                    o_rw_wait = mi.rw_wait,
                     o_tty_write = self.tty_write,
                     o_tty_write_data = self.tty_write_data,
                     i_tty_write_busy = self.tty_write_busy,
@@ -99,7 +116,7 @@ class CPU(Module):
                     o_led_1 = self.led_1,
                     o_led_3 = self.led_3
                   )
-        self.specials += mi
+        self.specials += mii
 
         fetch_act = Signal(fetch_action)
         fetch_target_pc = Signal(32)
@@ -110,9 +127,9 @@ class CPU(Module):
         fs = Instance("CPUFetchStage", name="fetch_stage",
             i_clk=ClockSignal(),
             i_rst=ResetSignal(),
-            o_memory_interface_fetch_address = memory_interface_fetch_address,
-            i_memory_interface_fetch_data = memory_interface_fetch_data,
-            i_memory_interface_fetch_valid = memory_interface_fetch_valid,
+            o_memory_interface_fetch_address = mi.fetch_address,
+            i_memory_interface_fetch_data = mi.fetch_data,
+            i_memory_interface_fetch_valid = mi.fetch_valid,
             i_fetch_action = fetch_act,
             i_target_pc = fetch_target_pc,
             o_output_pc = fetch_output_pc,
@@ -163,6 +180,25 @@ class CPU(Module):
         self.comb += load_store_address_low_2.eq(
                             decoder_immediate[:2] + register_rs1[:2])
 
+        load_store_misaligned = Signal()
+
+        lsa = self.get_ls_misaligned(load_store_misaligned, decoder_funct3,
+                                     load_store_address_low_2)
+        self.comb += lsa
+
+        # XXX rwaddr not 31:2 any more
+        self.comb += mi.rw_address.eq(load_store_address[2:])
+
+        unshifted_load_store_byte_mask = Signal(4)
+
+        self.comb += unshifted_load_store_byte_mask.eq(self.get_lsbm(
+                                                       decoder_funct3))
+
+        # XXX yuck.  this will cause migen simulation to fail
+        # (however conversion to verilog works)
+        self.comb += mi.rw_byte_mask.eq(
+                _Operator("<<", [unshifted_load_store_byte_mask,
+                                        load_store_address_low_2]))
 
 if __name__ == "__main__":
     example = CPU()
@@ -179,30 +215,6 @@ if __name__ == "__main__":
 
 """
 
-    function get_load_store_misaligned(
-        input [2:0] funct3,
-        input [1:0] load_store_address_low_2
-        );
-    begin
-        case(funct3[1:0])
-        `funct3_sb:
-            get_load_store_misaligned = 0;
-        `funct3_sh:
-            get_load_store_misaligned = load_store_address_low_2[0] != 0;
-        `funct3_sw:
-            get_load_store_misaligned = load_store_address_low_2[1:0] != 0;
-        default:
-            get_load_store_misaligned = 1'bX;
-        endcase
-    end
-    endfunction
-
-    wire load_store_misaligned = get_load_store_misaligned(decoder_funct3, load_store_address_low_2);
-
-    assign memory_interface_rw_address = load_store_address[31:2];
-
-    wire [3:0] unshifted_load_store_byte_mask = {decoder_funct3[1] ? 2'b11 : 2'b00, (decoder_funct3[1] | decoder_funct3[0]) ? 1'b1 : 1'b0, 1'b1};
-
     assign memory_interface_rw_byte_mask = unshifted_load_store_byte_mask << load_store_address_low_2;
 
     assign memory_interface_rw_data_in[31:24] = load_store_address_low_2[1]