From 3e9748cbd2eb89673443aecbd930bf3f6d67bf71 Mon Sep 17 00:00:00 2001 From: Ben1152000 Date: Sun, 16 Jan 2022 22:40:13 -0800 Subject: [PATCH 1/2] Bug fixes, reformatting --- sootty/__main__.py | 92 +- sootty/display.py | 16 +- sootty/exceptions.py | 9 +- sootty/limits.py | 3 +- sootty/storage/valuechange.py | 24 +- sootty/storage/wire.py | 65 +- sootty/storage/wiregroup.py | 2 +- sootty/storage/wiretrace.py | 125 ++- sootty/visualizer.py | 1524 +++++++++++++++++++-------------- 9 files changed, 1106 insertions(+), 754 deletions(-) diff --git a/sootty/__main__.py b/sootty/__main__.py index b562b49..98be314 100644 --- a/sootty/__main__.py +++ b/sootty/__main__.py @@ -3,31 +3,56 @@ from .storage import WireTrace from .visualizer import Visualizer + def main(): - parser = argparse.ArgumentParser(description='Converts .vcd wiretraces to .svg format.') - parser.add_argument('filename', metavar='FILENAME', type=str, help='input .vcd file') - parser.add_argument('-s', '--start', - type=str, metavar='FORMULA', dest='start', + parser = argparse.ArgumentParser( + description="Converts .vcd wiretraces to .svg format." + ) + parser.add_argument( + "filename", metavar="FILENAME", type=str, help="input .vcd file" + ) + parser.add_argument( + "-s", + "--start", + type=str, + metavar="FORMULA", + dest="start", help='formula for the start of the window (ex: \ "time 4", \ "after time 2 & clk", \ - "x == y | z == const 15")') - parser.add_argument('-e', '--end', - type=str, metavar='FORMULA', dest='end', - help='formula for the end of the window') - parser.add_argument('-b', '--break', - type=str, metavar='FORMULA', dest='breakpoints', - help='formula for the points in time to be highlighted') - parser.add_argument('-l', '--length', - type=int, dest='length', - help='number of cycles to display') - parser.add_argument('-d', '--display', - action='store_true', - help='display to command line') - parser.add_argument('-w', '--wires', - type=str, metavar='LIST', dest='wires', - help='comma-separated list of wires to view') + "x == y | z == const 15")', + ) + parser.add_argument( + "-e", + "--end", + type=str, + metavar="FORMULA", + dest="end", + help="formula for the end of the window", + ) + parser.add_argument( + "-b", + "--break", + type=str, + metavar="FORMULA", + dest="breakpoints", + help="formula for the points in time to be highlighted", + ) + parser.add_argument( + "-l", "--length", type=int, dest="length", help="number of cycles to display" + ) + parser.add_argument( + "-d", "--display", action="store_true", help="display to command line" + ) + parser.add_argument( + "-w", + "--wires", + type=str, + metavar="LIST", + dest="wires", + help="comma-separated list of wires to view", + ) args = parser.parse_args() # Load vcd file into wiretrace object. @@ -35,22 +60,22 @@ def main(): # Check that window bounds are well-defined. if args.end is not None and args.length is not None: - raise Exception('Length and end flags should not be provided simultaneously.') - + raise Exception("Length and end flags should not be provided simultaneously.") + # Calculate window bounds. if args.end is not None: if args.start is not None: start, end = wiretrace.compute_limits(args.start, args.end) else: - start, end = wiretrace.compute_limits('time 0', args.end) + start, end = wiretrace.compute_limits("time 0", args.end) length = end - start else: if args.start is not None: - start, end = wiretrace.compute_limits(args.start, 'time 0') + start, end = wiretrace.compute_limits(args.start, "time 0") else: start = 0 length = args.length if args.length is not None else wiretrace.length() - start - + # Calculate breakpoints breakpoints = None if args.breakpoints is not None: @@ -58,19 +83,24 @@ def main(): wires = None if args.wires: - wires = set([name.strip() for name in args.wires.split(',')]) - + wires = set([name.strip() for name in args.wires.split(",")]) + # Convert wiretrace to graphical vector image. - image = Visualizer().to_svg(wiretrace, start=start, length=length, wires=wires, breakpoints=breakpoints) + image = Visualizer().to_svg( + wiretrace, start=start, length=length, wires=wires, breakpoints=breakpoints + ) if wires is not None and len(wires): - raise Exception(f'Unknown wires {wires.__repr__()}\nThe following wires were detected in the wiretrace:\n{wiretrace.get_wire_names()}') - + raise Exception( + f"Unknown wires {wires.__repr__()}\nThe following wires were detected in the wiretrace:\n{wiretrace.get_wire_names()}" + ) + if args.display: image.display() - + else: print(image.source) + if __name__ == "__main__": main() diff --git a/sootty/display.py b/sootty/display.py index ee97e31..44d161a 100644 --- a/sootty/display.py +++ b/sootty/display.py @@ -2,6 +2,7 @@ from subprocess import call, Popen, STDOUT, PIPE from re import match + class VectorImage: """Encapsulates logic to store and display an SVG to the terminal.""" @@ -10,13 +11,14 @@ def __init__(self, source): def __str__(self): return self.source - + def display(self): # TODO: fix!!! these lines are for hacking together width relative to display - result = match(r' 0 else 0 - def search(self, function=lambda value: type(value) is int and value > 0, start=None, end=None): + def search( + self, + function=lambda value: type(value) is int and value > 0, + start=None, + end=None, + ): """Returns a list of times that satisfy the function, between start and end times.""" indices = [] prev = None @@ -42,7 +46,9 @@ def search(self, function=lambda value: type(value) is int and value > 0, start= def __invert__(self): data = ValueChange(width=self.width) for key in self: - data[key] = None if self[key] == None else (~self[key] & (2 << self.width - 1) - 1) + data[key] = ( + None if self[key] == None else (~self[key] & (2 << self.width - 1) - 1) + ) return data def __neg__(self): @@ -62,7 +68,11 @@ def _binop(self, other, binop, width): values[0] = self[key] if key in other: values[1] = other[key] - reduced = None if (values[0] is None or values[1] is None) else binop(values[0], values[1]) + reduced = ( + None + if (values[0] is None or values[1] is None) + else binop(values[0], values[1]) + ) if reduced != values[2]: values[2] = reduced data[key] = reduced @@ -106,10 +116,10 @@ def __add__(self, other): def __sub__(self, other): return self._binop(other, lambda x, y: x - y, max(self.width, other.width) + 1) - + def __mod__(self, other): return self._binop(other, lambda x, y: x % y, self.width) - + def _from(self): data = ValueChange(width=1) data[0] = 0 @@ -136,7 +146,7 @@ def _until(self): data[key + 1] = 0 break return data - + def _before(self): data = ValueChange(width=1) data[0] = 1 diff --git a/sootty/storage/wire.py b/sootty/storage/wire.py index 69cf8c1..fcf9874 100644 --- a/sootty/storage/wire.py +++ b/sootty/storage/wire.py @@ -4,16 +4,19 @@ from ..exceptions import * from .valuechange import ValueChange -class Wire: +class Wire: def __init__(self, name, width=1): self.name = name self._data = ValueChange(width) - - @staticmethod - def from_data(name, data, width=1): - wire = Wire(name=name, width=width) - for key in compress(range(len(data)), map(lambda pair: pair[0] != pair[1], zip(chain([None], data), data))): + + @classmethod + def from_data(cls, name, data, width=1): + wire = cls(name=name, width=width) + for key in compress( + range(len(data)), + map(lambda pair: pair[0] != pair[1], zip(chain([None], data), data)), + ): wire[key] = data[key] return wire @@ -41,6 +44,20 @@ def times(self, length=0): """Returns a list of times with high value on the wire.""" return self._data.search(end=max(length, self.length())) + @classmethod + def const(cls, value): + wire = cls(name=f"c_{value}", width=0) + wire[0] = value + return wire + + @classmethod + def time(cls, value): + wire = cls(name=f"t_{value}", width=1) + wire[0] = 0 + wire[value] = 1 + wire[value + 1] = 0 + return wire + def __invert__(self): wire = Wire(name="~" + self.name) wire._data = self._data.__invert__() @@ -50,77 +67,77 @@ def __neg__(self): wire = Wire(name="-" + self.name) wire._data = self._data.__invert__() return wire - + def __and__(self, other): wire = Wire(name="(" + self.name + " & " + other.name + ")") - wire._data = self._data.__and__(other) + wire._data = self._data.__and__(other._data) return wire def __or__(self, other): wire = Wire(name="(" + self.name + " | " + other.name + ")") - wire._data = self._data.__or__(other) + wire._data = self._data.__or__(other._data) return wire def __xor__(self, other): wire = Wire(name="(" + self.name + " ^ " + other.name + ")") - wire._data = self._data.__xor__(other) + wire._data = self._data.__xor__(other._data) return wire def __eq__(self, other): wire = Wire(name="(" + self.name + " == " + other.name + ")") - wire._data = self._data.__eq__(other) + wire._data = self._data.__eq__(other._data) return wire def __ne__(self, other): wire = Wire(name="(" + self.name + " != " + other.name + ")") - wire._data = self._data.__ne__(other) + wire._data = self._data.__ne__(other._data) return wire def __gt__(self, other): wire = Wire(name="(" + self.name + " > " + other.name + ")") - wire._data = self._data.__gt__(other) + wire._data = self._data.__gt__(other._data) return wire def __ge__(self, other): wire = Wire(name="(" + self.name + " >= " + other.name + ")") - wire._data = self._data.__ge__(other) + wire._data = self._data.__ge__(other._data) return wire def __lt__(self, other): wire = Wire(name="(" + self.name + " < " + other.name + ")") - wire._data = self._data.__lt__(other) + wire._data = self._data.__lt__(other._data) return wire def __le__(self, other): wire = Wire(name="(" + self.name + " <= " + other.name + ")") - wire._data = self._data.__le__(other) + wire._data = self._data.__le__(other._data) return wire def __lshift__(self, other): wire = Wire(name="(" + self.name + " << " + other.name + ")") - wire._data = self._data.__lshift__(other) + wire._data = self._data.__lshift__(other._data) return wire def __rshift__(self, other): wire = Wire(name="(" + self.name + " >> " + other.name + ")") - wire._data = self._data.__rshift__(other) + wire._data = self._data.__rshift__(other._data) return wire def __add__(self, other): wire = Wire(name="(" + self.name + " + " + other.name + ")") - wire._data = self._data.__add__(other) + wire._data = self._data.__add__(other._data) return wire - + def __sub__(self, other): wire = Wire(name="(" + self.name + " - " + other.name + ")") - wire._data = self._data.__sub__(other) + wire._data = self._data.__sub__(other._data) return wire - + def __mod__(self, other): wire = Wire(name="(" + self.name + " % " + other.name + ")") - wire._data = self._data.__mod__(other) + wire._data = self._data.__mod__(other._data) return wire - + def _from(self): wire = Wire(name="from " + self.name) wire._data = self._data._from() diff --git a/sootty/storage/wiregroup.py b/sootty/storage/wiregroup.py index 2c07fa1..e44d33b 100644 --- a/sootty/storage/wiregroup.py +++ b/sootty/storage/wiregroup.py @@ -3,8 +3,8 @@ from ..exceptions import * from .wire import Wire -class WireGroup: +class WireGroup: def __init__(self, name: str): self.name = name self.groups = [] diff --git a/sootty/storage/wiretrace.py b/sootty/storage/wiretrace.py index 5830fc4..ca8419f 100644 --- a/sootty/storage/wiretrace.py +++ b/sootty/storage/wiretrace.py @@ -6,23 +6,23 @@ from .wiregroup import WireGroup from .wire import Wire -class WireTrace: +class WireTrace: def __init__(self): self.root = WireGroup("__root__") - @staticmethod - def from_vcd(filename): + @classmethod + def from_vcd(cls, filename): """ Construct a WireTrace object from a parsed vcd file, using the pyvcd library. Syntax of four-state VCD file (IEEE 1364-2005 ยง18.2.1): - value_change_dump_definitions ::= + value_change_dump_definitions ::= { declaration_command }{ simulation_command } - declaration_command ::= - declaration_keyword - [ command_text ] + declaration_command ::= + declaration_keyword + [ command_text ] $end simulation_command ::= simulation_keyword { value_change } $end @@ -52,18 +52,18 @@ def from_vcd(filename): { ASCII character } """ - this = WireTrace() + this = cls() this.metadata = dict() # dictionary of vcd metadata wires = dict() # map from id_code to wire object stack = [this.root] # store stack of current group for scoping - with open(filename, 'rb') as stream: + with open(filename, "rb") as stream: tokens = tokenize(stream) for token in tokens: if token.kind is TokenKind.COMMENT: - this.metadata['comment'] = token.comment + this.metadata["comment"] = token.comment elif token.kind is TokenKind.DATE: - this.metadata['date'] = token.date + this.metadata["date"] = token.date elif token.kind is TokenKind.ENDDEFINITIONS: break # end of definitions elif token.kind is TokenKind.SCOPE: @@ -71,10 +71,10 @@ def from_vcd(filename): stack[-1].add_group(group) stack.append(group) elif token.kind is TokenKind.TIMESCALE: - this.metadata['timescale'] = token.timescale + this.metadata["timescale"] = token.timescale elif token.kind is TokenKind.UPSCOPE: if len(stack) == 0: - raise SoottyError(f'Illegal end of scope.') + raise SoottyError(f"Illegal end of scope.") stack.pop() elif token.kind is TokenKind.VAR: if token.var.id_code in wires: @@ -87,25 +87,29 @@ def from_vcd(filename): wires[token.var.id_code] = wire stack[-1].add_wire(wire) elif token.kind is TokenKind.VERSION: - this.metadata['version'] = token.version + this.metadata["version"] = token.version else: - raise SoottyError(f'Invalid vcd token when parsing: {token}') - + raise SoottyError(f"Invalid vcd token when parsing: {token}") + time = None for token in tokens: if token.kind is TokenKind.CHANGE_TIME: time = token.time_change elif token.kind is TokenKind.CHANGE_SCALAR: value = token.scalar_change.value - value = int(value) if value in ('0', '1') else value + value = int(value) if value in ("0", "1") else value wires[token.scalar_change.id_code][time] = value elif token.kind is TokenKind.CHANGE_VECTOR: value = token.vector_change.value wires[token.vector_change.id_code][time] = value elif token.kind is TokenKind.CHANGE_REAL: - raise SoottyInternalError(f'You forgot to implement token CHANGE_REAL.') + raise SoottyInternalError( + f"You forgot to implement token CHANGE_REAL." + ) elif token.kind is TokenKind.CHANGE_STRING: - raise SoottyInternalError(f'You forgot to implement token CHANGE_STRING.') + raise SoottyInternalError( + f"You forgot to implement token CHANGE_STRING." + ) elif token.kind is TokenKind.DUMPALL: pass # not sure what to do here elif token.kind is TokenKind.DUMPOFF: @@ -117,23 +121,26 @@ def from_vcd(filename): elif token.kind is TokenKind.END: pass # not sure what to do here else: - raise SoottyError(f'Invalid vcd token when parsing: {token}') + raise SoottyError(f"Invalid vcd token when parsing: {token}") return this - @staticmethod - def from_pyrtl(sim_trace): + @classmethod + def from_pyrtl(cls, sim_trace): """Parses a WireTrace object from a PyRTL SimulationTrace object. :param SimulationTrace sim_trace: The object that stores the PyRTL tracer. """ - trace = WireTrace() + trace = cls() for wirename in sim_trace.trace: print(sim_trace.trace[wirename], file=sys.stderr) - trace.root.add_wire(Wire.from_data( - name = wirename, - width = sim_trace._wires[wirename].bitwidth, - data = sim_trace.trace[wirename])) + trace.root.add_wire( + Wire.from_data( + name=wirename, + width=sim_trace._wires[wirename].bitwidth, + data=sim_trace.trace[wirename], + ) + ) return trace def num_wires(self): @@ -147,11 +154,11 @@ def length(self): def find(self, name: str): """Returns the wire object with the given name, raises an error if not found.""" return self.root.find(name) - + def get_wire_names(self): """Returns list of all wire names.""" return self.root.get_names() - + def evaluate(self, expr: str): wire = self._compute_wire(LimitExpression(expr).tree) return wire.times(self.length()) @@ -167,33 +174,61 @@ def _compute_wire(self, expr): elif expr.data.type == "NEG": return -self._compute_wire(expr.children[0]) elif expr.data.type == "AND": - return self._compute_wire(expr.children[0]) & self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) & self._compute_wire( + expr.children[1] + ) elif expr.data.type == "OR": - return self._compute_wire(expr.children[0]) | self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) | self._compute_wire( + expr.children[1] + ) elif expr.data.type == "XOR": - return self._compute_wire(expr.children[0]) ^ self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) ^ self._compute_wire( + expr.children[1] + ) elif expr.data.type == "EQ": - return self._compute_wire(expr.children[0]) == self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) == self._compute_wire( + expr.children[1] + ) elif expr.data.type == "NEQ": - return self._compute_wire(expr.children[0]) != self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) != self._compute_wire( + expr.children[1] + ) elif expr.data.type == "GT": - return self._compute_wire(expr.children[0]) > self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) > self._compute_wire( + expr.children[1] + ) elif expr.data.type == "GEQ": - return self._compute_wire(expr.children[0]) >= self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) >= self._compute_wire( + expr.children[1] + ) elif expr.data.type == "LT": - return self._compute_wire(expr.children[0]) < self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) < self._compute_wire( + expr.children[1] + ) elif expr.data.type == "LEQ": - return self._compute_wire(expr.children[0]) <= self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) <= self._compute_wire( + expr.children[1] + ) elif expr.data.type == "SL": - return self._compute_wire(expr.children[0]) << self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) << self._compute_wire( + expr.children[1] + ) elif expr.data.type == "SR": - return self._compute_wire(expr.children[0]) >> self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) >> self._compute_wire( + expr.children[1] + ) elif expr.data.type == "ADD": - return self._compute_wire(expr.children[0]) + self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) + self._compute_wire( + expr.children[1] + ) elif expr.data.type == "SUB": - return self._compute_wire(expr.children[0]) - self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) - self._compute_wire( + expr.children[1] + ) elif expr.data.type == "MOD": - return self._compute_wire(expr.children[0]) % self._compute_wire(expr.children[1]) + return self._compute_wire(expr.children[0]) % self._compute_wire( + expr.children[1] + ) elif expr.data.type == "FROM": return self._compute_wire(expr.children[0])._from() elif expr.data.type == "AFTER": @@ -209,9 +244,9 @@ def _compute_wire(self, expr): elif expr.data.type == "ACC": return self._compute_wire(expr.children[0])._acc() elif expr.data.type == "CONST": - return Wire(name=expr.data, width=0, data=[int(expr.children[0])]) + return Wire.const(int(expr.children[0])) elif expr.data.type == "TIME": - return Wire(name=f"t_{expr.data}", width=1, data=[0] * int(expr.children[0]) + [1, 0]) + return Wire.time(int(expr.children[0])) def compute_limits(self, start_expr: str, end_expr: str): starts = self.evaluate(start_expr) diff --git a/sootty/visualizer.py b/sootty/visualizer.py index 35d4542..2803e9c 100644 --- a/sootty/visualizer.py +++ b/sootty/visualizer.py @@ -8,7 +8,7 @@ class Style: """Container class for visualizer style settings.""" - class Default(): + class Default: TOP_MARGIN = 15 LEFT_MARGIN = 15 CHAR_WIDTH = 7 @@ -20,7 +20,7 @@ class Default(): TRANS_START = 5 TRANS_WIDTH = 5 BLOCK_TRANS = False - LINE_COLOR = "#FFFFFF" #line color now needs to be its own class (?) depending on wires and variables + LINE_COLOR = "#FFFFFF" # line color now needs to be its own class (?) depending on wires and variables LINE_COLOR_HIGH = "#00FF00" LINE_COLOR_LOW = "#3DB8B8" LINE_COLOR_Z = "#FFFF00" @@ -29,7 +29,7 @@ class Default(): BREAKPOINT_COLOR = "#FFFF00" TEXT_COLOR = "#FFFFFF" BKGD_COLOR = "#000000" - #wires going from 0 and 1 are two different colors, x variable is red rectangle, z variable is yellow + # wires going from 0 and 1 are two different colors, x variable is red rectangle, z variable is yellow class Dark(Default): pass @@ -49,9 +49,9 @@ class Silicon(Default): LINE_COLOR_LOW = "#a8acad" LINE_COLOR_Z = "#7a5b1b" LINE_COLOR_X = "#faf6bb" - #TEXT_COLOR = "#30FF30" + # TEXT_COLOR = "#30FF30" TEXT_COLOR = "#FFFFFF" - #BKGD_COLOR = "#003000" + # BKGD_COLOR = "#003000" BKGD_COLOR = "#2b5e2b" class Debug(Default): @@ -69,78 +69,100 @@ def to_svg(self, wiretrace, start=0, length=None, wires=None, breakpoints=None): if length is None: length = wiretrace.length() """Converts the provided wiretrace object to a VectorImage object (svg).""" - return VectorImage(self._wiretrace_to_svg(wiretrace, start, length, wires, breakpoints)) + return VectorImage( + self._wiretrace_to_svg(wiretrace, start, length, wires, breakpoints) + ) def _wiretrace_to_svg(self, wiretrace, start, length, wires=None, breakpoints=None): if wires and len(wires) == 0: # include all wires if empty list provided wires = None - width = 2 * self.style.LEFT_MARGIN + self.style.TEXT_WIDTH + self.style.FULL_WIDTH - height = 2 * self.style.TOP_MARGIN - self.style.WIRE_MARGIN + (self.style.WIRE_HEIGHT + \ - self.style.WIRE_MARGIN) * (1 + (len(wires) if wires else wiretrace.num_wires())) + width = ( + 2 * self.style.LEFT_MARGIN + self.style.TEXT_WIDTH + self.style.FULL_WIDTH + ) + height = ( + 2 * self.style.TOP_MARGIN + - self.style.WIRE_MARGIN + + (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN) + * (1 + (len(wires) if wires else wiretrace.num_wires())) + ) + + svg = ( + f'' + f'' + ) - svg = f'' \ - f'' - svg += self._timestamps_to_svg( - left = self.style.LEFT_MARGIN + self.style.TEXT_WIDTH, - top = self.style.TOP_MARGIN, - start = start, - length = length) + left=self.style.LEFT_MARGIN + self.style.TEXT_WIDTH, + top=self.style.TOP_MARGIN, + start=start, + length=length, + ) if not breakpoints: breakpoints = [] svg += self._breakpoints_to_svg( - breakpoints, - left = self.style.LEFT_MARGIN + self.style.TEXT_WIDTH, - top = self.style.TOP_MARGIN, - start = start, - length = length, - height = height - 2 * self.style.TOP_MARGIN + self.style.WIRE_MARGIN) - + breakpoints, + left=self.style.LEFT_MARGIN + self.style.TEXT_WIDTH, + top=self.style.TOP_MARGIN, + start=start, + length=length, + height=height - 2 * self.style.TOP_MARGIN + self.style.WIRE_MARGIN, + ) + svg += self._wiregroup_to_svg( - wiregroup = wiretrace.root, - left = self.style.LEFT_MARGIN, - top = self.style.TOP_MARGIN + self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN, - start = start, - length = length, - wires = wires)[0] # the first element is the svg data - - svg += '' + wiregroup=wiretrace.root, + left=self.style.LEFT_MARGIN, + top=self.style.TOP_MARGIN + self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN, + start=start, + length=length, + wires=wires, + )[ + 0 + ] # the first element is the svg data + + svg += "" return svg def _timestamps_to_svg(self, left, top, start, length): - svg = '' + svg = "" for index in range(start, start + length, ((length - 1) // 32) + 1): - svg += self._shape_to_svg({ - 'name': 'text', - 'x': left + (index - start + 1/2) * (self.style.FULL_WIDTH / length), - 'y': top + (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN) / 2, - 'class': 'small', - 'fill': self.style.TEXT_COLOR, - 'text-anchor': 'middle', - 'font-family': 'monospace', - 'content': index, - }) + svg += self._shape_to_svg( + { + "name": "text", + "x": left + + (index - start + 1 / 2) * (self.style.FULL_WIDTH / length), + "y": top + (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN) / 2, + "class": "small", + "fill": self.style.TEXT_COLOR, + "text-anchor": "middle", + "font-family": "monospace", + "content": index, + } + ) return svg def _breakpoints_to_svg(self, breakpoints, left, top, start, length, height): """Convert a list of breakpoint times to highlights on the svg.""" - svg = '' + svg = "" for index in breakpoints: if index >= start and index < start + length: - svg += self._shape_to_svg({ - 'name': 'rect', - 'x': left + (index - start) * (self.style.FULL_WIDTH / length) + self.style.TRANS_START, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': height, - 'fill': self.style.BREAKPOINT_COLOR, - 'fill-opacity': 0.4, - }) + svg += self._shape_to_svg( + { + "name": "rect", + "x": left + + (index - start) * (self.style.FULL_WIDTH / length) + + self.style.TRANS_START, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": height, + "fill": self.style.BREAKPOINT_COLOR, + "fill-opacity": 0.4, + } + ) return svg def _wiregroup_to_svg(self, wiregroup, left, top, start, length, wires=None): - svg = '' + svg = "" index = 0 for wire in wiregroup.wires: if wires == None or wire.name in wires: @@ -148,43 +170,51 @@ def _wiregroup_to_svg(self, wiregroup, left, top, start, length, wires=None): wires.remove(wire.name) svg += self._wire_to_svg( wire, - left = left, - top = top + (index * (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN)), - start = start, - length = length) + left=left, + top=top + + (index * (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN)), + start=start, + length=length, + ) index += 1 # recursively call function on nested wiregroups for group in wiregroup.groups: result = self._wiregroup_to_svg( group, - left = left, - top = top + (index * (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN)), - start = start, - length = length, - wires = wires) + left=left, + top=top + (index * (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN)), + start=start, + length=length, + wires=wires, + ) svg += result[0] index += result[1] return svg, index def _wire_to_svg(self, wire, left, top, start, length): - svg = self._shape_to_svg({ - 'name': 'text', - 'x': left, - 'y': top + 15, - 'class': 'small', - 'fill': self.style.TEXT_COLOR, - 'font-family': 'monospace', - 'content': wire.name if len(wire.name) <= 10 else wire.name[:7] + '...', - }) + svg = self._shape_to_svg( + { + "name": "text", + "x": left, + "y": top + 15, + "class": "small", + "fill": self.style.TEXT_COLOR, + "font-family": "monospace", + "content": wire.name if len(wire.name) <= 10 else wire.name[:7] + "...", + } + ) for index in range(start, start + length): svg += self._value_to_svg( - prev = wire[index - 1] if index > 0 else wire[index], - value = wire[index], - width = wire.width(), - left = left + ((index - start) * (self.style.FULL_WIDTH / length)) + self.style.TEXT_WIDTH, - top = top, - length = length, - initial = (index == start)) + prev=wire[index - 1] if index > 0 else wire[index], + value=wire[index], + width=wire.width(), + left=left + + ((index - start) * (self.style.FULL_WIDTH / length)) + + self.style.TEXT_WIDTH, + top=top, + length=length, + initial=(index == start), + ) return svg class ValueType(Enum): @@ -197,20 +227,22 @@ class ValueType(Enum): @staticmethod def type_from_value(value, width=1): if width == 1: - if value in (0, '0'): + if value in (0, "0"): return Visualizer.ValueType.LOW - elif value in (1, '1'): + elif value in (1, "1"): return Visualizer.ValueType.HIGH - elif value in ('x', 'X'): + elif value in ("x", "X"): return Visualizer.ValueType.X - elif value in ('z', 'Z'): + elif value in ("z", "Z"): return Visualizer.ValueType.Z elif value is None: return Visualizer.ValueType.X else: - raise SoottyInternalError(f'Invalid wire value, unable to visualize: {value}') + raise SoottyInternalError( + f"Invalid wire value, unable to visualize: {value}" + ) else: - if 'x' in str(value): + if "x" in str(value): return Visualizer.ValueType.X else: return Visualizer.ValueType.DATA @@ -219,567 +251,791 @@ def _value_to_svg(self, prev, value, width, left, top, length, initial=False): # deduce types from wire width and value: prev_type = Visualizer.type_from_value(prev, width) value_type = Visualizer.type_from_value(value, width) - is_transitioning = (prev != value) + is_transitioning = prev != value - # The following code builds a list of svg objects depending on the + # The following code builds a list of svg objects depending on the # current and previous value of the wire. shapes = [] - if prev_type is Visualizer.ValueType.LOW and value_type is Visualizer.ValueType.LOW: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - elif prev_type is Visualizer.ValueType.LOW and value_type is Visualizer.ValueType.HIGH: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - elif prev_type is Visualizer.ValueType.HIGH and value_type is Visualizer.ValueType.LOW: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': top, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - elif prev_type is Visualizer.ValueType.HIGH and value_type is Visualizer.ValueType.HIGH: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - elif prev_type is Visualizer.ValueType.LOW and value_type is Visualizer.ValueType.DATA: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - elif prev_type is Visualizer.ValueType.HIGH and value_type is Visualizer.ValueType.DATA: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.LOW: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.HIGH: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.DATA and not is_transitioning and not initial: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.DATA: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_DATA, - }) - shapes.append({ - 'name': 'text', - 'x': left + self.style.TRANS_START + self.style.TRANS_WIDTH + 5, # TODO: generalize formula - 'y': top + (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN) / 2, - 'class': 'small', - 'fill': self.style.TEXT_COLOR, - 'font-family': 'monospace', - 'content': value - }) + if ( + prev_type is Visualizer.ValueType.LOW + and value_type is Visualizer.ValueType.LOW + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + elif ( + prev_type is Visualizer.ValueType.LOW + and value_type is Visualizer.ValueType.HIGH + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + shapes.append( + { + "name": "line", + "x1": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + elif ( + prev_type is Visualizer.ValueType.HIGH + and value_type is Visualizer.ValueType.LOW + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": top, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + shapes.append( + { + "name": "line", + "x1": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + elif ( + prev_type is Visualizer.ValueType.HIGH + and value_type is Visualizer.ValueType.HIGH + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + elif ( + prev_type is Visualizer.ValueType.LOW + and value_type is Visualizer.ValueType.DATA + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + elif ( + prev_type is Visualizer.ValueType.HIGH + and value_type is Visualizer.ValueType.DATA + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.LOW + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.HIGH + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.DATA + and not is_transitioning + and not initial + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.DATA + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START + self.style.TRANS_WIDTH, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_DATA, + } + ) + shapes.append( + { + "name": "text", + "x": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH + + 5, # TODO: generalize formula + "y": top + (self.style.WIRE_HEIGHT + self.style.WIRE_MARGIN) / 2, + "class": "small", + "fill": self.style.TEXT_COLOR, + "font-family": "monospace", + "content": value, + } + ) # TODO: figure out how to display X values in svg: - elif prev_type is Visualizer.ValueType.LOW and value_type is Visualizer.ValueType.X: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - elif prev_type is Visualizer.ValueType.HIGH and value_type is Visualizer.ValueType.X: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.X: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - elif prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.LOW: - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': self.style.TRANS_START, - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - elif prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.HIGH: - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': self.style.TRANS_START, - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - elif prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.DATA: - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_X, - }) - elif prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.X: - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) + elif ( + prev_type is Visualizer.ValueType.LOW + and value_type is Visualizer.ValueType.X + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + elif ( + prev_type is Visualizer.ValueType.HIGH + and value_type is Visualizer.ValueType.X + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.X + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + elif ( + prev_type is Visualizer.ValueType.X + and value_type is Visualizer.ValueType.LOW + ): + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": self.style.TRANS_START, + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + elif ( + prev_type is Visualizer.ValueType.X + and value_type is Visualizer.ValueType.HIGH + ): + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": self.style.TRANS_START, + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + elif ( + prev_type is Visualizer.ValueType.X + and value_type is Visualizer.ValueType.DATA + ): + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_X, + } + ) + elif ( + prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.X + ): + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) # TODO: figure out how to display Z values in svg: - elif prev_type is Visualizer.ValueType.LOW and value_type is Visualizer.ValueType.Z: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - elif prev_type is Visualizer.ValueType.HIGH and value_type is Visualizer.ValueType.Z: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': top, - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - elif prev_type is Visualizer.ValueType.DATA and value_type is Visualizer.ValueType.Z: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - elif prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.Z: - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': self.style.TRANS_START, - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - elif prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.LOW: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top + self.style.WIRE_HEIGHT, - 'y2': top + self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_LOW, - }) - elif prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.HIGH: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + self.style.TRANS_START, - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + self.style.TRANS_START + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - shapes.append({ - 'name': 'line', - 'x1': left + self.style.TRANS_START, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': top, - 'y2': top, - 'stroke': self.style.LINE_COLOR_HIGH, - }) - elif prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.X: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) - shapes.append({ - 'name': 'rect', - 'x': left, - 'y': top, - 'width': (self.style.FULL_WIDTH / length), - 'height': self.style.WIRE_HEIGHT, - 'stroke': self.style.LINE_COLOR_X, - 'fill': self.style.LINE_COLOR_X, - }) - elif prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.Z: - shapes.append({ - 'name': 'line', - 'x1': left, - 'x2': left + (self.style.FULL_WIDTH / length), - 'y1': (top + (self.style.WIRE_HEIGHT)/2), - 'y2': (top + (self.style.WIRE_HEIGHT)/2), - 'stroke': self.style.LINE_COLOR_Z, - }) + elif ( + prev_type is Visualizer.ValueType.LOW + and value_type is Visualizer.ValueType.Z + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": top + self.style.WIRE_HEIGHT, + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + elif ( + prev_type is Visualizer.ValueType.HIGH + and value_type is Visualizer.ValueType.Z + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": top, + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + shapes.append( + { + "name": "line", + "x1": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + elif ( + prev_type is Visualizer.ValueType.DATA + and value_type is Visualizer.ValueType.Z + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + elif ( + prev_type is Visualizer.ValueType.X and value_type is Visualizer.ValueType.Z + ): + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": self.style.TRANS_START, + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + elif ( + prev_type is Visualizer.ValueType.Z + and value_type is Visualizer.ValueType.LOW + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + shapes.append( + { + "name": "line", + "x1": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top + self.style.WIRE_HEIGHT, + "y2": top + self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_LOW, + } + ) + elif ( + prev_type is Visualizer.ValueType.Z + and value_type is Visualizer.ValueType.HIGH + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + self.style.TRANS_START, + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + + self.style.TRANS_START + + self.style.TRANS_WIDTH * self.style.BLOCK_TRANS, + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + shapes.append( + { + "name": "line", + "x1": left + self.style.TRANS_START, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": top, + "y2": top, + "stroke": self.style.LINE_COLOR_HIGH, + } + ) + elif ( + prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.X + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) + shapes.append( + { + "name": "rect", + "x": left, + "y": top, + "width": (self.style.FULL_WIDTH / length), + "height": self.style.WIRE_HEIGHT, + "stroke": self.style.LINE_COLOR_X, + "fill": self.style.LINE_COLOR_X, + } + ) + elif ( + prev_type is Visualizer.ValueType.Z and value_type is Visualizer.ValueType.Z + ): + shapes.append( + { + "name": "line", + "x1": left, + "x2": left + (self.style.FULL_WIDTH / length), + "y1": (top + (self.style.WIRE_HEIGHT) / 2), + "y2": (top + (self.style.WIRE_HEIGHT) / 2), + "stroke": self.style.LINE_COLOR_Z, + } + ) else: - raise SoottyInternalError(f"Invalid wire transition, unable to visualize: {prev_type} to {value_type}") - - svg_data = '' + raise SoottyInternalError( + f"Invalid wire transition, unable to visualize: {prev_type} to {value_type}" + ) + + svg_data = "" for shape in shapes: svg_data += self._shape_to_svg(shape) return svg_data def _shape_to_svg(self, shape): """Convert a shape dictionary object to an svg string.""" - start_tag = '<' + str(shape['name']) - end_tag = ' />' + start_tag = "<" + str(shape["name"]) + end_tag = " />" for prop in shape: - if prop == 'content': - end_tag = '>' + str(shape['content']) + '' - elif prop != 'name': - start_tag += ' ' + prop + '="' + str(shape[prop]) + '"' + if prop == "content": + end_tag = ">" + str(shape["content"]) + "" + elif prop != "name": + start_tag += " " + prop + '="' + str(shape[prop]) + '"' return start_tag + end_tag From 226b773e9ebde370942daa4705c177436fa2d841 Mon Sep 17 00:00:00 2001 From: Ben1152000 Date: Sun, 16 Jan 2022 22:47:39 -0800 Subject: [PATCH 2/2] Reformatted tests --- tests/run_tests.py | 12 ++++++------ tests/test_general.py | 8 +++++--- tests/test_limits.py | 21 ++++++++++++++++---- tests/test_pyrtl.py | 41 +++++++++++++++++++++------------------- tests/test_style.py | 2 +- tests/test_wire_types.py | 2 +- 6 files changed, 52 insertions(+), 34 deletions(-) diff --git a/tests/run_tests.py b/tests/run_tests.py index a1a96b1..e9875f9 100644 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -1,10 +1,10 @@ if __name__ == "__main__": tests = [ - 'test_general', - 'test_limits', - 'test_pyrtl', - 'test_style', - 'test_wire_types' + "test_general", + "test_limits", + "test_pyrtl", + "test_style", + "test_wire_types", ] modules = map(__import__, tests) @@ -12,5 +12,5 @@ for module in modules: for name, test in module.__dict__.items(): if callable(test): - if name[:4] == 'test': + if name[:4] == "test": test() diff --git a/tests/test_general.py b/tests/test_general.py index e0ece1e..733d8a9 100644 --- a/tests/test_general.py +++ b/tests/test_general.py @@ -10,12 +10,13 @@ def test_svg_output(): image = Visualizer().to_svg(wiretrace, start=0, length=8) - pattern = r'(?:<\?xml\b[^>]*>[^<]*)?(?:[^<]*)*(?:]*>[^<]*)?(?:[^<]*)*(?: