Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert many LaTeX register/field macros to asciidoc #934

Merged
merged 3 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ build-no-container: build-registers
build-registers: $(REGISTERS_ADOC)

%.adoc: ../xml/%.xml $(REGISTERS_PY)
../registers.py --adoc $< > $@
../registers.py --adoc $@ --adoc-definitions $(patsubst %.adoc,%-def.adoc,$@) $<

clean:
@echo "Cleaning up generated files..."
rm -f $(PDF_RESULT)
rm -f $(PDF_RESULT) $(REGISTERS_ADOC)
@echo "Cleanup completed."
116 changes: 73 additions & 43 deletions registers.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ def toLatexIdentifier( *args ):
return text

def toAdocIdentifier( *args ):
text = "".join( (a or "").lower() for a in args )
text = "-".join( (a or "").lower().rstrip("_") for a in args )
text = re.sub( "\s+", "", text )
return text

def toCIdentifier( text ):
Expand All @@ -381,6 +382,17 @@ def write_definitions( fd, registers ):
toLatexIdentifier( registers.prefix, regid, f.name ),
f.name ) )

def write_adoc_definitions( fd, registers ):
for r in registers.registers:
regid = r.short or r.label
if r.define:
macroName = toAdocIdentifier( registers.prefix, regid )
fd.write( f":{macroName}: <<{macroName},{r.short or r.label}>>\n" )
for f in r.fields:
if f.define:
macroName = toAdocIdentifier( regid, f.name )
fd.write( f":{macroName}: <<{macroName},{f.name}>>\n" )

class Macro:
def __init__(self, name, expressionText):
self.name = name
Expand Down Expand Up @@ -805,6 +817,7 @@ def print_latex_register( registers ):
def remove_indent( text ):
return "\n".join( line.lstrip() for line in text.splitlines() )


def add_continuations(text):
lines = text.splitlines()
result = []
Expand All @@ -815,8 +828,7 @@ def add_continuations(text):
result.append(current_line)
return "\n".join(result)

def print_adoc( registers, source ):
print(f"// Registers auto-generated on {datetime.now()} from {source}")
def write_adoc( fd, registers ):
sub = "=" * registers.depth
for r in registers.registers:
if not r.fields and not r.description:
Expand All @@ -825,31 +837,31 @@ def print_adoc( registers, source ):
if r.short:
# TODO: Check that (((foo))) renders as ((foo)) inside parens
if r.address:
print(f"==={sub} {r.name} ((({r.short})), at {r.address})")
fd.write(f"==={sub} {r.name} ((({r.short})), at {r.address})\n")
else:
print(f"==={sub} {r.name} ((({r.short})))")
fd.write(f"==={sub} {r.name} ((({r.short})))\n")
# TODO: confirm that index works
else:
if r.address:
print(f"==={sub} ((`{r.name}`)) (at {r.address})")
fd.write(f"==={sub} ((`{r.name}`)) (at {r.address})\n")
else:
print(f"==={sub} ((`{r.name}`))")
print()
fd.write(f"==={sub} ((`{r.name}`))\n")
fd.write("\n")
if r.label and r.define:
print("[[%s]]" % toAdocIdentifier(registers.prefix, r.label))
print(remove_indent(r.description))
print()
fd.write("[[%s]]\n" % toAdocIdentifier(registers.prefix, r.label))
fd.write(remove_indent(r.description))
fd.write("\n")

if r.fields:
if registers.prefix == "CSR_":
if int(r.address, 0) >= 0xc00:
print("This CSR is read-only.")
fd.write("This CSR is read-only.\n")
elif all(f.access in ('R', '0') for f in r.fields):
print("Writing this read/write CSR has no effect.")
fd.write("Writing this read/write CSR has no effect.\n")
else:
print("This CSR is read/write.")
fd.write("This CSR is read/write.\n")
elif all(f.access in ('R', '0') for f in r.fields):
print("This entire register is read-only.")
fd.write("This entire register is read-only.\n")

# todo: use wavedrom to draw the picture
# print("\\begin{center}")
Expand Down Expand Up @@ -913,39 +925,35 @@ def print_adoc( registers, source ):
columns += [("^1", "Reset", lambda f: f.reset)]

if any( f.description for f in r.fields ):
#print("\\tabletail{\\hline \\multicolumn{%d}{|r|}" % len(columns))
#print(" {{Continued on next page}} \\\\ \\hline}")
cols = ",".join(c[0] for c in columns)
print(f'[float="center",align="center",cols="{cols}",options="header"]')
print("|===")
fd.write(f'[float="center",align="center",cols="{cols}",options="header"]\n')
fd.write("|===\n")

print("|" + " |".join(c[1] for c in columns))
fd.write("|" + " |".join(c[1] for c in columns) + "\n")

for f in r.fields:
if f.description or f.values:
identifier = toAdocIdentifier(r.short or r.label, f.name)
print(f"|[[{identifier},{identifier}]] `{columns[0][2](f)}`")
fd.write(f"|[[{identifier},{identifier}]] `{columns[0][2](f)}`\n")
for c in columns[1:]:
print("|" + add_continuations(remove_indent( c[2](f) )))
fd.write("|" + add_continuations(remove_indent( c[2](f) )) + "\n")

print("|===")
print()
fd.write("|===\n")
fd.write("\n")

def print_adoc_index( registers, source ):
print(f"// Index auto-generated on {datetime.now()} from {source}")

print(remove_indent(registers.description))
def write_adoc_index( fd, registers ):
fd.write(remove_indent(registers.description))

columns = [
("Address", "1"),
("Name", "6")]
if any(r.sdesc for r in registers.registers):
columns.append(("Description", "6"))

print(f"[[{toAdocIdentifier(registers.prefix, registers.label)}]]")
print('[cols="' + ",".join(c[1] for c in columns) + '",options="header"]')
print("|===")
print("|" + " |".join(c[0] for c in columns))
fd.write(f"[[{toAdocIdentifier(registers.prefix, registers.label)}]]\n")
fd.write('[cols="' + ",".join(c[1] for c in columns) + '",options="header"]\n')
fd.write("|===\n")
fd.write("|" + " |".join(c[0] for c in columns) + "\n")

for r in sorted( registers.registers,
key=cmp_to_key(lambda a, b: compare_address(a.address, b.address))):
Expand All @@ -954,10 +962,10 @@ def print_adoc_index( registers, source ):
else:
name = r.name
if r.sdesc:
print("|%s | %s | %s" % ( r.address, name, r.sdesc ))
fd.write("|%s |%s |%s\n" % ( r.address, name, r.sdesc ))
else:
print("|%s | %s" % ( r.address, name ))
print("|===")
fd.write("|%s |%s\n" % ( r.address, name ))
fd.write("|===\n")

def main():
parser = argparse.ArgumentParser()
Expand All @@ -967,8 +975,10 @@ def main():
'start/end positions.' )
parser.add_argument( '--custom', action='store_true',
help='Use custom LaTeX.' )
parser.add_argument( '--adoc', action='store_true',
help='Use asciidoc.' )
parser.add_argument( '--adoc',
help='Write asciidoc registers to the named file.' )
parser.add_argument( '--adoc-definitions',
help='Write asciidoc register style definitions to the named file.' )
parser.add_argument( '--definitions',
help='Write register style definitions to the named file.' )
parser.add_argument( '--cheader',
Expand Down Expand Up @@ -997,17 +1007,37 @@ def main():
write_cheader( open( parsed.cheader, "w" ), registers )
if parsed.chisel:
write_chisel( open( parsed.chisel, "w" ), registers )
if not registers.skip_index:
if parsed.adoc:
print_adoc_index( registers, parsed.path )
else:
print_latex_index( registers )
if not registers.skip_index and not parsed.adoc:
print_latex_index( registers )
if parsed.register:
assert(0)
print_latex_register( registers )
if parsed.custom:
print_latex_custom( registers )
if parsed.adoc:
print_adoc( registers, parsed.path )
with open( parsed.adoc, "w" ) as fd:
fd.write(f"// Auto-generated on {datetime.now()} from {parsed.path}")
if not registers.skip_index:
write_adoc_index( fd, registers )
write_adoc( fd, registers )
if parsed.adoc_definitions:
with open( parsed.adoc_definitions, "w" ) as fd:
fd.write(f"// Auto-generated on {datetime.now()} from {parsed.path}")
write_adoc_definitions( fd, registers )

#sed_convert(registers)

def sed_convert( registers ):
for r in registers.registers:
regid = r.short or r.label
if r.define:
latex = "\\\\R" + toLatexIdentifier( registers.prefix, regid )
adoc = "{" + toAdocIdentifier( registers.prefix, regid ) + "}"
print(f"s/{latex}/{adoc}/g")
for f in r.fields:
if f.define:
latex = "\\\\F" + toLatexIdentifier( registers.prefix, regid, f.name )
adoc = "{" + toAdocIdentifier( regid, f.name ) + "}"
print(f"s/{latex}/{adoc}/g")

sys.exit( main() )
9 changes: 9 additions & 0 deletions riscv-debug-header.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ Andy Wright, Bryan Wyatt, and Florian Zaruba.

_This document is released under a Creative Commons Attribution 4.0 International License._

// Include macros for registers and fields
include::build/abstract_commands-def.adoc[]
include::build/core_registers-def.adoc[]
include::build/dm_registers-def.adoc[]
include::build/hwbp_registers-def.adoc[]
include::build/jtag_registers-def.adoc[]
include::build/sample_registers-def.adoc[]
include::build/sw_registers-def.adoc[]

include::introduction.adoc[]
include::overview.adoc[]
include::debug_module.adoc[]
Expand Down
Loading