pass over store_done correctly from dcache over PortInterface
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 16 Jan 2022 16:28:49 +0000 (16:28 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 16 Jan 2022 16:28:49 +0000 (16:28 +0000)
into LDSTCompUnit so that it can set CR0 correctly on stdcx. etc.

src/soc/experiment/compldst_multi.py
src/soc/experiment/pimem.py
src/soc/fu/ldst/loadstore.py

index b0fb3b9cbc8fd0d656d8b5585935bf5e04c7e27d..d548f90c53c95fe1c85af5d10c88ea42d44780ed 100644 (file)
@@ -245,7 +245,7 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
 
         self.o_data = Data(self.data_wid, name="o")  # Dest1 out: RT
         self.addr_o = Data(self.data_wid, name="ea")  # Addr out: Update => RA
-        self.cr_o = Data(self.data_wid, name="cr0")  # CR0 (for stdcx etc)
+        self.cr_o = Data(4, name="cr0")  # CR0 (for stdcx etc)
         self.exc_o = cu.exc_o
         self.done_o = cu.done_o
         self.busy_o = cu.busy_o
@@ -401,8 +401,8 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
                                           self.n_dst))
 
         # CR0 operand latch (CR0 written to reg 3 if Rc=1)
-        op_is_rc1 = oper_r.rc.rc & oper_r.rc.ok
-        sync += cr0_l.s.eq(reset_i & op_is_rc1)
+        op_is_rc1 = self.oper_i.rc.rc & self.oper_i.rc.ok
+        comb += cr0_l.s.eq(issue_i & op_is_rc1)
         sync += cr0_l.r.eq(reset_c)
 
         # update-mode operand latch (EA written to reg 2)
@@ -427,10 +427,15 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
         with m.If(self.done_o | terminate):
             sync += oper_r.eq(0)
 
-        # and for LD
+        # and for LD and store-done
         ldd_r = Signal(self.data_wid, reset_less=True)  # Dest register
         latchregister(m, ldd_o, ldd_r, ld_ok, name="ldo_r")
 
+        # store actioned, communicate through CR0 (for atomic LR/SC)
+        latchregister(m, self.pi.store_done.data, store_done,
+                         self.pi.store_done.ok,
+                         name="std_r")
+
         # and for each input from the incoming src operands
         srl = []
         for i in range(self.n_src):
@@ -525,23 +530,26 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
 
         # put the LD-output register directly onto the output bus on a go_write
         comb += self.o_data.data.eq(self.dest[0])
+        comb += self.o_data.ok.eq(self.wr.rel_o[0])
         with m.If(self.wr.go_i[0]):
             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])
+        comb += self.addr_o.ok.eq(self.wr.rel_o[1])
         with m.If(op_is_update & self.wr.go_i[1]):
             comb += self.dest[1].eq(addr_r)
 
         # fun-fun-fun, calculate CR0 when Rc=1 requested.
         cr0 = self.dest[2]
         comb += self.cr_o.data.eq(cr0)
+        comb += self.cr_o.ok.eq(self.wr.rel_o[2])
         with m.If(cr0_l.q):
             comb += cr0.eq(Cat(C(0, 1), store_done, C(0, 2)))
 
         # need to look like MultiCompUnit: put wrmask out.
         # XXX may need to make this enable only when write active
-        comb += self.wrmask.eq(bro & Cat(op_is_ld, op_is_update))
+        comb += self.wrmask.eq(bro & Cat(op_is_ld, op_is_update, cr0_l.q))
 
         ###########################
         # PortInterface connections
@@ -608,9 +616,6 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable):
         # store - data goes in based on go_st
         comb += pi.st.ok.eq(self.st.go_i)  # go store signals st data valid
 
-        # store actioned, communicate through CR0 (for atomic LR/SC)
-        comb += store_done.eq(pi.store_done)
-
         return m
 
     def get_out(self, i):
index 9124021774447c3d03cb5c062eb5f6ae8bc46650..d7e97ebaf4f18983d55655f361043c317bfc8a8a 100644 (file)
@@ -116,11 +116,11 @@ class PortInterface(RecordObject):
         # addr is valid (TLB, L1 etc.)
         self.addr_ok_o = Signal(reset_less=True)
         self.exc_o = LDSTException("exc")
-        self.store_done          = Signal() # store has been actioned
 
         # LD/ST
         self.ld = Data(regwid, "ld_data_o")  # ok to be set by L0 Cache/Buf
         self.st = Data(regwid, "st_data_i")  # ok to be set by CompUnit
+        self.store_done = Data(1, "store_done_o") # store has been actioned
 
         #only priv_mode = not msr_pr is used currently
         # TODO: connect signals
index 0878d09219b088ab9305756b094761e20db217d5..d13e525e6f5b7d9c3a179932da5f7920cabc2934 100644 (file)
@@ -208,8 +208,9 @@ class LoadStore1(PortInterfaceBase):
         # put data into comb which is picked up in main elaborate()
         m.d.comb += self.d_w_valid.eq(1)
         m.d.comb += self.store_data.eq(data)
-        m.d.comb += self.pi.store_done.eq(self.d_in.store_done)
         st_ok = self.done # TODO indicates write data is valid
+        m.d.comb += self.pi.store_done.data.eq(self.d_in.store_done)
+        m.d.comb += self.pi.store_done.ok.eq(1)
         return st_ok
 
     def get_rd_data(self, m):