[Tool] Bug fix for testbench generation without self checking codes

This commit is contained in:
tangxifan 2021-06-29 16:27:29 -06:00
parent cbea4a3cb6
commit b83eef47b4
5 changed files with 53 additions and 32 deletions

View File

@ -84,7 +84,7 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell<Openfpg
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING);
/* add an option '--reference_benchmark_file_path'*/
CommandOptionId ref_bm_opt = shell_cmd.add_option("reference_benchmark_file_path", true, "specify the file path to the reference verilog netlist");
CommandOptionId ref_bm_opt = shell_cmd.add_option("reference_benchmark_file_path", false, "specify the file path to the reference verilog netlist. If specified, the testbench will include self-checking codes");
shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING);
/* add an option '--fast_configuration' */

View File

@ -334,7 +334,8 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
pin_constraints,
clock_port_names,
std::string(CHECKFLAG_PORT_POSTFIX),
clock_ports);
clock_ports,
options.no_self_checking());
if (!options.no_self_checking()) {
print_verilog_testbench_check(fp,
@ -359,7 +360,8 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
std::string(circuit_name + std::string("_formal.vcd")),
std::string(FORMAL_TB_SIM_START_PORT_NAME),
std::string(ERROR_COUNTER),
simulation_time);
simulation_time,
options.no_self_checking());
/* Testbench ends*/
print_verilog_module_end(fp, std::string(circuit_name) + std::string(FORMAL_RANDOM_TOP_TESTBENCH_POSTFIX));

View File

@ -304,7 +304,8 @@ void print_verilog_timeout_and_vcd(std::fstream& fp,
const std::string& vcd_fname,
const std::string& simulation_start_counter_name,
const std::string& error_counter_name,
const float& simulation_time) {
const float& simulation_time,
const bool& no_self_checking) {
/* Validate the file stream */
valid_file_stream(fp);
@ -323,16 +324,27 @@ void print_verilog_timeout_and_vcd(std::fstream& fp,
BasicPort sim_start_port(simulation_start_counter_name, 1);
fp << "initial begin" << std::endl;
fp << "\t" << generate_verilog_port(VERILOG_PORT_CONKT, sim_start_port) << " <= 1'b1;" << std::endl;
if (!no_self_checking) {
fp << "\t" << generate_verilog_port(VERILOG_PORT_CONKT, sim_start_port) << " <= 1'b1;" << std::endl;
}
fp << "\t$timeformat(-9, 2, \"ns\", 20);" << std::endl;
fp << "\t$display(\"Simulation start\");" << std::endl;
print_verilog_comment(fp, std::string("----- Can be changed by the user for his/her need -------"));
fp << "\t#" << std::setprecision(10) << simulation_time << std::endl;
fp << "\tif(" << error_counter_name << " == 0) begin" << std::endl;
fp << "\t\t$display(\"Simulation Succeed\");" << std::endl;
fp << "\tend else begin" << std::endl;
fp << "\t\t$display(\"Simulation Failed with " << std::string("%d") << " error(s)\", " << error_counter_name << ");" << std::endl;
fp << "\tend" << std::endl;
if (!no_self_checking) {
fp << "\tif(" << error_counter_name << " == 0) begin" << std::endl;
fp << "\t\t$display(\"Simulation Succeed\");" << std::endl;
fp << "\tend else begin" << std::endl;
fp << "\t\t$display(\"Simulation Failed with " << std::string("%d") << " error(s)\", " << error_counter_name << ");" << std::endl;
fp << "\tend" << std::endl;
} else {
VTR_ASSERT_SAFE(no_self_checking);
fp << "\t$display(\"Simulation Succeed\");" << std::endl;
}
fp << "\t$finish;" << std::endl;
fp << "end" << std::endl;
@ -530,7 +542,8 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
const PinConstraints& pin_constraints,
const std::vector<std::string>& clock_port_names,
const std::string& check_flag_port_postfix,
const std::vector<BasicPort>& clock_ports) {
const std::vector<BasicPort>& clock_ports,
const bool& no_self_checking) {
/* Validate the file stream */
valid_file_stream(fp);
@ -569,25 +582,27 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
}
}
/* Add an empty line as splitter */
fp << std::endl;
/* Set 0 to registers for checking flags */
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* Bypass non-I/O atom blocks ! */
if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) {
continue;
}
if (!no_self_checking) {
/* Add an empty line as splitter */
fp << std::endl;
/* The block may be renamed as it contains special characters which violate Verilog syntax */
std::string block_name = atom_ctx.nlist.block_name(atom_blk);
if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk);
}
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* Bypass non-I/O atom blocks ! */
if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) {
continue;
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1);
fp << "\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << " <= 1'b0;" << std::endl;
/* The block may be renamed as it contains special characters which violate Verilog syntax */
std::string block_name = atom_ctx.nlist.block_name(atom_blk);
if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk);
}
/* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1);
fp << "\t\t" << generate_verilog_port(VERILOG_PORT_CONKT, output_port) << " <= 1'b0;" << std::endl;
}
}
fp << "\tend" << std::endl;

View File

@ -56,7 +56,8 @@ void print_verilog_timeout_and_vcd(std::fstream& fp,
const std::string& vcd_fname,
const std::string& simulation_start_counter_name,
const std::string& error_counter_name,
const float& simulation_time);
const float& simulation_time,
const bool& no_self_checking);
std::vector<BasicPort> generate_verilog_testbench_clock_port(const std::vector<std::string>& clock_port_names,
const std::string& default_clock_name);
@ -85,7 +86,8 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
const PinConstraints& pin_constraints,
const std::vector<std::string>& clock_port_names,
const std::string& check_flag_port_postfix,
const std::vector<BasicPort>& clock_ports);
const std::vector<BasicPort>& clock_ports,
const bool& no_self_checking);
void print_verilog_testbench_shared_ports(std::fstream& fp,
const AtomContext& atom_ctx,

View File

@ -2038,7 +2038,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
pin_constraints,
clock_port_names,
std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX),
std::vector<BasicPort>(1, BasicPort(std::string(TOP_TB_OP_CLOCK_PORT_NAME), 1)));
std::vector<BasicPort>(1, BasicPort(std::string(TOP_TB_OP_CLOCK_PORT_NAME), 1)),
options.no_self_checking());
if (!options.no_self_checking()) {
/* Add output autocheck */
@ -2075,7 +2076,8 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
std::string(circuit_name + std::string("_formal.vcd")),
std::string(TOP_TESTBENCH_SIM_START_PORT_NAME),
std::string(TOP_TESTBENCH_ERROR_COUNTER),
std::ceil(simulation_time));
std::ceil(simulation_time),
options.no_self_checking());
/* Testbench ends*/