set up LoadStore1 in ConfigMemoryPortInterface and hook it up in MMU
[soc.git] / src / soc / simple / issuer.py
index eff313307db5dd8c4ef48d32d03efac916e606c3..a78eb0744d280815047cbcada42793cc9615a90b 100644 (file)
@@ -23,27 +23,28 @@ import sys
 
 from nmigen.lib.coding import PriorityEncoder
 
-from soc.decoder.power_decoder import create_pdecode
-from soc.decoder.power_decoder2 import PowerDecode2, SVP64PrefixDecoder
-from soc.decoder.decode2execute1 import IssuerDecode2ToOperand
-from soc.decoder.decode2execute1 import Data
+from openpower.decoder.power_decoder import create_pdecode
+from openpower.decoder.power_decoder2 import PowerDecode2, SVP64PrefixDecoder
+from openpower.decoder.decode2execute1 import IssuerDecode2ToOperand
+from openpower.decoder.decode2execute1 import Data
+from openpower.decoder.power_enums import (MicrOp, SVP64PredInt, SVP64PredCR,
+                                     SVP64PredMode)
+from openpower.state import CoreState
+from openpower.consts import (CR, SVP64CROffs)
 from soc.experiment.testmem import TestMemory # test only for instructions
 from soc.regfile.regfiles import StateRegs, FastRegs
 from soc.simple.core import NonProductionCore
 from soc.config.test.test_loadstore import TestMemPspec
 from soc.config.ifetch import ConfigFetchUnit
-from soc.decoder.power_enums import (MicrOp, SVP64PredInt, SVP64PredCR,
-                                     SVP64PredMode)
 from soc.debug.dmi import CoreDebug, DMIInterface
 from soc.debug.jtag import JTAG
 from soc.config.pinouts import get_pinspecs
-from soc.config.state import CoreState
 from soc.interrupts.xics import XICS_ICP, XICS_ICS
 from soc.bus.simple_gpio import SimpleGPIO
 from soc.bus.SPBlock512W64B8W import SPBlock512W64B8W
 from soc.clock.select import ClockSelect
 from soc.clock.dummypll import DummyPLL
-from soc.sv.svstate import SVSTATERec
+from openpower.sv.svstate import SVSTATERec
 
 
 from nmutil.util import rising_edge
@@ -123,29 +124,29 @@ def get_predcr(m, mask, name):
     invert = Signal(name=name+"crinvert")
     with m.Switch(mask):
         with m.Case(SVP64PredCR.LT.value):
-            comb += idx.eq(0)
-            comb += invert.eq(1)
-        with m.Case(SVP64PredCR.GE.value):
-            comb += idx.eq(0)
+            comb += idx.eq(CR.LT)
             comb += invert.eq(0)
-        with m.Case(SVP64PredCR.GT.value):
-            comb += idx.eq(1)
+        with m.Case(SVP64PredCR.GE.value):
+            comb += idx.eq(CR.LT)
             comb += invert.eq(1)
-        with m.Case(SVP64PredCR.LE.value):
-            comb += idx.eq(1)
+        with m.Case(SVP64PredCR.GT.value):
+            comb += idx.eq(CR.GT)
             comb += invert.eq(0)
-        with m.Case(SVP64PredCR.EQ.value):
-            comb += idx.eq(2)
+        with m.Case(SVP64PredCR.LE.value):
+            comb += idx.eq(CR.GT)
             comb += invert.eq(1)
-        with m.Case(SVP64PredCR.NE.value):
-            comb += idx.eq(1)
+        with m.Case(SVP64PredCR.EQ.value):
+            comb += idx.eq(CR.EQ)
             comb += invert.eq(0)
-        with m.Case(SVP64PredCR.SO.value):
-            comb += idx.eq(3)
+        with m.Case(SVP64PredCR.NE.value):
+            comb += idx.eq(CR.EQ)
             comb += invert.eq(1)
-        with m.Case(SVP64PredCR.NS.value):
-            comb += idx.eq(3)
+        with m.Case(SVP64PredCR.SO.value):
+            comb += idx.eq(CR.SO)
             comb += invert.eq(0)
+        with m.Case(SVP64PredCR.NS.value):
+            comb += idx.eq(CR.SO)
+            comb += invert.eq(1)
     return idx, invert
 
 
@@ -398,7 +399,7 @@ class TestIssuerInternal(Elaboratable):
         be done through multiple reads, extracting one relevant at a time.
         later, a faster way would be to use the 32-bit-wide CR port but
         this is more complex decoding, here.  equivalent code used in
-        ISACaller is "from soc.decoder.isa.caller import get_predcr"
+        ISACaller is "from openpower.decoder.isa.caller import get_predcr"
 
         note: this ENTIRE FSM is not to be called when svp64 is disabled
         """
@@ -413,24 +414,7 @@ class TestIssuerInternal(Elaboratable):
         cur_state = self.cur_state
         srcstep = cur_state.svstate.srcstep
         dststep = cur_state.svstate.dststep
-
-        # elif predmode == CR:
-        #    CR-src sidx, sinvert = get_predcr(m, srcpred)
-        #    CR-dst didx, dinvert = get_predcr(m, dstpred)
-        #    TODO read CR-src and CR-dst into self.srcmask+dstmask with loop
-        #         has to cope with first one then the other
-        #    for cr_idx = FSM-state-loop(0..VL-1):
-        #        FSM-state-trigger-CR-read:
-        #               cr_ren = (1<<7-(cr_idx+SVP64CROffs.CRPred))
-        #               comb += cr_pred.ren.eq(cr_ren)
-        #        FSM-state-1-clock-later-actual-Read:
-        #               cr_field = Signal(4)
-        #               cr_bit = Signal(1)
-        #               # read the CR field, select the appropriate bit
-        #               comb += cr_field.eq(cr_pred.data_o)
-        #               comb += cr_bit.eq(cr_field.bit_select(idx)))
-        #               # just like in branch BO tests
-        #               comd += self.srcmask[cr_idx].eq(inv ^ cr_bit)
+        cur_vl = cur_state.svstate.vl
 
         # decode predicates
         sregread, sinvert, sunary, sall1s = get_predint(m, srcpred, 's')
@@ -438,6 +422,12 @@ class TestIssuerInternal(Elaboratable):
         sidx, scrinvert = get_predcr(m, srcpred, 's')
         didx, dcrinvert = get_predcr(m, dstpred, 'd')
 
+        # store fetched masks, for either intpred or crpred
+        # when src/dst step is not zero, the skipped mask bits need to be
+        # shifted-out, before actually storing them in src/dest mask
+        new_srcmask = Signal(64, reset_less=True)
+        new_dstmask = Signal(64, reset_less=True)
+
         with m.FSM(name="fetch_predicate"):
 
             with m.State("FETCH_PRED_IDLE"):
@@ -446,7 +436,7 @@ class TestIssuerInternal(Elaboratable):
                     with m.If(predmode == SVP64PredMode.INT):
                         # skip fetching destination mask register, when zero
                         with m.If(dall1s):
-                            sync += self.dstmask.eq(-1)
+                            sync += new_dstmask.eq(-1)
                             # directly go to fetch source mask register
                             # guaranteed not to be zero (otherwise predmode
                             # would be SVP64PredMode.ALWAYS, not INT)
@@ -458,6 +448,11 @@ class TestIssuerInternal(Elaboratable):
                             comb += int_pred.addr.eq(dregread)
                             comb += int_pred.ren.eq(1)
                             m.next = "INT_DST_READ"
+                    with m.Elif(predmode == SVP64PredMode.CR):
+                        # go fetch masks from the CR register file
+                        sync += new_srcmask.eq(0)
+                        sync += new_dstmask.eq(0)
+                        m.next = "CR_READ"
                     with m.Else():
                         sync += self.srcmask.eq(-1)
                         sync += self.dstmask.eq(-1)
@@ -466,21 +461,18 @@ class TestIssuerInternal(Elaboratable):
             with m.State("INT_DST_READ"):
                 # store destination mask
                 inv = Repl(dinvert, 64)
-                new_dstmask = Signal(64)
                 with m.If(dunary):
                     # set selected mask bit for 1<<r3 mode
                     dst_shift = Signal(range(64))
                     comb += dst_shift.eq(self.int_pred.data_o & 0b111111)
-                    comb += new_dstmask.eq(1 << dst_shift)
+                    sync += new_dstmask.eq(1 << dst_shift)
                 with m.Else():
                     # invert mask if requested
-                    comb += new_dstmask.eq(self.int_pred.data_o ^ inv)
-                # shift-out already used mask bits
-                sync += self.dstmask.eq(new_dstmask >> dststep)
+                    sync += new_dstmask.eq(self.int_pred.data_o ^ inv)
                 # skip fetching source mask register, when zero
                 with m.If(sall1s):
-                    sync += self.srcmask.eq(-1)
-                    m.next = "FETCH_PRED_DONE"
+                    sync += new_srcmask.eq(-1)
+                    m.next = "FETCH_PRED_SHIFT_MASK"
                 # fetch source predicate register
                 with m.Else():
                     comb += int_pred.addr.eq(sregread)
@@ -490,17 +482,71 @@ class TestIssuerInternal(Elaboratable):
             with m.State("INT_SRC_READ"):
                 # store source mask
                 inv = Repl(sinvert, 64)
-                new_srcmask = Signal(64)
                 with m.If(sunary):
                     # set selected mask bit for 1<<r3 mode
                     src_shift = Signal(range(64))
                     comb += src_shift.eq(self.int_pred.data_o & 0b111111)
-                    comb += new_srcmask.eq(1 << src_shift)
+                    sync += new_srcmask.eq(1 << src_shift)
                 with m.Else():
                     # invert mask if requested
-                    comb += new_srcmask.eq(self.int_pred.data_o ^ inv)
-                # shift-out already used mask bits
+                    sync += new_srcmask.eq(self.int_pred.data_o ^ inv)
+                m.next = "FETCH_PRED_SHIFT_MASK"
+
+            # fetch masks from the CR register file
+            # implements the following loop:
+            # idx, inv = get_predcr(mask)
+            # mask = 0
+            # for cr_idx in range(vl):
+            #     cr = crl[cr_idx + SVP64CROffs.CRPred]  # takes one cycle
+            #     if cr[idx] ^ inv:
+            #         mask |= 1 << cr_idx
+            # return mask
+            with m.State("CR_READ"):
+                # CR index to be read, which will be ready by the next cycle
+                cr_idx = Signal.like(cur_vl, reset_less=True)
+                # submit the read operation to the regfile
+                with m.If(cr_idx != cur_vl):
+                    # the CR read port is unary ...
+                    # ren = 1 << cr_idx
+                    # ... in MSB0 convention ...
+                    # ren = 1 << (7 - cr_idx)
+                    # ... and with an offset:
+                    # ren = 1 << (7 - off - cr_idx)
+                    idx = SVP64CROffs.CRPred + cr_idx
+                    comb += cr_pred.ren.eq(1 << (7 - idx))
+                    # signal data valid in the next cycle
+                    cr_read = Signal(reset_less=True)
+                    sync += cr_read.eq(1)
+                    # load the next index
+                    sync += cr_idx.eq(cr_idx + 1)
+                with m.Else():
+                    # exit on loop end
+                    sync += cr_read.eq(0)
+                    sync += cr_idx.eq(0)
+                    m.next = "FETCH_PRED_SHIFT_MASK"
+                with m.If(cr_read):
+                    # compensate for the one cycle delay on the regfile
+                    cur_cr_idx = Signal.like(cur_vl)
+                    comb += cur_cr_idx.eq(cr_idx - 1)
+                    # read the CR field, select the appropriate bit
+                    cr_field = Signal(4)
+                    scr_bit = Signal()
+                    dcr_bit = Signal()
+                    comb += cr_field.eq(cr_pred.data_o)
+                    comb += scr_bit.eq(cr_field.bit_select(sidx, 1) ^ scrinvert)
+                    comb += dcr_bit.eq(cr_field.bit_select(didx, 1) ^ dcrinvert)
+                    # set the corresponding mask bit
+                    bit_to_set = Signal.like(self.srcmask)
+                    comb += bit_to_set.eq(1 << cur_cr_idx)
+                    with m.If(scr_bit):
+                        sync += new_srcmask.eq(new_srcmask | bit_to_set)
+                    with m.If(dcr_bit):
+                        sync += new_dstmask.eq(new_dstmask | bit_to_set)
+
+            with m.State("FETCH_PRED_SHIFT_MASK"):
+                # shift-out skipped mask bits
                 sync += self.srcmask.eq(new_srcmask >> srcstep)
+                sync += self.dstmask.eq(new_dstmask >> dststep)
                 m.next = "FETCH_PRED_DONE"
 
             with m.State("FETCH_PRED_DONE"):
@@ -1124,7 +1170,7 @@ class TestIssuerInternal(Elaboratable):
             ports += list(self.dbg.dmi.ports())
 
         ports += list(self.imem.ibus.fields.values())
-        ports += list(self.core.l0.cmpi.lsmem.lsi.slavebus.fields.values())
+        ports += list(self.core.l0.cmpi.wb_bus().fields.values())
 
         if self.sram4x4k:
             for sram in self.sram4k:
@@ -1155,6 +1201,7 @@ class TestIssuer(Elaboratable):
         self.pll_en = hasattr(pspec, "use_pll") and pspec.use_pll
         if self.pll_en:
             self.pll_18_o = Signal(reset_less=True)
+            self.clk_sel_i = Signal(reset_less=True)
 
     def elaborate(self, platform):
         m = Module()
@@ -1183,6 +1230,9 @@ class TestIssuer(Elaboratable):
             # output 18 mhz PLL test signal
             comb += self.pll_18_o.eq(pll.pll_18_o)
 
+            # input to pll clock selection
+            comb += Cat(pll.sel_a0_i, pll.sel_a1_i).eq(self.clk_sel_i)
+
             # now wire up ResetSignals.  don't mind them being in this domain
             pll_rst = ResetSignal("pllclk")
             comb += pll_rst.eq(ResetSignal())
@@ -1206,9 +1256,9 @@ class TestIssuer(Elaboratable):
         ports.append(ClockSignal())
         ports.append(ResetSignal())
         if self.pll_en:
-            ports.append(self.pll.clk_sel_i)
+            ports.append(self.clk_sel_i)
             ports.append(self.pll_18_o)
-            ports.append(self.pll.pll_lck_o)
+            ports.append(self.pll.pll_ana_o)
         return ports