add fast configuration option to fpga_verilog to speed up full testbench simulation

This commit is contained in:
tangxifan 2020-05-29 18:07:21 -06:00
parent 22648cdb9c
commit 8b3e79766c
10 changed files with 145 additions and 8 deletions

View File

@ -67,6 +67,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
CommandOptionId opt_print_top_testbench = cmd.option("print_top_testbench"); CommandOptionId opt_print_top_testbench = cmd.option("print_top_testbench");
CommandOptionId opt_fast_configuration = cmd.option("fast_configuration");
CommandOptionId opt_print_formal_verification_top_netlist = cmd.option("print_formal_verification_top_netlist"); CommandOptionId opt_print_formal_verification_top_netlist = cmd.option("print_formal_verification_top_netlist");
CommandOptionId opt_print_preconfig_top_testbench = cmd.option("print_preconfig_top_testbench"); CommandOptionId opt_print_preconfig_top_testbench = cmd.option("print_preconfig_top_testbench");
CommandOptionId opt_print_simulation_ini = cmd.option("print_simulation_ini"); CommandOptionId opt_print_simulation_ini = cmd.option("print_simulation_ini");
@ -81,6 +82,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
options.set_reference_benchmark_file_path(cmd_context.option_value(cmd, opt_reference_benchmark)); options.set_reference_benchmark_file_path(cmd_context.option_value(cmd, opt_reference_benchmark));
options.set_print_formal_verification_top_netlist(cmd_context.option_enable(cmd, opt_print_formal_verification_top_netlist)); options.set_print_formal_verification_top_netlist(cmd_context.option_enable(cmd, opt_print_formal_verification_top_netlist));
options.set_print_preconfig_top_testbench(cmd_context.option_enable(cmd, opt_print_preconfig_top_testbench)); options.set_print_preconfig_top_testbench(cmd_context.option_enable(cmd, opt_print_preconfig_top_testbench));
options.set_fast_configuration(cmd_context.option_enable(cmd, opt_fast_configuration));
options.set_print_top_testbench(cmd_context.option_enable(cmd, opt_print_top_testbench)); options.set_print_top_testbench(cmd_context.option_enable(cmd, opt_print_top_testbench));
options.set_print_simulation_ini(cmd_context.option_value(cmd, opt_print_simulation_ini)); options.set_print_simulation_ini(cmd_context.option_value(cmd, opt_print_simulation_ini));
options.set_explicit_port_mapping(cmd_context.option_enable(cmd, opt_explicit_port_mapping)); options.set_explicit_port_mapping(cmd_context.option_enable(cmd, opt_explicit_port_mapping));

View File

@ -79,6 +79,9 @@ ShellCommandId add_openfpga_write_verilog_testbench_command(openfpga::Shell<Open
/* Add an option '--print_top_testbench' */ /* Add an option '--print_top_testbench' */
shell_cmd.add_option("print_top_testbench", false, "Generate a full testbench for top-level fabric module with autocheck capability"); shell_cmd.add_option("print_top_testbench", false, "Generate a full testbench for top-level fabric module with autocheck capability");
/* Add an option '--fast_configuration' */
shell_cmd.add_option("fast_configuration", false, "Reduce the period of configuration by skip zero data points");
/* Add an option '--print_formal_verification_top_netlist' */ /* Add an option '--print_formal_verification_top_netlist' */
shell_cmd.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification"); shell_cmd.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification");

View File

@ -213,6 +213,7 @@ void fpga_verilog_testbench(const ModuleManager& module_manager,
netlist_name, netlist_name,
top_testbench_file_path, top_testbench_file_path,
simulation_setting, simulation_setting,
options.fast_configuration(),
options.explicit_port_mapping()); options.explicit_port_mapping());
} }

View File

@ -46,6 +46,10 @@ bool VerilogTestbenchOption::print_top_testbench() const {
return print_top_testbench_; return print_top_testbench_;
} }
bool VerilogTestbenchOption::fast_configuration() const {
return fast_configuration_;
}
bool VerilogTestbenchOption::print_simulation_ini() const { bool VerilogTestbenchOption::print_simulation_ini() const {
return !simulation_ini_path_.empty(); return !simulation_ini_path_.empty();
} }
@ -82,6 +86,10 @@ void VerilogTestbenchOption::set_print_formal_verification_top_netlist(const boo
print_formal_verification_top_netlist_ = enabled; print_formal_verification_top_netlist_ = enabled;
} }
void VerilogTestbenchOption::set_fast_configuration(const bool& enabled) {
fast_configuration_ = enabled;
}
void VerilogTestbenchOption::set_print_preconfig_top_testbench(const bool& enabled) { void VerilogTestbenchOption::set_print_preconfig_top_testbench(const bool& enabled) {
print_preconfig_top_testbench_ = enabled print_preconfig_top_testbench_ = enabled
&& (!reference_benchmark_file_path_.empty()); && (!reference_benchmark_file_path_.empty());

View File

@ -24,6 +24,7 @@ class VerilogTestbenchOption {
public: /* Public accessors */ public: /* Public accessors */
std::string output_directory() const; std::string output_directory() const;
std::string reference_benchmark_file_path() const; std::string reference_benchmark_file_path() const;
bool fast_configuration() const;
bool print_formal_verification_top_netlist() const; bool print_formal_verification_top_netlist() const;
bool print_preconfig_top_testbench() const; bool print_preconfig_top_testbench() const;
bool print_top_testbench() const; bool print_top_testbench() const;
@ -44,6 +45,7 @@ class VerilogTestbenchOption {
void set_print_formal_verification_top_netlist(const bool& enabled); void set_print_formal_verification_top_netlist(const bool& enabled);
/* The preconfig top testbench generation can be enabled only when formal verification top netlist is enabled */ /* The preconfig top testbench generation can be enabled only when formal verification top netlist is enabled */
void set_print_preconfig_top_testbench(const bool& enabled); void set_print_preconfig_top_testbench(const bool& enabled);
void set_fast_configuration(const bool& enabled);
void set_print_top_testbench(const bool& enabled); void set_print_top_testbench(const bool& enabled);
void set_print_simulation_ini(const std::string& simulation_ini_path); void set_print_simulation_ini(const std::string& simulation_ini_path);
void set_explicit_port_mapping(const bool& enabled); void set_explicit_port_mapping(const bool& enabled);
@ -51,6 +53,7 @@ class VerilogTestbenchOption {
private: /* Internal Data */ private: /* Internal Data */
std::string output_directory_; std::string output_directory_;
std::string reference_benchmark_file_path_; std::string reference_benchmark_file_path_;
bool fast_configuration_;
bool print_formal_verification_top_netlist_; bool print_formal_verification_top_netlist_;
bool print_preconfig_top_testbench_; bool print_preconfig_top_testbench_;
bool print_top_testbench_; bool print_top_testbench_;

View File

@ -481,6 +481,48 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
fp << "\tinteger " << TOP_TESTBENCH_ERROR_COUNTER << "= 0;" << std::endl; fp << "\tinteger " << TOP_TESTBENCH_ERROR_COUNTER << "= 0;" << std::endl;
} }
/********************************************************************
* Estimate the number of configuration clock cycles
* by traversing the linked-list and count the number of SRAM=1 or BL=1&WL=1 in it.
* We plus 1 additional config clock cycle here because we need to reset everything during the first clock cycle
* If we consider fast configuration, the number of clock cycles will be
* the number of non-zero data points in the fabric bitstream
* Note that this will not applicable to configuration chain!!!
*******************************************************************/
static
size_t calculate_num_config_clock_cycles(const e_config_protocol_type& sram_orgz_type,
const bool& fast_configuration,
const FabricBitstream& fabric_bitstream) {
size_t num_config_clock_cycles = 1 + fabric_bitstream.bits().size();
/* Branch on the type of configuration protocol */
switch (sram_orgz_type) {
case CONFIG_MEM_STANDALONE:
case CONFIG_MEM_SCAN_CHAIN:
case CONFIG_MEM_MEMORY_BANK:
/* TODO */
break;
case CONFIG_MEM_FRAME_BASED: {
/* For fast configuration, we will skip all the zero data points */
if (true == fast_configuration) {
num_config_clock_cycles = 1;
for (const FabricBitId& bit_id : fabric_bitstream.bits()) {
if (true == fabric_bitstream.bit_din(bit_id)) {
num_config_clock_cycles++;
}
}
}
break;
}
default:
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Invalid SRAM organization type!\n");
exit(1);
}
return num_config_clock_cycles;
}
/******************************************************************** /********************************************************************
* Instanciate the input benchmark module * Instanciate the input benchmark module
*******************************************************************/ *******************************************************************/
@ -865,6 +907,7 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp,
*******************************************************************/ *******************************************************************/
static static
void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp, void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp,
const bool& fast_configuration,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const FabricBitstream& fabric_bitstream) { const FabricBitstream& fabric_bitstream) {
@ -904,6 +947,12 @@ void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp,
* We will visit the fabric bitstream in a reverse way * We will visit the fabric bitstream in a reverse way
*/ */
for (const FabricBitId& bit_id : fabric_bitstream.bits()) { for (const FabricBitId& bit_id : fabric_bitstream.bits()) {
/* When fast configuration is enabled, we skip zero data_in values */
if ((true == fast_configuration)
&& (false == fabric_bitstream.bit_din(bit_id))) {
continue;
}
fp << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME); fp << "\t\t" << std::string(TOP_TESTBENCH_PROG_TASK_NAME);
fp << "(" << addr_port.get_width() << "'b"; fp << "(" << addr_port.get_width() << "'b";
VTR_ASSERT(addr_port.get_width() == fabric_bitstream.bit_address(bit_id).size()); VTR_ASSERT(addr_port.get_width() == fabric_bitstream.bit_address(bit_id).size());
@ -957,6 +1006,7 @@ void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp,
static static
void print_verilog_top_testbench_bitstream(std::fstream& fp, void print_verilog_top_testbench_bitstream(std::fstream& fp,
const e_config_protocol_type& sram_orgz_type, const e_config_protocol_type& sram_orgz_type,
const bool& fast_configuration,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const BitstreamManager& bitstream_manager, const BitstreamManager& bitstream_manager,
@ -973,7 +1023,7 @@ void print_verilog_top_testbench_bitstream(std::fstream& fp,
/* TODO */ /* TODO */
break; break;
case CONFIG_MEM_FRAME_BASED: case CONFIG_MEM_FRAME_BASED:
print_verilog_top_testbench_frame_decoder_bitstream(fp, print_verilog_top_testbench_frame_decoder_bitstream(fp, fast_configuration,
module_manager, top_module, module_manager, top_module,
fabric_bitstream); fabric_bitstream);
break; break;
@ -1017,6 +1067,7 @@ 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 SimulationSetting& simulation_parameters, const SimulationSetting& simulation_parameters,
const bool& fast_configuration,
const bool& explicit_port_mapping) { const bool& explicit_port_mapping) {
std::string timer_message = std::string("Write autocheck testbench for FPGA top-level Verilog netlist for '") + circuit_name + std::string("'"); std::string timer_message = std::string("Write autocheck testbench for FPGA top-level Verilog netlist for '") + circuit_name + std::string("'");
@ -1050,11 +1101,10 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
/* Find the clock period */ /* Find the clock period */
float prog_clock_period = (1./simulation_parameters.programming_clock_frequency()); float prog_clock_period = (1./simulation_parameters.programming_clock_frequency());
float op_clock_period = (1./simulation_parameters.operating_clock_frequency()); float op_clock_period = (1./simulation_parameters.operating_clock_frequency());
/* Estimate the number of configuration clock cycles /* Estimate the number of configuration clock cycles */
* by traversing the linked-list and count the number of SRAM=1 or BL=1&WL=1 in it. size_t num_config_clock_cycles = calculate_num_config_clock_cycles(sram_orgz_type,
* We plus 1 additional config clock cycle here because we need to reset everything during the first clock cycle fast_configuration,
*/ fabric_bitstream);
size_t num_config_clock_cycles = 1 + fabric_bitstream.bits().size();
/* Generate stimuli for general control signals */ /* Generate stimuli for general control signals */
print_verilog_top_testbench_generic_stimulus(fp, print_verilog_top_testbench_generic_stimulus(fp,
@ -1095,6 +1145,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
/* load bitstream to FPGA fabric in a configuration phase */ /* load bitstream to FPGA fabric in a configuration phase */
print_verilog_top_testbench_bitstream(fp, sram_orgz_type, print_verilog_top_testbench_bitstream(fp, sram_orgz_type,
fast_configuration,
module_manager, top_module, module_manager, top_module,
bitstream_manager, fabric_bitstream); bitstream_manager, fabric_bitstream);

View File

@ -35,6 +35,7 @@ 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 SimulationSetting& simulation_parameters, const SimulationSetting& simulation_parameters,
const bool& fast_configuration,
const bool& explicit_port_mapping); const bool& explicit_port_mapping);
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -49,7 +49,7 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --inc
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA # - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase # - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts # - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --explicit_port_mapping write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --explicit_port_mapping --fast_configuration
# Write the SDC files for PnR backend # Write the SDC files for PnR backend
# - Turn on every options here # - Turn on every options here

View File

@ -0,0 +1,68 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --file fabric_indepenent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --include_signal_init --support_icarus_simulator --print_user_defined_template --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --explicit_port_mapping
# Write the SDC files for PnR backend
# - Turn on every options here
write_pnr_sdc --file ./SDC
# Write SDC to disable timing for configure ports
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -8,7 +8,7 @@
[GENERAL] [GENERAL]
run_engine=openfpga_shell run_engine=openfpga_shell
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/OpenFPGAShellScripts/configuration_frame_example_script.openfpga openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/OpenFPGAShellScripts/full_testbench_example_script.openfpga
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true power_analysis = true
spice_output=false spice_output=false