X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fexperiment%2Fpi2ls.py;h=19edac10d7e74a3483986f519456891828243dea;hb=5dd8d33f5d9c8cddbdc4e19ad3c86b8b7893f3d3;hp=e51d41e7e43039bfe51ad45969f5ab402d9338c4;hpb=a2a001a8250da93af2cacdaebd0b388eaf6b1d47;p=soc.git diff --git a/src/soc/experiment/pi2ls.py b/src/soc/experiment/pi2ls.py index e51d41e7..19edac10 100644 --- a/src/soc/experiment/pi2ls.py +++ b/src/soc/experiment/pi2ls.py @@ -25,12 +25,50 @@ from soc.minerva.units.loadstore import LoadStoreUnitInterface from soc.experiment.pimem import PortInterface from soc.scoreboard.addr_match import LenExpand +from soc.experiment.pimem import PortInterfaceBase from nmigen.utils import log2_int from nmigen import Elaboratable, Module, Signal -class Pi2LSUI(Elaboratable): +class Pi2LSUI(PortInterfaceBase): + + def __init__(self, name, lsui=None, + data_wid=64, mask_wid=8, addr_wid=48): + print ("pi2lsui reg mask addr", data_wid, mask_wid, addr_wid) + super().__init__(data_wid, addr_wid) + if lsui is None: + lsui = LoadStoreUnitInterface(addr_wid, self.addrbits, data_wid) + self.lsui = lsui + + def set_wr_addr(self, m, addr, mask): + m.d.comb += self.lsui.x_mask_i.eq(mask) + m.d.comb += self.lsui.x_addr_i.eq(addr) + m.d.comb += self.lsui.x_valid_i.eq(1) + + def set_rd_addr(self, m, addr, mask): + m.d.comb += self.lsui.x_mask_i.eq(mask) + m.d.comb += self.lsui.x_addr_i.eq(addr) + m.d.comb += self.lsui.x_valid_i.eq(1) + + def set_wr_data(self, m, data, wen): # mask already done in addr setup + m.d.comb += self.lsui.x_st_data_i.eq(data) + return ~self.lsui.x_busy_o + + def get_rd_data(self, m): + return self.lsui.m_ld_data_o, ~self.lsui.x_busy_o + + def elaborate(self, platform): + m = super().elaborate(platform) + pi, lsui, addrbits = self.pi, self.lsui, self.addrbits + + m.d.comb += lsui.x_ld_i.eq(pi.is_ld_i) + m.d.comb += lsui.x_st_i.eq(pi.is_st_i) + + return m + + +class Pi2LSUI1(Elaboratable): def __init__(self, name, pi=None, lsui=None, data_wid=64, mask_wid=8, addr_wid=48): @@ -49,35 +87,44 @@ class Pi2LSUI(Elaboratable): """ return addr[:self.addrbits], addr[self.addrbits:] + def connect_port(self, inport): + return self.pi.connect_port(inport) + def elaborate(self, platform): m = Module() pi, lsui, addrbits = self.pi, self.lsui, self.addrbits m.submodules.lenexp = lenexp = LenExpand(log2_int(self.addrbits), 8) ld_in_progress = Signal(reset=0) + st_in_progress = Signal(reset=0) m.d.comb += lsui.x_ld_i.eq(pi.is_ld_i) m.d.comb += lsui.x_st_i.eq(pi.is_st_i) - m.d.comb += pi.busy_o.eq(lsui.x_busy_o) + m.d.comb += pi.busy_o.eq(pi.is_ld_i | pi.is_st_i)#lsui.x_busy_o) + + lsbaddr, msbaddr = self.splitaddr(pi.addr.data) + m.d.comb += lenexp.len_i.eq(pi.data_len) + m.d.comb += lenexp.addr_i.eq(lsbaddr) # LSBs of addr + m.d.comb += lsui.x_addr_i.eq(pi.addr.data) # XXX hmmm... with m.If(pi.addr.ok): # expand the LSBs of address plus LD/ST len into 16-bit mask - lsbaddr, msbaddr = self.splitaddr(pi.addr.data) - m.d.comb += lenexp.len_i.eq(pi.data_len) - m.d.comb += lenexp.addr_i.eq(lsbaddr) # LSBs of addr m.d.comb += lsui.x_mask_i.eq(lenexp.lexp_o) # pass through the address, indicate "valid" - m.d.comb += lsui.x_addr_i.eq(pi.addr.data) # XXX hmmm... m.d.comb += lsui.x_valid_i.eq(1) # indicate "OK" - XXX should be checking address valid m.d.comb += pi.addr_ok_o.eq(1) + with m.If(~lsui.x_busy_o & pi.is_st_i & pi.addr.ok): + m.d.sync += st_in_progress.eq(1) + with m.If(pi.is_ld_i): # shift/mask out the loaded data m.d.comb += pi.ld.data.eq((lsui.m_ld_data_o & lenexp.rexp_o) >> (lenexp.addr_i*8)) # remember we're in the process of loading - m.d.sync += ld_in_progress.eq(1) + with m.If(pi.addr.ok): + m.d.sync += ld_in_progress.eq(1) # If a load happened on the previous cycle and the memory is # not busy, that means it returned the data from the load. In @@ -91,5 +138,9 @@ class Pi2LSUI(Elaboratable): with m.If(pi.is_st_i & pi.st.ok): m.d.comb += lsui.x_st_data_i.eq(pi.st.data << (lenexp.addr_i*8)) + with m.If(st_in_progress): + m.d.sync += st_in_progress.eq(0) + with m.Else(): + m.d.comb += pi.busy_o.eq(0) return m