Skip to content

Commit

Permalink
Fix relative imports, formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben1152000 committed Sep 20, 2022
1 parent 8d4efae commit 6cdb351
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 68 deletions.
3 changes: 2 additions & 1 deletion sootty/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import argparse
import sys
from sootty.exceptions import SoottyError

from .exceptions import SoottyError
from .save import save_query, reload_query
from .storage import WireTrace
from .visualizer import Visualizer
Expand Down
3 changes: 2 additions & 1 deletion sootty/save.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os, sys
from sootty.exceptions import SoottyError
import time
import yaml

from .exceptions import SoottyError

PATH = os.getenv("HOME") + "/.config/sootty/save/"
SAVEFILE = PATH + "queries.yaml"
QUERYLIMIT = 500
Expand Down
227 changes: 161 additions & 66 deletions sootty/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from math import ceil, log
from io import BytesIO, BufferedReader
from sootty.exceptions import SoottyError

from .exceptions import SoottyError


def dec2anybase(input, base, width):
"""
Expand All @@ -15,9 +17,10 @@ def dec2anybase(input, base, width):
else:
res += chr(rem - 10 + ord("A"))
input = input // base

return res[::-1].zfill(ceil(log(2**width - 1, base)))


def vcdid_hash(s):
"""
Hash identifier_code into integers.
Expand All @@ -30,6 +33,7 @@ def vcdid_hash(s):

return val


def vcdid_unhash(value):
"""
Unhash identifier_code from integers.
Expand All @@ -40,11 +44,12 @@ def vcdid_unhash(value):
if vmod:
buf += chr(vmod + 32)
else:
buf += '~'
buf += "~"
value -= 94
value = int(value / 94)
return buf.encode() # bytes(buf, 'utf-8') or 'ascii'


def evcd_strcpy(src, direction):
"""
Convert EVCD value changes into VCD input/output value changes according to direction.
Expand All @@ -57,17 +62,18 @@ def evcd_strcpy(src, direction):
for vc_bit in src:
for i in range(23):
if evcd[i] == vc_bit:
value += vcd[i:i+1]
value += vcd[i : i + 1]
i -= 1 # choice of i can be alternative
break
if i == 22:
raise SoottyError("EVCD value error: value change is invalid")
return value


def evcd2vcd(stream):
"""
Main function to convert EVCD input stream into VCD input stream.
Syntax of extended VCD file (IEEE 1800-2017 §21.7.4):
value_change_dump_definitions ::= {declaration_command} {simulation_command}
Expand Down Expand Up @@ -117,7 +123,7 @@ def evcd2vcd(stream):
dumpports_command ::=
$dumpports (scope_identifier , string_literal | variable | expression )
"""

buf = stream.read()
toks = buf.split() # compared with re.split(b'\s+', buf), this automatically strip
tokit = iter(toks)
Expand All @@ -128,104 +134,159 @@ def evcd2vcd(stream):
tok = next(tokit)
while True:
# Basic formatter and syntax checker
if tok == b'$comment' or tok == b'$date' or tok == b'$timescale' or tok == b'$version':
vcd.write(tok + b'\n ')
if (
tok == b"$comment"
or tok == b"$date"
or tok == b"$timescale"
or tok == b"$version"
):
vcd.write(tok + b"\n ")
body = next(tokit)
while body != b'$end':
vcd.write(b' ' + body)
while body != b"$end":
vcd.write(b" " + body)
body = next(tokit)
vcd.write(b'\n$end\n') # body + \n
vcd.write(b"\n$end\n") # body + \n
tok = next(tokit)
elif tok == b'$enddefinitions':
if next(tokit) != b'$end':
raise SoottyError("EVCD syntax error: $enddefinitions not followed by $end")
elif tok == b"$enddefinitions":
if next(tokit) != b"$end":
raise SoottyError(
"EVCD syntax error: $enddefinitions not followed by $end"
)
else:
vcd.write(b'$enddefinitions $end\n')
vcd.write(b"$enddefinitions $end\n")
break
elif tok == b'$scope':
elif tok == b"$scope":
# Simply check scope, var, and upscope outside can also parse, but cannot precisely throw exceptions
while tok == b'$scope':
while tok == b"$scope":
scope_type = next(tokit)
if scope_type != b'module':
if scope_type == b'begin' or scope_type == b'fork' or scope_type == b'function' or scope_type == b'task':
raise SoottyError("EVCD syntax error: VCD scope_type detected")
if scope_type != b"module":
if (
scope_type == b"begin"
or scope_type == b"fork"
or scope_type == b"function"
or scope_type == b"task"
):
raise SoottyError(
"EVCD syntax error: VCD scope_type detected"
)
else:
raise SoottyError("EVCD syntax error: invalid scope_type")
scope_identifier = next(tokit)
if next(tokit) != b'$end':
raise SoottyError("EVCD syntax error: scope_identifier not followed by $end")
vcd.write(b'$scope module ' + scope_identifier + b' $end\n')
if next(tokit) != b"$end":
raise SoottyError(
"EVCD syntax error: scope_identifier not followed by $end"
)
vcd.write(b"$scope module " + scope_identifier + b" $end\n")
scope_layer += 1
tok = next(tokit)
# Empty scope: innermost scope not followed by var_section
while tok == b'$var':
while tok == b"$var":
var_type = next(tokit)
if var_type == b'port':
if var_type == b"port":
var_size = next(tokit)
if var_size.startswith(b'['): # VCS extension
if var_size.startswith(b"["): # VCS extension
p_hi = int(var_size[1:2])
p_lo = p_hi
p_colon = var_size.find(b':')
p_colon = var_size.find(b":")
if p_colon > 0:
p_lo = int(var_size[p_colon+1:p_colon+2])
len = p_hi - p_lo + 1 if p_hi > p_lo else p_lo - p_hi + 1
p_lo = int(var_size[p_colon + 1 : p_colon + 2])
len = (
p_hi - p_lo + 1 if p_hi > p_lo else p_lo - p_hi + 1
)
else:
len = int(var_size)
if len < 1:
raise SoottyError("EVCD value error: the size of a value must be a positive integer")
raise SoottyError(
"EVCD value error: the size of a value must be a positive integer"
)
id_code = next(tokit)
if not id_code.startswith(b'<'):
raise SoottyError("EVCD syntax error: identifier_code not preceded by '<'")
if not id_code.startswith(b"<"):
raise SoottyError(
"EVCD syntax error: identifier_code not preceded by '<'"
)
hash = vcdid_hash(id_code)
var_ref = next(tokit)
if next(tokit) != b'$end':
raise SoottyError("EVCD syntax error: var_section reference not followed by $end")
if next(tokit) != b"$end":
raise SoottyError(
"EVCD syntax error: var_section reference not followed by $end"
)
else:
node = vcd_ids.get(hash) # jrb_find_int(id_code, hash)
if node is None:
vcd_ids[hash] = len
else:
raise SoottyError("EVCD syntax error: identifier_code re-declared")
raise SoottyError(
"EVCD syntax error: identifier_code re-declared"
)
# var_ref containing "[" may effect: lbrack = var_ref.find(b'[')
# Alternatively, '%d%s%s'.format(digit, str, str).encode() is more complicated
# because %s needs string rather than bytes
# % operator to format bytes is from PEP 461
vcd.write(b'$var wire %d %s %s_I $end\n' % (len, vcdid_unhash(hash * 2), var_ref))
vcd.write(b'$var wire %d %s %s_O $end\n' % (len, vcdid_unhash(hash * 2 + 1), var_ref))
vcd.write(
b"$var wire %d %s %s_I $end\n"
% (len, vcdid_unhash(hash * 2), var_ref)
)
vcd.write(
b"$var wire %d %s %s_O $end\n"
% (len, vcdid_unhash(hash * 2 + 1), var_ref)
)
tok = next(tokit)
elif var_type == b'event' or var_type == b'integer' or var_type == b'parameter' or var_type == b'real' \
or var_type == b'realtime' or var_type == b'reg' or var_type == b'supply0' or var_type == b'supply1' \
or var_type == b'time' or var_type == b'tri' or var_type == b'triand' or var_type == b'trior' \
or var_type == b'trireg' or var_type == b'tri0' or var_type == b'tri1' or var_type == b'wand' \
or var_type == b'wire' or var_type == b'wor':
raise SoottyError("EVCD syntax error: VCD var_type detected")
elif (
var_type == b"event"
or var_type == b"integer"
or var_type == b"parameter"
or var_type == b"real"
or var_type == b"realtime"
or var_type == b"reg"
or var_type == b"supply0"
or var_type == b"supply1"
or var_type == b"time"
or var_type == b"tri"
or var_type == b"triand"
or var_type == b"trior"
or var_type == b"trireg"
or var_type == b"tri0"
or var_type == b"tri1"
or var_type == b"wand"
or var_type == b"wire"
or var_type == b"wor"
):
raise SoottyError(
"EVCD syntax error: VCD var_type detected"
)
else:
raise SoottyError("EVCD syntax error: invalid var_type")
# There should not be any vars or anything between scopes or upscopes
while tok == b'$upscope':
if next(tokit) == b'$end':
vcd.write(b'$upscope $end\n')
while tok == b"$upscope":
if next(tokit) == b"$end":
vcd.write(b"$upscope $end\n")
scope_layer -= 1
tok = next(tokit)
else:
raise SoottyError("EVCD syntax error: $upscope not followed by $end")
while tok == b'$upscope':
if next(tokit) == b'$end':
vcd.write(b'$upscope $end\n')
raise SoottyError(
"EVCD syntax error: $upscope not followed by $end"
)
while tok == b"$upscope":
if next(tokit) == b"$end":
vcd.write(b"$upscope $end\n")
scope_layer -= 1
tok = next(tokit)
else:
raise SoottyError("EVCD syntax error: $upscope not followed by $end")
raise SoottyError(
"EVCD syntax error: $upscope not followed by $end"
)
if scope_layer != 0:
raise SoottyError("EVCD syntax error: $scope and $upscope not matched")
raise SoottyError(
"EVCD syntax error: $scope and $upscope not matched"
)
else:
raise SoottyError("EVCD syntax error: invalid keyword")
sim_kw = False
while True:
tok = next(tokit)
if tok.startswith(b'#'):
vcd.write(tok + b'\n')
elif tok.startswith(b'p'):
if tok.startswith(b"#"):
vcd.write(tok + b"\n")
elif tok.startswith(b"p"):
value_change = tok[1:]
next(tokit) # 0_strength_component
next(tokit) # 1_strength_component
Expand All @@ -234,34 +295,68 @@ def evcd2vcd(stream):
node = vcd_ids.get(hash)
if node is not None:
if node == 1: # scalar change
vcd.write(b'%s%s\n' % (evcd_strcpy(value_change, False), vcdid_unhash(hash * 2)))
vcd.write(b'%s%s\n' % (evcd_strcpy(value_change, True), vcdid_unhash(hash * 2 + 1)))
vcd.write(
b"%s%s\n"
% (evcd_strcpy(value_change, False), vcdid_unhash(hash * 2))
)
vcd.write(
b"%s%s\n"
% (
evcd_strcpy(value_change, True),
vcdid_unhash(hash * 2 + 1),
)
)
else: # node > 1, vector change
vcd.write(b'b%s %s\n' % (evcd_strcpy(value_change, False), vcdid_unhash(hash * 2)))
vcd.write(b'b%s %s\n' % (evcd_strcpy(value_change, True), vcdid_unhash(hash * 2 + 1)))
vcd.write(
b"b%s %s\n"
% (evcd_strcpy(value_change, False), vcdid_unhash(hash * 2))
)
vcd.write(
b"b%s %s\n"
% (
evcd_strcpy(value_change, True),
vcdid_unhash(hash * 2 + 1),
)
)
else:
raise SoottyError("EVCD syntax error: undeclared identifier_code")
# Ignores simulation keywords not in comments
elif tok == b'$dumpports' or tok == b'$dumpportson' or tok == b'$dumpportsoff' or tok == b'$dumpportsall' \
or tok == b'$dumpportsflush' or tok == b'$dumpportslimit' or tok == b'$vcdclose':
elif (
tok == b"$dumpports"
or tok == b"$dumpportson"
or tok == b"$dumpportsoff"
or tok == b"$dumpportsall"
or tok == b"$dumpportsflush"
or tok == b"$dumpportslimit"
or tok == b"$vcdclose"
):
if not sim_kw:
sim_kw = True
continue
else:
raise SoottyError("EVCD syntax error: previous simulation keyword not enclosed by $end")
elif tok == b'$end':
raise SoottyError(
"EVCD syntax error: previous simulation keyword not enclosed by $end"
)
elif tok == b"$end":
if sim_kw:
sim_kw = False
continue
else:
raise SoottyError("EVCD syntax error: redundant $end")
# Check VCD simulation keywords not in comments
elif tok == b'$dumpvars' or tok == b'$dumpon' or tok == b'$dumpoff' or tok == b'$dumpflush' or tok == b'$dumplimit':
elif (
tok == b"$dumpvars"
or tok == b"$dumpon"
or tok == b"$dumpoff"
or tok == b"$dumpflush"
or tok == b"$dumplimit"
):
raise SoottyError("EVCD syntax error: VCD simulation keywords detected")
else:
raise SoottyError("EVCD syntax error: invalid simulation time or value changes")
raise SoottyError(
"EVCD syntax error: invalid simulation time or value changes"
)
except StopIteration:
pass
vcd.seek(0)
return BufferedReader(vcd)

0 comments on commit 6cdb351

Please sign in to comment.