From: Luke Kenneth Casson Leighton Date: Sat, 6 Jun 2020 15:33:53 +0000 (+0100) Subject: LDSTCompUnit test data structures linked up, starting debugging X-Git-Tag: div_pipeline~532 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d7db38b0fa82e1c87e5534b8663f162e189d2983;p=soc.git LDSTCompUnit test data structures linked up, starting debugging --- diff --git a/src/soc/experiment/compalu_multi.py b/src/soc/experiment/compalu_multi.py index 4c1f0191..090c22d4 100644 --- a/src/soc/experiment/compalu_multi.py +++ b/src/soc/experiment/compalu_multi.py @@ -77,6 +77,7 @@ class CompUnitRecord(RegSpec, RecordObject): j = i + 1 # name numbering to match dest1/2... name = "dest%d_o" % j rw = self._get_dstwid(i) + #dreg = Data(rw, name=name) XXX ??? output needs to be a Data type? dreg = Signal(rw, name=name, reset_less=True) setattr(self, name, dreg) dst.append(dreg) diff --git a/src/soc/experiment/compldst_multi.py b/src/soc/experiment/compldst_multi.py index f9c9ad6e..89c7bcaa 100644 --- a/src/soc/experiment/compldst_multi.py +++ b/src/soc/experiment/compldst_multi.py @@ -88,9 +88,11 @@ from nmutil.latch import SRLatch, latchregister from soc.experiment.compalu_multi import go_record, CompUnitRecord from soc.experiment.l0_cache import PortInterface from soc.experiment.testmem import TestMemory +from soc.fu.regspec import RegSpecAPI from soc.decoder.power_enums import InternalOp, Function from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset +from soc.decoder.power_decoder2 import Data class LDSTCompUnitRecord(CompUnitRecord): @@ -111,7 +113,7 @@ class LDSTCompUnitRecord(CompUnitRecord): self.stwd_mem_o = Signal(reset_less=True) # activate memory STORE -class LDSTCompUnit(Elaboratable): +class LDSTCompUnit(RegSpecAPI, Elaboratable): """LOAD / STORE Computation Unit Inputs @@ -165,7 +167,7 @@ class LDSTCompUnit(Elaboratable): def __init__(self, pi=None, rwid=64, awid=48, opsubset=CompLDSTOpSubset, debugtest=False): - self.rwid = rwid + super().__init__(rwid) self.awid = awid self.pi = pi self.cu = cu = LDSTCompUnitRecord(rwid, opsubset) @@ -190,8 +192,15 @@ class LDSTCompUnit(Elaboratable): # convenience names self.rd = cu.rd self.wr = cu.wr + self.rdmaskn = cu.rdmaskn + self.wrmask = cu.wrmask self.ad = cu.ad self.st = cu.st + self.dest = cu._dest + + # HACK: get data width from dest[0]. this is used across the board + # (it really shouldn't be) + self.data_wid = self.dest[0].shape() self.go_rd_i = self.rd.go # temporary naming self.go_wr_i = self.wr.go # temporary naming @@ -209,10 +218,9 @@ class LDSTCompUnit(Elaboratable): self.oper_i = cu.oper_i self.src_i = cu._src_i - self.dest = cu._dest - self.data_o = self.dest[0] # Dest1 out: RT - self.addr_o = self.dest[1] # Address out (LD or ST) - Update => RA + self.data_o = Data(self.data_wid, name="o") # Dest1 out: RT + self.addr_o = Data(self.data_wid, name="ea") # Addr out: Update => RA self.addr_exc_o = cu.addr_exc_o self.done_o = cu.done_o self.busy_o = cu.busy_o @@ -223,10 +231,6 @@ class LDSTCompUnit(Elaboratable): self.load_mem_o = cu.load_mem_o self.stwd_mem_o = cu.stwd_mem_o - # HACK: get data width from dest[0]. this is used across the board - # (it really shouldn't be) - self.data_wid = self.dest[0].shape() - def elaborate(self, platform): m = Module() @@ -392,10 +396,10 @@ class LDSTCompUnit(Elaboratable): comb += self.busy_o.eq(opc_l.q) # | self.pi.busy_o) # busy out # 1st operand read-request only when zero not active - comb += self.rd.rel[0].eq(src_l.q[0] & busy_o & ~op_is_z) - # 2nd operand only needed when immediate is not active - comb += self.rd.rel[1].eq(src_l.q[1] & busy_o & ~op_is_imm) + slg = Cat(op_is_z, op_is_imm) + bro = Repl(self.busy_o, self.n_src) + comb += self.rd.rel.eq(src_l.q & bro & ~slg & ~self.rdmaskn) # note when the address-related read "go" signals are active comb += rda_any.eq(self.rd.go[0] | self.rd.go[1]) @@ -435,12 +439,17 @@ class LDSTCompUnit(Elaboratable): # Data/Address outputs # put the LD-output register directly onto the output bus on a go_write + comb += self.data_o.data.eq(self.dest[0]) with m.If(self.wr.go[0]): - comb += self.data_o.eq(ldd_r) + comb += self.dest[0].eq(ldd_r) # "update" mode, put address out on 2nd go-write + comb += self.addr_o.data.eq(self.dest[1]) with m.If(op_is_update & self.wr.go[1]): - comb += self.addr_o.eq(addr_r) + comb += self.dest[1].eq(addr_r) + + # need to look like MultiCompUnit: put wrmask out + comb += self.wrmask.eq(self.wr.rel) ########################### # PortInterface connections @@ -464,6 +473,14 @@ class LDSTCompUnit(Elaboratable): return m + def get_out(self, i): + """make LDSTCompUnit look like RegSpecALUAPI""" + if i == 0: + return self.data_o + if i == 1: + return self.addr_o + #return self.dest[i] + def __iter__(self): yield self.rd.go yield self.go_ad_i diff --git a/src/soc/fu/compunits/compunits.py b/src/soc/fu/compunits/compunits.py index a3e95038..6b082d4e 100644 --- a/src/soc/fu/compunits/compunits.py +++ b/src/soc/fu/compunits/compunits.py @@ -64,6 +64,9 @@ from soc.fu.branch.pipe_data import BranchPipeSpec from soc.fu.shift_rot.pipeline import ShiftRotBasePipe from soc.fu.shift_rot.pipe_data import ShiftRotPipeSpec +from soc.fu.ldst.pipe_data import LDSTPipeSpec +from soc.experiment.compldst_multi import LDSTCompUnit # special-case + ################################################################### ###### FunctionUnitBaseSingle - use to make single-stge pipes ##### diff --git a/src/soc/fu/compunits/test/test_compunit.py b/src/soc/fu/compunits/test/test_compunit.py index 2d7fa7f2..425d1f92 100644 --- a/src/soc/fu/compunits/test/test_compunit.py +++ b/src/soc/fu/compunits/test/test_compunit.py @@ -5,6 +5,7 @@ from nmigen.cli import rtlil import unittest from soc.decoder.power_decoder import (create_pdecode) from soc.decoder.power_decoder2 import (PowerDecode2) +from soc.decoder.power_enums import Function from soc.decoder.isa.all import ISA from soc.experiment.compalu_multi import find_ok # hack @@ -108,7 +109,14 @@ class TestRunner(FHDLTestCase): pdecode = create_pdecode() m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode) - m.submodules.cu = cu = self.fukls() + if self.funit == Function.LDST: + from soc.experiment.l0_cache import TstL0CacheBuffer + m.submodules.l0 = l0 = TstL0CacheBuffer(n_units=1, regwid=64) + pi = l0.l0.dports[0].pi + m.submodules.cu = cu = self.fukls(pi, awid=4) + m.d.comb += cu.ad.go.eq(cu.ad.rel) # link addr-go direct to rel + else: + m.submodules.cu = cu = self.fukls() comb += pdecode2.dec.raw_opcode_in.eq(instruction) sim = Simulator(m) diff --git a/src/soc/fu/ldst/pipe_data.py b/src/soc/fu/ldst/pipe_data.py index 8200c994..a2f61e93 100644 --- a/src/soc/fu/ldst/pipe_data.py +++ b/src/soc/fu/ldst/pipe_data.py @@ -6,7 +6,7 @@ class LDSTInputData(IntegerData): regspec = [('INT', 'ra', '0:63'), # RA ('INT', 'rb', '0:63'), # RB/immediate ('INT', 'rc', '0:63'), # RC - ('XER', 'xer_so', '32') # XER bit 32: SO + # XXX TODO, later ('XER', 'xer_so', '32') # XER bit 32: SO ] def __init__(self, pspec): super().__init__(pspec, False) @@ -17,8 +17,9 @@ class LDSTInputData(IntegerData): class LDSTOutputData(IntegerData): regspec = [('INT', 'o', '0:63'), # RT ('INT', 'o1', '0:63'), # RA (effective address, update mode) - ('CR', 'cr_a', '0:3'), - ('XER', 'xer_so', '32')] + # TODO, later ('CR', 'cr_a', '0:3'), + # TODO, later ('XER', 'xer_so', '32') + ] def __init__(self, pspec): super().__init__(pspec, True) # convenience diff --git a/src/soc/fu/ldst/test/test_pipe_caller.py b/src/soc/fu/ldst/test/test_pipe_caller.py index d34323bf..9f2f0c09 100644 --- a/src/soc/fu/ldst/test/test_pipe_caller.py +++ b/src/soc/fu/ldst/test/test_pipe_caller.py @@ -64,8 +64,8 @@ class LDSTTestCase(FHDLTestCase): lst = ["stw 2, 0(1)", "lwz 3, 0(1)"] initial_regs = [0] * 32 - initial_regs[1] = 0x0010 - initial_regs[2] = 0x1234 + initial_regs[1] = 0x0004 + initial_regs[2] = 0x0008 self.run_tst_program(Program(lst), initial_regs) def test_ilang(self): diff --git a/src/soc/fu/regspec.py b/src/soc/fu/regspec.py index 75c629ab..1524e8aa 100644 --- a/src/soc/fu/regspec.py +++ b/src/soc/fu/regspec.py @@ -57,15 +57,13 @@ class RegSpec: return get_regspec_bitwidth(self._rwid, 0, i) -class RegSpecALUAPI: - def __init__(self, rwid, alu): +class RegSpecAPI: + def __init__(self, rwid): """RegSpecAPI * :rwid: regspec - * :alu: ALU covered by this regspec """ self.rwid = rwid - self.alu = alu # actual ALU - set as a "submodule" of the CU def get_in_spec(self, i): return self.rwid[0][i] @@ -79,6 +77,17 @@ class RegSpecALUAPI: def get_out_name(self, i): return self.get_out_spec(i)[1] + +class RegSpecALUAPI(RegSpecAPI): + def __init__(self, rwid, alu): + """RegSpecAPI + + * :rwid: regspec + * :alu: ALU covered by this regspec + """ + super().__init__(rwid) + self.alu = alu + def get_out(self, i): if isinstance(self.rwid, int): # old - testing - API (rwid is int) return self.alu.out[i]