From ffd2be2ba077829927bfc4194f047df8d1b4d55c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 24 Sep 2019 17:51:06 +0200 Subject: [PATCH] csr: add we signal to CSR, CSRStatus Doing actions on register read is generally not a good design practice (it's better to do separate register write to trigger actions) but in some very specific cases being able to know that register has been read can solve cases that are difficult to do with the recommended practives and that can justify doing an exception. This commit add a we signal to CSR, CSRStatus and this allow the logic to know when the CSR, CSRStatus is read. --- litex/soc/interconnect/csr.py | 23 +++++++++++++++++++---- litex/soc/interconnect/csr_bus.py | 5 ++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/litex/soc/interconnect/csr.py b/litex/soc/interconnect/csr.py index 228290fa..a7defd0a 100644 --- a/litex/soc/interconnect/csr.py +++ b/litex/soc/interconnect/csr.py @@ -94,17 +94,26 @@ class CSR(_CSRBase): w : Signal(size), in The value to be read from the bus. Must be provided at all times. + + we : Signal(), out + The strobe signal for ``w``. + It is active for one cycle, after or during a read from the bus. """ def __init__(self, size=1, name=None): _CSRBase.__init__(self, size, name) self.re = Signal(name=self.name + "_re") - self.r = Signal(self.size, name=self.name + "_r") - self.w = Signal(self.size, name=self.name + "_w") + self.r = Signal(self.size, name=self.name + "_r") + self.we = Signal(name=self.name + "_we") + self.w = Signal(self.size, name=self.name + "_w") def read(self): """Read method for simulation.""" - return (yield self.w) + yield self.we.eq(1) + value = (yield self.w) + yield + yield self.we.eq(0) + return value def write(self, value): """Write method for simulation.""" @@ -282,6 +291,7 @@ class CSRStatus(_CompoundCSR): _CompoundCSR.__init__(self, size, name) self.description = description self.status = Signal(self.size, reset=reset) + self.we = Signal() for field in fields: self.comb += self.status[field.offset:field.offset + field.size].eq(getattr(self.fields, field.name)) @@ -292,10 +302,15 @@ class CSRStatus(_CompoundCSR): sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name) self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits]) self.simple_csrs.append(sc) + self.comb += self.we.eq(sc.we) def read(self): """Read method for simulation.""" - return (yield self.status) + yield self.we.eq(1) + value = (yield self.status) + yield + yield self.we.eq(0) + return value # CSRStorage --------------------------------------------------------------------------------------- diff --git a/litex/soc/interconnect/csr_bus.py b/litex/soc/interconnect/csr_bus.py index 038cdd59..dac45972 100644 --- a/litex/soc/interconnect/csr_bus.py +++ b/litex/soc/interconnect/csr_bus.py @@ -171,7 +171,10 @@ class CSRBank(csr.GenericBank): c.r.eq(self.bus.dat_w[:c.size]), c.re.eq(sel & \ self.bus.we & \ - (self.bus.adr[adr_shift:adr_shift+self.decode_bits] == i)) + (self.bus.adr[adr_shift:adr_shift+self.decode_bits] == i)), + c.we.eq(sel & \ + ~self.bus.we & \ + (self.bus.adr[adr_shift:adr_shift+self.decode_bits] == i)), ] brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs)) -- 2.30.2