expand instruction bus width to 64 bit, start on a mini-cache
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Jun 2020 17:23:08 +0000 (18:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Jun 2020 17:23:08 +0000 (18:23 +0100)
for instructions (one line)

src/soc/simple/issuer.py
src/soc/simple/test/test_issuer.py

index b211a3630f8507cbfdd65c840f9e58e78ba38925..7dfa9d6797732a4ed10da59cb4062f29f0f65925 100644 (file)
@@ -35,9 +35,12 @@ class TestIssuer(Elaboratable):
         self.core = core = NonProductionCore(addrwid, ifacetype=ifacetype)
 
         # Test Instruction memory
-        self.imem = TestMemory(32, idepth)
+        self.imemwid = 64
+        self.imem = TestMemory(self.imemwid, idepth)
         self.i_rd = self.imem.rdport
-        #self.i_wr = self.imem.write_port() errr...
+        # one-row cache of instruction read
+        self.iline = Signal(64) # one instruction line
+        self.iprev_adr = Signal(64) # previous address: if different, do read
 
         # instruction go/monitor
         self.go_insn_i = Signal(reset_less=True)
@@ -103,14 +106,14 @@ class TestIssuer(Elaboratable):
                     # capture the PC and also drop it into Insn Memory
                     # we have joined a pair of combinatorial memory
                     # lookups together.  this is Generally Bad.
-                    comb += self.i_rd.addr.eq(pc[2:]) # ignore last 2 bits
-                    comb += current_insn.eq(self.i_rd.data)
+                    comb += self.i_rd.addr.eq(pc[3:]) # ignore last 3 bits
                     sync += current_pc.eq(pc)
                     m.next = "INSN_READ" # move to "issue" phase
 
             # got the instruction: start issue
             with m.State("INSN_READ"):
-                comb += current_insn.eq(self.i_rd.data)
+                insn = self.i_rd.data.word_select(current_pc[2], 32) #
+                comb += current_insn.eq(insn)
                 comb += core_ivalid_i.eq(1) # say instruction is valid
                 comb += core_issue_i.eq(1)  # and issued (ivalid_i redundant)
                 comb += core_be_i.eq(0)     # little-endian mode
index b6cc9f6edc66294219826125fb506e0eb2d41c5b..04a7bd437455374d4f000bb9aad6e47bf904fd09 100644 (file)
@@ -38,11 +38,21 @@ def setup_i_memory(imem, startaddr, instructions):
     print ("insn before, init mem", mem.depth, mem.width, mem)
     for i in range(mem.depth):
         yield mem._array[i].eq(0)
-    startaddr //= 4 # assume i-mem is 32-bit wide
+    yield Settle()
+    startaddr //= 4 # instructions are 32-bit
+    mask = ((1<<64)-1)
     for insn, code in instructions:
-        print ("instr: %06x 0x%x %s" % (4*startaddr, insn, code))
-        yield mem._array[startaddr].eq(insn)
+        msbs = (startaddr>>1) & mask
+        val = yield mem._array[msbs]
+        print ("before set", hex(startaddr), hex(msbs), hex(val))
+        lsb = 1 if (startaddr & 1) else 0
+        val = (val | (insn << (lsb*32))) & mask
+        yield mem._array[msbs].eq(val)
+        yield Settle()
+        print ("after  set", hex(startaddr), hex(msbs), hex(val))
+        print ("instr: %06x 0x%x %s %08x" % (4*startaddr, insn, code, val))
         startaddr += 1
+        startaddr = startaddr & mask
 
 
 class TestRunner(FHDLTestCase):