Example #1
0
void read_net (char *net_file, t_subblock_data *subblock_data_ptr) {

/* Main routine that parses a netlist file in my (.net) format. */

 char buf[BUFSIZE], *ptr;
 int doall;
 FILE *fp_net;

/* Make two variables below accessible anywhere in the module because I'm *
 * too lazy to pass them all over the place.                              */

 max_subblocks_per_block = subblock_data_ptr->max_subblocks_per_block;
 subblock_lut_size = subblock_data_ptr->subblock_lut_size;

 fp_net = my_fopen (net_file, "r", 0);

/* First pass builds the symbol table and counts the number of pins  *
 * on each net.  Then I allocate exactly the right amount of storage *
 * for each net.  Finally, the second pass loads the block and net   *
 * arrays.                                                           */

 for (doall=0;doall<=1;doall++) {  /* Pass number. */
    init_parse(doall);

    linenum = 0;   /* Reset line number. */
    ptr = my_fgets (buf, BUFSIZE, fp_net);

    while (ptr != NULL) {
       ptr = get_tok (buf, doall, fp_net);
    }
    rewind (fp_net);  /* Start at beginning of file again */
 } 

 fclose(fp_net);

/* Return the three data structures below through subblock_data_ptr.        */

 subblock_data_ptr->subblock_inf = subblock_inf;
 subblock_data_ptr->num_subblocks_per_block = num_subblocks_per_block;
 subblock_data_ptr->chunk_head_ptr = ch_subblock_head_ptr;

 check_netlist (subblock_data_ptr, num_driver);
 free_parse();
}
Example #2
0
/*---------------------------------------------------------------------------
 * (function: do_high_level_synthesis)
 *-------------------------------------------------------------------------*/
void do_high_level_synthesis()
{
	double elaboration_time = wall_time();

	printf("--------------------------------------------------------------------\n");
	printf("High-level synthesis Begin\n");
	/* Perform any initialization routines here */
	#ifdef VPR6
	find_hard_multipliers();
	find_hard_adders();
	//find_hard_adders_for_sub();
	register_hard_blocks();
	#endif
	global_param_table_sc = sc_new_string_cache();

	/* parse to abstract syntax tree */
	printf("Parser starting - we'll create an abstract syntax tree.  "
			"Note this tree can be viewed using GraphViz (see documentation)\n");
	parse_to_ast();
	/* Note that the entry point for ast optimzations is done per module with the
	 * function void next_parsed_verilog_file(ast_node_t *file_items_list) */

	/* after the ast is made potentiatlly do tagging for downstream links to verilog */
	if (global_args.high_level_block != NULL)
	{
		add_tag_data();
	}

	/* Now that we have a parse tree (abstract syntax tree [ast]) of
	 * the Verilog we want to make into a netlist. */
	printf("Converting AST into a Netlist. "
			"Note this netlist can be viewed using GraphViz (see documentation)\n");
	create_netlist();

	// Can't levelize yet since the large muxes can look like combinational loops when they're not
	check_netlist(verilog_netlist);

	/* point for all netlist optimizations. */
	printf("Performing Optimizations of the Netlist\n");
	netlist_optimizations_top(verilog_netlist);

	if (configuration.output_netlist_graphs )
	{
		/* Path is where we are */
		graphVizOutputNetlist(configuration.debug_output_path, "optimized", 1, verilog_netlist);
	}

	/* point where we convert netlist to FPGA or other hardware target compatible format */
	printf("Performing Partial Map to target device\n");
	partial_map_top(verilog_netlist);

	#ifdef VPR5
	/* check for problems in the partial mapped netlist */
	printf("Check for liveness and combinational loops\n");
	levelize_and_check_for_combinational_loop_and_liveness(TRUE, verilog_netlist);
	#endif

	/* point for outputs.  This includes soft and hard mapping all structures to the
	 * target format.  Some of these could be considred optimizations */
	printf("Outputting the netlist to the specified output format\n");
	output_top(verilog_netlist);

	elaboration_time = wall_time() - elaboration_time;

	printf("Successful High-level synthesis by Odin in ");
	print_time(elaboration_time);
	printf("\n");
	printf("--------------------------------------------------------------------\n");

	// FIXME: free contents?
	sc_free_string_cache(global_param_table_sc);
}
Example #3
0
/* 
 * Sets globals: nx, ny
 * Allocs globals: chan_width_x, chan_width_y, grid
 * Depends on num_clbs, pins_per_clb */
void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch) {
	int *num_instances_type, *num_blocks_type;
	int i;
	int current, high, low;
	boolean fit;

	/* Read in netlist file for placement and routing */
	if (vpr_setup.FileNameOpts.NetFile) {
		read_netlist(vpr_setup.FileNameOpts.NetFile, &Arch, &num_blocks, &block,
				&num_nets, &clb_net);
		/* This is done so that all blocks have subblocks and can be treated the same */
		check_netlist();
	}

	/* Output the current settings to console. */
	printClusteredNetlistStats();

	if (vpr_setup.Operation == TIMING_ANALYSIS_ONLY) {
		do_constant_net_delay_timing_analysis(vpr_setup.Timing,
				vpr_setup.constant_net_delay);
	} else {
		current = nint((float)sqrt((float)num_blocks)); /* current is the value of the smaller side of the FPGA */
		low = 1;
		high = -1;

		num_instances_type = (int*) my_calloc(num_types, sizeof(int));
		num_blocks_type = (int*) my_calloc(num_types, sizeof(int));

		for (i = 0; i < num_blocks; i++) {
			num_blocks_type[block[i].type->index]++;
		}

		if (Arch.clb_grid.IsAuto) {
			/* Auto-size FPGA, perform a binary search */
			while (high == -1 || low < high) {
				/* Generate grid */
				if (Arch.clb_grid.Aspect >= 1.0) {
					ny = current;
					nx = nint(current * Arch.clb_grid.Aspect);
				} else {
					nx = current;
					ny = nint(current / Arch.clb_grid.Aspect);
				}
#if DEBUG
				vpr_printf(TIO_MESSAGE_INFO,
						"Auto-sizing FPGA at x = %d y = %d\n", nx, ny);
#endif
				alloc_and_load_grid(num_instances_type, &Arch);
				freeGrid();

				/* Test if netlist fits in grid */
				fit = TRUE;
				for (i = 0; i < num_types; i++) {
					if (num_blocks_type[i] > num_instances_type[i]) {
						fit = FALSE;
						break;
					}
				}

				/* get next value */
				if (!fit) {
					/* increase size of max */
					if (high == -1) {
						current = current * 2;
						if (current > MAX_SHORT) {
							vpr_printf(TIO_MESSAGE_ERROR,
									"FPGA required is too large for current architecture settings.\n");
							exit(1);
						}
					} else {
						if (low == current)
							current++;
						low = current;
						current = low + ((high - low) / 2);
					}
				} else {
					high = current;
					current = low + ((high - low) / 2);
				}
			}
			/* Generate grid */
			if (Arch.clb_grid.Aspect >= 1.0) {
				ny = current;
				nx = nint(current * Arch.clb_grid.Aspect);
			} else {
				nx = current;
				ny = nint(current / Arch.clb_grid.Aspect);
			}
			alloc_and_load_grid(num_instances_type, &Arch);
			vpr_printf(TIO_MESSAGE_INFO, "FPGA auto-sized to x = %d y = %d\n",
					nx, ny);
		} else {
			nx = Arch.clb_grid.W;
			ny = Arch.clb_grid.H;
			alloc_and_load_grid(num_instances_type, &Arch);
		}

		vpr_printf(TIO_MESSAGE_INFO,
				"The circuit will be mapped into a %d x %d array of clbs.\n",
				nx, ny);

		/* Test if netlist fits in grid */
		fit = TRUE;
		for (i = 0; i < num_types; i++) {
			if (num_blocks_type[i] > num_instances_type[i]) {
				fit = FALSE;
				break;
			}
		}
		if (!fit) {
			vpr_printf(TIO_MESSAGE_ERROR,
					"Not enough physical locations for type %s, number of blocks is %d but number of locations is %d.\n",
					type_descriptors[i].name, num_blocks_type[i],
					num_instances_type[i]);
			exit(1);
		}

		vpr_printf(TIO_MESSAGE_INFO, "\n");
		vpr_printf(TIO_MESSAGE_INFO, "Resource usage...\n");
		for (i = 0; i < num_types; i++) {
			vpr_printf(TIO_MESSAGE_INFO,
					"\tNetlist      %d\tblocks of type: %s\n",
					num_blocks_type[i], type_descriptors[i].name);
			vpr_printf(TIO_MESSAGE_INFO,
					"\tArchitecture %d\tblocks of type: %s\n",
					num_instances_type[i], type_descriptors[i].name);
		}
		vpr_printf(TIO_MESSAGE_INFO, "\n");
		chan_width_x = (int *) my_malloc((ny + 1) * sizeof(int));
		chan_width_y = (int *) my_malloc((nx + 1) * sizeof(int));

		free(num_blocks_type);
		free(num_instances_type);
	}
}