Skip to content
Snippets Groups Projects
Commit 117b30be authored by Pieter Donker's avatar Pieter Donker
Browse files

Task #893: add args_documentation new draft

parent 7d1d6883
No related branches found
No related tags found
No related merge requests found
...@@ -36,7 +36,8 @@ import traceback ...@@ -36,7 +36,8 @@ import traceback
import yaml import yaml
import time import time
from subprocess import CalledProcessError from subprocess import CalledProcessError
from pylatex import Document, Section, Subsection, Command, Package, Tabular, MultiColumn, MultiRow, SmallText, LargeText from pylatex import Document, Section, Subsection, Subsubsection, Command, Package, Tabular, MultiColumn, MultiRow, NewLine
from pylatex import SmallText, MediumText, LargeText, HugeText
from pylatex.utils import italic, bold, NoEscape, verbatim, escape_latex from pylatex.utils import italic, bold, NoEscape, verbatim, escape_latex
from py_args_lib import * from py_args_lib import *
...@@ -46,272 +47,166 @@ import common as cm ...@@ -46,272 +47,166 @@ import common as cm
def main(): def main():
try: try:
for systemname in args.system: for systemname in args.system:
try: doc = SystemDocumentation(systemname)
system_filename = "./systems/{}.system.yaml".format(systemname) doc.fill()
config = yaml.load(open(system_filename, "r")) doc.make_pdf()
name = config['system_name'] del doc
documentation = Documentation(name) time.sleep(0.5)
system = System(system_filename)
documentation.add(config['system_name'], system)
documentation.generate_pdf()
del documentation
del system
time.sleep(1.0)
except CalledProcessError:
pass
for peripheralname in args.peripheral: for peripheralname in args.peripheral:
try: doc = PeripheralDocumentation(peripheralname)
peripheral_filename = "./peripherals/{}.peripheral.yaml".format(peripheralname) doc.fill()
logger.info("Load peripheral(s) from '%s'", peripheral_filename) doc.make_pdf()
config = yaml.load(open(peripheral_filename, "r")) del doc
name = config['hdl_library_name'] time.sleep(0.5)
for peripheral_config in config['peripherals']:
peripheral = Peripheral(peripheral_config)
logger.info(" read peripheral '%s'" % peripheral.component_name())
peripheral.eval_peripheral()
documentation = Documentation(name)
peripheral.eval_peripheral()
documentation.add(config['hdl_library_name'], peripheral)
documentation.generate_pdf()
del documentation
del system
time.sleep(1.0)
except CalledProcessError:
pass
except IOError: except IOError:
logger.error("config file '{}' does not exist".format(filename)) logger.error("config file '{}' does not exist".format(filename))
class Documentation(object):
""" make documentation for system or peripheral(s) class SystemDocumentation(object):
""" def __init__(self, systemname):
def __init__(self, document_name): self.systemname = systemname
self.root_dir = os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML') self.system_filename = "./systems/{}.system.yaml".format(systemname)
self.document_name = document_name self.config = yaml.load(open(self.system_filename, "r"))
self.config = {}
geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"} geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"}
self.doc = Document(geometry_options=geometry_options) self.doc = Document(geometry_options=geometry_options)
#doc.packages.append(Package(u'listings')) self.doc.preamble.append(Command('title', 'ARGS Documentation for {}'.format(self.systemname)))
#doc.append(NoEscape(r'\lstset{columns=flexible}')) self.doc.preamble.append(Command('author', 'oneclick-args-documentation-script'))
#doc.append(NoEscape(r'\lstset{keepspaces=true}')) self.doc.preamble.append(Command('date', NoEscape(r'\today')))
#doc.append(NoEscape(r'\lstset{basicstyle=\ttfamily\color{blue}}')) self.doc.append(NoEscape(r'\maketitle'))
self.add_title()
def generate_pdf(self): #self.doc = Documentation(self.config['system_name'])
self.doc.generate_pdf('{}'.format(self.document_name), clean_tex=True) self.system = System(self.system_filename)
#self.doc.generate_tex()
def add_title(self):
""" add title to document """
self.doc.preamble.append(Command('title', 'MM Documentation for {}'.format(self.document_name))) def __del__(self):
self.doc.preamble.append(Command('author', 'oneclick-mm-documentation-script')) del self.doc
self.doc.preamble.append(Command('date', NoEscape(r'\today'))) del self.system
time.sleep(0.5)
def fill(self):
with self.doc.create(Section("{} system.".format(self.config['system_name']))):
self.doc.append(self.system.system_description)
self.doc.append(NoEscape(r'\maketitle')) with self.doc.create(Section("Peripherals.")):
added_instances = []
for peri_name, peri_class in sorted(self.system.peripherals.items()):
if peri_class.name() in added_instances:
continue
added_instances.append(peri_class.name())
def add(self, header, data): with self.doc.create(Section(peri_class.name(), numbering=True)):
""" add section (data) to the document with header as section name """ self.doc.append(peri_class.get_kv('peripheral_description').replace('"', ''))
if isinstance(data, str): self.doc.append(NewLine())
self.add_text(header, data)
elif isinstance(data, dict):
self.add_dict(header, data)
elif isinstance(data, Peripheral):
self.add_peripheral(header, data)
elif isinstance(data, System):
self.add_system(header, data)
else:
pass
def add_text(self, header, text): #self.doc.append(MediumText(bold("slave ports.")))
""" add text to the document """
self.add_section(header, text)
def add_dict(self, header, data): for val_info, val_type in ((peri_class.registers, 'Registers'),
""" add a dict to the document """ (peri_class.rams, 'Rams'),
for key, val in data.items(): (peri_class.fifos, 'Fifos')):
self.add(key, val)
def add_peripheral(self, header, data): if len(val_info) == 0:
""" add a peripheral to the document """ continue
self.add_section(data.name(), data.get_description() )
def add_system(self, header, data): #self.doc.add(text=val_type, size="medium")
""" add a system to the document """
self.doc.append(Command('begin', 'huge'))
self.doc.append(NoEscape("{} description.".format(header)))
self.doc.append(Command('end', 'huge'))
self.add("", data.system_description) added_val_types = []
for key, val in sorted(val_info.items()):
if val.name() in added_val_types:
continue
added_val_types.append(val.name())
with self.doc.create(Subsection("{} slave.".format(val.name().lower()), numbering=True)):
if val.get_kv('slave_description') is not None:
self.doc.append(val.get_kv('slave_description').replace('"', ''))
added_fields = []
for field_key, field_val in sorted(val.fields.items()):
real_name = field_val.name().strip().split('.')[0]
if real_name in added_fields:
continue
added_fields.append(real_name)
with self.doc.create(Subsubsection("{} field.".format("{}".format(real_name)), numbering=True)):
self.doc.append(field_val.get_kv('field_description').replace('"', '') )
#self.doc.append(NewLine())
self.doc.append(Command('begin', 'huge')) def make_pdf(self):
self.doc.append(NoEscape("Peripherals.")) try:
self.doc.append(Command('end', 'huge')) self.doc.generate_pdf('{}'.format(self.systemname), clean_tex=True)
time.sleep(0.5)
except CalledProcessError:
pass
class PeripheralDocumentation(object):
def __init__(self, peripheralname):
self.peripheralname = peripheralname
self.peripheral_filename = "./peripherals/{}.peripheral.yaml".format(peripheralname)
self.config = yaml.load(open(self.peripheral_filename, "r"))
geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"}
self.doc = Document(geometry_options=geometry_options)
self.doc.preamble.append(Command('title', 'ARGS Documentation for {}'.format(self.peripheralname)))
self.doc.preamble.append(Command('author', 'oneclick-args-documentation-script'))
self.doc.preamble.append(Command('date', NoEscape(r'\today')))
self.doc.append(NoEscape(r'\maketitle'))
def fill(self):
with self.doc.create(Section("{} library.".format(self.config['hdl_library_name']))):
self.doc.append(self.config['hdl_library_description'])
with self.doc.create(Section("Peripherals.")):
added_instances = [] added_instances = []
for key, val in sorted(data.peripherals.items()): for peri_info in self.config['peripherals']:
if val.name() in added_instances: peri_class = Peripheral(peri_info)
if peri_class.name() in added_instances:
continue
added_instances.append(peri_class.name())
with self.doc.create(Section(peri_class.name(), numbering=True)):
self.doc.append(peri_class.get_kv('peripheral_description').replace('"', ''))
self.doc.append(NewLine())
#self.doc.append(MediumText(bold("slave ports.")))
for val_info, val_type in ((peri_class.registers, 'Registers'),
(peri_class.rams, 'Rams'),
(peri_class.fifos, 'Fifos')):
if len(val_info) == 0:
continue continue
added_instances.append(val.name())
_header = val.name().strip() #self.doc.add(text=val_type, size="medium")
_text = val.get_kv('peripheral_description')
self.add(_header, _text) added_val_types = []
for key, val in sorted(val_info.items()):
def add_section(self, heading='', text=''): if val.name() in added_val_types:
with self.doc.create(Section('%s' % heading)) as sec:
lines = text.splitlines(True)
n_lines = len(lines)
block_data = []
line_nr = 0
while line_nr < n_lines:
if lines[line_nr].startswith('+--'):
block_data = []
block_data.append(lines[line_nr])
line_nr += 1
while line_nr < n_lines:
block_data.append(lines[line_nr])
if lines[line_nr].startswith('+--'):
logger.debug("append table")
self.add_table(sec, block_data)
line_nr += 1
break
line_nr += 1
elif lines[line_nr].startswith('A|'):
block_data = []
block_data.append(lines[line_nr][2:])
line_nr += 1
while line_nr < n_lines:
block_data.append(lines[line_nr][2:])
if not lines[line_nr].startswith('A|'):
logger.debug("append AscciiArt")
self.add_ascii_art(sec, block_data)
break
line_nr += 1
else:
self.add_line(sec, lines[line_nr])
line_nr += 1
return
def add_line(self, doc, line, add=True):
n_spaces = 0
_line = []
text = []
line = line.strip()
#print('3 ', line)
for ch_nr, ch in enumerate(line):
if ch == ' ':
n_spaces += 1
else:
if n_spaces == 1:
text.append(' ')
elif n_spaces:
if text:
_line.append('%s' % ''.join(text))
text = []
_line.append(NoEscape(r'\hspace{%fcm}' % (n_spaces * 0.184)))
n_spaces = 0
text.append(ch)
if text:
_line.append('%s' % ''.join(text))
#_line.append('\n')
if add:
for i in _line:
doc.append(i)
return
return _line
def add_ascii_art(self, doc, data):
doc.append(Command('begin', 'small'))
doc.append(Command('begin', 'verbatim'))
doc.append(NoEscape(''.join(data)))
doc.append(Command('end', 'verbatim'))
doc.append(Command('end', 'small'))
def add_table(self, doc, data):
table = None
table_column_pos = []
table_n_columns = 0
# get vertical line positions of second line
pos = 0
while pos >= 0:
pos = data[1].find('|', pos)
if pos > -1:
table_column_pos.append(pos)
pos += 1
# make table
table_n_columns = len(table_column_pos) - 1
#table = Tabular('c'.join('|'*len(table_column_pos)))
tabular = ['|']
p1 = table_column_pos[0]
for p2 in table_column_pos[1:]:
cols = p2 - p1
tabular.append('p{%fcm}|' % (cols * 0.16))
p1 = p2
table = Tabular(''.join(tabular))
#table.add_hline()
for line_nr, line in enumerate(data):
logger.debug("%s, %d", line, len(line))
if line.startswith('+---'): # or line.startswith('|---'):
table.add_hline()
continue continue
if line.startswith('|---'): added_val_types.append(val.name())
with self.doc.create(Subsection("{} slave.".format(val.name().lower()), numbering=True)):
if val.get_kv('slave_description') is not None:
self.doc.append(val.get_kv('slave_description').replace('"', ''))
added_fields = []
for field_key, field_val in sorted(val.fields.items()):
real_name = field_val.name().strip().split('.')[0]
if real_name in added_fields:
continue continue
added_fields.append(real_name)
with self.doc.create(Subsubsection("{} field.".format("{}".format(real_name)), numbering=True)):
self.doc.append(field_val.get_kv('field_description').replace('"', '') )
#self.doc.append(NewLine())
def make_pdf(self):
try:
self.doc.generate_pdf('{}'.format(self.peripheralname), clean_tex=True)
time.sleep(0.5)
except CalledProcessError:
pass
if line_nr == 1:
row_data = [bold(i) for i in line.strip()[1:-1].split('|')]
else:
row_data = [i for i in line.strip()[1:-1].split('|')]
logger.debug("%s", str(row_data))
row_n_cols = len(row_data)
# if all colums used add data
if row_n_cols == table_n_columns:
if len(table) > 1:
table.add_hline()
table.add_row(row_data)
else:
row_cells = []
row_data_index = 0
pos = table_column_pos[0] + 1
last_index = 0
while pos >= 0:
pos = line.find('|', pos)
if pos > -1:
for index, tcp in enumerate(table_column_pos):
if pos == tcp:
#rint "same pos, %d" % pos
#if (index - last_index) == 1:
# row_cells.append(row_data[row_data_index])
#else:
cols = index - last_index
text = row_data[row_data_index]
if len(row_data[row_data_index][:2].strip()) == 0:
row_cells.append(MultiColumn(cols, align='|c|', data=SmallText(text)))
else:
row_cells.append(MultiColumn(cols, align='|l|', data=SmallText(text)))
last_index = index
row_data_index += 1
pos += 1
else:
table.add_hline()
table.add_row(row_cells)
doc.append(table)
doc.append('\n')
return table
if __name__ == "__main__": if __name__ == "__main__":
# setup first log system before importing other user libraries # setup first log system before importing other user libraries
......
...@@ -33,7 +33,7 @@ peripherals: ...@@ -33,7 +33,7 @@ peripherals:
field_description: | field_description: |
"Contains the weights. "Contains the weights.
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part." The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
slave_discription: | slave_discription: >
" " " "
- -
...@@ -50,7 +50,7 @@ peripherals: ...@@ -50,7 +50,7 @@ peripherals:
number_of_fields: g_bf.nof_subbands * g_bf.nof_input_streams * c_nof_signal_paths_per_stream # 16*4=64, nof_input_streams*nof_signal_paths_per_stream number_of_fields: g_bf.nof_subbands * g_bf.nof_input_streams * c_nof_signal_paths_per_stream # 16*4=64, nof_input_streams*nof_signal_paths_per_stream
field_description: | field_description: |
"Contains the addresses to select from the stored subbands." "Contains the addresses to select from the stored subbands."
slave_discription: | slave_discription: >
" " " "
- -
...@@ -69,7 +69,7 @@ peripherals: ...@@ -69,7 +69,7 @@ peripherals:
field_description: | field_description: |
"Contains the weights. "Contains the weights.
The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part." The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
slave_discription: | slave_discription: >
- -
# reg_st_sst_bf # reg_st_sst_bf
...@@ -80,14 +80,14 @@ peripherals: ...@@ -80,14 +80,14 @@ peripherals:
slave_type: REG slave_type: REG
fields: fields:
- -
field_name : Treshold field_name : treshold
address_offset: 0x0 address_offset: 0x0
field_description : | field_description : |
"When the treshold register is set to 0 the statistics will be auto-correlations. "When the treshold register is set to 0 the statistics will be auto-correlations.
In case the treshold register is set to a non-zero value, it allows to create a sample & hold function In case the treshold register is set to a non-zero value, it allows to create a sample & hold function
for the a-input of the multiplier. for the a-input of the multiplier.
The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created." The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created."
slave_discription: | slave_discription: >
" " " "
peripheral_description: | peripheral_description: |
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment