add fast configuration option to fpga_verilog to speed up full testbench simulation
This commit is contained in:
parent
22648cdb9c
commit
8b3e79766c
|
@ -67,6 +67,7 @@ int write_verilog_testbench(OpenfpgaContext& openfpga_ctx,
|
|||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
|
||||
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_preconfig_top_testbench = cmd.option("print_preconfig_top_testbench");
|
||||
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_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_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_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));
|
||||
|
|
|
@ -79,6 +79,9 @@ ShellCommandId add_openfpga_write_verilog_testbench_command(openfpga::Shell<Open
|
|||
/* 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");
|
||||
|
||||
/* 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' */
|
||||
shell_cmd.add_option("print_formal_verification_top_netlist", false, "Generate a top-level module which can be used in formal verification");
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ void fpga_verilog_testbench(const ModuleManager& module_manager,
|
|||
netlist_name,
|
||||
top_testbench_file_path,
|
||||
simulation_setting,
|
||||
options.fast_configuration(),
|
||||
options.explicit_port_mapping());
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ bool VerilogTestbenchOption::print_top_testbench() const {
|
|||
return print_top_testbench_;
|
||||
}
|
||||
|
||||
bool VerilogTestbenchOption::fast_configuration() const {
|
||||
return fast_configuration_;
|
||||
}
|
||||
|
||||
bool VerilogTestbenchOption::print_simulation_ini() const {
|
||||
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;
|
||||
}
|
||||
|
||||
void VerilogTestbenchOption::set_fast_configuration(const bool& enabled) {
|
||||
fast_configuration_ = enabled;
|
||||
}
|
||||
|
||||
void VerilogTestbenchOption::set_print_preconfig_top_testbench(const bool& enabled) {
|
||||
print_preconfig_top_testbench_ = enabled
|
||||
&& (!reference_benchmark_file_path_.empty());
|
||||
|
|
|
@ -24,6 +24,7 @@ class VerilogTestbenchOption {
|
|||
public: /* Public accessors */
|
||||
std::string output_directory() const;
|
||||
std::string reference_benchmark_file_path() const;
|
||||
bool fast_configuration() const;
|
||||
bool print_formal_verification_top_netlist() const;
|
||||
bool print_preconfig_top_testbench() const;
|
||||
bool print_top_testbench() const;
|
||||
|
@ -44,6 +45,7 @@ class VerilogTestbenchOption {
|
|||
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 */
|
||||
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_simulation_ini(const std::string& simulation_ini_path);
|
||||
void set_explicit_port_mapping(const bool& enabled);
|
||||
|
@ -51,6 +53,7 @@ class VerilogTestbenchOption {
|
|||
private: /* Internal Data */
|
||||
std::string output_directory_;
|
||||
std::string reference_benchmark_file_path_;
|
||||
bool fast_configuration_;
|
||||
bool print_formal_verification_top_netlist_;
|
||||
bool print_preconfig_top_testbench_;
|
||||
bool print_top_testbench_;
|
||||
|
|
|
@ -481,6 +481,48 @@ void print_verilog_top_testbench_ports(std::fstream& fp,
|
|||
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
|
||||
*******************************************************************/
|
||||
|
@ -865,6 +907,7 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp,
|
|||
*******************************************************************/
|
||||
static
|
||||
void print_verilog_top_testbench_frame_decoder_bitstream(std::fstream& fp,
|
||||
const bool& fast_configuration,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
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
|
||||
*/
|
||||
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 << "(" << addr_port.get_width() << "'b";
|
||||
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
|
||||
void print_verilog_top_testbench_bitstream(std::fstream& fp,
|
||||
const e_config_protocol_type& sram_orgz_type,
|
||||
const bool& fast_configuration,
|
||||
const ModuleManager& module_manager,
|
||||
const ModuleId& top_module,
|
||||
const BitstreamManager& bitstream_manager,
|
||||
|
@ -973,7 +1023,7 @@ void print_verilog_top_testbench_bitstream(std::fstream& fp,
|
|||
/* TODO */
|
||||
break;
|
||||
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,
|
||||
fabric_bitstream);
|
||||
break;
|
||||
|
@ -1017,6 +1067,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
const std::string& circuit_name,
|
||||
const std::string& verilog_fname,
|
||||
const SimulationSetting& simulation_parameters,
|
||||
const bool& fast_configuration,
|
||||
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("'");
|
||||
|
@ -1050,11 +1101,10 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
/* Find the clock period */
|
||||
float prog_clock_period = (1./simulation_parameters.programming_clock_frequency());
|
||||
float op_clock_period = (1./simulation_parameters.operating_clock_frequency());
|
||||
/* 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
|
||||
*/
|
||||
size_t num_config_clock_cycles = 1 + fabric_bitstream.bits().size();
|
||||
/* Estimate the number of configuration clock cycles */
|
||||
size_t num_config_clock_cycles = calculate_num_config_clock_cycles(sram_orgz_type,
|
||||
fast_configuration,
|
||||
fabric_bitstream);
|
||||
|
||||
/* Generate stimuli for general control signals */
|
||||
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 */
|
||||
print_verilog_top_testbench_bitstream(fp, sram_orgz_type,
|
||||
fast_configuration,
|
||||
module_manager, top_module,
|
||||
bitstream_manager, fabric_bitstream);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
const std::string& circuit_name,
|
||||
const std::string& verilog_fname,
|
||||
const SimulationSetting& simulation_parameters,
|
||||
const bool& fast_configuration,
|
||||
const bool& explicit_port_mapping);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -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 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_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
|
||||
# - Turn on every options here
|
||||
|
|
|
@ -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
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
[GENERAL]
|
||||
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_analysis = true
|
||||
spice_output=false
|
||||
|
|
Loading…
Reference in New Issue