[FPGA-Verilog] Adding bus group support to all Verilog testbench generators
This commit is contained in:
parent
c96f0d199d
commit
6da0ede9b0
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue