[FPGA-Verilog] Adding bus group support to all Verilog testbench generators

This commit is contained in:
tangxifan 2022-02-17 23:48:44 -08:00
parent c96f0d199d
commit 6da0ede9b0
9 changed files with 80 additions and 17 deletions

View File

@ -211,6 +211,7 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
CommandOptionId opt_bgf = cmd.option("bus_group_file");
CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path");
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
@ -240,10 +241,17 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx,
if (true == cmd_context.option_enable(cmd, opt_pcf)) {
pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str());
}
/* If bug group file are enabled by command options, read the file */
BusGroup bus_group;
if (true == cmd_context.option_enable(cmd, opt_bgf)) {
bus_group = read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str());
}
return fpga_verilog_preconfigured_testbench(openfpga_ctx.module_graph(),
g_vpr_ctx.atom(),
pin_constraints,
bus_group,
openfpga_ctx.fabric_global_port_info(),
openfpga_ctx.vpr_netlist_annotation(),
openfpga_ctx.simulation_setting(),

View File

@ -220,6 +220,11 @@ ShellCommandId add_openfpga_write_preconfigured_testbench_command(openfpga::Shel
shell_cmd.set_option_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING);
/* add an option '--bus_group_file in short '-bgf' */
CommandOptionId bgf_opt = shell_cmd.add_option("bus_group_file", false, "specify the file path to the group pins to bus");
shell_cmd.set_option_short_name(bgf_opt, "bgf");
shell_cmd.set_option_require_value(bgf_opt, openfpga::OPT_STRING);
/* Add an option '--reference_benchmark_file_path'*/
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);

View File

@ -261,6 +261,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
const AtomContext &atom_ctx,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation,
const SimulationSetting &simulation_setting,
@ -286,6 +287,7 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
module_manager,
fabric_global_port_info,
pin_constraints,
bus_group,
simulation_setting,
options);

View File

@ -79,6 +79,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
const AtomContext &atom_ctx,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation,
const SimulationSetting &simulation_setting,

View File

@ -109,6 +109,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& explicit_port_mapping) {
/* Validate the file stream */
valid_file_stream(fp);
@ -132,6 +133,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
std::vector<std::string>(),
atom_ctx, netlist_annotation,
pin_constraints,
bus_group,
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -149,6 +151,7 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& explicit_port_mapping) {
/* Validate the file stream */
valid_file_stream(fp);
@ -172,6 +175,7 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp,
std::vector<std::string>(),
atom_ctx, netlist_annotation,
pin_constraints,
bus_group,
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End FPGA Fabric Instanication -------"));
@ -288,6 +292,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
const ModuleManager& module_manager,
const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const SimulationSetting& simulation_parameters,
const VerilogTestbenchOption &options) {
std::string timer_message = std::string("Write configuration-skip testbench for FPGA top-level Verilog netlist implemented by '") + circuit_name.c_str() + std::string("'");
@ -316,6 +321,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
print_verilog_random_testbench_fpga_instance(fp, circuit_name,
atom_ctx, netlist_annotation,
pin_constraints,
bus_group,
options.explicit_port_mapping());
/* Call defined benchmark */
@ -323,6 +329,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name,
atom_ctx, netlist_annotation,
pin_constraints,
bus_group,
options.explicit_port_mapping());
}

View File

@ -11,6 +11,7 @@
#include "fabric_global_port_info.h"
#include "simulation_setting.h"
#include "verilog_testbench_options.h"
#include "bus_group.h"
/********************************************************************
* Function declaration
@ -26,6 +27,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
const ModuleManager& module_manager,
const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const SimulationSetting& simulation_parameters,
const VerilogTestbenchOption &options);

View File

@ -85,13 +85,17 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& use_explicit_port_map) {
/* Validate the file stream */
valid_file_stream(fp);
fp << "\t" << module_name << " " << instance_name << "(" << std::endl;
size_t port_counter = 0;
/* Consider all the unique port names */
std::vector<std::string> port_names;
std::vector<AtomBlockType> port_types;
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* Bypass non-I/O atom blocks ! */
if ( (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk))
@ -105,41 +109,70 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
block_name = netlist_annotation.block_name(atom_blk);
}
/* The first port does not need a comma */
if(0 < port_counter){
fp << "," << std::endl;
/* If the pin is part of a bus,
* - Check if the bus is already in the list
* - If not, add it to the port list
* - If yes, do nothing and move onto the next port
* If the pin does not belong to any bus
* - Add it to the bus port
*/
BusGroupId bus_id = bus_group.find_pin_bus(block_name);
if (bus_id) {
if (port_names.end() == std::find(port_names.begin(), port_names.end(), bus_group.bus_port(bus_id).get_name())) {
port_names.push_back(bus_group.bus_port(bus_id).get_name());
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
continue;
}
/* Input port follows the logical block name while output port requires a special postfix */
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
fp << "\t\t";
if (true == use_explicit_port_map) {
fp << "." << block_name << module_input_port_postfix << "(";
}
std::string port_name;
/* Polarity of some input may have to be inverted, as defined in pin constraints
* For example, the reset signal of the benchmark is active low
* while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/
if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(block_name)) {
fp << "~";
port_name += std::string("~");
}
/* For clock ports, skip postfix */
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
fp << block_name;
port_name += block_name;
} else {
fp << block_name << input_port_postfix;
port_name += block_name + input_port_postfix;
}
port_names.push_back(port_name);
} else {
VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk));
port_names.push_back(block_name);
}
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
size_t port_counter = 0;
for (size_t iport = 0; iport < port_names.size(); ++iport) {
/* The first port does not need a comma */
if (0 < port_counter){
fp << "," << std::endl;
}
fp << "\t\t";
if (AtomBlockType::INPAD == port_types[iport]) {
if (true == use_explicit_port_map) {
fp << "." << port_names[iport] << module_input_port_postfix << "(";
}
fp << port_names[iport];
if (true == use_explicit_port_map) {
fp << ")";
}
} else {
VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk));
fp << "\t\t";
VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == port_types[iport]);
/* Note that VPR added a prefix "out_" or "out:" to the name of output blocks
* We can remove this when specified through input argument
*/
std::string output_block_name = block_name;
std::string output_block_name = port_names[iport];
for (const std::string& prefix_to_remove : output_port_prefix_to_remove) {
if (!prefix_to_remove.empty()) {
if (0 == output_block_name.find(prefix_to_remove)) {
@ -152,11 +185,12 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
if (true == use_explicit_port_map) {
fp << "." << output_block_name << module_output_port_postfix << "(";
}
fp << block_name << output_port_postfix;
fp << port_names[iport] << output_port_postfix;
if (true == use_explicit_port_map) {
fp << ")";
}
}
}
/* Update the counter */
port_counter++;
}

View File

@ -45,6 +45,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& use_explicit_port_map);
void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,

View File

@ -937,6 +937,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::vector<std::string>& clock_port_names,
const bool& explicit_port_mapping) {
/* Validate the file stream */
@ -961,6 +962,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
clock_port_names,
atom_ctx, netlist_annotation,
pin_constraints,
bus_group,
explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -2080,6 +2082,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
atom_ctx,
netlist_annotation,
pin_constraints,
bus_group,
clock_port_names,
explicit_port_mapping);
}