Skip to content

Commit

Permalink
Merge 497984b into 74a7bd6
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed Feb 22, 2019
2 parents 74a7bd6 + 497984b commit d3a60d0
Show file tree
Hide file tree
Showing 31 changed files with 201 additions and 151 deletions.
14 changes: 6 additions & 8 deletions magma/ssa/ssa.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import astor


def flatten(l : list):
def flatten(l: list):
"""
Non-recursive flatten that ignores non-list children
"""
Expand All @@ -23,7 +23,7 @@ def __init__(self):
super().__init__()
self.last_name = defaultdict(lambda: "")
self.var_counter = defaultdict(lambda: -1)
self.args = set()
self.args = []
self.cond_stack = []
self.return_values = []

Expand All @@ -38,7 +38,7 @@ def visit_Assign(self, node):

def visit_FunctionDef(self, node):
for a in node.args.args:
self.args.add(a.arg)
self.args.append(a.arg)
self.last_name[a.arg] = f"{a.arg}_0"
a.arg = f"{a.arg}_0"
node.body = flatten([self.visit(s) for s in node.body])
Expand Down Expand Up @@ -144,15 +144,13 @@ def convert_tree_to_ssa(tree: ast.AST, defn_env: dict):
for c in conds[:-1]:
c = ast.BinOp(cond, ast.And(), c)
tree.body.append(ast.Call(ast.Name("phi", ast.Load()), [
ast.List([name, prev_name], ast.Load()),
cond
], []))
return tree
ast.List([name, prev_name], ast.Load()), cond], []))
return tree, ssa_visitor.args


@ast_utils.inspect_enclosing_env
def ssa(defn_env: dict, fn: types.FunctionType):
tree = ast_utils.get_func_ast(fn)
tree = convert_tree_to_ssa(tree, defn_env)
tree, _ = convert_tree_to_ssa(tree, defn_env)
tree.body.append(ast.Return(ast.Name("O", ast.Load())))
return ast_utils.compile_function_to_file(tree, defn_env=defn_env)
51 changes: 31 additions & 20 deletions magma/syntax/combinational.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,34 @@ def visit_If(self, node):
key = ast.dump(stmt.targets[0])
if key in seen:
# TODO: Print the line number
report_transformer_warning("Assigning to value twice inside `if` block,"
" taking the last value (first value is ignored)", self.filename, node.lineno + self.starting_line, self.lines[node.lineno])
report_transformer_warning(
"Assigning to value twice inside `if` block,"
" taking the last value (first value is ignored)",
self.filename, node.lineno + self.starting_line,
self.lines[node.lineno])
seen[key] = stmt
orelse_seen = set()
for stmt in node.orelse:
key = ast.dump(stmt.targets[0])
if key in seen:
if key in orelse_seen:
report_transformer_warning("Assigning to value twice inside `else` block,"
" taking the last value (first value is ignored)", self.filename, node.lineno + self.starting_line, self.lines[node.lineno])
report_transformer_warning(
"Assigning to value twice inside `else` block,"
" taking the last value (first value is ignored)",
self.filename, node.lineno + self.starting_line,
self.lines[node.lineno])
orelse_seen.add(key)
seen[key].value = ast.Call(
ast.Name("phi", ast.Load()),
[ast.List([stmt.value, seen[key].value],
ast.Load()), node.test],
[])
else:
report_transformer_warning("NOT IMPLEMENTED: Assigning to a variable once in"
" `else` block (not in then block)", self.filename, node.lineno + self.starting_line, self.lines[node.lineno])
report_transformer_warning(
"NOT IMPLEMENTED: Assigning to a variable once in"
" `else` block (not in then block)",
self.filename, node.lineno + self.starting_line,
self.lines[node.lineno])
raise NotImplementedError()
return [node for node in seen.values()]

Expand All @@ -96,9 +105,10 @@ def visit_IfExp(self, node):


class FunctionToCircuitDefTransformer(ast.NodeTransformer):
def __init__(self):
def __init__(self, renamed_args):
super().__init__()
self.IO = set()
self.IO = {}
self.renamed_args = renamed_args

def visit(self, node):
new_node = super().visit(node)
Expand All @@ -110,11 +120,11 @@ def qualify(self, node, direction):
return ast.Call(m_dot(direction), [node], [])

def visit_FunctionDef(self, node):
names = [arg.arg for arg in node.args.args]
names = self.renamed_args
types = [arg.annotation for arg in node.args.args]
IO = []
for name, type_ in zip(names, types):
self.IO.add(name)
self.IO[name + "_0"] = name # Add ssa rename
IO.extend([ast.Str(name),
self.qualify(type_, "In")])
if isinstance(node.returns, ast.Tuple):
Expand All @@ -129,7 +139,8 @@ def visit_FunctionDef(self, node):
node.body.append(ast.Expr(ast.Call(
m_dot("wire"),
[ast.Name(f"O{i}", ast.Load()),
ast.Attribute(ast.Name("io", ast.Load()), f"O{i}", ast.Load())],
ast.Attribute(ast.Name("io", ast.Load()), f"O{i}",
ast.Load())],
[]
)))
else:
Expand Down Expand Up @@ -157,15 +168,13 @@ def visit_FunctionDef(self, node):
node.body,
[ast.Name("classmethod", ast.Load())],
None
)

],
)],
[])
return class_def

def visit_Name(self, node):
if node.id in self.IO:
return ast.Attribute(ast.Name("io", ast.Load()), node.id,
return ast.Attribute(ast.Name("io", ast.Load()), self.IO[node.id],
ast.Load())
return node

Expand All @@ -181,12 +190,13 @@ def visit_Name(self, node):


@ast_utils.inspect_enclosing_env
def combinational(defn_env : dict, fn : types.FunctionType):
def combinational(defn_env: dict, fn: types.FunctionType):
tree = ast_utils.get_func_ast(fn)
tree = convert_tree_to_ssa(tree, defn_env)
tree = FunctionToCircuitDefTransformer().visit(tree)
tree, renamed_args = convert_tree_to_ssa(tree, defn_env)
tree = FunctionToCircuitDefTransformer(renamed_args).visit(tree)
tree = ast.fix_missing_locations(tree)
tree = IfTransformer(inspect.getsourcefile(fn), inspect.getsourcelines(fn)).visit(tree)
tree = IfTransformer(inspect.getsourcefile(fn),
inspect.getsourcelines(fn)).visit(tree)
tree = ast.fix_missing_locations(tree)
tree.decorator_list = ast_utils.filter_decorator(
combinational, tree.decorator_list, defn_env)
Expand All @@ -201,7 +211,8 @@ def combinational(defn_env : dict, fn : types.FunctionType):
source += f" {i}: {line}\n"

debug(source)
circuit_def = ast_utils.compile_function_to_file(tree, fn.__name__, defn_env)
circuit_def = ast_utils.compile_function_to_file(tree, fn.__name__,
defn_env)
circuit_def.debug_info = debug_info(circuit_def.debug_info.filename,
circuit_def.debug_info.lineno,
inspect.getmodule(fn))
Expand Down
10 changes: 10 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[pycodestyle]
max-line-length = 80

# E741: do not use variables named ‘l’, ‘O’, or ‘I’
# We ignore this because I and O is currently idiomatic magma for port names
ignore = E741

[tool:pytest]
codestyle_max_line_length = 80
codestyle_ignore = E741
14 changes: 7 additions & 7 deletions tests/test_syntax/gold/basic_function_call.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
"modules":{
"basic_func":{
"type":["Record",[
["I_0",["Array",2,"BitIn"]],
["S_0","BitIn"],
["I",["Array",2,"BitIn"]],
["S","BitIn"],
["O","Bit"]
]],
"connections":[
["self.O","self.I_0.1"]
["self.O","self.I.1"]
]
},
"basic_function_call":{
"type":["Record",[
["I_0",["Array",2,"BitIn"]],
["S_0","BitIn"],
["I",["Array",2,"BitIn"]],
["S","BitIn"],
["O","Bit"]
]],
"instances":{
Expand All @@ -24,9 +24,9 @@
}
},
"connections":[
["self.I_0","basic_func_inst0.I_0"],
["self.I","basic_func_inst0.I"],
["self.O","basic_func_inst0.O"],
["self.S_0","basic_func_inst0.S_0"]
["self.S","basic_func_inst0.S"]
]
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/test_syntax/gold/basic_function_call.v
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module basic_func (input [1:0] I_0, input S_0, output O);
assign O = I_0[1];
module basic_func (input [1:0] I, input S, output O);
assign O = I[1];
endmodule

module basic_function_call (input [1:0] I_0, input S_0, output O);
module basic_function_call (input [1:0] I, input S, output O);
wire basic_func_inst0_O;
basic_func basic_func_inst0 (.I_0(I_0), .S_0(S_0), .O(basic_func_inst0_O));
basic_func basic_func_inst0 (.I(I), .S(S), .O(basic_func_inst0_O));
assign O = basic_func_inst0_O;
endmodule

6 changes: 3 additions & 3 deletions tests/test_syntax/gold/if_statement_basic.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"modules":{
"basic_if":{
"type":["Record",[
["I_0",["Array",2,"BitIn"]],
["S_0","BitIn"],
["I",["Array",2,"BitIn"]],
["S","BitIn"],
["O","Bit"]
]],
"connections":[
["self.O","self.I_0.1"]
["self.O","self.I.1"]
]
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/test_syntax/gold/if_statement_basic.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module basic_if (input [1:0] I_0, input S_0, output O);
assign O = I_0[1];
module basic_if (input [1:0] I, input S, output O);
assign O = I[1];
endmodule

6 changes: 3 additions & 3 deletions tests/test_syntax/gold/if_statement_nested.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"modules":{
"if_statement_nested":{
"type":["Record",[
["I_0",["Array",4,"BitIn"]],
["S_0",["Array",2,"BitIn"]],
["I",["Array",4,"BitIn"]],
["S",["Array",2,"BitIn"]],
["O","Bit"]
]],
"connections":[
["self.O","self.I_0.3"]
["self.O","self.I.3"]
]
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/test_syntax/gold/if_statement_nested.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module if_statement_nested (input [3:0] I_0, input [1:0] S_0, output O);
assign O = I_0[3];
module if_statement_nested (input [3:0] I, input [1:0] S, output O);
assign O = I[3];
endmodule

6 changes: 3 additions & 3 deletions tests/test_syntax/gold/multiple_assign.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"connections":[
["self.c","logic_inst0.O0"],
["self.a","logic_inst0.a_0"]
["self.a","logic_inst0.a"]
]
},
"Mux2":{
Expand Down Expand Up @@ -43,7 +43,7 @@
},
"logic":{
"type":["Record",[
["a_0","BitIn"],
["a","BitIn"],
["O0","Bit"]
]],
"instances":{
Expand All @@ -68,7 +68,7 @@
["self.O0","Mux2_inst0.O"],
["eq_inst0.O","Mux2_inst0.S"],
["eq_inst0.I1","bit_const_0_None.out"],
["self.a_0","eq_inst0.I0"]
["self.a","eq_inst0.I0"]
]
}
}
Expand Down
6 changes: 3 additions & 3 deletions tests/test_syntax/gold/multiple_assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ module eq (input I0, input I1, output O);
assign O = 1'b0;
endmodule

module logic (input a_0, output O0);
module logic (input a, output O0);
wire eq_inst0_O;
wire Mux2_inst0_O;
eq eq_inst0 (.I0(a_0), .I1(1'b0), .O(eq_inst0_O));
eq eq_inst0 (.I0(a), .I1(1'b0), .O(eq_inst0_O));
Mux2 Mux2_inst0 (.I0(1'b1), .I1(1'b0), .S(eq_inst0_O), .O(Mux2_inst0_O));
assign O0 = Mux2_inst0_O;
endmodule

module Foo (input a, output c);
wire logic_inst0_O0;
logic logic_inst0 (.a_0(a), .O0(logic_inst0_O0));
logic logic_inst0 (.a(a), .O0(logic_inst0_O0));
assign c = logic_inst0_O0;
endmodule

8 changes: 4 additions & 4 deletions tests/test_syntax/gold/optional_assignment.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"connections":[
["self.c","logic_inst0.O0"],
["self.d","logic_inst0.O1"],
["self.a","logic_inst0.a_0"]
["self.a","logic_inst0.a"]
]
},
"Mux2":{
Expand Down Expand Up @@ -45,7 +45,7 @@
},
"logic":{
"type":["Record",[
["a_0","BitIn"],
["a","BitIn"],
["O0","Bit"],
["O1","Bit"]
]],
Expand Down Expand Up @@ -82,8 +82,8 @@
["eq_inst1.O","Mux2_inst1.S"],
["eq_inst0.I1","bit_const_0_None.out"],
["eq_inst1.I1","bit_const_0_None.out"],
["self.a_0","eq_inst0.I0"],
["self.a_0","eq_inst1.I0"]
["self.a","eq_inst0.I0"],
["self.a","eq_inst1.I0"]
]
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/test_syntax/gold/optional_assignment.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ module eq (input I0, input I1, output O);
assign O = 1'b0;
endmodule

module logic (input a_0, output O0, output O1);
module logic (input a, output O0, output O1);
wire eq_inst0_O;
wire Mux2_inst0_O;
wire eq_inst1_O;
wire Mux2_inst1_O;
eq eq_inst0 (.I0(a_0), .I1(1'b0), .O(eq_inst0_O));
eq eq_inst0 (.I0(a), .I1(1'b0), .O(eq_inst0_O));
Mux2 Mux2_inst0 (.I0(1'b1), .I1(1'b1), .S(eq_inst0_O), .O(Mux2_inst0_O));
eq eq_inst1 (.I0(a_0), .I1(1'b0), .O(eq_inst1_O));
eq eq_inst1 (.I0(a), .I1(1'b0), .O(eq_inst1_O));
Mux2 Mux2_inst1 (.I0(1'b0), .I1(1'b1), .S(eq_inst1_O), .O(Mux2_inst1_O));
assign O0 = Mux2_inst1_O;
assign O1 = Mux2_inst0_O;
Expand All @@ -18,7 +18,7 @@ endmodule
module Foo (input a, output c, output d);
wire logic_inst0_O0;
wire logic_inst0_O1;
logic logic_inst0 (.a_0(a), .O0(logic_inst0_O0), .O1(logic_inst0_O1));
logic logic_inst0 (.a(a), .O0(logic_inst0_O0), .O1(logic_inst0_O1));
assign c = logic_inst0_O0;
assign d = logic_inst0_O1;
endmodule
Expand Down
6 changes: 3 additions & 3 deletions tests/test_syntax/gold/return_magma_named_tuple.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"modules":{
"return_magma_named_tuple":{
"type":["Record",[
["I_0",["Array",2,"BitIn"]],
["I",["Array",2,"BitIn"]],
["O",["Record",[["x","Bit"],["y","Bit"]]]]
]],
"connections":[
["self.O.x","self.I_0.0"],
["self.O.y","self.I_0.1"]
["self.O.x","self.I.0"],
["self.O.y","self.I.1"]
]
}
}
Expand Down

0 comments on commit d3a60d0

Please sign in to comment.