make documented events optional
This commit is contained in:
parent
5d6c851f32
commit
3dc18efe70
|
@ -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(' <resetValue>0x{:02x}</resetValue>'.format(csr.reset_value))
|
||||
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
|
||||
svd.append(' <fields>')
|
||||
if hasattr(csr, "fields") and len(csr.fields) > 0:
|
||||
|
|
|
@ -135,8 +135,9 @@ class EventManager(Module, AutoCSR):
|
|||
asserted.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, document_fields=False):
|
||||
self.irq = Signal()
|
||||
self.document_fields = document_fields
|
||||
|
||||
def do_finalize(self):
|
||||
def source_description(src):
|
||||
|
@ -159,77 +160,91 @@ class EventManager(Module, AutoCSR):
|
|||
sources = sorted(sources_u, key=lambda x: x.duid)
|
||||
n = len(sources)
|
||||
|
||||
# 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 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)
|
||||
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
|
||||
# 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)
|
||||
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)
|
||||
# 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)),
|
||||
]
|
||||
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)]
|
||||
irqs = [self.pending.status[i] & self.enable.storage[i] for i in range(n)]
|
||||
else:
|
||||
self.status = CSR(n)
|
||||
self.pending = CSR(n)
|
||||
self.enable = CSRStorage(n)
|
||||
|
||||
for i, source in enumerate(sources):
|
||||
self.comb += [
|
||||
self.status.w[i].eq(source.status),
|
||||
If(self.pending.re & self.pending.r[i], source.clear.eq(1)),
|
||||
self.pending.w[i].eq(source.pending)
|
||||
]
|
||||
|
||||
irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
|
||||
self.comb += self.irq.eq(reduce(or_, irqs))
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
|
|
Loading…
Reference in New Issue