doc: align to improve readability.
This commit is contained in:
parent
4f935714de
commit
4c83c975b1
|
@ -35,9 +35,13 @@ def generate_svd(soc, buildpath, filename=None, name="soc", **kwargs):
|
||||||
svd.write(export.get_svd(soc, **kwargs))
|
svd.write(export.get_svd(soc, **kwargs))
|
||||||
|
|
||||||
|
|
||||||
def generate_docs(soc, base_dir, project_name="LiteX SoC Project",
|
def generate_docs(soc, base_dir,
|
||||||
author="Anonymous", sphinx_extensions=[], quiet=False, note_pulses=False,
|
project_name = "LiteX SoC Project",
|
||||||
from_scratch=True):
|
author = "Anonymous",
|
||||||
|
sphinx_extensions = [],
|
||||||
|
quiet = False,
|
||||||
|
note_pulses = False,
|
||||||
|
from_scratch = True):
|
||||||
"""Possible extra extensions:
|
"""Possible extra extensions:
|
||||||
[
|
[
|
||||||
'm2r',
|
'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
|
# that are larger than the buswidth will be turned into multiple
|
||||||
# DocumentedCSRs.
|
# DocumentedCSRs.
|
||||||
documented_regions = []
|
documented_regions = []
|
||||||
seen_modules = set()
|
seen_modules = set()
|
||||||
for name, region in soc.csr.regions.items():
|
for name, region in soc.csr.regions.items():
|
||||||
module = None
|
module = None
|
||||||
if hasattr(soc, name):
|
if hasattr(soc, name):
|
||||||
|
|
|
@ -34,32 +34,41 @@ class DocumentedCSR:
|
||||||
return reflow(docstring)
|
return reflow(docstring)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __init__(self, name, address, short_numbered_name="", short_name="", reset=0, offset=0, size=8, description=None, access="read-write", fields=[]):
|
def __init__(self, name, address,
|
||||||
self.name = name
|
short_numbered_name = "",
|
||||||
self.short_name = short_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.short_numbered_name = short_numbered_name
|
||||||
self.address = address
|
self.address = address
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.size = size
|
self.size = size
|
||||||
if size == 0:
|
if size == 0:
|
||||||
print("!!! Warning: creating CSR of size 0 {}".format(name))
|
print("!!! Warning: creating CSR of size 0 {}".format(name))
|
||||||
self.description = self.trim(description)
|
self.description = self.trim(description)
|
||||||
self.reset_value = reset
|
self.reset_value = reset
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
self.access = access
|
self.access = access
|
||||||
for f in self.fields:
|
for f in self.fields:
|
||||||
f.description = self.trim(f.description)
|
f.description = self.trim(f.description)
|
||||||
|
|
||||||
class DocumentedCSRRegion:
|
class DocumentedCSRRegion:
|
||||||
def __init__(self, name, region, module=None, submodules=[], csr_data_width=8):
|
def __init__(self, name, region, module=None, submodules=[], csr_data_width=8):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.origin = region.origin
|
self.origin = region.origin
|
||||||
self.busword = region.busword
|
self.busword = region.busword
|
||||||
self.raw_csrs = region.obj
|
self.raw_csrs = region.obj
|
||||||
self.current_address = self.origin
|
self.current_address = self.origin
|
||||||
self.sections = []
|
self.sections = []
|
||||||
self.csrs = []
|
self.csrs = []
|
||||||
self.csr_data_width = csr_data_width
|
self.csr_data_width = csr_data_width
|
||||||
|
|
||||||
# If the section has extra documentation, gather it.
|
# If the section has extra documentation, gather it.
|
||||||
if isinstance(module, ModuleDoc):
|
if isinstance(module, ModuleDoc):
|
||||||
|
@ -81,10 +90,16 @@ class DocumentedCSRRegion:
|
||||||
print("{}: Unknown module: {}".format(self.name, csr))
|
print("{}: Unknown module: {}".format(self.name, csr))
|
||||||
elif isinstance(self.raw_csrs, Memory):
|
elif isinstance(self.raw_csrs, Memory):
|
||||||
self.csrs.append(DocumentedCSR(
|
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,
|
name = self.name.upper(),
|
||||||
description="{} x {}-bit memory".format(self.raw_csrs.width, self.raw_csrs.depth)
|
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:
|
else:
|
||||||
print("{}@{:x}: Unexpected item on the CSR bus: {}".format(self.name, self.origin, self.raw_csrs))
|
print("{}@{:x}: Unexpected item on the CSR bus: {}".format(self.name, self.origin, self.raw_csrs))
|
||||||
|
|
||||||
|
@ -127,9 +142,15 @@ class DocumentedCSRRegion:
|
||||||
fields = []
|
fields = []
|
||||||
for i, source in enumerate(sources):
|
for i, source in enumerate(sources):
|
||||||
if hasattr(source, "name") and source.name is not None:
|
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:
|
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
|
dcsr.fields = fields
|
||||||
if dcsr.description is None:
|
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."
|
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 = []
|
fields = []
|
||||||
for i, source in enumerate(sources):
|
for i, source in enumerate(sources):
|
||||||
if hasattr(source, "name") and source.name is not None:
|
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:
|
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
|
dcsr.fields = fields
|
||||||
if dcsr.description is None:
|
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."
|
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 = []
|
fields = []
|
||||||
for i, source in enumerate(sources):
|
for i, source in enumerate(sources):
|
||||||
if hasattr(source, "name") and source.name is not None:
|
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:
|
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
|
dcsr.fields = fields
|
||||||
if dcsr.description is None:
|
if dcsr.description is None:
|
||||||
dcsr.description = "This register enables the corresponding Events. Write a `0` to this register to disable individual events."
|
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):
|
def sub_csr_bit_range(self, csr, offset):
|
||||||
nwords = (csr.size + self.busword - 1)//self.busword
|
nwords = (csr.size + self.busword - 1)//self.busword
|
||||||
i = nwords - offset - 1
|
i = nwords - offset - 1
|
||||||
nbits = min(csr.size - i*self.busword, self.busword) - 1
|
nbits = min(csr.size - i*self.busword, self.busword) - 1
|
||||||
name = (csr.name + str(i) if nwords > 1 else csr.name).upper()
|
name = (csr.name + str(i) if nwords > 1 else csr.name).upper()
|
||||||
origin = i*self.busword
|
origin = i*self.busword
|
||||||
return (origin, nbits, name)
|
return (origin, nbits, name)
|
||||||
|
|
||||||
|
@ -268,11 +301,11 @@ class DocumentedCSRRegion:
|
||||||
def document_csr(self, csr):
|
def document_csr(self, csr):
|
||||||
"""Generates one or more DocumentedCSR, which will get appended
|
"""Generates one or more DocumentedCSR, which will get appended
|
||||||
to self.csrs"""
|
to self.csrs"""
|
||||||
fields = []
|
fields = []
|
||||||
description = None
|
description = None
|
||||||
atomic_write = False
|
atomic_write = False
|
||||||
full_name = self.name.upper() + "_" + csr.name.upper()
|
full_name = self.name.upper() + "_" + csr.name.upper()
|
||||||
reset = 0
|
reset = 0
|
||||||
if isinstance(csr, CSRStatus):
|
if isinstance(csr, CSRStatus):
|
||||||
access = "read-only"
|
access = "read-only"
|
||||||
else:
|
else:
|
||||||
|
@ -306,28 +339,49 @@ class DocumentedCSRRegion:
|
||||||
else:
|
else:
|
||||||
d = bits_str + " " + reflow(d)
|
d = bits_str + " " + reflow(d)
|
||||||
self.csrs.append(DocumentedCSR(
|
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),
|
name = sub_name,
|
||||||
offset=start, size=self.csr_data_width,
|
address = self.current_address,
|
||||||
description=d, fields=self.split_fields(fields, start, start + length), access=access
|
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:
|
else:
|
||||||
self.csrs.append(DocumentedCSR(
|
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),
|
name = sub_name,
|
||||||
offset=start, size=self.csr_data_width,
|
address = self.current_address,
|
||||||
description=bits_str, fields=self.split_fields(fields, start, start + length), access=access
|
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
|
self.current_address += 4
|
||||||
else:
|
else:
|
||||||
self.csrs.append(DocumentedCSR(
|
self.csrs.append(DocumentedCSR(
|
||||||
full_name, self.current_address, short_numbered_name=csr.name.upper(), short_name=csr.name.upper(), reset=reset, size=size,
|
name = full_name,
|
||||||
description=description, fields=fields, access=access
|
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
|
self.current_address += 4
|
||||||
|
|
||||||
def make_value_table(self, values):
|
def make_value_table(self, values):
|
||||||
ret = ""
|
ret = ""
|
||||||
max_value_width=len("Value")
|
max_value_width = len("Value")
|
||||||
max_description_width=len("Description")
|
max_description_width = len("Description")
|
||||||
for v in values:
|
for v in values:
|
||||||
(value, name, description) = (None, None, None)
|
(value, name, description) = (None, None, None)
|
||||||
if len(v) == 2:
|
if len(v) == 2:
|
||||||
|
@ -380,7 +434,7 @@ class DocumentedCSRRegion:
|
||||||
|
|
||||||
for section in self.sections:
|
for section in self.sections:
|
||||||
title = textwrap.dedent(section.title())
|
title = textwrap.dedent(section.title())
|
||||||
body = textwrap.dedent(section.body())
|
body = textwrap.dedent(section.body())
|
||||||
print("{}".format(title), file=stream)
|
print("{}".format(title), file=stream)
|
||||||
print("-" * len(title), file=stream)
|
print("-" * len(title), file=stream)
|
||||||
|
|
||||||
|
@ -417,11 +471,10 @@ class DocumentedCSRRegion:
|
||||||
print(textwrap.indent(csr.description, prefix=" "), file=stream)
|
print(textwrap.indent(csr.description, prefix=" "), file=stream)
|
||||||
self.print_reg(csr, stream)
|
self.print_reg(csr, stream)
|
||||||
if len(csr.fields) > 0:
|
if len(csr.fields) > 0:
|
||||||
max_field_width=len("Field")
|
max_field_width = len("Field")
|
||||||
max_name_width=len("Name")
|
max_name_width = len("Name")
|
||||||
max_description_width=len("Description")
|
max_description_width = len("Description")
|
||||||
value_tables = {}
|
value_tables = {}
|
||||||
|
|
||||||
for f in csr.fields:
|
for f in csr.fields:
|
||||||
field = self.bit_range(f.offset, f.offset + f.size)
|
field = self.bit_range(f.offset, f.offset + f.size)
|
||||||
max_field_width = max(max_field_width, len(field))
|
max_field_width = max(max_field_width, len(field))
|
||||||
|
|
|
@ -33,9 +33,9 @@ def gather_submodules_inner(module, depth, seen_modules, submodules):
|
||||||
return submodules
|
return submodules
|
||||||
|
|
||||||
def gather_submodules(module):
|
def gather_submodules(module):
|
||||||
depth = 0
|
depth = 0
|
||||||
seen_modules = set()
|
seen_modules = set()
|
||||||
submodules = {
|
submodules = {
|
||||||
"event_managers": [],
|
"event_managers": [],
|
||||||
"module_doc": [],
|
"module_doc": [],
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class DocumentedModule:
|
||||||
"""Multi-section Documentation of a Module"""
|
"""Multi-section Documentation of a Module"""
|
||||||
|
|
||||||
def __init__(self, name, module, has_documentation=False):
|
def __init__(self, name, module, has_documentation=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sections = []
|
self.sections = []
|
||||||
|
|
||||||
if isinstance(module, ModuleDoc):
|
if isinstance(module, ModuleDoc):
|
||||||
|
|
Loading…
Reference in New Issue