Merge pull request #1484 from lnis-uofu/xt_hotfix
Support VCS simulator for QL memory bank in full testbench
This commit is contained in:
commit
b494740781
|
@ -61,6 +61,10 @@ write_full_testbench
|
|||
|
||||
The bitstream file to be loaded to the full testbench, which should be in the same file format that OpenFPGA can outputs (See detailes in :ref:`file_formats_fabric_bitstream_plain_text`). For example, ``--bitstream and2.bit``
|
||||
|
||||
.. option:: --simulator <string>
|
||||
|
||||
Specify the type of simulator which the full testbench will be used for. Currently support ``iverilog`` | ``vcs``. By default, assume the simulator is iverilog. For example, ``--simulator iverilog``. For different types of simulator, some syntax in the testbench may differ to help fast convergence.
|
||||
|
||||
.. option:: --fabric_netlist_file_path <string>
|
||||
|
||||
Specify the fabric Verilog file if they are not in the same directory as the testbenches to be generated. If not specified, OpenFPGA will assume that the fabric netlists are the in the same directory as testbenches and assign default names. For example, ``--file /temp/fabric/fabric_netlists.v``
|
||||
|
|
|
@ -104,6 +104,11 @@ ShellCommandId add_write_full_testbench_command_template(
|
|||
"bitstream", true, "specify the bitstream to be loaded in the testbench");
|
||||
shell_cmd.set_option_require_value(bitstream_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* add an option '--simulator'*/
|
||||
CommandOptionId sim_opt = shell_cmd.add_option(
|
||||
"simulator", false, "specify the simulator to be used for the testbench");
|
||||
shell_cmd.set_option_require_value(sim_opt, openfpga::OPT_STRING);
|
||||
|
||||
/* add an option '--fabric_netlist_file_path'*/
|
||||
CommandOptionId fabric_netlist_opt =
|
||||
shell_cmd.add_option("fabric_netlist_file_path", false,
|
||||
|
|
|
@ -74,6 +74,7 @@ int write_full_testbench_template(const T& openfpga_ctx, const Command& cmd,
|
|||
const CommandContext& cmd_context) {
|
||||
CommandOptionId opt_output_dir = cmd.option("file");
|
||||
CommandOptionId opt_bitstream = cmd.option("bitstream");
|
||||
CommandOptionId opt_sim = cmd.option("simulator");
|
||||
CommandOptionId opt_dut_module = cmd.option("dut_module");
|
||||
CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path");
|
||||
CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
|
||||
|
@ -132,6 +133,11 @@ int write_full_testbench_template(const T& openfpga_ctx, const Command& cmd,
|
|||
read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str());
|
||||
}
|
||||
|
||||
/* Configure the simulator */
|
||||
if (true == cmd_context.option_enable(cmd, opt_sim)) {
|
||||
options.set_simulator_type(cmd_context.option_value(cmd, opt_sim));
|
||||
}
|
||||
|
||||
return fpga_verilog_full_testbench(
|
||||
openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(),
|
||||
openfpga_ctx.fabric_bitstream(), openfpga_ctx.blwl_shift_register_banks(),
|
||||
|
|
|
@ -30,7 +30,10 @@ VerilogTestbenchOption::VerilogTestbenchOption() {
|
|||
time_unit_ = 1E-3;
|
||||
time_stamp_ = true;
|
||||
use_relative_path_ = false;
|
||||
simulator_type_ = e_simulator_type::IVERILOG;
|
||||
verbose_output_ = false;
|
||||
|
||||
SIMULATOR_TYPE_STRING_ = {{"iverilog", "vcs"}};
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
|
@ -107,6 +110,11 @@ bool VerilogTestbenchOption::use_relative_path() const {
|
|||
|
||||
bool VerilogTestbenchOption::verbose_output() const { return verbose_output_; }
|
||||
|
||||
VerilogTestbenchOption::e_simulator_type
|
||||
VerilogTestbenchOption::simulator_type() const {
|
||||
return simulator_type_;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
|
@ -259,4 +267,52 @@ void VerilogTestbenchOption::set_verbose_output(const bool& enabled) {
|
|||
verbose_output_ = enabled;
|
||||
}
|
||||
|
||||
int VerilogTestbenchOption::set_simulator_type(const std::string& value) {
|
||||
simulator_type_ = str2simulator_type(value);
|
||||
return valid_simulator_type(simulator_type_);
|
||||
}
|
||||
|
||||
std::string VerilogTestbenchOption::simulator_type_all2str() const {
|
||||
std::string full_types = "[";
|
||||
for (int itype = size_t(VerilogTestbenchOption::e_simulator_type::IVERILOG);
|
||||
itype != size_t(VerilogTestbenchOption::e_simulator_type::NUM_TYPES);
|
||||
++itype) {
|
||||
full_types += std::string(SIMULATOR_TYPE_STRING_[itype]) + std::string("|");
|
||||
}
|
||||
full_types.pop_back();
|
||||
full_types += "]";
|
||||
return full_types;
|
||||
}
|
||||
|
||||
VerilogTestbenchOption::e_simulator_type
|
||||
VerilogTestbenchOption::str2simulator_type(const std::string& type_str,
|
||||
const bool& verbose) const {
|
||||
for (int itype = size_t(VerilogTestbenchOption::e_simulator_type::IVERILOG);
|
||||
itype != size_t(VerilogTestbenchOption::e_simulator_type::NUM_TYPES);
|
||||
++itype) {
|
||||
if (type_str == std::string(SIMULATOR_TYPE_STRING_[itype])) {
|
||||
return static_cast<VerilogTestbenchOption::e_simulator_type>(itype);
|
||||
}
|
||||
}
|
||||
VTR_LOGV_ERROR(verbose, "Invalid simulator type! Expect %s\n",
|
||||
simulator_type_all2str().c_str());
|
||||
return VerilogTestbenchOption::e_simulator_type::NUM_TYPES;
|
||||
}
|
||||
|
||||
std::string VerilogTestbenchOption::simulator_type2str(
|
||||
const VerilogTestbenchOption::e_simulator_type& sim_type,
|
||||
const bool& verbose) const {
|
||||
if (!valid_simulator_type(sim_type)) {
|
||||
VTR_LOGV_ERROR(verbose, "Invalid type for simulator! Expect %s\n",
|
||||
simulator_type_all2str().c_str());
|
||||
return std::string();
|
||||
}
|
||||
return std::string(SIMULATOR_TYPE_STRING_[size_t(sim_type)]);
|
||||
}
|
||||
|
||||
bool VerilogTestbenchOption::valid_simulator_type(
|
||||
const VerilogTestbenchOption::e_simulator_type& sim_type) const {
|
||||
return sim_type != VerilogTestbenchOption::e_simulator_type::NUM_TYPES;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -31,6 +31,16 @@ constexpr std::array<const char*, NUM_EMBEDDED_BITSTREAM_HDL_TYPES + 1>
|
|||
*
|
||||
*******************************************************************/
|
||||
class VerilogTestbenchOption {
|
||||
/* Public types */
|
||||
public:
|
||||
/* Embedded bitstream code style */
|
||||
enum class e_simulator_type { IVERILOG = 0, VCS, NUM_TYPES };
|
||||
/* Constants */
|
||||
private:
|
||||
/* String version of simulator types. Used for debugging/error messages */
|
||||
std::array<const char*, size_t(e_simulator_type::NUM_TYPES)>
|
||||
SIMULATOR_TYPE_STRING_;
|
||||
|
||||
public: /* Public constructor */
|
||||
/* Set default options */
|
||||
VerilogTestbenchOption();
|
||||
|
@ -56,6 +66,7 @@ class VerilogTestbenchOption {
|
|||
bool time_stamp() const;
|
||||
bool use_relative_path() const;
|
||||
bool verbose_output() const;
|
||||
e_simulator_type simulator_type() const;
|
||||
|
||||
public: /* Public validator */
|
||||
bool validate() const;
|
||||
|
@ -95,6 +106,18 @@ class VerilogTestbenchOption {
|
|||
void set_use_relative_path(const bool& enabled);
|
||||
void set_verbose_output(const bool& enabled);
|
||||
|
||||
/* @brief Create the simulator type by parsing a given string. Return error
|
||||
* when failed */
|
||||
int set_simulator_type(const std::string& value);
|
||||
|
||||
private: /* Private utility and validators */
|
||||
e_simulator_type str2simulator_type(const std::string& value,
|
||||
const bool& verbose = false) const;
|
||||
std::string simulator_type2str(const e_simulator_type& sim_type,
|
||||
const bool& verbose = false) const;
|
||||
std::string simulator_type_all2str() const;
|
||||
bool valid_simulator_type(const e_simulator_type& sim_type) const;
|
||||
|
||||
private: /* Internal Data */
|
||||
std::string output_directory_;
|
||||
std::string top_module_;
|
||||
|
@ -111,6 +134,7 @@ class VerilogTestbenchOption {
|
|||
bool include_signal_init_;
|
||||
e_verilog_default_net_type default_net_type_;
|
||||
e_embedded_bitstream_hdl_type embedded_bitstream_hdl_type_;
|
||||
e_simulator_type simulator_type_;
|
||||
float time_unit_;
|
||||
bool time_stamp_;
|
||||
bool use_relative_path_;
|
||||
|
|
|
@ -1423,7 +1423,8 @@ static int print_verilog_top_testbench_configuration_protocol_stimulus(
|
|||
const ModuleId& top_module, const bool& fast_configuration,
|
||||
const bool& bit_value_to_skip, const FabricBitstream& fabric_bitstream,
|
||||
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
|
||||
const float& prog_clock_period, const float& timescale) {
|
||||
const float& prog_clock_period, const float& timescale,
|
||||
const VerilogTestbenchOption::e_simulator_type sim_type) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
|
@ -1437,7 +1438,7 @@ static int print_verilog_top_testbench_configuration_protocol_stimulus(
|
|||
return print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(
|
||||
fp, config_protocol, sim_settings, module_manager, top_module,
|
||||
fast_configuration, bit_value_to_skip, fabric_bitstream, blwl_sr_banks,
|
||||
prog_clock_period, timescale);
|
||||
prog_clock_period, timescale, sim_type);
|
||||
break;
|
||||
case CONFIG_MEM_MEMORY_BANK:
|
||||
case CONFIG_MEM_FRAME_BASED: {
|
||||
|
@ -2564,7 +2565,7 @@ int print_verilog_full_testbench(
|
|||
status = print_verilog_top_testbench_configuration_protocol_stimulus(
|
||||
fp, config_protocol, simulation_parameters, module_manager, core_module,
|
||||
fast_configuration, bit_value_to_skip, fabric_bitstream, blwl_sr_banks,
|
||||
prog_clock_period, VERILOG_SIM_TIMESCALE);
|
||||
prog_clock_period, VERILOG_SIM_TIMESCALE, options.simulator_type());
|
||||
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
|
|
|
@ -317,7 +317,8 @@ void print_verilog_top_testbench_global_shift_register_clock_ports_stimuli(
|
|||
static void
|
||||
print_verilog_full_testbench_ql_memory_bank_shift_register_virtual_clock_generator(
|
||||
std::fstream& fp, const BasicPort& start_sr_port,
|
||||
const BasicPort& sr_clock_port, const float& sr_clock_period) {
|
||||
const BasicPort& sr_clock_port, const float& sr_clock_period,
|
||||
const VerilogTestbenchOption::e_simulator_type sim_type) {
|
||||
/* Validate the file stream */
|
||||
valid_file_stream(fp);
|
||||
|
||||
|
@ -345,10 +346,14 @@ print_verilog_full_testbench_ql_memory_bank_shift_register_virtual_clock_generat
|
|||
fp << "end";
|
||||
fp << std::endl;
|
||||
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(
|
||||
sr_clock_port, std::vector<size_t>(sr_clock_port.get_width(), 0), true);
|
||||
fp << ";" << std::endl;
|
||||
// The following code does not work when using Synopsys VCS. Comment them out.
|
||||
// See if iverilog is fine or not
|
||||
if (sim_type == VerilogTestbenchOption::e_simulator_type::IVERILOG) {
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(
|
||||
sr_clock_port, std::vector<size_t>(sr_clock_port.get_width(), 0), true);
|
||||
fp << ";" << std::endl;
|
||||
}
|
||||
|
||||
fp << "end";
|
||||
fp << std::endl;
|
||||
|
@ -453,7 +458,8 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(
|
|||
const ModuleId& top_module, const bool& fast_configuration,
|
||||
const bool& bit_value_to_skip, const FabricBitstream& fabric_bitstream,
|
||||
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
|
||||
const float& prog_clock_period, const float& timescale) {
|
||||
const float& prog_clock_period, const float& timescale,
|
||||
const VerilogTestbenchOption::e_simulator_type sim_type) {
|
||||
ModulePortId en_port_id = module_manager.find_module_port(
|
||||
top_module, std::string(DECODER_ENABLE_PORT_NAME));
|
||||
BasicPort en_port(std::string(DECODER_ENABLE_PORT_NAME), 1);
|
||||
|
@ -531,7 +537,8 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(
|
|||
print_verilog_comment(
|
||||
fp, "----- BL Shift register virtual clock generator -----");
|
||||
print_verilog_full_testbench_ql_memory_bank_shift_register_virtual_clock_generator(
|
||||
fp, start_bl_sr_port, virtual_bl_sr_clock_port, bl_sr_clock_period);
|
||||
fp, start_bl_sr_port, virtual_bl_sr_clock_port, bl_sr_clock_period,
|
||||
sim_type);
|
||||
|
||||
print_verilog_comment(fp,
|
||||
"----- BL Shift register clock generator -----");
|
||||
|
@ -543,7 +550,8 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(
|
|||
print_verilog_comment(
|
||||
fp, "----- WL Shift register virtual clock generator -----");
|
||||
print_verilog_full_testbench_ql_memory_bank_shift_register_virtual_clock_generator(
|
||||
fp, start_wl_sr_port, virtual_wl_sr_clock_port, wl_sr_clock_period);
|
||||
fp, start_wl_sr_port, virtual_wl_sr_clock_port, wl_sr_clock_period,
|
||||
sim_type);
|
||||
print_verilog_comment(fp,
|
||||
"----- WL Shift register clock generator -----");
|
||||
print_verilog_full_testbench_ql_memory_bank_shift_register_clock_generator(
|
||||
|
|
|
@ -54,7 +54,8 @@ int print_verilog_top_testbench_configuration_protocol_ql_memory_bank_stimulus(
|
|||
const ModuleId& top_module, const bool& fast_configuration,
|
||||
const bool& bit_value_to_skip, const FabricBitstream& fabric_bitstream,
|
||||
const MemoryBankShiftRegisterBanks& blwl_sr_banks,
|
||||
const float& prog_clock_period, const float& timescale);
|
||||
const float& prog_clock_period, const float& timescale,
|
||||
const VerilogTestbenchOption::e_simulator_type sim_type);
|
||||
|
||||
/**
|
||||
* @brief Print stimulus for a FPGA fabric with a memory bank configuration
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# Run VPR for the 'and' design
|
||||
#--write_rr_graph example_rr_graph.xml
|
||||
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal ${OPENFPGA_VPR_DEVICE_LAYOUT}
|
||||
|
||||
# Read OpenFPGA architecture definition
|
||||
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
|
||||
|
||||
# Read OpenFPGA simulation settings
|
||||
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_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 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 --write_file fabric_independent_bitstream.xml
|
||||
|
||||
# Build fabric-dependent bitstream
|
||||
build_fabric_bitstream --verbose
|
||||
|
||||
# Write fabric-dependent bitstream
|
||||
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text ${OPENFPGA_FAST_CONFIGURATION}
|
||||
|
||||
# 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 --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_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --include_signal_init --explicit_port_mapping --bitstream fabric_bitstream.bit ${OPENFPGA_FAST_CONFIGURATION} ${OPENFPGA_SIMULATOR}
|
||||
|
||||
# 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
|
|
@ -83,6 +83,9 @@ run-task basic_tests/full_testbench/ql_memory_bank_shift_register $@
|
|||
run-task basic_tests/full_testbench/ql_memory_bank_shift_register_use_wlr $@
|
||||
run-task basic_tests/full_testbench/ql_memory_bank_shift_register_multi_chain $@
|
||||
|
||||
echo -e "Testing simulator support";
|
||||
run-task basic_tests/full_testbench/ql_memory_bank_shift_register_vcs $@
|
||||
|
||||
echo -e "Testing testbenches without self checking features";
|
||||
run-task basic_tests/full_testbench/full_testbench_without_self_checking $@
|
||||
run-task basic_tests/preconfig_testbench/preconfigured_testbench_without_self_checking $@
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# Configuration file for running experiments
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
|
||||
# Each job execute fpga_flow script on combination of architecture & benchmark
|
||||
# timeout_each_job is timeout for each job
|
||||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
|
||||
[GENERAL]
|
||||
run_engine=openfpga_shell
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = true
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/write_full_testbench_simulator_support_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbanksr_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_shift_register_sim_openfpga.xml
|
||||
|
||||
openfpga_vpr_device_layout=
|
||||
openfpga_fast_configuration=
|
||||
openfpga_simulator=--simulator vcs
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/or2/or2.v
|
||||
bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch/and2_latch.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench0_top = and2
|
||||
bench0_chan_width = 300
|
||||
|
||||
bench1_top = or2
|
||||
bench1_chan_width = 300
|
||||
|
||||
bench2_top = and2_latch
|
||||
bench2_chan_width = 300
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
#end_flow_with_test=
|
Loading…
Reference in New Issue