From 4cda523f0cbb6f487869d044a4e309dbd3a0b72b Mon Sep 17 00:00:00 2001 From: Tobias Platen Date: Sat, 2 Oct 2021 14:17:17 +0200 Subject: [PATCH] PortInterfaceBase: add dcbz handling --- src/soc/experiment/pimem.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/soc/experiment/pimem.py b/src/soc/experiment/pimem.py index 3d6dc8c7..3119c3ba 100644 --- a/src/soc/experiment/pimem.py +++ b/src/soc/experiment/pimem.py @@ -31,6 +31,7 @@ from soc.experiment.mem_types import LDSTException # for testing purposes from soc.experiment.testmem import TestMemory #from soc.scoreboard.addr_split import LDSTSplitter +from nmutil.util import Display import unittest @@ -95,9 +96,11 @@ class PortInterface(RecordObject): RecordObject.__init__(self, name=name) - # distinguish op type (ld/st) - self.is_ld_i = Signal(reset_less=True) - self.is_st_i = Signal(reset_less=True) + # distinguish op type (ld/st/dcbz) + self.is_ld_i = Signal(reset_less=True) + self.is_st_i = Signal(reset_less=True) + self.is_dcbz_i = Signal(reset_less=True) + self.is_dcbz = self.is_dcbz_i # renamed signal hack # LD/ST data length (TODO: other things may be needed) self.data_len = Signal(4, reset_less=True) @@ -115,13 +118,12 @@ class PortInterface(RecordObject): self.st = Data(regwid, "st_data_i") # ok to be set by CompUnit # additional "modes" - self.is_dcbz = Signal() # data cache block zero request self.is_nc = Signal() # no cacheing self.msr_pr = Signal() # 1==virtual, 0==privileged # mmu self.mmu_done = Signal() # keep for now - + # dcache self.ldst_error = Signal() ## Signalling ld/st error - NC cache hit, TLB miss, prot/RC failure @@ -176,6 +178,7 @@ class PortInterfaceBase(Elaboratable): def set_rd_addr(self, m, addr, mask, misalign, msr_pr): pass def set_wr_data(self, m, data, wen): pass def get_rd_data(self, m): pass + def set_dcbz_addr(self, m, addr): pass def elaborate(self, platform): m = Module() @@ -185,6 +188,8 @@ class PortInterfaceBase(Elaboratable): m.submodules.st_active = st_active = SRLatch(False, name="st_active") m.submodules.st_done = st_done = SRLatch(False, name="st_done") m.submodules.ld_active = ld_active = SRLatch(False, name="ld_active") + dcbz_active = SRLatch(False, name="dcbz_active") + m.submodules.dcbz_active = dcbz_active # this one is new and untested m.submodules.reset_l = reset_l = SRLatch(True, name="reset") m.submodules.adrok_l = adrok_l = SRLatch(False, name="addr_acked") m.submodules.busy_l = busy_l = SRLatch(False, name="busy") @@ -192,10 +197,13 @@ class PortInterfaceBase(Elaboratable): self.busy_l = busy_l + comb += Display("PortInterfaceBase dcbz_active.q=%i",dcbz_active.q) + sync += st_done.s.eq(0) comb += st_done.r.eq(0) comb += st_active.r.eq(0) comb += ld_active.r.eq(0) + comb += dcbz_active.r.eq(0) comb += cyc_l.s.eq(0) comb += cyc_l.r.eq(0) comb += busy_l.s.eq(0) @@ -208,9 +216,11 @@ class PortInterfaceBase(Elaboratable): lds = Signal(reset_less=True) sts = Signal(reset_less=True) + dcbzs = Signal(reset_less=True) pi = self.pi comb += lds.eq(pi.is_ld_i) # ld-req signals comb += sts.eq(pi.is_st_i) # st-req signals + comb += dcbzs.eq(pi.is_dcbz_i) # dcbz-req signals (new, untested) pr = pi.msr_pr # MSR problem state: PR=1 ==> virt, PR==0 ==> priv # detect busy "edge" @@ -229,6 +239,7 @@ class PortInterfaceBase(Elaboratable): # activate mode: only on "edge" comb += ld_active.s.eq(rising_edge(m, lds)) # activate LD mode comb += st_active.s.eq(rising_edge(m, sts)) # activate ST mode + comb += dcbz_active.s.eq(rising_edge(m, dcbzs)) # activate ST mode # LD/ST requested activates "busy" (only if not already busy) with m.If(self.pi.is_ld_i | self.pi.is_st_i): @@ -246,6 +257,11 @@ class PortInterfaceBase(Elaboratable): comb += pi.addr_ok_o.eq(1) # acknowledge addr ok sync += adrok_l.s.eq(1) # and pull "ack" latch + # if now in "DCBZ" mode: wait for addr_ok, then send the address out + # to memory, acknowledge address, and send out LD data + with m.If(dcbz_active.q): + self.set_dcbz_addr(m, pi.addr.data) + # if now in "ST" mode: likewise do the same but with "ST" # to memory, acknowledge address, and send out LD data with m.If(st_active.q): @@ -295,8 +311,9 @@ class PortInterfaceBase(Elaboratable): # after waiting one cycle (reset_l is "sync" mode), reset the port with m.If(reset_l.q): - comb += ld_active.r.eq(1) # leave the ST active for 1 cycle + comb += ld_active.r.eq(1) # leave the LD active for 1 cycle comb += st_active.r.eq(1) # leave the ST active for 1 cycle + comb += dcbz_active.r.eq(1) # leave the DCBZ active for 1 cycle comb += reset_l.r.eq(1) # clear reset comb += adrok_l.r.eq(1) # address reset comb += st_done.r.eq(1) # store done reset -- 2.30.2