def test_path_any_to_any(self): # Pipeline np = self.compile_test('pipeline_loops.sv') path = np.get_any_path(Waypoints('i_data', 'data_q')) self.assertTrue(len(path) == 3) # TODO: check the paths # Pipeline module np = self.compile_test('pipeline_module.sv') path = np.get_any_path(Waypoints('i_data', 'data_q')) self.assertTrue(len(path) == 7)
def test_pipeline_paths(self): # A pipeline implementation that uses loops and a register array. # Registers within the array cannot be distinguished. np = self.compile_test('pipeline_loops.sv') self.assertTrue(np.reg_exists('pipeline_loops.data_q')) self.assertTrue( np.path_exists( Waypoints('pipeline_loops.i_data', 'pipeline_loops.data_q'))) self.assertTrue( np.path_exists( Waypoints('pipeline_loops.data_q', 'pipeline_loops.o_data')))
def test_vlvbound(self): np = self.compile_test('vlvbound.sv') # Test that the inlined tasks do not share a merged VlVbound node. # See https://www.veripool.org/boards/3/topics/2619 self.assertTrue( np.path_exists(Waypoints("i_foo_current", "o_foo_inactive"))) self.assertTrue( np.path_exists(Waypoints("i_foo_next", "o_next_foo_inactive"))) self.assertFalse( np.path_exists(Waypoints("i_foo_current", "o_next_foo_inactive"))) self.assertFalse( np.path_exists(Waypoints("i_foo_next", "o_foo_inactive")))
def test_adder_path_exists(self): """ Test basic querying of path existence. """ np = self.compile_test('adder.sv') Options.get_instance().set_match_exact() for prefix in ['', 'adder.']: # Check all valid paths are reported. self.assertTrue( np.path_exists(Waypoints(prefix + 'i_a', prefix + 'o_sum'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_a', prefix + 'o_co'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_b', prefix + 'o_sum'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_b', prefix + 'o_co'))) # Check for invalid paths. self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_sum', prefix + 'i_a')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_co', prefix + 'i_a')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_sum', prefix + 'i_b')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_co', prefix + 'i_b'))
def test_any_start_finish_points(self): """ Test matching of distinct paths through common mid points. """ np = self.compile_test('multiple_separate_paths.sv') Options.get_instance().set_match_wildcard() Options.get_instance().set_match_any_vertex() path = np.get_any_path(Waypoints('i_*', 'o_*')) self.assertTrue(len(path)) path = np.get_any_path(Waypoints('i_b', 'o_b')) self.assertTrue(len(path)) Options.get_instance().set_match_one_vertex() path = np.get_any_path(Waypoints('i_c', 'o_c')) self.assertTrue(len(path))
def test_path_any_to_any(self): """ Test querying of any paths. """ # Pipeline np = self.compile_test('pipeline_loops.sv') path = np.get_any_path(Waypoints('i_data', 'pipeline_loops.data_q')) self.assertTrue(len(path) == 3) # Pipeline module np = self.compile_test('pipeline_module.sv') path = np.get_any_path( Waypoints('i_data', 'pipeline_module.g_pipestage[0].u_pipestage.data_q')) self.assertTrue(len(path) == 7)
def test_path_all_any_to_any(self): """ Test querying of all paths. """ np = self.compile_test('multiple_paths.sv') paths = np.get_all_paths(Waypoints('in', 'out')) self.assertTrue(len(paths) == 3)
def test_adder_paths(self): np = self.compile_test('adder.sv') for prefix in ['', 'adder.']: # Check all valid paths are reported. self.assertTrue( np.path_exists(Waypoints(prefix + 'i_a', prefix + 'o_sum'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_a', prefix + 'o_co'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_b', prefix + 'o_sum'))) self.assertTrue( np.path_exists(Waypoints(prefix + 'i_b', prefix + 'o_co'))) # Check for invalid paths. self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_sum', prefix + 'i_a')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_co', prefix + 'i_a')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_sum', prefix + 'i_b')) self.assertRaises(RuntimeError, np.path_exists, Waypoints(prefix + 'o_co', prefix + 'i_b'))
def test_pipeline_module_paths(self): np = self.compile_test('pipeline_module.sv') self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[0\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[1\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[1\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[2\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[2\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[3\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[3\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[4\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[4\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[5\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[5\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[6\\].u_pipestage.data_q"))) self.assertTrue( np.path_exists( Waypoints( "pipeline_module.g_pipestage\\[6\\].u_pipestage.data_q", "pipeline_module.g_pipestage\\[7\\].u_pipestage.data_q")))
def test_counter_paths(self): np = self.compile_test('counter.sv') # Check all valid paths are reported. self.assertTrue( np.path_exists(Waypoints('counter.i_clk', 'counter.counter_q'))) self.assertTrue( np.path_exists(Waypoints('counter.i_rst', 'counter.counter_q'))) self.assertTrue( np.path_exists(Waypoints('counter.counter_q', 'counter.o_count'))) self.assertTrue( np.path_exists(Waypoints('counter.counter_q', 'counter.o_wrap'))) # Check invalid paths. self.assertRaises(RuntimeError, np.path_exists, Waypoints('counter.o_count', 'counter.counter_q')) self.assertRaises(RuntimeError, np.path_exists, Waypoints('counter.count_q', 'counter.i_clk')) self.assertRaises(RuntimeError, np.path_exists, Waypoints('counter.count_q', 'counter.i_rst')) self.assertFalse( np.path_exists(Waypoints('counter.i_clk', 'counter.o_count'))) self.assertFalse( np.path_exists(Waypoints('counter.i_clk', 'counter.o_wrap'))) self.assertFalse( np.path_exists(Waypoints('counter.i_rst', 'counter.o_count'))) self.assertFalse( np.path_exists(Waypoints('counter.i_rst', 'counter.o_wrap')))
def main(): parser = argparse.ArgumentParser(description="Query a Verilog netlist") parser.add_argument('files', nargs='+', help='Input files') parser.add_argument('-c', '--compile', action='store_true', help='Run Verilator to compile a netlist') parser.add_argument( '-I', metavar='include_path', help='Add an source include path (only with --compile)') parser.add_argument( '-D', metavar='definition', help='Define a preprocessor macro (only with --compile)') parser.add_argument('-o,--output', default=None, dest='output_file', metavar='output file', help='Specify an output file') parser.add_argument('--dump-names', nargs='?', default=None, const='.*', metavar='regex', help='Dump all names, filter by regex') parser.add_argument('--dump-dot', action='store_true', help='Dump a dotfile of the netlist\'s graph') parser.add_argument('--from', dest='start_point', metavar='point', help='Start point') parser.add_argument('--to', dest='finish_point', metavar='point', help='Finish point') parser.add_argument('--though', nargs=1, action='append', dest='through_points', default=[], metavar='point', help='Though point') parser.add_argument( '--all-paths', action='store_true', help='Find all paths between two points (exponential time)') parser.add_argument('--regex', action='store_true', help='Enable regular expression matching of names') parser.add_argument('-v', '--verbose', action='store_true', help='Print execution information') parser.add_argument('-d', '--debug', action='store_true', help='Print debugging information') args = parser.parse_args() # Setup options if args.regex: Options.get_instance().set_match_regex() if args.verbose: Options.get_instance().set_verbose() if args.debug: Options.get_instance().set_debug() try: # Verilator compilation # (Only support one source file.) if (args.compile): comp = RunVerilator(defs.INSTALL_PREFIX) temp_name = next(tempfile._get_candidate_names()) if comp.run(args.files[0], temp_name) > 0: raise RuntimeError('error compiling design') # Create the netlist netlist = Netlist(temp_name) # If compiling and no no further steps performed and an output file is # specified, rename XML to the output, otherwise delete it. if args.compile: if args.output_file and \ not args.dump_names and \ not args.dump_dot and \ not (args.start_point or args.finish_point): os.rename(temp_name, args.output_file) else: os.remove(temp_name) # Dump names if args.dump_names: dump_names(netlist, args.dump_names, sys.stdout) return 0 if args.dump_dot: netlist.dump_dot_file( args.output_file if args.output_file else DEFAULT_DOT_FILE) return 0 # Point-to-point path if args.start_point and args.finish_point: waypoints = Waypoints() waypoints.add_start_point(args.start_point) waypoints.add_finish_point(args.finish_point) [ waypoints.add_through_point(point) for point in args.through_points ] if args.all_paths: path = netlist.get_all_paths(waypoints) dump_path_list_report(netlist, path, sys.stdout) else: path = netlist.get_any_path(waypoints) dump_path_report(netlist, path, sys.stdout) return 0 # Fan out paths if args.start_point and not args.finish_point: if len(args.through_points) > 0: raise RuntimeError( 'cannot specify through points with fanout paths') paths = netlist.get_all_fanout_paths(args.start_point) dump_path_list_report(netlist, paths, sys.stdout) return 0 # Fan in paths if args.finish_point and not args.start_point: if len(args.through_points) > 0: raise RuntimeError( 'cannot specify through points with fanin paths') paths = netlist.get_all_fanin_paths(args.finish_point) dump_path_list_report(netlist, paths, sys.stdout) return 0 except RuntimeError as e: print('Error: ' + str(e)) return 1
def main(): parser = argparse.ArgumentParser(description="Query a Verilog netlist") parser.add_argument('files', nargs='+', help='Input files') parser.add_argument('-c', '--compile', action='store_true', help='Run Verilator to compile a netlist') parser.add_argument( '-I', metavar='include_path', help='Add an source include path (only with --compile)') parser.add_argument( '-D', metavar='definition', help='Define a preprocessor macro (only with --compile)') parser.add_argument('-o', '--output', default=None, dest='output_file', metavar='output file', help='Specify an output file') parser.add_argument('--dump-names', nargs='?', default=None, const='', metavar='pattern', help='Dump all named entities, filter by regex') parser.add_argument('--dump-nets', nargs='?', default=None, const='', metavar='pattern', help='Dump all nets, filter by regex') parser.add_argument('--dump-ports', nargs='?', default=None, const='', metavar='pattern', help='Dump all ports, filter by regex') parser.add_argument('--dump-regs', nargs='?', default=None, const='', metavar='pattern', help='Dump all registers, filter by regex') parser.add_argument('--dump-dot', action='store_true', help='Dump a dotfile of the netlist\'s graph') parser.add_argument('--from', dest='start_point', metavar='point', help='Specify a path start point') parser.add_argument('--to', dest='finish_point', metavar='point', help='Specify a path finish point') parser.add_argument('--through', action='append', default=[], dest='through_points', metavar='point', help='Specify a path though point') parser.add_argument('--avoid', action='append', default=[], dest='avoid_points', metavar='point', help='Specify a point for a path to avoid') parser.add_argument( '--traverse-registers', action='store_const', const=lambda: Options.get_instance().enable_traverse_registers(), default=lambda *args: None, help='Allow paths to traverse registers') parser.add_argument( '--all-paths', action='store_true', help='Find all paths between two points (exponential time)') parser.add_argument('--regex', action='store_const', const=lambda: Options.get_instance().set_match_regex(), default=lambda *args: None, help='Enable regular expression matching of names') parser.add_argument( '--wildcard', action='store_const', const=lambda: Options.get_instance().set_match_wildcard(), default=lambda *args: None, help='Enable wildcard matching of names') parser.add_argument('--ignore-hierarchy-markers', action='store_const', const=lambda: Options.ignore_hierarchy_markers(), default=lambda *args: None, help='Ignore hierarchy markers: _ . /') parser.add_argument('-v', '--verbose', action='store_const', const=lambda: Options.get_instance().set_verbose(), default=lambda *args: None, help='Print execution information') parser.add_argument('-d', '--debug', action='store_const', const=lambda: Options.get_instance().set_debug(), default=lambda *args: None, help='Print debugging information') args = parser.parse_args() # Setup options. args.traverse_registers() args.regex() args.wildcard() args.ignore_hierarchy_markers() args.verbose() args.debug() try: # Verilator compilation # (Only supports one source file currently, useful for testing.) if args.compile: if args.output_file == None: output_filename = next(tempfile._get_candidate_names()) else: output_filename = args.output_file comp = RunVerilator(defs.INSTALL_PREFIX) if comp.run(args.files[0], output_filename) > 0: raise RuntimeError('error compiling design') else: if len(args.files) != 1: raise RuntimeError('cannot specify multiple netlist XML files') output_filename = args.files[0] # Create the netlist netlist = Netlist(output_filename) # Delete the temporary XML output file. if args.compile and args.output_file == None: os.remove(output_filename) # Dump all names if args.dump_names != None: dump_names(netlist.get_named_vertices(args.dump_names), sys.stdout) return 0 # Dump nets if args.dump_nets != None: dump_names(netlist.get_net_vertices(args.dump_nets), sys.stdout) return 0 # Dump ports if args.dump_ports != None: dump_names(netlist.get_port_vertices(args.dump_ports), sys.stdout) return 0 # Dump regs if args.dump_regs != None: dump_names(netlist.get_reg_vertices(args.dump_regs), sys.stdout) return 0 # Dump graph dotfile if args.dump_dot: netlist.dump_dot_file( args.output_file if args.output_file else DEFAULT_DOT_FILE) return 0 # Point-to-point path if args.start_point and args.finish_point: waypoints = Waypoints() waypoints.add_start_point(args.start_point) waypoints.add_finish_point(args.finish_point) [ waypoints.add_through_point(point) for point in args.through_points ] [waypoints.add_avoid_point(point) for point in args.avoid_points] if args.all_paths: path = netlist.get_all_paths(waypoints) dump_path_list_report(netlist, path, sys.stdout) else: path = netlist.get_any_path(waypoints) dump_path_report(netlist, path, sys.stdout) return 0 # Fan out paths if args.start_point and not args.finish_point: if len(args.through_points) > 0: raise RuntimeError( 'cannot specify through points with fanout paths') if len(args.avoid_points) > 0: raise RuntimeError( 'cannot specify avoid points with fanout paths') paths = netlist.get_all_fanout_paths(args.start_point) dump_path_list_report(netlist, paths, sys.stdout) return 0 # Fan in paths if args.finish_point and not args.start_point: if len(args.through_points) > 0: raise RuntimeError( 'cannot specify through points with fanin paths') if len(args.avoid_points) > 0: raise RuntimeError( 'cannot specify avoid points with fanin paths') paths = netlist.get_all_fanin_paths(args.finish_point) dump_path_list_report(netlist, paths, sys.stdout) return 0 except RuntimeError as e: print('Error: ' + str(e)) return 1