diff --git a/litex/soc/doc/__init__.py b/litex/soc/doc/__init__.py index 09949544f..0ee6c3d58 100644 --- a/litex/soc/doc/__init__.py +++ b/litex/soc/doc/__init__.py @@ -35,9 +35,13 @@ def generate_svd(soc, buildpath, filename=None, name="soc", **kwargs): svd.write(export.get_svd(soc, **kwargs)) -def generate_docs(soc, base_dir, project_name="LiteX SoC Project", - author="Anonymous", sphinx_extensions=[], quiet=False, note_pulses=False, - from_scratch=True): +def generate_docs(soc, base_dir, + project_name = "LiteX SoC Project", + author = "Anonymous", + sphinx_extensions = [], + quiet = False, + note_pulses = False, + from_scratch = True): """Possible extra extensions: [ 'm2r', @@ -79,7 +83,7 @@ def generate_docs(soc, base_dir, project_name="LiteX SoC Project", # that are larger than the buswidth will be turned into multiple # DocumentedCSRs. documented_regions = [] - seen_modules = set() + seen_modules = set() for name, region in soc.csr.regions.items(): module = None if hasattr(soc, name): diff --git a/litex/soc/doc/csr.py b/litex/soc/doc/csr.py index ffaecda5a..31b4b8167 100644 --- a/litex/soc/doc/csr.py +++ b/litex/soc/doc/csr.py @@ -34,32 +34,41 @@ class DocumentedCSR: return reflow(docstring) return None - def __init__(self, name, address, short_numbered_name="", short_name="", reset=0, offset=0, size=8, description=None, access="read-write", fields=[]): - self.name = name - self.short_name = short_name + def __init__(self, name, address, + short_numbered_name = "", + short_name = "", + reset = 0, + offset = 0, + size = 8, + description = None, + access = "read-write", + fields = []): + + self.name = name + self.short_name = short_name self.short_numbered_name = short_numbered_name - self.address = address - self.offset = offset - self.size = size + self.address = address + self.offset = offset + self.size = size if size == 0: print("!!! Warning: creating CSR of size 0 {}".format(name)) self.description = self.trim(description) self.reset_value = reset - self.fields = fields - self.access = access + self.fields = fields + self.access = access for f in self.fields: f.description = self.trim(f.description) class DocumentedCSRRegion: def __init__(self, name, region, module=None, submodules=[], csr_data_width=8): - self.name = name - self.origin = region.origin - self.busword = region.busword - self.raw_csrs = region.obj + self.name = name + self.origin = region.origin + self.busword = region.busword + self.raw_csrs = region.obj self.current_address = self.origin - self.sections = [] - self.csrs = [] - self.csr_data_width = csr_data_width + self.sections = [] + self.csrs = [] + self.csr_data_width = csr_data_width # If the section has extra documentation, gather it. if isinstance(module, ModuleDoc): @@ -81,10 +90,16 @@ class DocumentedCSRRegion: print("{}: Unknown module: {}".format(self.name, csr)) elif isinstance(self.raw_csrs, Memory): self.csrs.append(DocumentedCSR( - self.name.upper(), self.origin, short_numbered_name=self.name.upper(), short_name=self.name.upper(), reset=0, size=self.raw_csrs.width, - description="{} x {}-bit memory".format(self.raw_csrs.width, self.raw_csrs.depth) + name = self.name.upper(), + address = self.origin, + short_numbered_name = self.name.upper(), + short_name = self.name.upper(), + reset = 0, + size = self.raw_csrs.width, + description = "{} x {}-bit memory".format(self.raw_csrs.width, self.raw_csrs.depth) )) - print("{}@{:x}: Found memory that's {} x {} (but memories aren't documented yet)".format(self.name, self.origin, self.raw_csrs.width, self.raw_csrs.depth)) + print("{}@{:x}: Found memory that's {} x {} (but memories aren't documented yet)".format( + self.name, self.origin, self.raw_csrs.width, self.raw_csrs.depth)) else: print("{}@{:x}: Unexpected item on the CSR bus: {}".format(self.name, self.origin, self.raw_csrs)) @@ -127,9 +142,15 @@ class DocumentedCSRRegion: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: - fields.append(DocumentedCSRField(CSRField(source.name, offset=i, description="Level of the `{}` event".format(source.name)))) + fields.append(DocumentedCSRField(CSRField( + name = source.name, + offset = i, + description = "Level of the `{}` event".format(source.name)))) else: - fields.append(DocumentedCSRField(CSRField("event{}".format(i), offset=i, description="Level of the `event{}` event".format(i)))) + fields.append(DocumentedCSRField(CSRField( + name = "event{}".format(i), + offset = i, + description = "Level of the `event{}` event".format(i)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "This register contains the current raw level of the Event trigger. Writes to this register have no effect." @@ -138,9 +159,15 @@ class DocumentedCSRRegion: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: - fields.append(DocumentedCSRField(CSRField(source.name, offset=i, description=source_description(source)))) + fields.append(DocumentedCSRField(CSRField( + name = source.name, + offset = i, + description = source_description(source)))) else: - fields.append(DocumentedCSRField(CSRField("event{}".format(i), offset=i, description=source_description(source)))) + fields.append(DocumentedCSRField(CSRField( + name = "event{}".format(i), + offset = i, + description = source_description(source)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "When an Event occurs, the corresponding bit will be set in this register. To clear the Event, set the corresponding bit in this register." @@ -149,18 +176,24 @@ class DocumentedCSRRegion: fields = [] for i, source in enumerate(sources): if hasattr(source, "name") and source.name is not None: - fields.append(DocumentedCSRField(CSRField(source.name, offset=i, description="Write a `1` to enable the `{}` Event".format(source.name)))) + fields.append(DocumentedCSRField(CSRField( + name = source.name, + offset = i, + description = "Write a `1` to enable the `{}` Event".format(source.name)))) else: - fields.append(DocumentedCSRField(CSRField("event{}".format(i), offset=i, description="Write a `1` to enable the `{}` Event".format(i)))) + fields.append(DocumentedCSRField(CSRField( + name = "event{}".format(i), + offset = i, + description = "Write a `1` to enable the `{}` Event".format(i)))) dcsr.fields = fields if dcsr.description is None: dcsr.description = "This register enables the corresponding Events. Write a `0` to this register to disable individual events." def sub_csr_bit_range(self, csr, offset): nwords = (csr.size + self.busword - 1)//self.busword - i = nwords - offset - 1 - nbits = min(csr.size - i*self.busword, self.busword) - 1 - name = (csr.name + str(i) if nwords > 1 else csr.name).upper() + i = nwords - offset - 1 + nbits = min(csr.size - i*self.busword, self.busword) - 1 + name = (csr.name + str(i) if nwords > 1 else csr.name).upper() origin = i*self.busword return (origin, nbits, name) @@ -268,11 +301,11 @@ class DocumentedCSRRegion: def document_csr(self, csr): """Generates one or more DocumentedCSR, which will get appended to self.csrs""" - fields = [] - description = None + fields = [] + description = None atomic_write = False - full_name = self.name.upper() + "_" + csr.name.upper() - reset = 0 + full_name = self.name.upper() + "_" + csr.name.upper() + reset = 0 if isinstance(csr, CSRStatus): access = "read-only" else: @@ -306,28 +339,49 @@ class DocumentedCSRRegion: else: d = bits_str + " " + reflow(d) self.csrs.append(DocumentedCSR( - sub_name, self.current_address, short_numbered_name=name.upper(), short_name=csr.name.upper(), reset=(reset>>start)&((2**length)-1), - offset=start, size=self.csr_data_width, - description=d, fields=self.split_fields(fields, start, start + length), access=access + name = sub_name, + address = self.current_address, + short_numbered_name = name.upper(), + short_name = csr.name.upper(), + reset = (reset>>start)&((2**length)-1), + offset = start, + size = self.csr_data_width, + description = d, + fields = self.split_fields(fields, start, start + length), + access = access )) else: self.csrs.append(DocumentedCSR( - sub_name, self.current_address, short_numbered_name=name.upper(), short_name=csr.name.upper(), reset=(reset>>start)&((2**length)-1), - offset=start, size=self.csr_data_width, - description=bits_str, fields=self.split_fields(fields, start, start + length), access=access + name = sub_name, + address = self.current_address, + short_numbered_name = name.upper(), + short_name = csr.name.upper(), + reset = (reset>>start)&((2**length)-1), + offset = start, + size = self.csr_data_width, + description = bits_str, + fields = self.split_fields(fields, start, start + length), + access = access )) self.current_address += 4 else: self.csrs.append(DocumentedCSR( - full_name, self.current_address, short_numbered_name=csr.name.upper(), short_name=csr.name.upper(), reset=reset, size=size, - description=description, fields=fields, access=access + name = full_name, + address = self.current_address, + short_numbered_name = csr.name.upper(), + short_name = csr.name.upper(), + reset = reset, + size = size, + description = description, + fields = fields, + access = access )) self.current_address += 4 def make_value_table(self, values): - ret = "" - max_value_width=len("Value") - max_description_width=len("Description") + ret = "" + max_value_width = len("Value") + max_description_width = len("Description") for v in values: (value, name, description) = (None, None, None) if len(v) == 2: @@ -380,7 +434,7 @@ class DocumentedCSRRegion: for section in self.sections: title = textwrap.dedent(section.title()) - body = textwrap.dedent(section.body()) + body = textwrap.dedent(section.body()) print("{}".format(title), file=stream) print("-" * len(title), file=stream) @@ -417,11 +471,10 @@ class DocumentedCSRRegion: print(textwrap.indent(csr.description, prefix=" "), file=stream) self.print_reg(csr, stream) if len(csr.fields) > 0: - max_field_width=len("Field") - max_name_width=len("Name") - max_description_width=len("Description") - value_tables = {} - + max_field_width = len("Field") + max_name_width = len("Name") + max_description_width = len("Description") + value_tables = {} for f in csr.fields: field = self.bit_range(f.offset, f.offset + f.size) max_field_width = max(max_field_width, len(field)) diff --git a/litex/soc/doc/module.py b/litex/soc/doc/module.py index 63380b3d6..fef096c8d 100644 --- a/litex/soc/doc/module.py +++ b/litex/soc/doc/module.py @@ -33,9 +33,9 @@ def gather_submodules_inner(module, depth, seen_modules, submodules): return submodules def gather_submodules(module): - depth = 0 + depth = 0 seen_modules = set() - submodules = { + submodules = { "event_managers": [], "module_doc": [], } @@ -50,7 +50,7 @@ class DocumentedModule: """Multi-section Documentation of a Module""" def __init__(self, name, module, has_documentation=False): - self.name = name + self.name = name self.sections = [] if isinstance(module, ModuleDoc):