bring autocheck top testbench back to simulation deck, start testing

This commit is contained in:
tangxifan 2019-11-04 15:35:04 -07:00
parent 3274a49779
commit 69bc858e62
7 changed files with 150 additions and 100 deletions

View File

@ -448,18 +448,19 @@ void vpr_fpga_verilog(ModuleManager& module_manager,
+ std::string(chomped_circuit_name) + std::string(chomped_circuit_name)
+ std::string(autocheck_top_testbench_verilog_file_postfix); + std::string(autocheck_top_testbench_verilog_file_postfix);
/* TODO: this is an old function, to be shadowed */ /* TODO: this is an old function, to be shadowed */
/*
dump_verilog_autocheck_top_testbench(sram_verilog_orgz_info, chomped_circuit_name, dump_verilog_autocheck_top_testbench(sram_verilog_orgz_info, chomped_circuit_name,
autocheck_top_testbench_file_path.c_str(), src_dir_path, autocheck_top_testbench_file_path.c_str(), src_dir_path,
vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice)); vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts, *(Arch.spice));
*/
/* TODO: new function: to be tested */ /* TODO: new function: to be tested */
print_verilog_top_testbench(module_manager, bitstream_manager, fabric_bitstream, print_verilog_top_testbench(module_manager, bitstream_manager, fabric_bitstream,
sram_verilog_orgz_info->type, sram_verilog_orgz_info->type,
Arch.spice->circuit_lib, global_ports, Arch.spice->circuit_lib, global_ports,
L_logical_blocks, device_size, L_grids, L_blocks, L_logical_blocks, device_size, L_grids, L_blocks,
std::string(chomped_circuit_name), std::string(chomped_circuit_name),
std::string(autocheck_top_testbench_file_path + std::string(".bak")), autocheck_top_testbench_file_path,
std::string(src_dir_path), std::string(src_dir_path),
std::string(vpr_setup.FPGA_SPICE_Opts.SynVerilogOpts.reference_verilog_benchmark_file),
Arch.spice->spice_params); Arch.spice->spice_params);
} }

View File

@ -61,94 +61,21 @@ void print_verilog_top_random_testbench_ports(std::fstream& fp,
/* Print the declaration for the module */ /* Print the declaration for the module */
fp << "module " << circuit_name << FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX << ";" << std::endl; fp << "module " << circuit_name << FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX << ";" << std::endl;
/* Instantiate register for inputs stimulis */
print_verilog_comment(fp, std::string("----- Shared inputs -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_INPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort input_port(std::string(lb.name), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Create a clock port if the benchmark does not have one! /* Create a clock port if the benchmark does not have one!
* The clock is used for counting and synchronizing input stimulus * The clock is used for counting and synchronizing input stimulus
*/ */
if (0 == clock_port_names.size()) {
BasicPort clock_port = generate_verilog_testbench_clock_port(clock_port_names, std::string(DEFAULT_CLOCK_NAME)); BasicPort clock_port = generate_verilog_testbench_clock_port(clock_port_names, std::string(DEFAULT_CLOCK_NAME));
print_verilog_comment(fp, std::string("----- Default clock port is added here since benchmark does not contain one -------")); print_verilog_comment(fp, std::string("----- Default clock port is added here since benchmark does not contain one -------"));
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, clock_port) << ";" << std::endl; fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, clock_port) << ";" << std::endl;
}
/* Add an empty line as splitter */ /* Add an empty line as splitter */
fp << std::endl; fp << std::endl;
/* Instantiate wires for FPGA fabric outputs */ print_verilog_testbench_shared_ports(fp, L_logical_blocks,
print_verilog_comment(fp, std::string("----- FPGA fabric outputs -------")); std::string(BENCHMARK_PORT_POSTFIX),
std::string(FPGA_PORT_POSTFIX),
for (const t_logical_block& lb : L_logical_blocks) { std::string(CHECKFLAG_PORT_POSTFIX),
/* We care only those logic blocks which are input I/Os */ std::string(autochecked_simulation_flag));
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + std::string(FPGA_PORT_POSTFIX)), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Benchmark is instanciated conditionally: only when a preprocessing flag is enable */
print_verilog_preprocessing_flag(fp, std::string(autochecked_simulation_flag));
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate wire for benchmark output */
print_verilog_comment(fp, std::string("----- Benchmark outputs -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + std::string(BENCHMARK_PORT_POSTFIX)), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate register for output comparison */
print_verilog_comment(fp, std::string("----- Output vectors checking flags -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + std::string(CHECKFLAG_PORT_POSTFIX)), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Condition ends for the benchmark instanciation */
print_verilog_endif(fp);
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate an integer to count the number of error /* Instantiate an integer to count the number of error
* and determine if the simulation succeed or failed * and determine if the simulation succeed or failed

View File

@ -90,26 +90,36 @@ void write_include_netlists (char* src_dir_formatted,
*/ */
fprintf(fp, "`include \"%s%s\"\n", src_dir_formatted, fprintf(fp, "`include \"%s%s\"\n", src_dir_formatted,
generate_fpga_top_netlist_name(std::string(verilog_netlist_file_postfix)).c_str()); generate_fpga_top_netlist_name(std::string(verilog_netlist_file_postfix)).c_str());
fprintf(fp, "\n");
fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag); fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag);
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "\t`include \"%s%s%s\"\n", src_dir_formatted,
chomped_circuit_name, chomped_circuit_name,
formal_verification_verilog_file_postfix); formal_verification_verilog_file_postfix);
fprintf(fp, " `ifdef %s\n", formal_simulation_flag); fprintf(fp, "\t`ifdef %s\n", formal_simulation_flag);
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "\t\t`include \"%s%s%s\"\n", src_dir_formatted,
chomped_circuit_name, chomped_circuit_name,
random_top_testbench_verilog_file_postfix); random_top_testbench_verilog_file_postfix);
fprintf(fp, " \t`endif\n");
fprintf(fp, "`endif\n"); fprintf(fp, "`endif\n");
fprintf(fp, "`elsif %s\n", initial_simulation_flag);
fprintf(fp, "\n");
fprintf(fp, "`ifdef %s\n", autochecked_simulation_flag);
/* TODO: bring these testbench onboard when it is ready /* TODO: bring these testbench onboard when it is ready
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted,
chomped_circuit_name, chomped_circuit_name,
top_testbench_verilog_file_postfix); top_testbench_verilog_file_postfix);
fprintf(fp, "`elsif %s\n", autochecked_simulation_flag); fprintf(fp, "`elsif %s\n", autochecked_simulation_flag);
*/
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted,
chomped_circuit_name, chomped_circuit_name,
autocheck_top_testbench_verilog_file_postfix); autocheck_top_testbench_verilog_file_postfix);
*/
fprintf(fp, "`endif\n"); fprintf(fp, "`endif\n");
fprintf(fp, "\n");
fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted, fprintf(fp, "`include \"%s%s%s\"\n", src_dir_formatted,
default_rr_dir_name, default_rr_dir_name,
routing_verilog_file_name); routing_verilog_file_name);

View File

@ -461,3 +461,104 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
fp << std::endl; fp << std::endl;
} }
/********************************************************************
* Print Verilog declaration of shared ports appear in testbenches
* which are
* 1. the shared input ports (registers) to drive both
* FPGA fabric and benchmark instance
* 2. the output ports (wires) for both FPGA fabric and benchmark instance
* 3. the checking flag ports to evaluate if outputs matches under the
* same input vectors
*******************************************************************/
void print_verilog_testbench_shared_ports(std::fstream& fp,
const std::vector<t_logical_block>& L_logical_blocks,
const std::string& benchmark_output_port_postfix,
const std::string& fpga_output_port_postfix,
const std::string& check_flag_port_postfix,
const std::string& autocheck_preprocessing_flag) {
/* Validate the file stream */
check_file_handler(fp);
/* Instantiate register for inputs stimulis */
print_verilog_comment(fp, std::string("----- Shared inputs -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_INPAD != lb.type) {
continue;
}
/* Skip clocks because they are handled in another function */
if (TRUE == lb.is_clock) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort input_port(std::string(lb.name), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate wires for FPGA fabric outputs */
print_verilog_comment(fp, std::string("----- FPGA fabric outputs -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + fpga_output_port_postfix), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Benchmark is instanciated conditionally: only when a preprocessing flag is enable */
print_verilog_preprocessing_flag(fp, std::string(autocheck_preprocessing_flag));
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate wire for benchmark output */
print_verilog_comment(fp, std::string("----- Benchmark outputs -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + benchmark_output_port_postfix), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Instantiate register for output comparison */
print_verilog_comment(fp, std::string("----- Output vectors checking flags -------"));
for (const t_logical_block& lb : L_logical_blocks) {
/* We care only those logic blocks which are input I/Os */
if (VPACK_OUTPAD != lb.type) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(std::string(lb.name) + check_flag_port_postfix), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, output_port) << ";" << std::endl;
}
/* Add an empty line as splitter */
fp << std::endl;
/* Condition ends for the benchmark instanciation */
print_verilog_endif(fp);
/* Add an empty line as splitter */
fp << std::endl;
}

View File

@ -64,4 +64,11 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
const std::string& check_flag_port_postfix, const std::string& check_flag_port_postfix,
const BasicPort& clock_port); const BasicPort& clock_port);
void print_verilog_testbench_shared_ports(std::fstream& fp,
const std::vector<t_logical_block>& L_logical_blocks,
const std::string& benchmark_output_port_postfix,
const std::string& fpga_output_port_postfix,
const std::string& check_flag_port_postfix,
const std::string& autocheck_preprocessing_flag);
#endif #endif

View File

@ -288,6 +288,7 @@ static
void print_verilog_top_testbench_ports(std::fstream& fp, void print_verilog_top_testbench_ports(std::fstream& fp,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const std::vector<t_logical_block>& L_logical_blocks,
const e_sram_orgz& sram_orgz_type, const e_sram_orgz& sram_orgz_type,
const std::string& circuit_name){ const std::string& circuit_name){
/* Validate the file stream */ /* Validate the file stream */
@ -295,7 +296,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
/* Print module definition */ /* Print module definition */
fp << "module " << circuit_name << std::string(modelsim_autocheck_testbench_module_postfix); fp << "module " << circuit_name << std::string(modelsim_autocheck_testbench_module_postfix);
fp << " (" << std::endl; fp << ";" << std::endl;
/* Print regular local wires: /* Print regular local wires:
* 1. global ports, i.e., reset, set and clock signals * 1. global ports, i.e., reset, set and clock signals
@ -304,7 +305,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
/* Global ports of top-level module */ /* Global ports of top-level module */
print_verilog_comment(fp, std::string("----- Local wires for global ports of FPGA fabric -----")); print_verilog_comment(fp, std::string("----- Local wires for global ports of FPGA fabric -----"));
for (const BasicPort& module_port : module_manager.module_ports_by_type(top_module, ModuleManager::MODULE_GLOBAL_PORT)) { for (const BasicPort& module_port : module_manager.module_ports_by_type(top_module, ModuleManager::MODULE_GLOBAL_PORT)) {
fp << generate_verilog_port(VERILOG_PORT_REG, module_port) << ";" << std::endl; fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" << std::endl;
} }
/* Add an empty line as a splitter */ /* Add an empty line as a splitter */
fp << std::endl; fp << std::endl;
@ -312,7 +313,7 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
/* Datapath I/Os of top-level module */ /* Datapath I/Os of top-level module */
print_verilog_comment(fp, std::string("----- Local wires for I/Os of FPGA fabric -----")); print_verilog_comment(fp, std::string("----- Local wires for I/Os of FPGA fabric -----"));
for (const BasicPort& module_port : module_manager.module_ports_by_type(top_module, ModuleManager::MODULE_GPIO_PORT)) { for (const BasicPort& module_port : module_manager.module_ports_by_type(top_module, ModuleManager::MODULE_GPIO_PORT)) {
fp << generate_verilog_port(VERILOG_PORT_REG, module_port) << ";" << std::endl; fp << generate_verilog_port(VERILOG_PORT_WIRE, module_port) << ";" << std::endl;
} }
/* Add an empty line as a splitter */ /* Add an empty line as a splitter */
fp << std::endl; fp << std::endl;
@ -352,6 +353,12 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
/* Configuration ports depend on the organization of SRAMs */ /* Configuration ports depend on the organization of SRAMs */
print_verilog_top_testbench_config_protocol_port(fp, sram_orgz_type); print_verilog_top_testbench_config_protocol_port(fp, sram_orgz_type);
print_verilog_testbench_shared_ports(fp, L_logical_blocks,
std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX),
std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX),
std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX),
std::string(autochecked_simulation_flag));
/* Instantiate an integer to count the number of error and /* Instantiate an integer to count the number of error and
* determine if the simulation succeed or failed * determine if the simulation succeed or failed
*/ */
@ -625,8 +632,10 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp,
fp << "initial" << std::endl; fp << "initial" << std::endl;
fp << "\tbegin" << std::endl; fp << "\tbegin" << std::endl;
print_verilog_comment(fp, "----- Configuration chain default input -----"); print_verilog_comment(fp, "----- Configuration chain default input -----");
fp << "\t"; fp << "\t\t";
print_verilog_wire_constant_values(fp, config_chain_head_port, initial_values); fp << generate_verilog_port_constant_values(config_chain_head_port, initial_values);
fp << ";";
fp << std::endl; fp << std::endl;
/* Attention: the configuration chain protcol requires the last configuration bit is fed first /* Attention: the configuration chain protcol requires the last configuration bit is fed first
@ -718,7 +727,6 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
const std::string& circuit_name, const std::string& circuit_name,
const std::string& verilog_fname, const std::string& verilog_fname,
const std::string& verilog_dir, const std::string& verilog_dir,
const std::string& reference_benchmark_file,
const t_spice_params& simulation_parameters) { const t_spice_params& simulation_parameters) {
vpr_printf(TIO_MESSAGE_INFO, vpr_printf(TIO_MESSAGE_INFO,
"Writing Autocheck Testbench for FPGA Top-level Verilog netlist for %s...", "Writing Autocheck Testbench for FPGA Top-level Verilog netlist for %s...",
@ -741,16 +749,13 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
/* Print preprocessing flags and external netlists */ /* Print preprocessing flags and external netlists */
print_verilog_include_defines_preproc_file(fp, verilog_dir); print_verilog_include_defines_preproc_file(fp, verilog_dir);
/* Include reference benchmark file */
print_verilog_include_netlist(fp, reference_benchmark_file);
/* Find the top_module */ /* Find the top_module */
ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name()); ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name());
VTR_ASSERT(true == module_manager.valid_module_id(top_module)); VTR_ASSERT(true == module_manager.valid_module_id(top_module));
/* Start of testbench */ /* Start of testbench */
//dump_verilog_top_auto_testbench_ports(fp, cur_sram_orgz_info, circuit_name, fpga_verilog_opts); //dump_verilog_top_auto_testbench_ports(fp, cur_sram_orgz_info, circuit_name, fpga_verilog_opts);
print_verilog_top_testbench_ports(fp, module_manager, top_module, print_verilog_top_testbench_ports(fp, module_manager, top_module, L_logical_blocks,
sram_orgz_type, circuit_name); sram_orgz_type, circuit_name);
/* Find the clock period */ /* Find the clock period */

View File

@ -20,7 +20,6 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
const std::string& circuit_name, const std::string& circuit_name,
const std::string& verilog_fname, const std::string& verilog_fname,
const std::string& verilog_dir, const std::string& verilog_dir,
const std::string& reference_benchmark_file,
const t_spice_params& simulation_parameters); const t_spice_params& simulation_parameters);
void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head, void dump_verilog_top_testbench_global_ports(FILE* fp, t_llist* head,