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.
This commit is contained in:
parent
47dc332498
commit
ffd2be2ba0
|
@ -94,17 +94,26 @@ class CSR(_CSRBase):
|
||||||
w : Signal(size), in
|
w : Signal(size), in
|
||||||
The value to be read from the bus.
|
The value to be read from the bus.
|
||||||
Must be provided at all times.
|
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):
|
def __init__(self, size=1, name=None):
|
||||||
_CSRBase.__init__(self, size, name)
|
_CSRBase.__init__(self, size, name)
|
||||||
self.re = Signal(name=self.name + "_re")
|
self.re = Signal(name=self.name + "_re")
|
||||||
self.r = Signal(self.size, name=self.name + "_r")
|
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")
|
self.w = Signal(self.size, name=self.name + "_w")
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
"""Read method for simulation."""
|
"""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):
|
def write(self, value):
|
||||||
"""Write method for simulation."""
|
"""Write method for simulation."""
|
||||||
|
@ -282,6 +291,7 @@ class CSRStatus(_CompoundCSR):
|
||||||
_CompoundCSR.__init__(self, size, name)
|
_CompoundCSR.__init__(self, size, name)
|
||||||
self.description = description
|
self.description = description
|
||||||
self.status = Signal(self.size, reset=reset)
|
self.status = Signal(self.size, reset=reset)
|
||||||
|
self.we = Signal()
|
||||||
for field in fields:
|
for field in fields:
|
||||||
self.comb += self.status[field.offset:field.offset + field.size].eq(getattr(self.fields, field.name))
|
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)
|
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.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
|
||||||
self.simple_csrs.append(sc)
|
self.simple_csrs.append(sc)
|
||||||
|
self.comb += self.we.eq(sc.we)
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
"""Read method for simulation."""
|
"""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 ---------------------------------------------------------------------------------------
|
# CSRStorage ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,10 @@ class CSRBank(csr.GenericBank):
|
||||||
c.r.eq(self.bus.dat_w[:c.size]),
|
c.r.eq(self.bus.dat_w[:c.size]),
|
||||||
c.re.eq(sel & \
|
c.re.eq(sel & \
|
||||||
self.bus.we & \
|
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))
|
brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
|
||||||
|
|
Loading…
Reference in New Issue