blob: f948af2d3117e169e21378ae0d5981afbbac570d [file] [log] [blame]
# -------------------------------------------------------------------------------
# reorder.py
#
# Reorders DFNode trees in order of DFBranch, DFOperator, and DFTerminal
#
# Copyright (C) 2013, Shinya Takamaeda-Yamazaki
# License: Apache 2.0
# -------------------------------------------------------------------------------
from __future__ import absolute_import
from __future__ import print_function
import sys
import os
import copy
from pyverilog.dataflow.dataflow import *
def reorder(tree):
if tree is None:
return None
if isinstance(tree, DFConstant):
return tree
if isinstance(tree, DFTerminal):
return tree
if isinstance(tree, DFEvalValue):
return tree
if isinstance(tree, DFUndefined):
return tree
if isinstance(tree, DFHighImpedance):
return tree
if isinstance(tree, DFBranch):
truenode = reorder(tree.truenode)
falsenode = reorder(tree.falsenode)
condnode = reorder(tree.condnode)
if isinstance(condnode, DFBranch):
return insertBranch(condnode, truenode, falsenode)
return DFBranch(condnode, truenode, falsenode)
if isinstance(tree, DFOperator):
resolvednodes = []
for n in tree.nextnodes:
resolvednodes.append(reorder(n))
for r in resolvednodes:
if isinstance(r, DFBranch):
return insertOpList(resolvednodes, tree.operator)
return DFOperator(tuple(resolvednodes), tree.operator)
if isinstance(tree, DFConcat):
resolvednodes = []
for n in tree.nextnodes:
resolvednodes.append(reorder(n))
for r in resolvednodes:
if isinstance(r, DFBranch):
return insertConcat(resolvednodes)
return DFConcat(tuple(resolvednodes))
if isinstance(tree, DFPartselect):
resolved_msb = reorder(tree.msb)
resolved_lsb = reorder(tree.lsb)
resolved_var = reorder(tree.var)
if isinstance(resolved_msb, DFBranch) or isinstance(resolved_lsb, DFBranch):
raise FormatError('MSB and LSB should not be DFBranch')
if isinstance(resolved_var, DFBranch):
return insertPartselect(resolved_var, resolved_msb, resolved_lsb)
return DFPartselect(resolved_var, resolved_msb, resolved_lsb)
if isinstance(tree, DFPointer):
resolved_ptr = reorder(tree.ptr)
resolved_var = reorder(tree.var)
if isinstance(resolved_ptr, DFBranch):
# raise FormatError('PTR should not be DFBranch')n
return DFBranch(resolved_ptr.condnode,
reorder(DFPointer(resolved_var, resolved_ptr.truenode)),
reorder(DFPointer(resolved_var, resolved_ptr.falsenode)))
if isinstance(resolved_var, DFBranch):
return insertPointer(resolved_var, resolved_ptr)
return DFPointer(resolved_var, resolved_ptr)
if isinstance(tree, DFDelay):
return DFDelay(reorder(tree.nextnode))
raise DefinitionError('Undefined DFNode type: %s %s' % (str(type(tree)), str(tree)))
############################################################################
def insertBranch(base, truenode, falsenode):
if isinstance(base, DFBranch):
return DFBranch(base.condnode, insertBranch(base.truenode, truenode, falsenode), insertBranch(base.falsenode, truenode, falsenode))
return DFBranch(base, truenode, falsenode)
def insertUnaryOp(base, op):
if isinstance(base, DFBranch):
return DFBranch(base.condnode, insertUnaryOp(base.truenode, op), insertUnaryOp(base.falsenode, op))
return DFOperator((base,), op)
def insertOp(left, right, op):
if isinstance(left, DFBranch):
return DFBranch(left.condnode, insertOp(left.truenode, right, op), insertOp(left.falsenode, right, op))
elif isinstance(right, DFBranch):
return DFBranch(right.condnode, insertOp(left, right.truenode, op), insertOp(left, right.falsenode, op))
return DFOperator((left, right), op)
def insertOpList(nextnodes, op):
donenodes = []
restnodes = list(nextnodes)
for n in nextnodes:
restnodes.pop(0)
if isinstance(n, DFBranch):
return DFBranch(n.condnode, insertOpList(tuple(donenodes + [n.truenode, ] + restnodes), op), insertOpList(tuple(donenodes + [n.falsenode, ] + restnodes), op))
donenodes.append(n)
return DFOperator(nextnodes, op)
def insertConcat(nextnodes):
donenodes = []
restnodes = list(nextnodes)
for n in nextnodes:
restnodes.pop(0)
if isinstance(n, DFBranch):
return DFBranch(n.condnode, insertConcat(tuple(donenodes + [n.truenode, ] + restnodes)), insertConcat(tuple(donenodes + [n.falsenode, ] + restnodes)))
donenodes.append(n)
return DFConcat(nextnodes)
def insertPartselect(var, msb, lsb):
if isinstance(var, DFBranch):
return DFBranch(var.condnode, insertPartselect(var.truenode, msb, lsb), insertPartselect(var.falsenode, msb, lsb))
if var is None:
return None
return DFPartselect(var, msb, lsb)
def insertPointer(var, ptr):
if isinstance(var, DFBranch):
return DFBranch(var.condnode, insertPointer(var.truenode, ptr), insertPointer(var.falsenode, ptr))
if var is None:
return None
return DFPointer(var, ptr)