blob: 4383496c7198c032b6548f2fc2ad7531ad260da2 [file] [log] [blame] [edit]
/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "globals.h"
#include "types.h"
#include "util.h"
#include "netlist_utils.h"
#include "arch_types.h"
#include "parse_making_ast.h"
#include "netlist_create_from_ast.h"
#include "outputs.h"
#include "netlist_optimizations.h"
#include "read_xml_config_file.h"
#include "read_xml_arch_file.h"
#include "partial_map.h"
#include "multipliers.h"
#include "netlist_check.h"
#include "read_blif.h"
#include "read_netlist.h"
#include "activity_estimation.h"
#include "high_level_data.h"
#include "hard_blocks.h"
#include "memories.h"
#include "simulate_blif.h"
#include "errors.h"
#include "netlist_visualizer.h"
#include "adders.h"
#include "subtractions.h"
#include "odin_ii_func.h"
#include "ast_elaborate.h"
#include "netlist_cleanup.h"
/*---------------------------------------------------------------------------
* (function: set_default_options)
*-------------------------------------------------------------------------*/
void set_default_options()
{
/* Set up the global arguments to their default. */
global_args.config_file = NULL;
global_args.verilog_file = NULL;
global_args.blif_file = NULL;
global_args.output_file = "./default_out.blif";
global_args.arch_file = NULL;
global_args.activation_blif_file = NULL;
global_args.activation_netlist_file = NULL;
global_args.high_level_block = NULL;
global_args.sim_vector_input_file = NULL;
global_args.sim_vector_output_file = NULL;
global_args.sim_additional_pins = NULL;
global_args.sim_num_test_vectors = 0;
global_args.sim_generate_three_valued_logic = 0;
global_args.sim_hold_low = NULL;
global_args.sim_hold_high = NULL;
global_args.sim_output_both_edges = 0;
global_args.sim_output_rising_edge = 0;
global_args.sim_initial_value = -1;
global_args.all_warnings = 0;
/* Set up the global configuration. */
configuration.list_of_file_names = NULL;
configuration.num_list_of_file_names = 0;
configuration.output_type = "blif";
configuration.output_ast_graphs = 0;
configuration.output_netlist_graphs = 0;
configuration.print_parse_tokens = 0;
configuration.output_preproc_source = 0;
configuration.debug_output_path = ".";
configuration.arch_file = NULL;
configuration.fixed_hard_multiplier = 0;
configuration.split_hard_multiplier = 0;
configuration.split_memory_width = 0;
configuration.split_memory_depth = 0;
/*
* Soft logic cutoffs. If a memory or a memory resulting from a split
* has a width AND depth below these, it will be converted to soft logic.
*/
configuration.soft_logic_memory_width_threshold = 0;
configuration.soft_logic_memory_depth_threshold = 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 potentially do tagging for downstream links to verilog */
if (global_args.high_level_block != NULL)
{
add_tag_data();
}
/* Simplify the AST by reducing complex statements - for loops */
simplify_ast();
/* 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);
/* Find any unused logic in the netlist and remove it */
remove_unused_logic(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);
}
/*---------------------------------------------------------------------------------------------
* (function: do_simulation_of_netlist)
*-------------------------------------------------------------------------------------------*/
void do_simulation_of_netlist()
{
if (!global_args.sim_num_test_vectors && !global_args.sim_vector_input_file)
return;
printf("Netlist Simulation Begin\n");
simulate_netlist(verilog_netlist);
printf("--------------------------------------------------------------------\n");
}
/*---------------------------------------------------------------------------------------------
* (function: do_activation_estimation)
*-------------------------------------------------------------------------------------------*/
#ifdef VPR5
void do_activation_estimation(
int num_types,
t_type_descriptor * type_descriptors)
{
netlist_t *blif_netlist;
netlist_t *net_netlist;
int lut_size;
if ((global_args.activation_blif_file == NULL) || (global_args.activation_netlist_file == NULL) || (global_args.arch_file == NULL))
{
return;
}
lut_size = type_descriptors[2].max_subblock_inputs;
printf("--------------------------------------------------------------------\n");
printf("Activation Estimation Begin\n");
/* read in the blif file */
printf("Reading blif format in for probability densitity estimation\n");
read_blif (global_args.activation_blif_file);
blif_netlist = verilog_netlist;
/* read in the blif file */
/* IO type is known from read_arch library #define EMPTY_TYPE_INDEX 0 #define IO_TYPE_INDEX 1 */
printf("Reading netlist format in for probability densitity estimation\n");
net_netlist = read_netlist (global_args.activation_netlist_file, num_types, type_descriptors, &type_descriptors[1]);
/* do activation estimation */
activity_estimation(NULL, global_args.output_file, lut_size, blif_netlist, net_netlist);
free_netlist(blif_netlist);
free_netlist(net_netlist);
printf("Successful Activation Estimation \n");
printf("--------------------------------------------------------------------\n");
}
#endif