#-------------------------------------------------------------------------------
# graphgen.py
#
# Dataflow graph generator (Only Python 2.7)
#
# pygraphviz and graphviz are required
#
# 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 pygraphviz as pgv
from optparse import OptionParser

# the next line can be removed after installation
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import pyverilog.utils.version
from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer
from pyverilog.dataflow.optimizer import VerilogDataflowOptimizer
from pyverilog.dataflow.graphgen import VerilogGraphGenerator

def main():
    INFO = "Graph generator from dataflow"
    VERSION = pyverilog.utils.version.VERSION
    USAGE = "Usage: python example_graphgen.py -t TOPMODULE -s TARGETSIGNAL file ..."

    def showVersion():
        print(INFO)
        print(VERSION)
        print(USAGE)
        sys.exit()
    
    optparser = OptionParser()
    optparser.add_option("-v","--version",action="store_true",dest="showversion",
                         default=False,help="Show the version")
    optparser.add_option("-I","--include",dest="include",action="append",
                         default=[],help="Include path")
    optparser.add_option("-D",dest="define",action="append",
                         default=[],help="Macro Definition")
    optparser.add_option("-t","--top",dest="topmodule",
                         default="TOP",help="Top module, Default=TOP")
    optparser.add_option("--nobind",action="store_true",dest="nobind",
                         default=False,help="No binding traversal, Default=False")
    optparser.add_option("--noreorder",action="store_true",dest="noreorder",
                         default=False,help="No reordering of binding dataflow, Default=False")
    optparser.add_option("-s","--search",dest="searchtarget",action="append",
                         default=[],help="Search Target Signal")
    optparser.add_option("-o","--output",dest="outputfile",
                         default="out.png",help="Graph file name, Default=out.png")
    optparser.add_option("--identical",action="store_true",dest="identical",
                         default=False,help="# Identical Laef, Default=False")
    optparser.add_option("--walk",action="store_true",dest="walk",
                         default=False,help="Walk contineous signals, Default=False")
    optparser.add_option("--step",dest="step",type='int', 
                         default=1,help="# Search Steps, Default=1")
    optparser.add_option("--reorder",action="store_true",dest="reorder",
                         default=False,help="Reorder the contineous tree, Default=False")
    optparser.add_option("--delay",action="store_true",dest="delay",
                         default=False,help="Inset Delay Node to walk Regs, Default=False")
    (options, args) = optparser.parse_args()

    filelist = args
    if options.showversion:
        showVersion()

    for f in filelist:
        if not os.path.exists(f): raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showVersion()

    analyzer = VerilogDataflowAnalyzer(filelist, options.topmodule,
                                       noreorder=options.noreorder,
                                       nobind=options.nobind,
                                       preprocess_include=options.include,
                                       preprocess_define=options.define)
    analyzer.generate()

    directives = analyzer.get_directives()
    terms = analyzer.getTerms()
    binddict = analyzer.getBinddict()

    optimizer = VerilogDataflowOptimizer(terms, binddict)

    optimizer.resolveConstant()
    resolved_terms = optimizer.getResolvedTerms()
    resolved_binddict = optimizer.getResolvedBinddict()
    constlist = optimizer.getConstlist()

    graphgen = VerilogGraphGenerator(options.topmodule, terms, binddict, 
                                     resolved_terms, resolved_binddict, constlist, options.outputfile)

    for target in options.searchtarget:
        graphgen.generate(target, walk=options.walk, identical=options.identical, 
                          step=options.step, reorder=options.reorder, delay=options.delay)

    graphgen.draw()
    
if __name__ == '__main__':
    main()
