fine tuning top testbench and getting ready for testing
This commit is contained in:
parent
d7bbae76a4
commit
3274a49779
|
@ -291,10 +291,14 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
|
|||
/* Call defined benchmark */
|
||||
print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name, L_logical_blocks);
|
||||
|
||||
/* Find clock port to be used */
|
||||
BasicPort clock_port = generate_verilog_testbench_clock_port(clock_port_names, std::string(DEFAULT_CLOCK_NAME));
|
||||
|
||||
/* Add stimuli for reset, set, clock and iopad signals */
|
||||
print_verilog_testbench_random_stimuli(fp, simulation_parameters, L_logical_blocks,
|
||||
std::string(CHECKFLAG_PORT_POSTFIX),
|
||||
clock_port_names, std::string(DEFAULT_CLOCK_NAME));
|
||||
print_verilog_testbench_clock_stimuli(fp, simulation_parameters,
|
||||
clock_port);
|
||||
print_verilog_testbench_random_stimuli(fp, L_logical_blocks,
|
||||
std::string(CHECKFLAG_PORT_POSTFIX), clock_port);
|
||||
|
||||
print_verilog_testbench_check(fp,
|
||||
std::string(autochecked_simulation_flag),
|
||||
|
|
|
@ -422,6 +422,7 @@ void print_verilog_preconfig_top_module(const ModuleManager& module_manager,
|
|||
L_logical_blocks, device_size, L_grids,
|
||||
L_blocks,
|
||||
std::string(formal_verification_top_module_port_postfix),
|
||||
std::string(formal_verification_top_module_port_postfix),
|
||||
(size_t)verilog_default_signal_init_value);
|
||||
|
||||
/* Assign FPGA internal SRAM/Memory ports to bitstream values */
|
||||
|
|
|
@ -108,7 +108,8 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
|
|||
const vtr::Point<size_t>& device_size,
|
||||
const std::vector<std::vector<t_grid_tile>>& L_grids,
|
||||
const std::vector<t_block>& L_blocks,
|
||||
const std::string& io_port_name_postfix,
|
||||
const std::string& io_input_port_name_postfix,
|
||||
const std::string& io_output_port_name_postfix,
|
||||
const size_t& unused_io_value) {
|
||||
/* Validate the file stream */
|
||||
check_file_handler(fp);
|
||||
|
@ -140,14 +141,21 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
|
|||
VTR_ASSERT(io_index < module_mapped_io_port.get_width());
|
||||
module_mapped_io_port.set_width(io_index, io_index);
|
||||
|
||||
/* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1 */
|
||||
BasicPort benchmark_io_port(std::string(std::string(io_lb.name)+ io_port_name_postfix), 1);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Blif Benchmark inout " + std::string(io_lb.name) + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----"));
|
||||
/* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1
|
||||
* In addition, the input and output ports may have different postfix in naming
|
||||
* due to verification context! Here, we give full customization on naming
|
||||
*/
|
||||
BasicPort benchmark_io_port;
|
||||
if (VPACK_INPAD == io_lb.type) {
|
||||
benchmark_io_port.set_name(std::string(std::string(io_lb.name) + io_input_port_name_postfix));
|
||||
benchmark_io_port.set_width(1);
|
||||
print_verilog_comment(fp, std::string("----- Blif Benchmark input " + std::string(io_lb.name) + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----"));
|
||||
print_verilog_wire_connection(fp, module_mapped_io_port, benchmark_io_port, false);
|
||||
} else {
|
||||
VTR_ASSERT(VPACK_OUTPAD == io_lb.type);
|
||||
benchmark_io_port.set_name(std::string(std::string(io_lb.name) + io_output_port_name_postfix));
|
||||
benchmark_io_port.set_width(1);
|
||||
print_verilog_comment(fp, std::string("----- Blif Benchmark output " + std::string(io_lb.name) + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----"));
|
||||
print_verilog_wire_connection(fp, benchmark_io_port, module_mapped_io_port, false);
|
||||
}
|
||||
|
||||
|
@ -336,33 +344,51 @@ void print_verilog_testbench_check(std::fstream& fp,
|
|||
}
|
||||
|
||||
/********************************************************************
|
||||
* Generate random stimulus for the input ports
|
||||
* Generate random stimulus for the clock port
|
||||
* This function is designed to drive the clock port of a benchmark module
|
||||
* If there is no clock port found, we will give a default clock name
|
||||
* In such case, this clock will not be wired to the benchmark module
|
||||
* but be only used as a synchronizer in verification
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||
const t_spice_params& simulation_parameters,
|
||||
const std::vector<t_logical_block>& L_logical_blocks,
|
||||
const std::string& check_flag_port_postfix,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const std::string& default_clock_name) {
|
||||
void print_verilog_testbench_clock_stimuli(std::fstream& fp,
|
||||
const t_spice_params& simulation_parameters,
|
||||
const BasicPort& clock_port) {
|
||||
/* Validate the file stream */
|
||||
check_file_handler(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Initialization -------"));
|
||||
print_verilog_comment(fp, std::string("----- Clock Initialization -------"));
|
||||
|
||||
fp << "\tinitial begin" << std::endl;
|
||||
/* Create clock stimuli */
|
||||
BasicPort clock_port = generate_verilog_testbench_clock_port(clock_port_names, default_clock_name);
|
||||
fp << "\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, clock_port) << " <= 1'b0;" << std::endl;
|
||||
fp << "\t\twhile(1) begin" << std::endl;
|
||||
fp << "\t\t\t#" << std::setprecision(2) << ((0.5/simulation_parameters.stimulate_params.op_clock_freq)/verilog_sim_timescale) << std::endl;
|
||||
fp << "\t\t\t#" << std::setprecision(10) << ((0.5/simulation_parameters.stimulate_params.op_clock_freq)/verilog_sim_timescale) << std::endl;
|
||||
fp << "\t\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, clock_port);
|
||||
fp << " <= !";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, clock_port);
|
||||
fp << ";" << std::endl;
|
||||
fp << "\t\tend" << std::endl;
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
|
||||
/* Add an empty line as splitter */
|
||||
fp << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Generate random stimulus for the input ports (non-clock signals)
|
||||
* For clock signals, please use print_verilog_testbench_clock_stimuli
|
||||
*******************************************************************/
|
||||
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||
const std::vector<t_logical_block>& L_logical_blocks,
|
||||
const std::string& check_flag_port_postfix,
|
||||
const BasicPort& clock_port) {
|
||||
/* Validate the file stream */
|
||||
check_file_handler(fp);
|
||||
|
||||
print_verilog_comment(fp, std::string("----- Input Initialization -------"));
|
||||
|
||||
fp << "\tinitial begin" << std::endl;
|
||||
|
||||
for (const t_logical_block& lb : L_logical_blocks) {
|
||||
/* Bypass non-I/O logical blocks ! */
|
||||
|
|
|
@ -29,7 +29,8 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
|
|||
const vtr::Point<size_t>& device_size,
|
||||
const std::vector<std::vector<t_grid_tile>>& L_grids,
|
||||
const std::vector<t_block>& L_blocks,
|
||||
const std::string& io_port_name_postfix,
|
||||
const std::string& io_input_port_name_postfix,
|
||||
const std::string& io_output_port_name_postfix,
|
||||
const size_t& unused_io_value);
|
||||
|
||||
void print_verilog_timeout_and_vcd(std::fstream& fp,
|
||||
|
@ -54,11 +55,13 @@ void print_verilog_testbench_check(std::fstream& fp,
|
|||
const std::vector<std::string>& clock_port_names,
|
||||
const std::string& default_clock_name);
|
||||
|
||||
void print_verilog_testbench_clock_stimuli(std::fstream& fp,
|
||||
const t_spice_params& simulation_parameters,
|
||||
const BasicPort& clock_port);
|
||||
|
||||
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||
const t_spice_params& simulation_parameters,
|
||||
const std::vector<t_logical_block>& L_logical_blocks,
|
||||
const std::string& check_flag_port_postfix,
|
||||
const std::vector<std::string>& clock_port_names,
|
||||
const std::string& default_clock_name);
|
||||
const BasicPort& clock_port);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,12 +29,10 @@
|
|||
constexpr char* TOP_TESTBENCH_REFERENCE_INSTANCE_NAME = "REF_DUT";
|
||||
constexpr char* TOP_TESTBENCH_FPGA_INSTANCE_NAME = "FPGA_DUT";
|
||||
constexpr char* TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX = "_benchmark";
|
||||
constexpr char* TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX = "_verification";
|
||||
constexpr char* TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX = "_fpga";
|
||||
|
||||
constexpr char* TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX = "_flag";
|
||||
|
||||
constexpr char* TOP_TESTBENCH_CONFIG_CHAIN_HEAD_PORT_NAME = "cc_in";
|
||||
constexpr char* TOP_TESTBENCH_CONFIG_CHAIN_TAIL_PORT_NAME = "cc_out";
|
||||
constexpr char* TOP_TESTBENCH_CC_PROG_TASK_NAME = "prog_cycle_task";
|
||||
|
||||
constexpr char* TOP_TESTBENCH_SIM_START_PORT_NAME = "sim_start";
|
||||
|
@ -52,13 +50,13 @@ void print_verilog_top_testbench_config_chain_port(std::fstream& fp) {
|
|||
|
||||
/* Print the head of configuraion-chains here */
|
||||
print_verilog_comment(fp, std::string("---- Configuration-chain head -----"));
|
||||
BasicPort config_chain_head_port(std::string(TOP_TESTBENCH_CONFIG_CHAIN_HEAD_PORT_NAME), 1);
|
||||
BasicPort config_chain_head_port(generate_configuration_chain_head_name(), 1);
|
||||
fp << generate_verilog_port(VERILOG_PORT_REG, config_chain_head_port) << ";" << std::endl;
|
||||
|
||||
/* Print the tail of configuration-chains here */
|
||||
print_verilog_comment(fp, std::string("---- Configuration-chain tail -----"));
|
||||
BasicPort config_chain_tail_port(std::string(TOP_TESTBENCH_CONFIG_CHAIN_TAIL_PORT_NAME), 1);
|
||||
fp << generate_verilog_port(VERILOG_PORT_REG, config_chain_tail_port) << ";" << std::endl;
|
||||
BasicPort config_chain_tail_port(generate_configuration_chain_tail_name(), 1);
|
||||
fp << generate_verilog_port(VERILOG_PORT_WIRE, config_chain_tail_port) << ";" << std::endl;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -411,8 +409,8 @@ void print_verilog_top_testbench_load_bitstream_task_configuration_chain(std::fs
|
|||
check_file_handler(fp);
|
||||
|
||||
BasicPort prog_clock_port(std::string(top_tb_prog_clock_port_name), 1);
|
||||
BasicPort cc_head_port(std::string(TOP_TESTBENCH_CONFIG_CHAIN_HEAD_PORT_NAME), 1);
|
||||
BasicPort cc_head_value(std::string(TOP_TESTBENCH_CONFIG_CHAIN_HEAD_PORT_NAME) + std::string("_val"), 1);
|
||||
BasicPort cc_head_port(generate_configuration_chain_head_name(), 1);
|
||||
BasicPort cc_head_value(generate_configuration_chain_head_name() + std::string("_val"), 1);
|
||||
|
||||
/* Add an empty line as splitter */
|
||||
fp << std::endl;
|
||||
|
@ -425,8 +423,12 @@ void print_verilog_top_testbench_load_bitstream_task_configuration_chain(std::fs
|
|||
fp << generate_verilog_port(VERILOG_PORT_INPUT, cc_head_value) << ";" << std::endl;
|
||||
fp << "\tbegin" << std::endl;
|
||||
fp << "\t\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ");" << std::endl;
|
||||
fp << "\t\t";
|
||||
print_verilog_wire_connection(fp, cc_head_port, cc_head_value, false);
|
||||
fp << "\t\t\t";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, cc_head_port);
|
||||
fp << " = ";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, cc_head_value);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
fp << "endtask" << std::endl;
|
||||
|
||||
|
@ -499,7 +501,7 @@ void print_verilog_top_testbench_generic_stimulus(std::fstream& fp,
|
|||
print_verilog_comment(fp, "----- Begin configuration done signal generation -----");
|
||||
print_verilog_pulse_stimuli(fp, config_done_port,
|
||||
0, /* Initial value */
|
||||
num_config_clock_cycles * prog_clock_period / timescale, 1);
|
||||
num_config_clock_cycles * prog_clock_period / timescale, 0);
|
||||
print_verilog_comment(fp, "----- End configuration done signal generation -----");
|
||||
fp << std::endl;
|
||||
|
||||
|
@ -616,7 +618,7 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp,
|
|||
* We do not care the value of scan_chain head during the first programming cycle
|
||||
* It is reset anyway
|
||||
*/
|
||||
BasicPort config_chain_head_port(std::string(TOP_TESTBENCH_CONFIG_CHAIN_HEAD_PORT_NAME), 1);
|
||||
BasicPort config_chain_head_port(generate_configuration_chain_head_name(), 1);
|
||||
std::vector<size_t> initial_values(config_chain_head_port.get_width(), 0);
|
||||
|
||||
print_verilog_comment(fp, "----- Begin bitstream loading during configuration phase -----");
|
||||
|
@ -636,6 +638,19 @@ void print_verilog_top_testbench_configuration_chain_bitstream(std::fstream& fp,
|
|||
fp << "\t\t" << std::string(TOP_TESTBENCH_CC_PROG_TASK_NAME);
|
||||
fp << "(1'b" << (size_t)bitstream_manager.bit_value(bit_id) << ");" << std::endl;
|
||||
}
|
||||
|
||||
/* Raise the flag of configuration done when bitstream loading is complete */
|
||||
BasicPort prog_clock_port(std::string(top_tb_prog_clock_port_name), 1);
|
||||
fp << "\t\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, prog_clock_port) << ");" << std::endl;
|
||||
|
||||
BasicPort config_done_port(std::string(top_tb_config_done_port_name), 1);
|
||||
fp << "\t\t\t";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, config_done_port);
|
||||
fp << " <= ";
|
||||
std::vector<size_t> config_done_enable_values(config_done_port.get_width(), 1);
|
||||
fp << generate_verilog_constant_values(config_done_enable_values);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
print_verilog_comment(fp, "----- End bitstream loading during configuration phase -----");
|
||||
}
|
||||
|
@ -767,6 +782,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module,
|
||||
L_logical_blocks, device_size, L_grids,
|
||||
L_blocks,
|
||||
std::string(),
|
||||
std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX),
|
||||
(size_t)verilog_default_signal_init_value);
|
||||
|
||||
|
@ -786,9 +802,9 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
|||
std::vector<std::string> clock_port_names = find_benchmark_clock_port_name(L_logical_blocks);
|
||||
|
||||
/* Add stimuli for reset, set, clock and iopad signals */
|
||||
print_verilog_testbench_random_stimuli(fp, simulation_parameters, L_logical_blocks,
|
||||
print_verilog_testbench_random_stimuli(fp, L_logical_blocks,
|
||||
std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX),
|
||||
clock_port_names, std::string(top_tb_op_clock_port_name));
|
||||
BasicPort(std::string(top_tb_op_clock_port_name), 1));
|
||||
|
||||
/* Add output autocheck */
|
||||
print_verilog_testbench_check(fp,
|
||||
|
|
|
@ -1234,13 +1234,17 @@ void print_verilog_pulse_stimuli(std::fstream& fp,
|
|||
fp << "\tbegin" << std::endl;
|
||||
fp << "\t";
|
||||
std::vector<size_t> initial_values(port.get_width(), initial_value);
|
||||
print_verilog_wire_constant_values(fp, port, initial_values);
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(port, initial_values);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
/* if flip_value is the same as initial value, we do not need to flip the signal ! */
|
||||
if (flip_value != initial_value) {
|
||||
fp << "\t" << "#" << std::setprecision(2) << pulse_width;
|
||||
fp << "\t" << "#" << std::setprecision(10) << pulse_width;
|
||||
std::vector<size_t> port_flip_values(port.get_width(), flip_value);
|
||||
print_verilog_wire_constant_values(fp, port, port_flip_values);
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(port, port_flip_values);
|
||||
fp << ";" << std::endl;
|
||||
}
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
|
@ -1274,7 +1278,9 @@ void print_verilog_pulse_stimuli(std::fstream& fp,
|
|||
fp << "\tbegin" << std::endl;
|
||||
fp << "\t";
|
||||
std::vector<size_t> initial_values(port.get_width(), initial_value);
|
||||
print_verilog_wire_constant_values(fp, port, initial_values);
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(port, initial_values);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
/* Set a wait condition if specified */
|
||||
if (false == wait_condition.empty()) {
|
||||
|
@ -1284,9 +1290,11 @@ void print_verilog_pulse_stimuli(std::fstream& fp,
|
|||
/* Number of flip conditions and values should match */
|
||||
VTR_ASSERT(flip_values.size() == pulse_widths.size());
|
||||
for (size_t ipulse = 0; ipulse < pulse_widths.size(); ++ipulse) {
|
||||
fp << "\t" << "#" << std::setprecision(2) << pulse_widths[ipulse];
|
||||
fp << "\t" << "#" << std::setprecision(10) << pulse_widths[ipulse];
|
||||
std::vector<size_t> port_flip_value(port.get_width(), flip_values[ipulse]);
|
||||
print_verilog_wire_constant_values(fp, port, port_flip_value);
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port_constant_values(port, port_flip_value);
|
||||
fp << ";" << std::endl;
|
||||
}
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
|
@ -1318,9 +1326,12 @@ void print_verilog_clock_stimuli(std::fstream& fp,
|
|||
/* Config_done signal: indicate when configuration is finished */
|
||||
fp << "initial" << std::endl;
|
||||
fp << "\tbegin" << std::endl;
|
||||
fp << "\t";
|
||||
|
||||
std::vector<size_t> initial_values(port.get_width(), initial_value);
|
||||
print_verilog_wire_constant_values(fp, port, initial_values);
|
||||
fp << "\t\t";
|
||||
fp << generate_verilog_port_constant_values(port, initial_values);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
fp << "always";
|
||||
|
||||
|
@ -1332,8 +1343,15 @@ void print_verilog_clock_stimuli(std::fstream& fp,
|
|||
}
|
||||
|
||||
fp << "\tbegin" << std::endl;
|
||||
fp << "\t\t" << "#" << std::setprecision(2) << pulse_width;
|
||||
print_verilog_wire_connection(fp, port, port, true);
|
||||
fp << "\t\t" << "#" << std::setprecision(10) << pulse_width;
|
||||
|
||||
fp << "\t";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, port);
|
||||
fp << " = ";
|
||||
fp << "~";
|
||||
fp << generate_verilog_port(VERILOG_PORT_CONKT, port);
|
||||
fp << ";" << std::endl;
|
||||
|
||||
fp << "\tend" << std::endl;
|
||||
|
||||
/* Print an empty line as splitter */
|
||||
|
|
Loading…
Reference in New Issue