|
| 1 | +#------------------------------------------------------------------------------- |
| 2 | +# active_condition.py |
| 3 | +# |
| 4 | +# Active condition list generator from Verilog Definitions with Pyverilog |
| 5 | +# |
| 6 | +# Copyright (C) 2013, Shinya Takamaeda-Yamazaki |
| 7 | +# License: Apache 2.0 |
| 8 | +#------------------------------------------------------------------------------- |
| 9 | + |
| 10 | +import sys |
| 11 | +import os |
| 12 | + |
| 13 | +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) ) |
| 14 | + |
| 15 | +import pyverilog.utils.version |
| 16 | +import pyverilog.utils.util as util |
| 17 | +import pyverilog.utils.tree_reorder as tree_reorder |
| 18 | +import pyverilog.utils.tree_splitter as tree_splitter |
| 19 | +import pyverilog.utils.inference as inference |
| 20 | +import pyverilog.utils.state_transition as state_transition |
| 21 | +from pyverilog.utils.dataflow import * |
| 22 | + |
| 23 | +from pyverilog.controlflow.controlflow import VerilogControlflow |
| 24 | + |
| 25 | +class VerilogActiveCondition(VerilogControlflow): |
| 26 | + def __init__(self, topmodule, terms, binddict, |
| 27 | + resolved_terms, resolved_binddict, constlist): |
| 28 | + VerilogControlflow.__init__(self, topmodule, terms, binddict, |
| 29 | + resolved_terms, resolved_binddict, constlist) |
| 30 | + self.fsm_loops, self.fsms = self.getLoops() |
| 31 | + |
| 32 | + ############################################################################ |
| 33 | + def getActiveConditions(self, termname, condition=tree_splitter.active_constant): |
| 34 | + if not termname in self.resolved_binddict: return {} |
| 35 | + tree = self.makeTree(termname) |
| 36 | + funcdict = tree_splitter.split(tree) |
| 37 | + funcdict = tree_splitter.filter(funcdict, termname, condition) |
| 38 | + funcdict = tree_splitter.remove_reset_condition(funcdict) |
| 39 | + |
| 40 | + if len(funcdict) == 1 and len(list(funcdict.keys())[0]) == 0: |
| 41 | + func = funcdict.values()[0] |
| 42 | + return {termname : ( ('any', None), )} |
| 43 | + |
| 44 | + active_conditions = {} |
| 45 | + active_conditions_size = 0 |
| 46 | + for fsm_sig in self.fsms.keys(): |
| 47 | + rslt = self.getActiveConditions_fsm(fsm_sig, funcdict) |
| 48 | + if len(rslt) > 0: active_conditions[fsm_sig] = rslt |
| 49 | + active_conditions_size += len(rslt) |
| 50 | + |
| 51 | + if active_conditions_size == 0: |
| 52 | + rslt = self.getActiveConditions_fsm(termname, funcdict) |
| 53 | + if len(rslt) > 0: active_conditions[termname] = rslt |
| 54 | + |
| 55 | + return active_conditions |
| 56 | + |
| 57 | + def getActiveConditions_fsm(self, fsm_sig, funcdict): |
| 58 | + # returns a list of some (state, transcond) pairs |
| 59 | + active_conditions = [] |
| 60 | + fsm_sig_width = self.getWidth(fsm_sig) |
| 61 | + for condlist, func in sorted(funcdict.items(), key=lambda x:len(x[0])): |
| 62 | + node = state_transition.walkCondlist(condlist, fsm_sig, fsm_sig_width) |
| 63 | + state_node_list = [] |
| 64 | + if isinstance(node, state_transition.StateNodeList): |
| 65 | + for n in node.nodelist: state_node_list.append(n) |
| 66 | + elif node: |
| 67 | + state_node_list.append(node) |
| 68 | + |
| 69 | + for state_node in state_node_list: |
| 70 | + #if state_node.isany: |
| 71 | + # active_conditions.append( ('any', state_node.transcond) ) |
| 72 | + for rs, re in state_node.range_pairs: |
| 73 | + for state in range(rs, re+1): |
| 74 | + transcond = self.optimizer.optimize(state_node.transcond) |
| 75 | + if isinstance(transcond, DFEvalValue) and transcond.value == 0: continue |
| 76 | + active_conditions.append( (state, transcond) ) |
| 77 | + return tuple(active_conditions) |
| 78 | + |
| 79 | +################################################################################ |
| 80 | +if __name__ == '__main__': |
| 81 | + from optparse import OptionParser |
| 82 | + from pyverilog.definition_analyzer.definition_analyzer import VerilogDefinitionAnalyzer |
| 83 | + from pyverilog.definition_resolver.definition_resolver import VerilogDefinitionResolver |
| 84 | + INFO = "Active condition analyzer for Verilog definitions with Pyverilog" |
| 85 | + VERSION = pyverilog.utils.version.VERSION |
| 86 | + USAGE = "Usage: python active_analyzer.py -t TOPMODULE file ..." |
| 87 | + |
| 88 | + def showVersion(): |
| 89 | + print(INFO) |
| 90 | + print(VERSION) |
| 91 | + print(USAGE) |
| 92 | + sys.exit() |
| 93 | + |
| 94 | + optparser = OptionParser() |
| 95 | + optparser.add_option("-v","--version",action="store_true",dest="showversion", |
| 96 | + default=False,help="Show the version") |
| 97 | + optparser.add_option("-t","--top",dest="topmodule", |
| 98 | + default="TOP",help="Top module, Default=TOP") |
| 99 | + optparser.add_option("-s","--search",dest="searchtarget",action="append", |
| 100 | + default=[],help="Search Target Signal") |
| 101 | + (options, args) = optparser.parse_args() |
| 102 | + |
| 103 | + filelist = args |
| 104 | + if options.showversion: |
| 105 | + showVersion() |
| 106 | + |
| 107 | + for f in filelist: |
| 108 | + if not os.path.exists(f): raise IOError("file not found: " + f) |
| 109 | + |
| 110 | + if len(filelist) == 0: |
| 111 | + showVersion() |
| 112 | + |
| 113 | + verilogdefinitionanalyzer = VerilogDefinitionAnalyzer(filelist, options.topmodule) |
| 114 | + verilogdefinitionanalyzer.generate() |
| 115 | + |
| 116 | + directives = verilogdefinitionanalyzer.get_directives() |
| 117 | + terms = verilogdefinitionanalyzer.getTerms() |
| 118 | + binddict = verilogdefinitionanalyzer.getBinddict() |
| 119 | + |
| 120 | + verilogdefinitionresolver = VerilogDefinitionResolver(terms, binddict) |
| 121 | + |
| 122 | + verilogdefinitionresolver.resolveConstant() |
| 123 | + resolved_terms = verilogdefinitionresolver.getResolvedTerms() |
| 124 | + resolved_binddict = verilogdefinitionresolver.getResolvedBinddict() |
| 125 | + constlist = verilogdefinitionresolver.getConstlist() |
| 126 | + |
| 127 | + active = VerilogActiveCondition(options.topmodule, terms, binddict, resolved_terms, resolved_binddict, constlist) |
| 128 | + |
| 129 | + for target in options.searchtarget: |
| 130 | + signal = util.toTermname(target) |
| 131 | + active_conditions = active.getActiveConditions( signal ) |
| 132 | + |
| 133 | + #active_conditions = active.getActiveConditions( signal, condition=tree_splitter.active_modify ) |
| 134 | + #active_conditions = active.getActiveConditions( signal, condition=tree_splitter.active_unmodify ) |
| 135 | + |
| 136 | + print('Active Cases: %s' % signal) |
| 137 | + for fsm_sig, active_conditions in sorted(active_conditions.items(), key=lambda x:str(x[0])): |
| 138 | + print('FSM: %s' % fsm_sig) |
| 139 | + for state, active_condition in sorted(active_conditions, key=lambda x:str(x[0])): |
| 140 | + s = [] |
| 141 | + s.append('state: %d -> ' % state) |
| 142 | + if active_condition: s.append(active_condition.tocode()) |
| 143 | + else: s.append('empty') |
| 144 | + print(''.join(s)) |
0 commit comments