Merge pull request #699 from betrusted-io/document_events
Create EventManager option for documented bits
This commit is contained in:
commit
b8b6fe2165
|
@ -19,7 +19,7 @@ class I2S_FORMAT(Enum):
|
||||||
I2S_LEFT_JUSTIFIED = 2
|
I2S_LEFT_JUSTIFIED = 2
|
||||||
|
|
||||||
class S7I2S(Module, AutoCSR, AutoDoc):
|
class S7I2S(Module, AutoCSR, AutoDoc):
|
||||||
def __init__(self, pads, fifo_depth=256, controller=False, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28):
|
def __init__(self, pads, fifo_depth=256, controller=False, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28, document_interrupts=False):
|
||||||
if master == True:
|
if master == True:
|
||||||
print("Master/slave terminology deprecated, please use controller/peripheral. Please see http://oshwa.org/a-resolution-to-redefine-spi-signal-names.")
|
print("Master/slave terminology deprecated, please use controller/peripheral. Please see http://oshwa.org/a-resolution-to-redefine-spi-signal-names.")
|
||||||
controller = True
|
controller = True
|
||||||
|
@ -198,7 +198,7 @@ class S7I2S(Module, AutoCSR, AutoDoc):
|
||||||
]
|
]
|
||||||
|
|
||||||
# Interrupts
|
# Interrupts
|
||||||
self.submodules.ev = EventManager()
|
self.submodules.ev = EventManager(document_fields=document_interrupts)
|
||||||
if hasattr(pads, 'rx'):
|
if hasattr(pads, 'rx'):
|
||||||
self.ev.rx_ready = EventSourcePulse(description="Indicates FIFO is ready to read") # Rising edge triggered
|
self.ev.rx_ready = EventSourcePulse(description="Indicates FIFO is ready to read") # Rising edge triggered
|
||||||
self.ev.rx_error = EventSourcePulse(description="Indicates an Rx error has happened (over/underflow)")
|
self.ev.rx_error = EventSourcePulse(description="Indicates an Rx error has happened (over/underflow)")
|
||||||
|
|
|
@ -308,7 +308,7 @@ def get_csr_svd(soc, vendor="litex", name="soc", description=None):
|
||||||
svd.append(' <addressOffset>0x{:04x}</addressOffset>'.format(csr_address))
|
svd.append(' <addressOffset>0x{:04x}</addressOffset>'.format(csr_address))
|
||||||
svd.append(' <resetValue>0x{:02x}</resetValue>'.format(csr.reset_value))
|
svd.append(' <resetValue>0x{:02x}</resetValue>'.format(csr.reset_value))
|
||||||
svd.append(' <size>{}</size>'.format(length))
|
svd.append(' <size>{}</size>'.format(length))
|
||||||
svd.append(' <access>{}</access>'.format(csr.access))
|
# svd.append(' <access>{}</access>'.format(csr.access)) # 'access' is a lie: "read-only" registers can legitimately change state based on a write, and is in fact used to handle the "pending" field in events
|
||||||
csr_address = csr_address + 4
|
csr_address = csr_address + 4
|
||||||
svd.append(' <fields>')
|
svd.append(' <fields>')
|
||||||
if hasattr(csr, "fields") and len(csr.fields) > 0:
|
if hasattr(csr, "fields") and len(csr.fields) > 0:
|
||||||
|
|
|
@ -135,13 +135,104 @@ class EventManager(Module, AutoCSR):
|
||||||
asserted.
|
asserted.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, document_fields=False):
|
||||||
self.irq = Signal()
|
self.irq = Signal()
|
||||||
|
self.document_fields = document_fields
|
||||||
|
|
||||||
def do_finalize(self):
|
def do_finalize(self):
|
||||||
|
def source_description(src):
|
||||||
|
if hasattr(src, "name") and src.name is not None:
|
||||||
|
base_text = "`1` if a `{}` event occurred. ".format(src.name)
|
||||||
|
else:
|
||||||
|
base_text = "`1` if a this particular event occurred. "
|
||||||
|
if hasattr(src, "description") and src.description is not None:
|
||||||
|
return src.description
|
||||||
|
elif isinstance(src, EventSourceLevel):
|
||||||
|
return base_text + "This Event is **level triggered** when the signal is **high**."
|
||||||
|
elif isinstance(src, EventSourcePulse):
|
||||||
|
return base_text + "This Event is triggered on a **rising** edge."
|
||||||
|
elif isinstance(src, EventSourceProcess):
|
||||||
|
return base_text + "This Event is triggered on a **falling** edge."
|
||||||
|
else:
|
||||||
|
return base_text + "This Event uses an unknown method of triggering."
|
||||||
|
|
||||||
sources_u = [v for k, v in xdir(self, True) if isinstance(v, _EventSource)]
|
sources_u = [v for k, v in xdir(self, True) if isinstance(v, _EventSource)]
|
||||||
sources = sorted(sources_u, key=lambda x: x.duid)
|
sources = sorted(sources_u, key=lambda x: x.duid)
|
||||||
n = len(sources)
|
n = len(sources)
|
||||||
|
|
||||||
|
if self.document_fields:
|
||||||
|
# annotate status
|
||||||
|
fields = []
|
||||||
|
for i, source in enumerate(sources):
|
||||||
|
if source.description == None:
|
||||||
|
desc = "This register contains the current raw level of the {} event trigger. Writes to this register have no effect.".format(str(source.name))
|
||||||
|
else:
|
||||||
|
desc = source.description
|
||||||
|
|
||||||
|
if hasattr(source, "name") and source.name is not None:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name=source.name,
|
||||||
|
size=1,
|
||||||
|
description="Level of the ``{}`` event".format(source.name)))
|
||||||
|
else:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name="event{}".format(i),
|
||||||
|
size=1,
|
||||||
|
description="Level of the ``event{}`` event".format(i)))
|
||||||
|
self.status = CSRStatus(n, description=desc, fields=fields)
|
||||||
|
|
||||||
|
# annotate pending
|
||||||
|
fields = []
|
||||||
|
for i, source in enumerate(sources):
|
||||||
|
if source.description is None:
|
||||||
|
desc = "When a {} event occurs, the corresponding bit will be set in this register. To clear the Event, set the corresponding bit in this register.".format(str(source.name))
|
||||||
|
else:
|
||||||
|
desc = source.description
|
||||||
|
|
||||||
|
if hasattr(source, "name") and source.name is not None:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name=source.name,
|
||||||
|
size=1,
|
||||||
|
description=source_description(source)))
|
||||||
|
else:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name="event{}".format(i),
|
||||||
|
size=1,
|
||||||
|
description=source_description(source)))
|
||||||
|
self.pending = CSRStatus(n, description=desc, fields=fields)
|
||||||
|
|
||||||
|
# annotate enable
|
||||||
|
fields = []
|
||||||
|
for i, source in enumerate(sources):
|
||||||
|
if source.description is None:
|
||||||
|
desc = "This register enables the corresponding {} events. Write a ``0`` to this register to disable individual events.".format(str(source.name))
|
||||||
|
else:
|
||||||
|
desc = source.description
|
||||||
|
if hasattr(source, "name") and source.name is not None:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name=source.name,
|
||||||
|
offset=i,
|
||||||
|
description="Write a ``1`` to enable the ``{}`` Event".format(source.name)))
|
||||||
|
else:
|
||||||
|
fields.append(CSRField(
|
||||||
|
name="event{}".format(i),
|
||||||
|
offset=i,
|
||||||
|
description="Write a ``1`` to enable the ``{}`` Event".format(i)))
|
||||||
|
self.enable = CSRStorage(n, description=desc, fields=fields)
|
||||||
|
|
||||||
|
for i, source in enumerate(sources):
|
||||||
|
if source.name == None:
|
||||||
|
src_name = "event{}".format(i)
|
||||||
|
else:
|
||||||
|
src_name = source.name
|
||||||
|
self.comb += [
|
||||||
|
getattr(self.status.fields, src_name).eq(source.status),
|
||||||
|
getattr(self.pending.fields, src_name).eq(source.pending),
|
||||||
|
If(self.pending.re & getattr(self.pending.fields, src_name), source.clear.eq(1)),
|
||||||
|
]
|
||||||
|
|
||||||
|
irqs = [self.pending.status[i] & self.enable.storage[i] for i in range(n)]
|
||||||
|
else:
|
||||||
self.status = CSR(n)
|
self.status = CSR(n)
|
||||||
self.pending = CSR(n)
|
self.pending = CSR(n)
|
||||||
self.enable = CSRStorage(n)
|
self.enable = CSRStorage(n)
|
||||||
|
|
Loading…
Reference in New Issue