Source code for hwtBuildsystem.yosys.logParser.synthesis

import re


[docs]class YosysSynthesisLogParser(): RE_TABLE_HEADER_LINE = re.compile("^=== (.+) ===$") RE_INDENT = re.compile("^( *)") RE_CELLS = re.compile("^ *(.+) (\d+)$") """ :ivar text: text of the log from yosys synthesis run """ def __init__(self, text: str, topName: str): self.lines = text.split("\r\n") self.topName = topName self.tables = {} def _parseTableColumns(self, line): assert line indent = self.RE_INDENT.match(line).group(1) indent = len(indent) if indent == 3: # first indent key, val = line.split(":") else: m = self.RE_CELLS.match(line) key = m.group(1) val = m.group(2) key = key.strip() val = val.strip() return indent, key, val
[docs] def parse(self): """ Parse tables which do look like one in code bellow. :note: The items with some indents have key as a tuple of parents and self e.g. ('Number of cells', 'SB_LUT4') .. code-block:: text === ExampleTop0 === Number of wires: 11 Number of cells: 14 SB_CARRY 6 SB_LUT4 8 """ table_name = None table_content = None header_separator = False actual_parent = [] for line in self.lines: if table_name: if not line: if not header_separator: header_separator = True table_content = [] continue # end of table assert table_name not in self.tables, table_name self.tables[table_name] = table_content table_name = None table_content = None actual_parent = [] else: indent, key, val = self._parseTableColumns(line) while actual_parent and actual_parent[-1][0] >= indent: actual_parent.pop() if actual_parent: key = (*(k for _, k in actual_parent), key) actual_parent.append((indent, key)) table_content.append((key, val)) else: m = self.RE_TABLE_HEADER_LINE.match(line) if m: table_name = m.group(1)
[docs] def getBasicResourceReport(self): """ A small report function which extracts the most important values from the tables contained in a report. """ top = { k: v for k, v in self.tables[self.topName]} ic40_ffs = [ 'SB_DFF', 'SB_DFFE', 'SB_DFFER', 'SB_DFFES', 'SB_DFFESR', 'SB_DFFESS', 'SB_DFFN', 'SB_DFFNE', 'SB_DFFNER', 'SB_DFFNES', 'SB_DFFNESR', 'SB_DFFNESS', 'SB_DFFNR', 'SB_DFFNS', 'SB_DFFNSR', 'SB_DFFNSS', 'SB_DFFR', 'SB_DFFS', 'SB_DFFSR', 'SB_DFFSS', ] ice40_rams = [ 'SB_RAM40_4K', 'SB_RAM40_4KNR', 'SB_RAM40_4KNW', 'SB_RAM40_4KNRNW' ] return { "lut": int(top.get(('Number of cells', 'SB_LUT4'), 0)), 'ff': sum(int(top.get(('Number of cells', ff), 0)) for ff in ic40_ffs), 'bram': sum(int(top.get(('Number of cells', ram), 0)) for ram in ice40_rams), 'uram': 0, # no URAMS on chip 'dsp': int(top.get(('Number of cells', 'SB_MAC16'), 0)), 'latch': 0, # the latches do syntetize only to LUT }