3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-06 06:03:23 +00:00

IPC progress

Signed-off-by: Claire Xenia Wolf <claire@clairexen.net>
This commit is contained in:
Claire Xenia Wolf 2022-01-10 18:31:28 +01:00
parent 7233e6f8f5
commit d3a79afce2

View file

@ -41,7 +41,7 @@ def pp(v, indent=""):
else: else:
print(indent + "=" + str(v)) print(indent + "=" + str(v))
class SvaParserError(Exception): class SviParserError(Exception):
def __init__(self, text, expected): def __init__(self, text, expected):
self.text = text self.text = text
self.expected = expected self.expected = expected
@ -49,32 +49,47 @@ class SvaParserError(Exception):
def parse_str(text, s): def parse_str(text, s):
text = text.lstrip() text = text.lstrip()
if not text.startswith(s): if not text.startswith(s):
raise SvaParserError(text, s) raise SviParserError(text, s)
return Op("str", [s], text[len(s):]) return Op("str", [s], text[len(s):])
def parse_binop(text, ops, arg1_parser, arg2_parser=None): def parse_binop(text, ops, arg_parser, assoc="L"):
if arg2_parser is None:
arg2_parser = arg1_parser
text = text.lstrip() text = text.lstrip()
p = arg1_parser(text) args = [arg_parser(text)]
opers = []
for op, cmd in ops: while True:
try: for op, cmd in ops:
q = parse_str(p.tail, op) try:
q = arg2_parser(q.tail) q = parse_str(args[-1].tail, op)
return Op(cmd, [p, q], q.tail) q = arg2_parser(q.tail)
except SvaParserError: args.append(q)
pass opers.append(cmd)
except SviParserError:
pass
else:
break
return p if len(opers) == 1:
args, opers = [Op(opers[0], args, args[-1].tail)], []
elif assoc == "L":
while len(opers) > 1:
args = [Op(opers[0], args[0:2], args[1].tail), *args[2:]]
opers = opers[1:]
elif assoc == "R":
while len(opers) > 1:
args = [Op(opers[-1], args[-2:], args[-1].tail), *args[0:-2]]
opers = opers[:-1]
else:
assert False
return args[0]
def parse_int(text, label, base, digits): def parse_int(text, label, base, digits):
text = text.lstrip() text = text.lstrip()
tail = text.lstrip(digits) tail = text.lstrip(digits)
if len(text) == len(tail) or text.startswith("_"): if len(text) == len(tail) or text.startswith("_"):
raise SvaParserError(text, label) raise SviParserError(text, label)
text = text[:-len(tail)].replace("_", "") text = text[:-len(tail)].replace("_", "")
return Op("int", int(text, base), tail) return Op("int", int(text, base), tail)
@ -98,7 +113,7 @@ def parse_name(text):
tail = tail[1:] tail = tail[1:]
if len(text) == len(tail): if len(text) == len(tail):
raise SvaParserError(text, "name") raise SviParserError(text, "name")
return Op("name", text[:-len(tail)], tail) return Op("name", text[:-len(tail)], tail)
@ -112,14 +127,14 @@ def parse_const(text):
q = parse_str(p.tail, "'h") q = parse_str(p.tail, "'h")
q = parse_hex(q.tail) q = parse_hex(q.tail)
return Op("const", [p.args, q.args], q.tail) return Op("const", [p.args, q.args], q.tail)
except SvaParserError: except SviParserError:
pass pass
try: try:
q = parse_str(p.tail, "'b") q = parse_str(p.tail, "'b")
q = parse_bin(q.tail) q = parse_bin(q.tail)
return Op("const", [p.args, q.args], q.tail) return Op("const", [p.args, q.args], q.tail)
except SvaParserError: except SviParserError:
pass pass
return Op("const", [32, p.args], p.tail) return Op("const", [32, p.args], p.tail)
@ -140,7 +155,7 @@ def parse_signal(text):
r = parse_dec(r.tail) r = parse_dec(r.tail)
s = parse_str(r.tail, "]") s = parse_str(r.tail, "]")
return Op("signal", [p.args, r.args, q.args-r.args+1], s.tail) return Op("signal", [p.args, r.args, q.args-r.args+1], s.tail)
except SvaParserError: except SviParserError:
pass pass
try: try:
@ -148,36 +163,38 @@ def parse_signal(text):
r = parse_dec(r.tail) r = parse_dec(r.tail)
s = parse_str(r.tail, "]") s = parse_str(r.tail, "]")
return Op("signal", [p.args, q.args, r.args], s.tail) return Op("signal", [p.args, q.args, r.args], s.tail)
except SvaParserError: except SviParserError:
pass pass
r = parse_str(q.tail, "]") r = parse_str(q.tail, "]")
return Op("signal", [p.args, q.args], r.tail) return Op("signal", [p.args, q.args], r.tail)
except SvaParserError: except SviParserError:
pass pass
return Op("signal", [p.args], p.tail) return Op("signal", [p.args], p.tail)
# atom: ! atom # lvl0:
# atom: const # "!" lvl0
# atom: signal # "~" lvl0
# atom: ( expr ) # const
def parse_atom(text): # signal
# "(" expr ")"
def parse_lvl0(text):
try: try:
p = parse_str(text, "!") p = parse_str(text, "!")
p = parse_atom(p.tail) p = parse_atom(p.tail)
return Op("not", [p], p.tail) return Op("not", [p], p.tail)
except SvaParserError: except SviParserError:
pass pass
try: try:
return parse_const(text) return parse_const(text)
except SvaParserError: except SviParserError:
pass pass
try: try:
return parse_signal(text) return parse_signal(text)
except SvaParserError: except SviParserError:
pass pass
p = parse_str(text, "(") p = parse_str(text, "(")
@ -185,15 +202,45 @@ def parse_atom(text):
q = parse_str(p.tail, ")") q = parse_str(p.tail, ")")
return p._replace(tail=q.tail) return p._replace(tail=q.tail)
# prod: atom # lvl1:
# prod: atom & prod # lvl0
def parse_prod(text): # lvl1 + lvl0
return parse_binop(text, [("&", "and")], parse_atom, parse_prod) # lvl1 - lvl0
def parse_lvl1(text):
return parse_binop(text, [("+", "add"), ("-", "sub")], parse_lvl0)
# sum: prod # lvl2:
# sum: prod | sum # lvl2 "<<" lvl1
def parse_sum(text): # lvl2 ">>" lvl1
return parse_binop(text, [("|", "or")], parse_prod, parse_sum) def parse_lvl2(text):
return parse_binop(text, [("<<", "shl"), (">>", "shr")], parse_lvl1)
# lvl3:
# lvl3 ("<"|">"|"<="|">="|"=="|"!=") lvl2
def parse_lvl3(text):
return parse_binop(text, [
("<", "lt"),
(">", "gt"),
("<=", "le"),
(">=", "ge"),
("==", "eq"),
("!=", "ne")
], parse_lvl2)
# lvl4:
# lvl3 op lvl3
def parse_lvl4(text):
return parse_binop(text, [("&", "or")], parse_lvl3)
# lvl5:
# lvl4 op lvl4
def parse_lvl4(text):
return parse_binop(text, [("&", "or")], parse_lvl3)
# lvlN:
# lvlN op lvlK
def parse_lvlN(text):
return parse_binop(text, [("|", "or")], parse_lvlK)
# term: sum # term: sum
# term: sum ^ term # term: sum ^ term
@ -234,9 +281,9 @@ if __name__ == '__main__':
if False: if False:
import fileinput import fileinput
with fileinput.input() as f: with fileinput.input() as f:
sva_text = "".join(f).rstrip() svi_text = "".join(f).rstrip()
else: else:
sva_text = """ svi_text = """
1 & S[1] |-> S[3:2] and 8'h a_B | S[2+:2] | 1 ^ 3 'b 101 == S; 1 & S[1] |-> S[3:2] and 8'h a_B | S[2+:2] | 1 ^ 3 'b 101 == S;
a a
@ -247,21 +294,21 @@ x |-> c > d;
""".strip() """.strip()
print("--- Input ---") print("--- Input ---")
print(sva_text) print(svi_text)
print("-------------") print("-------------")
props = [] props = []
try: try:
while len(sva_text): while len(svi_text):
props.append(parse_prop(sva_text)) props.append(parse_prop(svi_text))
sva_text = props[-1].tail svi_text = props[-1].tail
except SvaParserError as e: except SviParserError as e:
print(e) print(e)
if len(props) == 1: if len(props) == 1:
props = props[0] props = props[0]
else: else:
props = Op("conj", props, sva_text) props = Op("conj", props, svi_text)
print() print()
print("--- Property ---") print("--- Property ---")