diff --git a/litex/soc/integration/export.py b/litex/soc/integration/export.py index 2a6c01484..4d9b70c0e 100644 --- a/litex/soc/integration/export.py +++ b/litex/soc/integration/export.py @@ -308,7 +308,7 @@ def get_csr_svd(soc, vendor="litex", name="soc", description=None): svd.append(' 0x{:04x}'.format(csr_address)) svd.append(' 0x{:02x}'.format(csr.reset_value)) svd.append(' {}'.format(length)) - svd.append(' {}'.format(csr.access)) + # svd.append(' {}'.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(' ') if hasattr(csr, "fields") and len(csr.fields) > 0: diff --git a/litex/soc/interconnect/csr_eventmanager.py b/litex/soc/interconnect/csr_eventmanager.py index 43c57c2f5..5e4edf9a8 100644 --- a/litex/soc/interconnect/csr_eventmanager.py +++ b/litex/soc/interconnect/csr_eventmanager.py @@ -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):