kdrag.printers.verilog
Functions
|
Produces a pure combinatorial module in Verilog. |
|
|
|
Convert an SMT-LIB expression to a Verilog expression. |
- kdrag.printers.verilog.to_verilog(modname: str, ins: list[ExprRef], outs: dict[ExprRef, ExprRef]) str
Produces a pure combinatorial module in Verilog.
>>> x,y,z = smt.Consts("x y z", smt.BitVecSort(8)) >>> a,b,c = smt.Consts("a b c", smt.BoolSort()) >>> print(to_verilog("foo", [x, y], {a: smt.ULE(x + y, 17), z: x & y})) // Generated by knuckledragger module foo ( input [7:0] x, input [7:0] y, output a, output [7:0] z ); assign a = ((x + y) <= 8'd17); assign z = (x & y); endmodule
- Parameters:
modname (str)
ins (list[ExprRef])
outs (dict[ExprRef, ExprRef])
- Return type:
str
- kdrag.printers.verilog.verilog_decl(v: ExprRef) str
- Parameters:
v (ExprRef)
- Return type:
str
- kdrag.printers.verilog.verilog_of_expr(expr: ExprRef) str
Convert an SMT-LIB expression to a Verilog expression.
>>> x,y,z = smt.Consts("x y z", smt.BitVecSort(8)) >>> a,b,c = smt.Consts("a b c", smt.BoolSort()) >>> verilog_of_expr(x + y + z) '((x + y) + z)' >>> verilog_of_expr(smt.Concat(x, y, z)) '{{x, y}, z}' >>> verilog_of_expr(a & True) "(a && 1'b1)"
- Parameters:
expr (ExprRef)
- Return type:
str
import kdrag.smt as smt
binops = {
"bvand": "&",
"bvor": "|",
"bvxor": "^",
"bvule": "<=",
"bvult": "<",
"bvuge": ">=",
"bvugt": ">",
"bvadd": "+",
"bvsub": "-",
# "bvudiv" : " / ", # TODO: think about this one
"bvmul": "*",
"=": "==",
"distinct": "!=",
"bvshl": "<<",
"bvlshr": ">>",
"bvashr": ">>>",
}
def verilog_of_expr(expr: smt.ExprRef) -> str:
"""
Convert an SMT-LIB expression to a Verilog expression.
>>> x,y,z = smt.Consts("x y z", smt.BitVecSort(8))
>>> a,b,c = smt.Consts("a b c", smt.BoolSort())
>>> verilog_of_expr(x + y + z)
'((x + y) + z)'
>>> verilog_of_expr(smt.Concat(x, y, z))
'{{x, y}, z}'
>>> verilog_of_expr(a & True)
"(a && 1'b1)"
"""
if isinstance(expr, smt.BitVecNumRef):
return str(expr.size()) + "'d" + str(expr.as_long())
elif smt.is_true(expr):
return "1'b1"
elif smt.is_false(expr):
return "1'b0"
elif smt.is_const(expr):
return expr.decl().name()
elif smt.is_app(expr):
children = [verilog_of_expr(c) for c in expr.children()]
name = expr.decl().name()
if smt.is_select(expr):
return f"{children[0]}[{children[1]}]"
elif name == "ite":
return f"({children[0]} ? {children[1]} : {children[2]})"
elif name == "and":
return "(" + " && ".join(children) + ")"
elif name == "or":
return "(" + " || ".join(children) + ")"
elif name == "not":
return f"(!{children[0]})"
elif name in binops:
assert len(children) == 2
return f"({children[0]} {binops[name]} {children[1]})"
elif name == "bvnot":
assert len(children) == 1
return f"(~{children[0]})"
elif name == "concat":
return f"{{{', '.join(children)}}}"
else:
raise Exception(f"Unknown expression: {expr}")
else:
raise Exception(f"Unknown expression: {expr}")
def verilog_decl(v: smt.ExprRef) -> str:
assert smt.is_const(v)
sort = v.sort()
if sort == smt.BoolSort():
return f"{v.decl().name()}"
elif isinstance(v, smt.BitVecRef):
return f"[{v.size() - 1}:0] {v.decl().name()}"
else:
raise Exception(f"Unknown sort: {sort}")
def to_verilog(
modname: str, ins: list[smt.ExprRef], outs: dict[smt.ExprRef, smt.ExprRef]
) -> str:
"""
Produces a pure combinatorial module in Verilog.
>>> x,y,z = smt.Consts("x y z", smt.BitVecSort(8))
>>> a,b,c = smt.Consts("a b c", smt.BoolSort())
>>> print(to_verilog("foo", [x, y], {a: smt.ULE(x + y, 17), z: x & y}))
// Generated by knuckledragger
module foo (
input [7:0] x,
input [7:0] y,
output a,
output [7:0] z
);
assign a = ((x + y) <= 8'd17);
assign z = (x & y);
endmodule
"""
assert len(set(ins)) == len(ins)
assert all([v not in outs for v in ins])
for k, v in outs.items():
if k.sort() != v.sort():
raise Exception(f"Output {k} and value {v} have different sorts")
outdecls = ["output " + verilog_decl(out) for out in outs.keys()]
indecls = ["input " + verilog_decl(in_) for in_ in ins]
decls = ",\n ".join(indecls + outdecls)
assigns = "\n".join(
[
f"assign {out.decl().name()} = {verilog_of_expr(value)};"
for out, value in outs.items()
]
)
return f"""\
// Generated by knuckledragger
module {modname} (
{decls}
);
{assigns}
endmodule
"""