diff --git a/.gitignore b/.gitignore index a07698c..aa8306d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ pyverilog_toolbox/verify_tool/parsetab.py *.output pyverilog_toolbox/testcode/parsetab.py *.out +pyverilog_toolbox/verify_tool/out.csv diff --git a/Readme.md b/Readme.md index e31f0d7..b1e6681 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ Introduction ============================== -Pyverilog_toolbox is Pyverilog based verification/design tool. +Pyverilog_toolbox is Pyverilog-based verification/design tool. Including only register map analyzer now. diff --git a/pyverilog_toolbox/testcode/regmap2.v b/pyverilog_toolbox/testcode/regmap2.v new file mode 100644 index 0000000..6a9e48d --- /dev/null +++ b/pyverilog_toolbox/testcode/regmap2.v @@ -0,0 +1,30 @@ +module TOP(CLK, RST, WRITE, READ, ADDR, WRITE_DATA, READ_DATA); + input CLK,RST,WRITE,READ; + input [2:0] ADDR; + input [1:0] WRITE_DATA; + output reg [1:0] READ_DATA; + reg [4:3] reg0; + + + + always @(posedge CLK) begin + if(RST) begin + reg0[4:3] <= 0; + end else if(WRITE) begin + case(ADDR) + 0:reg0[4:3] <= WRITE_DATA[1:0]; + endcase + //reg0[4:3] <= WRITE_DATA[1:0]; + end + end + + always @* begin + case(ADDR) + 0:READ_DATA[1:0] = reg0[4:3]; + endcase + end + + + +endmodule + diff --git a/pyverilog_toolbox/testcode/regmap_split2.v b/pyverilog_toolbox/testcode/regmap_split2.v new file mode 100644 index 0000000..0e26412 --- /dev/null +++ b/pyverilog_toolbox/testcode/regmap_split2.v @@ -0,0 +1,21 @@ +module TOP(CLK, RST, WRITE, READ, ADDR, WRITE_DATA, READ_DATA); + input CLK,RST,WRITE,READ; + input [2:0] ADDR; + input [3:0] WRITE_DATA; + output [3:0] READ_DATA; + + reg [1:0] reg1,reg0; + + always @(posedge CLK) begin + if(RST) begin + reg0[1:0] <= 0; + reg1[1:0] <= 0; + end else if(WRITE) begin + case(ADDR) + 1:{reg1[1:0], reg0[1:0]} <= WRITE_DATA[3:0]; + endcase + end + end + +endmodule + diff --git a/pyverilog_toolbox/testcode/test_ra.py b/pyverilog_toolbox/testcode/test_ra.py index 5e47a4b..f3c1f82 100644 --- a/pyverilog_toolbox/testcode/test_ra.py +++ b/pyverilog_toolbox/testcode/test_ra.py @@ -22,11 +22,13 @@ def setUp(self): pass def test_normal(self): - write_map, read_map = analize_regmap('regmap.v', 'setup.txt') + ranalyzer = RegMapAnalyzer("regmap.v", "setup.txt") + write_map, read_map = ranalyzer.getRegMaps() self.assertEqual(str(write_map.map), "{0: {0: ('TOP.reg0', 0), 1: ('TOP.reg0', 1)}, 1: {0: ('TOP.reg1', 0)}}") self.assertEqual(str(read_map.map), "{0: {0: ('TOP.reg0', 0), 1: ('TOP.reg0', 1)}, 1: {0: ('TOP.reg1', 0)}}") def test_split(self): - write_map, read_map = analize_regmap('regmap_split.v', 'setup.txt') + ranalyzer = RegMapAnalyzer("regmap_split.v", "setup.txt") + write_map, read_map = ranalyzer.getRegMaps() self.assertEqual(str(write_map.map), "{1: {0: ('TOP.reg0', 0), 1: ('TOP.reg0', 1), 2: ('TOP.reg1', 2), 3: ('TOP.reg1', 3)}}") self.assertEqual(str(read_map.map), diff --git a/pyverilog_toolbox/verify_tool/bindlibrary.py b/pyverilog_toolbox/verify_tool/bindlibrary.py index 696bf39..b4e0672 100644 --- a/pyverilog_toolbox/verify_tool/bindlibrary.py +++ b/pyverilog_toolbox/verify_tool/bindlibrary.py @@ -46,7 +46,7 @@ def helper(self, target_tree, tree_list, term_lsb, bit, dftype): #@dfx_memoize def extract_all_dfxxx(self, target_tree, tree_list, term_lsb, bit, dftype): """[FUNCTIONS] - type + return set of DFXXX target_tree:DF*** tree_list:{(type, DF***, bit),(type, DF***, bit),...} term_lsb:integar @@ -56,14 +56,14 @@ def extract_all_dfxxx(self, target_tree, tree_list, term_lsb, bit, dftype): if dftype == pyverilog.dataflow.dataflow.DFTerminal and isinstance(target_tree, pyverilog.dataflow.dataflow.DFTerminal): target_scope = self.get_scope(target_tree) if target_scope in self._binddict.keys(): - target_bind, target_term_lsb = self.get_next_bind(target_scope, bit) + target_bind, target_term_lsb = self.get_next_bind(target_scope, bit - term_lsb) if not target_bind.isCombination(): - tree_list.add((target_tree, bit)) - else: - tree_list.add((target_tree, bit)) + tree_list.add((target_tree, bit - term_lsb)) + else:#TOP Input port + tree_list.add((target_tree, bit - term_lsb)) else: if isinstance(target_tree, dftype): - tree_list.add((target_tree, bit)) + tree_list.add((target_tree, bit - term_lsb)) if hasattr(target_tree, "nextnodes"): if isinstance(target_tree, pyverilog.dataflow.dataflow.DFConcat): @@ -79,8 +79,6 @@ def extract_all_dfxxx(self, target_tree, tree_list, term_lsb, bit, dftype): for nextnode in target_tree.nextnodes: if isinstance(target_tree, pyverilog.dataflow.dataflow.DFBranch) and nextnode == target_tree.condnode: tree_list = self.extract_all_dfxxx(nextnode,tree_list, term_lsb, 0, dftype) - #elif isinstance(target_tree, pyverilog.dataflow.dataflow.DFOperator) and target_tree.is_alith: - # raise verror.ImplementationError('not supported in regmap analyzer.') else: tree_list = self.extract_all_dfxxx(nextnode,tree_list, term_lsb, bit, dftype) elif isinstance(target_tree, pyverilog.dataflow.dataflow.DFBranch): @@ -90,20 +88,13 @@ def extract_all_dfxxx(self, target_tree, tree_list, term_lsb, bit, dftype): elif isinstance(target_tree, pyverilog.dataflow.dataflow.DFTerminal): target_scope = self.get_scope(target_tree) if target_scope in self._binddict.keys(): - target_bind, target_term_lsb = self.get_next_bind(target_scope, bit) + target_bind, target_term_lsb = self.get_next_bind(target_scope, bit - term_lsb) if target_bind.isCombination(): tree_list = self.extract_all_dfxxx(target_bind.tree, tree_list, target_term_lsb, bit, dftype) elif isinstance(target_tree, pyverilog.dataflow.dataflow.DFPartselect): var_node = target_tree.var ref_bit = self.eval_value(target_tree.lsb) + bit - term_lsb - if isinstance(var_node, pyverilog.dataflow.dataflow.DFConcat) or isinstance(var_node, pyverilog.dataflow.dataflow.DFPartselect): - ref_term_lsb = 0 - elif isinstance(var_node, pyverilog.dataflow.dataflow.DFIntConst): - return tree_list - else: - var_scope = self.get_scope(var_node) - ref_term_lsb = self.get_next_bind(var_scope, ref_bit)[1] - tree_list = self.extract_all_dfxxx(var_node,tree_list, ref_term_lsb, ref_bit, dftype) + tree_list = self.extract_all_dfxxx(var_node,tree_list, term_lsb, ref_bit, dftype) return tree_list def delete_cache(self): @@ -117,12 +108,13 @@ def helper(x,y,z): return cache[(x,y,z)] return helper - @gnb_memoize + #@gnb_memoize def get_next_bind(self, scope, bit): """[FUNCTIONS] get root bind.(mainly use at 'Rename' terminal.) """ if scope in self._binddict.keys(): target_binds = self._binddict[scope] + #target_bind_index = self.get_bind_index(target_binds, bit + self.eval_value(self._terms[scope].lsb), self._terms[scope]) target_bind_index = self.get_bind_index(target_binds, bit, self._terms[scope]) target_bind = target_binds[target_bind_index] return target_bind, self.get_bind_lsb(target_bind) @@ -139,7 +131,7 @@ def get_bind_index(self, binds=None, bit=None, term=None, scope=None): binds = self._binddict[scope] term = self._terms[scope] for index,bind in enumerate(binds): - if bind.lsb is None:#need for assign sentente ex. assign LED[7:0] = enable ? 'hff : 0; + if bind.lsb is None: return 0 if self.get_bind_lsb(bind) <= bit <= self.get_bind_msb(bind): return index @@ -218,4 +210,5 @@ def get_scope(self, tree): if name in self.scope_dict.keys(): return self.scope_dict[name] else: - return None \ No newline at end of file + return None + diff --git a/pyverilog_toolbox/verify_tool/dataflow_facade.py b/pyverilog_toolbox/verify_tool/dataflow_facade.py new file mode 100644 index 0000000..6fce1f2 --- /dev/null +++ b/pyverilog_toolbox/verify_tool/dataflow_facade.py @@ -0,0 +1,84 @@ +#------------------------------------------------------------------------------- +# get_dataflow_facade.py +# +# interface of register map analyzer +# +# +# Copyright (C) 2015, Ryosuke Fukatani +# License: Apache 2.0 +#------------------------------------------------------------------------------- + + +import sys +import os +import pyverilog + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) ) + +import pyverilog.controlflow.controlflow_analyzer as controlflow_analyzer +from optparse import OptionParser +import pyverilog.utils.util as util +from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer +from pyverilog.dataflow.optimizer import VerilogDataflowOptimizer +from bindlibrary import BindLibrary +from pyverilog.controlflow.controlflow_analyzer import VerilogControlflowAnalyzer + +class dataflow_facade(VerilogControlflowAnalyzer): + def __init__(self, code_file_name,setup_file): + topmodule, terms, binddict, resolved_terms, resolved_binddict, constlist = self.get_dataflow(code_file_name,setup_file) + VerilogControlflowAnalyzer.__init__(self, topmodule, terms, binddict, + resolved_terms, resolved_binddict,constlist) + self.binds = BindLibrary(binddict, terms) + + def get_dataflow(self, code_file_name,setup_file): + optparser = OptionParser() + optparser.add_option("-t","--top",dest="topmodule", + default="TOP",help="Top module, Default=TOP") + + 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("-S",dest="regmap_config", + default=[],help="regmap config") + + (options, args) = optparser.parse_args() + + if args: + filelist = args + else: + filelist = {code_file_name} + + if options.regmap_config: + self.setup_file = options.regmap_config + + for f in filelist: + if not os.path.exists(f): raise IOError("file not found: " + f) + + analyzer = VerilogDataflowAnalyzer(filelist, options.topmodule, + 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() + return options.topmodule, terms, binddict, resolved_terms, resolved_binddict, constlist + + def print_bind_info(self): + binds = BindLibrary(self.resolved_binddict, self.resolved_terms) + for tv,tk,bvi,bit,term_lsb in binds.walk_reg_each_bit(): + tree = self.makeTree(tk) + trees = binds.extract_all_dfxxx(tree, set([]), term_lsb, bit, pyverilog.dataflow.dataflow.DFTerminal) + print str(tk) + '[' + str(bit) + ']' + str(trees) + +if __name__ == '__main__': + df = dataflow_facade("../testcode/regmap2.v", "../testcode/setup.txt") + df.print_bind_info() diff --git a/pyverilog_toolbox/verify_tool/out.csv b/pyverilog_toolbox/verify_tool/out.csv deleted file mode 100644 index 8580d6e..0000000 --- a/pyverilog_toolbox/verify_tool/out.csv +++ /dev/null @@ -1,9 +0,0 @@ - -Write Map -ADD,1,0, -0,TOP.reg0[1],TOP.reg0[0], -1,,TOP.reg1[0], -Read Map -ADD,1,0, -0,TOP.reg0[1],TOP.reg0[0], -1,,TOP.reg1[0], \ No newline at end of file diff --git a/pyverilog_toolbox/verify_tool/ra_interface.py b/pyverilog_toolbox/verify_tool/ra_interface.py deleted file mode 100644 index 3eb8024..0000000 --- a/pyverilog_toolbox/verify_tool/ra_interface.py +++ /dev/null @@ -1,78 +0,0 @@ -#------------------------------------------------------------------------------- -# ra_interface.py -# -# interface of register map analyzer -# -# -# Copyright (C) 2015, Ryosuke Fukatani -# License: Apache 2.0 -#------------------------------------------------------------------------------- - - -import sys -import os -import pyverilog - -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) ) - -from regmap_analyzer import * -import pyverilog.controlflow.controlflow_analyzer as controlflow_analyzer - - -def analize_regmap(code_file_name="",setup_file=""): - from optparse import OptionParser - import pyverilog.utils.util as util - from pyverilog.dataflow.dataflow_analyzer import VerilogDataflowAnalyzer - from pyverilog.dataflow.optimizer import VerilogDataflowOptimizer - - optparser = OptionParser() - optparser.add_option("-t","--top",dest="topmodule", - default="TOP",help="Top module, Default=TOP") - 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("-S",dest="regmap_config", - default=[],help="regmap config") - - (options, args) = optparser.parse_args() - if args: - filelist = args - else: - filelist = {code_file_name} - - if options.regmap_config: - setup_file = options.regmap_config - - for f in filelist: - if not os.path.exists(f): raise IOError("file not found: " + f) - - analyzer = VerilogDataflowAnalyzer(filelist, options.topmodule, - 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() - - - canalyzer = RegMapAnalyzer(options.topmodule, terms, binddict, - resolved_terms, resolved_binddict, constlist, fsm_vars={'reg','r_'}) - map_factory = MapFactory(setup_file) - write_map, read_map = canalyzer.getRegMaps(map_factory) - - print 'Write_map:\n' + str(write_map.map) - print 'Read_map:\n' + str(read_map.map) - return write_map, read_map - -if __name__ == '__main__': - #analize_regmap("../testcode/regmap.v", "../testcode/setup.txt") - analize_regmap("../testcode/regmap_split.v", "../testcode/setup.txt") \ No newline at end of file diff --git a/pyverilog_toolbox/verify_tool/regmap_analyzer.py b/pyverilog_toolbox/verify_tool/regmap_analyzer.py index bcad31c..ce19239 100644 --- a/pyverilog_toolbox/verify_tool/regmap_analyzer.py +++ b/pyverilog_toolbox/verify_tool/regmap_analyzer.py @@ -22,43 +22,39 @@ from pyverilog.dataflow.subset import VerilogSubset from pyverilog.dataflow.walker import VerilogDataflowWalker from pyverilog.dataflow.dataflow import * -from pyverilog.controlflow.controlflow_analyzer import VerilogControlflowAnalyzer -from bindlibrary import BindLibrary +from pyverilog_toolbox.verify_tool.dataflow_facade import * import pyverilog.controlflow.splitter as splitter import pyverilog.controlflow.transition as transition -class RegMapAnalyzer(VerilogControlflowAnalyzer): +class RegMapAnalyzer(dataflow_facade): - def __init__(self, topmodule, terms, binddict, - resolved_terms, resolved_binddict, - constlist, fsm_vars=('fsm', 'state', 'count', 'cnt', 'step', 'mode'), - out_file = 'out.csv' ): - - VerilogControlflowAnalyzer.__init__(self, topmodule, terms, binddict, - resolved_terms, resolved_binddict, - constlist, fsm_vars=('fsm', 'state', 'count', 'cnt', 'step', 'mode')) - - self.binds = BindLibrary(binddict, terms) + def __init__(self, code_file_name,setup_file,out_file = 'out.csv'): + dataflow_facade.__init__(self, code_file_name,setup_file) self.out_file_name = out_file + self.reg_control = MapFactory(setup_file) + + def getRegMaps(self): - def getRegMaps(self, reg_control): - write_map = reg_control.create_map('write') - read_map = reg_control.create_map('read') + write_map = self.reg_control.create_map('write') + read_map = self.reg_control.create_map('read') binds = self.binds for tv,tk,bvi,bit,term_lsb in binds.walk_reg_each_bit(): tree = self.makeTree(tk) funcdict = splitter.split(tree) funcdict = splitter.remove_reset_condition(funcdict) - trees = binds.extract_all_dfxxx(tree, set([]), 0, bit-term_lsb, pyverilog.dataflow.dataflow.DFTerminal) + trees = binds.extract_all_dfxxx(tree, set([]), term_lsb, bit, pyverilog.dataflow.dataflow.DFTerminal) write_map.check_new_reg(str(tv), term_lsb, trees, funcdict) read_map.check_new_reg(str(tv), term_lsb, trees, funcdict, bit) self.out_file = open(self.out_file_name, "w") write_map.output_csv(self.out_file) read_map.output_csv(self.out_file) self.out_file.close() + + print 'Write_map:\n' + str(write_map.map) + print 'Read_map:\n' + str(read_map.map) return write_map, read_map class MapFactory(object): @@ -134,7 +130,8 @@ def calc_map_spec(self): if max(reg.keys()) > max_bit: max_bit = max(reg.keys()) self.max_bit = max_bit + 1 - self.max_address = max(self.map.keys()) + if self.map: + self.max_address = max(self.map.keys()) def _add_new_reg(self, reg_name, term_lsb, address, bit): if address not in self.map.keys(): self.map[address] = {} @@ -194,3 +191,7 @@ def get_map_info(self, trees, funcdict, bit): sig_name = str(tree[0]) if sig_name == str(verb) or (hasattr(verb, 'nextnodes') and sig_name in str(verb.nextnodes)): self._add_new_reg(sig_name, 0, address, bit) + +if __name__ == '__main__': + ranalyzer = RegMapAnalyzer("../testcode/regmap2.v", "../testcode/setup.txt") + ranalyzer.getRegMaps()