This commit is contained in:
alaindargelas 2024-03-05 10:15:01 -08:00
commit fcaaba0e55
3 changed files with 177 additions and 160 deletions

View File

@ -41,6 +41,8 @@ int pcf2place(const PcfData& pcf_data,
VTR_LOG("PCF basic check passed\n"); VTR_LOG("PCF basic check passed\n");
} }
/* Map from location to net */
std::map<std::array<size_t, 3>, std::string> net_map;
/* Build the I/O place */ /* Build the I/O place */
for (const PcfIoConstraintId& io_id : pcf_data.io_constraints()) { for (const PcfIoConstraintId& io_id : pcf_data.io_constraints()) {
/* Find the net name */ /* Find the net name */
@ -102,6 +104,20 @@ int pcf2place(const PcfData& pcf_data,
continue; continue;
} }
std::array<size_t, 3> loc = {x, y, z};
auto itr = net_map.find(loc);
if (itr == net_map.end()) {
net_map.insert({loc, net});
} else {
VTR_LOG_ERROR(
"Illegal pin constraint: Two nets '%s' and '%s' are mapped to the I/O "
"pin '%s[%lu]' which belongs to the same coordinate (%ld, %ld, %ld)!\n",
itr->second.c_str(), net.c_str(), int_pin.get_name().c_str(),
int_pin.get_lsb(), x, y, z);
num_err++;
continue;
}
/* Add a fixed prefix to net namei, this is hard coded by VPR */ /* Add a fixed prefix to net namei, this is hard coded by VPR */
if (IoPinTable::OUTPUT == pin_direction) { if (IoPinTable::OUTPUT == pin_direction) {
net = "out:" + net; net = "out:" + net;

View File

@ -35,16 +35,16 @@ namespace openfpga {
); );
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_fpga_instance( void print_verilog_testbench_fpga_instance(
std::fstream& fp, const ModuleManager& module_manager, std::fstream& fp, const ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& core_module, const ModuleId& top_module, const ModuleId& core_module,
const std::string& top_instance_name, const std::string& net_postfix, const std::string& top_instance_name, const std::string& net_postfix,
const IoNameMap& io_name_map, const bool& explicit_port_mapping) { const IoNameMap& io_name_map, const bool& explicit_port_mapping) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
/* Include defined top-level module */ /* Include defined top-level module */
print_verilog_comment( print_verilog_comment(
fp, std::string("----- FPGA top-level module to be capsulated -----")); fp, std::string("----- FPGA top-level module to be capsulated -----"));
/* Precheck on the top module and decide if we need to consider I/O naming /* Precheck on the top module and decide if we need to consider I/O naming
* - If we do have a fpga_core module added, and dut is fpga_top, we need a * - If we do have a fpga_core module added, and dut is fpga_top, we need a
@ -68,7 +68,7 @@ void print_verilog_testbench_fpga_instance(
for (const ModulePortId& module_port_id : for (const ModulePortId& module_port_id :
module_manager.module_ports(top_module)) { module_manager.module_ports(top_module)) {
BasicPort module_port = BasicPort module_port =
module_manager.module_port(top_module, module_port_id); module_manager.module_port(top_module, module_port_id);
BasicPort net_port = module_port; BasicPort net_port = module_port;
net_port.set_name(module_port.get_name() + net_postfix); net_port.set_name(module_port.get_name() + net_postfix);
port2port_name_map[module_port.get_name()] = net_port; port2port_name_map[module_port.get_name()] = net_port;
@ -81,11 +81,11 @@ void print_verilog_testbench_fpga_instance(
for (const ModulePortId& module_port_id : for (const ModulePortId& module_port_id :
module_manager.module_ports(top_module)) { module_manager.module_ports(top_module)) {
BasicPort module_port = BasicPort module_port =
module_manager.module_port(top_module, module_port_id); module_manager.module_port(top_module, module_port_id);
/* Bypass dummy port: the port does not exist at core module */ /* Bypass dummy port: the port does not exist at core module */
if (io_name_map.fpga_top_port_is_dummy(module_port)) { if (io_name_map.fpga_top_port_is_dummy(module_port)) {
ModulePortId core_module_port = ModulePortId core_module_port = module_manager.find_module_port(
module_manager.find_module_port(core_module, module_port.get_name()); core_module, module_port.get_name());
if (!module_manager.valid_module_port_id(core_module, if (!module_manager.valid_module_port_id(core_module,
core_module_port)) { core_module_port)) {
/* Print the wire for the dummy port */ /* Print the wire for the dummy port */
@ -128,16 +128,17 @@ std::string escapeNames(const std::string& original) {
* Instanciate the input benchmark module * Instanciate the input benchmark module
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_benchmark_instance( void print_verilog_testbench_benchmark_instance(
std::fstream& fp, const std::string& module_name, std::fstream& fp, const std::string& module_name,
const std::string& instance_name, const std::string& instance_name,
const std::string& module_input_port_postfix, const std::string& module_input_port_postfix,
const std::string& module_output_port_postfix, const std::string& module_output_port_postfix,
const std::string& input_port_postfix, const std::string& output_port_postfix, const std::string& input_port_postfix,
const std::vector<std::string>& clock_port_names, const std::string& output_port_postfix,
const bool& include_clock_port_postfix, const AtomContext& atom_ctx, const std::vector<std::string>& clock_port_names,
const VprNetlistAnnotation& netlist_annotation, const bool& include_clock_port_postfix, const AtomContext& atom_ctx,
const PinConstraints& pin_constraints, const BusGroup& bus_group, const VprNetlistAnnotation& netlist_annotation,
const bool& use_explicit_port_map) { const PinConstraints& pin_constraints, const BusGroup& bus_group,
const bool& use_explicit_port_map) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -327,15 +328,15 @@ void print_verilog_testbench_benchmark_instance(
* by default * by default
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_connect_fpga_ios( void print_verilog_testbench_connect_fpga_ios(
std::fstream& fp, const ModuleManager& module_manager, std::fstream& fp, const ModuleManager& module_manager,
const ModuleId& top_module, const AtomContext& atom_ctx, const ModuleId& top_module, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const IoLocationMap& io_location_map, const PlacementContext& place_ctx, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, const BusGroup& bus_group, const VprNetlistAnnotation& netlist_annotation, const BusGroup& bus_group,
const std::string& net_name_postfix, const std::string& net_name_postfix,
const std::string& io_input_port_name_postfix, const std::string& io_input_port_name_postfix,
const std::string& io_output_port_name_postfix, const std::string& io_output_port_name_postfix,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const size_t& unused_io_value) { const size_t& unused_io_value) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -359,25 +360,25 @@ void print_verilog_testbench_connect_fpga_ios(
std::map<ModulePortId, std::vector<bool>> io_used; std::map<ModulePortId, std::vector<bool>> io_used;
for (const ModulePortId& module_io_port_id : module_io_ports) { for (const ModulePortId& module_io_port_id : module_io_ports) {
const BasicPort& module_io_port = const BasicPort& module_io_port =
module_manager.module_port(top_module, module_io_port_id); module_manager.module_port(top_module, module_io_port_id);
io_used[module_io_port_id] = io_used[module_io_port_id] =
std::vector<bool>(module_io_port.get_width(), false); std::vector<bool>(module_io_port.get_width(), false);
} }
/* Type mapping between VPR block and Module port */ /* Type mapping between VPR block and Module port */
std::map<AtomBlockType, ModuleManager::e_module_port_type> std::map<AtomBlockType, ModuleManager::e_module_port_type>
atom_block_type_to_module_port_type; atom_block_type_to_module_port_type;
atom_block_type_to_module_port_type[AtomBlockType::INPAD] = atom_block_type_to_module_port_type[AtomBlockType::INPAD] =
ModuleManager::MODULE_GPIN_PORT; ModuleManager::MODULE_GPIN_PORT;
atom_block_type_to_module_port_type[AtomBlockType::OUTPAD] = atom_block_type_to_module_port_type[AtomBlockType::OUTPAD] =
ModuleManager::MODULE_GPOUT_PORT; ModuleManager::MODULE_GPOUT_PORT;
/* See if this I/O should be wired to a benchmark input/output */ /* See if this I/O should be wired to a benchmark input/output */
/* Add signals from blif benchmark and short-wire them to FPGA I/O PADs /* Add signals from blif benchmark and short-wire them to FPGA I/O PADs
* This brings convenience to checking functionality * This brings convenience to checking functionality
*/ */
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Link BLIF Benchmark I/Os to FPGA I/Os -----")); fp, std::string("----- Link BLIF Benchmark I/Os to FPGA I/Os -----"));
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) { for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* Bypass non-I/O atom blocks ! */ /* Bypass non-I/O atom blocks ! */
@ -391,17 +392,17 @@ void print_verilog_testbench_connect_fpga_ios(
* or should find a GPOUT for OUTPAD * or should find a GPOUT for OUTPAD
*/ */
std::pair<ModulePortId, size_t> mapped_module_io_info = std::pair<ModulePortId, size_t> mapped_module_io_info =
std::make_pair(ModulePortId::INVALID(), -1); std::make_pair(ModulePortId::INVALID(), -1);
for (const ModulePortId& module_io_port_id : module_io_ports) { for (const ModulePortId& module_io_port_id : module_io_ports) {
const BasicPort& module_io_port = const BasicPort& module_io_port =
module_manager.module_port(top_module, module_io_port_id); module_manager.module_port(top_module, module_io_port_id);
/* Find the index of the mapped GPIO in top-level FPGA fabric */ /* Find the index of the mapped GPIO in top-level FPGA fabric */
size_t temp_io_index = io_location_map.io_index( size_t temp_io_index = io_location_map.io_index(
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.x,
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.y,
place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile, place_ctx.block_locs[atom_ctx.lookup.atom_clb(atom_blk)].loc.sub_tile,
module_io_port.get_name()); module_io_port.get_name());
/* Bypass invalid index (not mapped to this GPIO port) */ /* Bypass invalid index (not mapped to this GPIO port) */
if (size_t(-1) == temp_io_index) { if (size_t(-1) == temp_io_index) {
@ -412,28 +413,28 @@ void print_verilog_testbench_connect_fpga_ios(
if (ModuleManager::MODULE_GPIO_PORT == if (ModuleManager::MODULE_GPIO_PORT ==
module_manager.port_type(top_module, module_io_port_id)) { module_manager.port_type(top_module, module_io_port_id)) {
mapped_module_io_info = mapped_module_io_info =
std::make_pair(module_io_port_id, temp_io_index); std::make_pair(module_io_port_id, temp_io_index);
break; break;
} }
/* If this is an INPAD, we can use an GPIN port (if available) */ /* If this is an INPAD, we can use an GPIN port (if available) */
if (atom_block_type_to_module_port_type[atom_ctx.nlist.block_type( if (atom_block_type_to_module_port_type[atom_ctx.nlist.block_type(
atom_blk)] == atom_blk)] ==
module_manager.port_type(top_module, module_io_port_id)) { module_manager.port_type(top_module, module_io_port_id)) {
mapped_module_io_info = mapped_module_io_info =
std::make_pair(module_io_port_id, temp_io_index); std::make_pair(module_io_port_id, temp_io_index);
break; break;
} }
} }
/* We must find a valid one */ /* We must find a valid one */
VTR_ASSERT(true == module_manager.valid_module_port_id( VTR_ASSERT(true == module_manager.valid_module_port_id(
top_module, mapped_module_io_info.first)); top_module, mapped_module_io_info.first));
VTR_ASSERT(size_t(-1) != mapped_module_io_info.second); VTR_ASSERT(size_t(-1) != mapped_module_io_info.second);
/* Ensure that IO index is in range */ /* Ensure that IO index is in range */
BasicPort module_mapped_io_port = BasicPort module_mapped_io_port =
module_manager.module_port(top_module, mapped_module_io_info.first); module_manager.module_port(top_module, mapped_module_io_info.first);
size_t io_index = mapped_module_io_info.second; size_t io_index = mapped_module_io_info.second;
/* Set the port pin index */ /* Set the port pin index */
@ -483,24 +484,24 @@ void print_verilog_testbench_connect_fpga_ios(
benchmark_io_port.set_name(block_name); benchmark_io_port.set_name(block_name);
} else { } else {
benchmark_io_port.set_name( benchmark_io_port.set_name(
std::string(block_name + io_input_port_name_postfix)); std::string(block_name + io_input_port_name_postfix));
} }
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Blif Benchmark input " + block_name + fp, std::string("----- Blif Benchmark input " + block_name +
" is mapped to FPGA IOPAD " + " is mapped to FPGA IOPAD " +
module_mapped_io_port.get_name() + "[" + module_mapped_io_port.get_name() + "[" +
std::to_string(io_index) + "] -----")); std::to_string(io_index) + "] -----"));
print_verilog_wire_connection(fp, module_mapped_io_port, print_verilog_wire_connection(fp, module_mapped_io_port,
benchmark_io_port, false); benchmark_io_port, false);
} else { } else {
VTR_ASSERT(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)); VTR_ASSERT(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk));
benchmark_io_port.set_name( benchmark_io_port.set_name(
std::string(block_name + io_output_port_name_postfix)); std::string(block_name + io_output_port_name_postfix));
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Blif Benchmark output " + block_name + fp, std::string("----- Blif Benchmark output " + block_name +
" is mapped to FPGA IOPAD " + " is mapped to FPGA IOPAD " +
module_mapped_io_port.get_name() + "[" + module_mapped_io_port.get_name() + "[" +
std::to_string(io_index) + "] -----")); std::to_string(io_index) + "] -----"));
print_verilog_wire_connection(fp, benchmark_io_port, print_verilog_wire_connection(fp, benchmark_io_port,
module_mapped_io_port, false); module_mapped_io_port, false);
} }
@ -514,7 +515,7 @@ void print_verilog_testbench_connect_fpga_ios(
/* Wire the unused iopads to a constant */ /* Wire the unused iopads to a constant */
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Wire unused FPGA I/Os to constants -----")); fp, std::string("----- Wire unused FPGA I/Os to constants -----"));
for (const ModulePortId& module_io_port_id : module_io_ports) { for (const ModulePortId& module_io_port_id : module_io_ports) {
for (size_t io_index = 0; io_index < io_used[module_io_port_id].size(); for (size_t io_index = 0; io_index < io_used[module_io_port_id].size();
++io_index) { ++io_index) {
@ -531,7 +532,7 @@ void print_verilog_testbench_connect_fpga_ios(
/* Wire to a contant */ /* Wire to a contant */
BasicPort module_unused_io_port = BasicPort module_unused_io_port =
module_manager.module_port(top_module, module_io_port_id); module_manager.module_port(top_module, module_io_port_id);
/* Set the port pin index */ /* Set the port pin index */
module_unused_io_port.set_name(module_unused_io_port.get_name() + module_unused_io_port.set_name(module_unused_io_port.get_name() +
net_name_postfix); net_name_postfix);
@ -555,16 +556,16 @@ void print_verilog_testbench_connect_fpga_ios(
* Note that: these codes are tuned for Icarus simulator!!! * Note that: these codes are tuned for Icarus simulator!!!
*******************************************************************/ *******************************************************************/
void print_verilog_timeout_and_vcd( void print_verilog_timeout_and_vcd(
std::fstream& fp, const std::string& module_name, std::fstream& fp, const std::string& module_name,
const std::string& vcd_fname, const std::string& vcd_fname,
const std::string& simulation_start_counter_name, const std::string& simulation_start_counter_name,
const std::string& error_counter_name, const float& simulation_time, const std::string& error_counter_name, const float& simulation_time,
const bool& no_self_checking) { const bool& no_self_checking) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Begin output waveform to VCD file-------")); fp, std::string("----- Begin output waveform to VCD file-------"));
fp << "\tinitial begin" << std::endl; fp << "\tinitial begin" << std::endl;
fp << "\t\t$dumpfile(\"" << vcd_fname << "\");" << std::endl; fp << "\t\t$dumpfile(\"" << vcd_fname << "\");" << std::endl;
@ -572,7 +573,7 @@ void print_verilog_timeout_and_vcd(
fp << "\tend" << std::endl; fp << "\tend" << std::endl;
print_verilog_comment( print_verilog_comment(
fp, std::string("----- END output waveform to VCD file -------")); fp, std::string("----- END output waveform to VCD file -------"));
/* Add an empty line as splitter */ /* Add an empty line as splitter */
fp << std::endl; fp << std::endl;
@ -589,8 +590,8 @@ void print_verilog_timeout_and_vcd(
fp << "\t$timeformat(-9, 2, \"ns\", 20);" << std::endl; fp << "\t$timeformat(-9, 2, \"ns\", 20);" << std::endl;
fp << "\t$display(\"Simulation start\");" << std::endl; fp << "\t$display(\"Simulation start\");" << std::endl;
print_verilog_comment( print_verilog_comment(
fp, fp,
std::string("----- Can be changed by the user for his/her need -------")); std::string("----- Can be changed by the user for his/her need -------"));
fp << "\t#" << std::setprecision(10) << simulation_time << std::endl; fp << "\t#" << std::setprecision(10) << simulation_time << std::endl;
if (!no_self_checking) { if (!no_self_checking) {
@ -619,8 +620,8 @@ void print_verilog_timeout_and_vcd(
* Assume this is a single clock benchmark * Assume this is a single clock benchmark
*******************************************************************/ *******************************************************************/
std::vector<BasicPort> generate_verilog_testbench_clock_port( std::vector<BasicPort> generate_verilog_testbench_clock_port(
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const std::string& default_clock_name) { const std::string& default_clock_name) {
std::vector<BasicPort> clock_ports; std::vector<BasicPort> clock_ports;
if (0 == clock_port_names.size()) { if (0 == clock_port_names.size()) {
clock_ports.push_back(BasicPort(default_clock_name, 1)); clock_ports.push_back(BasicPort(default_clock_name, 1));
@ -639,23 +640,23 @@ std::vector<BasicPort> generate_verilog_testbench_clock_port(
* Restriction: this function only supports single clock benchmarks! * Restriction: this function only supports single clock benchmarks!
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_check( void print_verilog_testbench_check(
std::fstream& fp, const std::string& simulation_start_counter_name, std::fstream& fp, const std::string& simulation_start_counter_name,
const std::string& benchmark_port_postfix, const std::string& benchmark_port_postfix,
const std::string& fpga_port_postfix, const std::string& fpga_port_postfix,
const std::string& check_flag_port_postfix, const std::string& check_flag_port_postfix,
const std::string& config_done_name, const std::string& error_counter_name, const std::string& config_done_name, const std::string& error_counter_name,
const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const std::string& default_clock_name) { const std::string& default_clock_name) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
/* Add output autocheck */ /* Add output autocheck */
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Begin checking output vectors -------")); fp, std::string("----- Begin checking output vectors -------"));
std::vector<BasicPort> clock_ports = std::vector<BasicPort> clock_ports = generate_verilog_testbench_clock_port(
generate_verilog_testbench_clock_port(clock_port_names, default_clock_name); clock_port_names, default_clock_name);
print_verilog_comment(fp, print_verilog_comment(fp,
std::string("----- Skip the first falling edge of " std::string("----- Skip the first falling edge of "
@ -765,21 +766,21 @@ void print_verilog_testbench_check(
* but be only used as a synchronizer in verification * but be only used as a synchronizer in verification
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_clock_stimuli( void print_verilog_testbench_clock_stimuli(
std::fstream& fp, const PinConstraints& pin_constraints, std::fstream& fp, const PinConstraints& pin_constraints,
const SimulationSetting& simulation_parameters, const SimulationSetting& simulation_parameters,
const std::vector<BasicPort>& clock_ports) { const std::vector<BasicPort>& clock_ports) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
for (const BasicPort& clock_port : clock_ports) { for (const BasicPort& clock_port : clock_ports) {
print_verilog_comment(fp, std::string("----- Clock '") + print_verilog_comment(fp, std::string("----- Clock '") +
clock_port.get_name() + clock_port.get_name() +
std::string("' Initialization -------")); std::string("' Initialization -------"));
/* Find the corresponding clock frequency from the simulation parameters */ /* Find the corresponding clock frequency from the simulation parameters */
float clk_freq_to_use = float clk_freq_to_use =
(0.5 / simulation_parameters.default_operating_clock_frequency()) / (0.5 / simulation_parameters.default_operating_clock_frequency()) /
VERILOG_SIM_TIMESCALE; VERILOG_SIM_TIMESCALE;
/* Check pin constraints to see if this clock is constrained to a specific /* Check pin constraints to see if this clock is constrained to a specific
* pin If constrained, * pin If constrained,
* - connect this clock to default values if it is set to be OPEN * - connect this clock to default values if it is set to be OPEN
@ -801,8 +802,8 @@ void print_verilog_testbench_clock_stimuli(
if (pin_constraints.pin(pin_constraint) == if (pin_constraints.pin(pin_constraint) ==
simulation_parameters.clock_port(sim_clock_id)) { simulation_parameters.clock_port(sim_clock_id)) {
clk_freq_to_use = clk_freq_to_use =
(0.5 / simulation_parameters.clock_frequency(sim_clock_id)) / (0.5 / simulation_parameters.clock_frequency(sim_clock_id)) /
VERILOG_SIM_TIMESCALE; VERILOG_SIM_TIMESCALE;
} }
} }
} }
@ -831,15 +832,15 @@ void print_verilog_testbench_clock_stimuli(
* For clock signals, please use print_verilog_testbench_clock_stimuli * For clock signals, please use print_verilog_testbench_clock_stimuli
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_random_stimuli( void print_verilog_testbench_random_stimuli(
std::fstream& fp, const AtomContext& atom_ctx, std::fstream& fp, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const ModuleManager& module_manager, const ModuleNameMap& module_name_map, const ModuleManager& module_manager, const ModuleNameMap& module_name_map,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const std::string& input_port_postfix, const std::string& input_port_postfix,
const std::string& check_flag_port_postfix, const std::string& check_flag_port_postfix,
const std::vector<BasicPort>& clock_ports, const bool& no_self_checking) { const std::vector<BasicPort>& clock_ports, const bool& no_self_checking) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -875,8 +876,8 @@ void print_verilog_testbench_random_stimuli(
* fabric because their stimulus cannot be random * fabric because their stimulus cannot be random
*/ */
if (true == port_is_fabric_global_reset_port( if (true == port_is_fabric_global_reset_port(
global_ports, module_manager, module_name_map, global_ports, module_manager, module_name_map,
pin_constraints.net_pin(block_name))) { pin_constraints.net_pin(block_name))) {
continue; continue;
} }
@ -959,8 +960,8 @@ void print_verilog_testbench_random_stimuli(
* fabric because their stimulus cannot be random * fabric because their stimulus cannot be random
*/ */
if (true == port_is_fabric_global_reset_port( if (true == port_is_fabric_global_reset_port(
global_ports, module_manager, module_name_map, global_ports, module_manager, module_name_map,
pin_constraints.net_pin(block_name))) { pin_constraints.net_pin(block_name))) {
continue; continue;
} }
@ -985,14 +986,14 @@ void print_verilog_testbench_random_stimuli(
* same input vectors * same input vectors
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_shared_input_ports( void print_verilog_testbench_shared_input_ports(
std::fstream& fp, const ModuleManager& module_manager, std::fstream& fp, const ModuleManager& module_manager,
const ModuleNameMap& module_name_map, const ModuleNameMap& module_name_map,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const PinConstraints& pin_constraints, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const bool& include_clock_ports, const std::string& shared_input_port_postfix, const bool& include_clock_ports,
const bool& use_reg_port) { const std::string& shared_input_port_postfix, const bool& use_reg_port) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -1024,8 +1025,8 @@ void print_verilog_testbench_shared_input_ports(
BasicPort input_port(block_name + shared_input_port_postfix, 1); BasicPort input_port(block_name + shared_input_port_postfix, 1);
/* For global ports, use wires; otherwise, use registers*/ /* For global ports, use wires; otherwise, use registers*/
if (false == port_is_fabric_global_reset_port( if (false == port_is_fabric_global_reset_port(
global_ports, module_manager, module_name_map, global_ports, module_manager, module_name_map,
pin_constraints.net_pin(block_name))) { pin_constraints.net_pin(block_name))) {
if (use_reg_port) { if (use_reg_port) {
fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";" fp << "\t" << generate_verilog_port(VERILOG_PORT_REG, input_port) << ";"
<< std::endl; << std::endl;
@ -1049,9 +1050,9 @@ void print_verilog_testbench_shared_input_ports(
* 2. the output ports (wires) for FPGA fabric * 2. the output ports (wires) for FPGA fabric
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_shared_fpga_output_ports( void print_verilog_testbench_shared_fpga_output_ports(
std::fstream& fp, const AtomContext& atom_ctx, std::fstream& fp, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::string& fpga_output_port_postfix) { const std::string& fpga_output_port_postfix) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -1089,9 +1090,9 @@ void print_verilog_testbench_shared_fpga_output_ports(
* 2. the output ports (wires) for benchmark instance * 2. the output ports (wires) for benchmark instance
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_shared_benchmark_output_ports( void print_verilog_testbench_shared_benchmark_output_ports(
std::fstream& fp, const AtomContext& atom_ctx, std::fstream& fp, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::string& benchmark_output_port_postfix) { const std::string& benchmark_output_port_postfix) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -1113,7 +1114,7 @@ void print_verilog_testbench_shared_benchmark_output_ports(
/* Each logical block assumes a single-width port */ /* Each logical block assumes a single-width port */
BasicPort output_port( BasicPort output_port(
std::string(block_name + benchmark_output_port_postfix), 1); std::string(block_name + benchmark_output_port_postfix), 1);
fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";" fp << "\t" << generate_verilog_port(VERILOG_PORT_WIRE, output_port) << ";"
<< std::endl; << std::endl;
} }
@ -1132,15 +1133,15 @@ void print_verilog_testbench_shared_benchmark_output_ports(
* same input vectors * same input vectors
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_shared_check_flags( void print_verilog_testbench_shared_check_flags(
std::fstream& fp, const AtomContext& atom_ctx, std::fstream& fp, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::string& check_flag_port_postfix) { const std::string& check_flag_port_postfix) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
/* Instantiate register for output comparison */ /* Instantiate register for output comparison */
print_verilog_comment( print_verilog_comment(
fp, std::string("----- Output vectors checking flags -------")); fp, std::string("----- Output vectors checking flags -------"));
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) { for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* We care only those logic blocks which are output I/Os */ /* We care only those logic blocks which are output I/Os */
if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) { if (AtomBlockType::OUTPAD != atom_ctx.nlist.block_type(atom_blk)) {
@ -1175,30 +1176,30 @@ void print_verilog_testbench_shared_check_flags(
* same input vectors * same input vectors
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_shared_ports( void print_verilog_testbench_shared_ports(
std::fstream& fp, const ModuleManager& module_manager, std::fstream& fp, const ModuleManager& module_manager,
const ModuleNameMap& module_name_map, const ModuleNameMap& module_name_map,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints, const AtomContext& atom_ctx, const PinConstraints& pin_constraints, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const std::string& shared_input_port_postfix, const std::string& shared_input_port_postfix,
const std::string& benchmark_output_port_postfix, const std::string& benchmark_output_port_postfix,
const std::string& fpga_output_port_postfix, const std::string& fpga_output_port_postfix,
const std::string& check_flag_port_postfix, const bool& no_self_checking) { const std::string& check_flag_port_postfix, const bool& no_self_checking) {
print_verilog_testbench_shared_input_ports( print_verilog_testbench_shared_input_ports(
fp, module_manager, module_name_map, global_ports, pin_constraints, fp, module_manager, module_name_map, global_ports, pin_constraints,
atom_ctx, netlist_annotation, clock_port_names, false, atom_ctx, netlist_annotation, clock_port_names, false,
shared_input_port_postfix, true); shared_input_port_postfix, true);
print_verilog_testbench_shared_fpga_output_ports( print_verilog_testbench_shared_fpga_output_ports(
fp, atom_ctx, netlist_annotation, fpga_output_port_postfix); fp, atom_ctx, netlist_annotation, fpga_output_port_postfix);
if (no_self_checking) { if (no_self_checking) {
return; return;
} }
print_verilog_testbench_shared_benchmark_output_ports( print_verilog_testbench_shared_benchmark_output_ports(
fp, atom_ctx, netlist_annotation, benchmark_output_port_postfix); fp, atom_ctx, netlist_annotation, benchmark_output_port_postfix);
print_verilog_testbench_shared_check_flags(fp, atom_ctx, netlist_annotation, print_verilog_testbench_shared_check_flags(fp, atom_ctx, netlist_annotation,
check_flag_port_postfix); check_flag_port_postfix);
@ -1213,11 +1214,11 @@ void print_verilog_testbench_shared_ports(
* in the graph of modules * in the graph of modules
*******************************************************************/ *******************************************************************/
static void rec_print_verilog_testbench_primitive_module_signal_initialization( static void rec_print_verilog_testbench_primitive_module_signal_initialization(
std::fstream& fp, const std::string& hie_path, std::fstream& fp, const std::string& hie_path,
const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model, const CircuitLibrary& circuit_lib, const CircuitModelId& circuit_model,
const std::vector<CircuitPortId>& circuit_input_ports, const std::vector<CircuitPortId>& circuit_input_ports,
const ModuleManager& module_manager, const ModuleId& parent_module, const ModuleManager& module_manager, const ModuleId& parent_module,
const ModuleId& primitive_module, const bool& deposit_random_values) { const ModuleId& primitive_module, const bool& deposit_random_values) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -1235,20 +1236,20 @@ static void rec_print_verilog_testbench_primitive_module_signal_initialization(
for (const size_t& child_instance : for (const size_t& child_instance :
module_manager.child_module_instances(parent_module, child_module)) { module_manager.child_module_instances(parent_module, child_module)) {
std::string instance_name = module_manager.instance_name( std::string instance_name = module_manager.instance_name(
parent_module, child_module, child_instance); parent_module, child_module, child_instance);
/* Use default instanec name if not assigned */ /* Use default instanec name if not assigned */
if (true == instance_name.empty()) { if (true == instance_name.empty()) {
instance_name = generate_instance_name( instance_name = generate_instance_name(
module_manager.module_name(child_module), child_instance); module_manager.module_name(child_module), child_instance);
} }
std::string child_hie_path = hie_path + "." + instance_name; std::string child_hie_path = hie_path + "." + instance_name;
if (child_module != primitive_module) { if (child_module != primitive_module) {
rec_print_verilog_testbench_primitive_module_signal_initialization( rec_print_verilog_testbench_primitive_module_signal_initialization(
fp, child_hie_path, circuit_lib, circuit_model, circuit_input_ports, fp, child_hie_path, circuit_lib, circuit_model, circuit_input_ports,
module_manager, child_module, primitive_module, module_manager, child_module, primitive_module,
deposit_random_values); deposit_random_values);
} else { } else {
/* If the child module is the primitive module, /* If the child module is the primitive module,
* we output the signal initialization codes for the input ports * we output the signal initialization codes for the input ports
@ -1256,7 +1257,7 @@ static void rec_print_verilog_testbench_primitive_module_signal_initialization(
VTR_ASSERT_SAFE(child_module == primitive_module); VTR_ASSERT_SAFE(child_module == primitive_module);
print_verilog_comment( print_verilog_comment(
fp, std::string("------ BEGIN driver initialization -----")); fp, std::string("------ BEGIN driver initialization -----"));
fp << "\tinitial begin" << std::endl; fp << "\tinitial begin" << std::endl;
for (const auto& input_port : circuit_input_ports) { for (const auto& input_port : circuit_input_ports) {
@ -1282,7 +1283,7 @@ static void rec_print_verilog_testbench_primitive_module_signal_initialization(
fp << "\tend" << std::endl; fp << "\tend" << std::endl;
print_verilog_comment( print_verilog_comment(
fp, std::string("------ END driver initialization -----")); fp, std::string("------ END driver initialization -----"));
} }
} }
} }
@ -1296,9 +1297,9 @@ static void rec_print_verilog_testbench_primitive_module_signal_initialization(
* - Logic gates (ONLY for MUX2) * - Logic gates (ONLY for MUX2)
*******************************************************************/ *******************************************************************/
void print_verilog_testbench_signal_initialization( void print_verilog_testbench_signal_initialization(
std::fstream& fp, const std::string& top_instance_name, std::fstream& fp, const std::string& top_instance_name,
const CircuitLibrary& circuit_lib, const ModuleManager& module_manager, const CircuitLibrary& circuit_lib, const ModuleManager& module_manager,
const ModuleId& top_module, const bool& deposit_random_values) { const ModuleId& top_module, const bool& deposit_random_values) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -1307,7 +1308,7 @@ void print_verilog_testbench_signal_initialization(
/* Collect the input ports that require signal initialization */ /* Collect the input ports that require signal initialization */
std::map<CircuitModelId, std::vector<CircuitPortId>> std::map<CircuitModelId, std::vector<CircuitPortId>>
signal_init_circuit_ports; signal_init_circuit_ports;
for (const CircuitModelId& model : for (const CircuitModelId& model :
circuit_lib.models_by_type(CIRCUIT_MODEL_PASSGATE)) { circuit_lib.models_by_type(CIRCUIT_MODEL_PASSGATE)) {
@ -1316,7 +1317,7 @@ void print_verilog_testbench_signal_initialization(
* which is the first port, i.e., the datapath inputs * which is the first port, i.e., the datapath inputs
*/ */
std::vector<CircuitPortId> input_ports = std::vector<CircuitPortId> input_ports =
circuit_lib.model_input_ports(model); circuit_lib.model_input_ports(model);
VTR_ASSERT(0 < input_ports.size()); VTR_ASSERT(0 < input_ports.size());
signal_init_circuit_ports[model].push_back(input_ports[0]); signal_init_circuit_ports[model].push_back(input_ports[0]);
} }
@ -1329,7 +1330,7 @@ void print_verilog_testbench_signal_initialization(
* which is the first two port, i.e., the datapath inputs * which is the first two port, i.e., the datapath inputs
*/ */
std::vector<CircuitPortId> input_ports = std::vector<CircuitPortId> input_ports =
circuit_lib.model_input_ports(model); circuit_lib.model_input_ports(model);
VTR_ASSERT(1 < input_ports.size()); VTR_ASSERT(1 < input_ports.size());
signal_init_circuit_ports[model].push_back(input_ports[0]); signal_init_circuit_ports[model].push_back(input_ports[0]);
signal_init_circuit_ports[model].push_back(input_ports[1]); signal_init_circuit_ports[model].push_back(input_ports[1]);
@ -1348,14 +1349,14 @@ void print_verilog_testbench_signal_initialization(
/* Find the module id corresponding to the circuit model from module graph /* Find the module id corresponding to the circuit model from module graph
*/ */
ModuleId primitive_module = module_manager.find_module( ModuleId primitive_module = module_manager.find_module(
circuit_lib.model_name(signal_init_circuit_model)); circuit_lib.model_name(signal_init_circuit_model));
VTR_ASSERT(true == module_manager.valid_module_id(primitive_module)); VTR_ASSERT(true == module_manager.valid_module_id(primitive_module));
/* Find all the instances created by the circuit model across the fabric*/ /* Find all the instances created by the circuit model across the fabric*/
rec_print_verilog_testbench_primitive_module_signal_initialization( rec_print_verilog_testbench_primitive_module_signal_initialization(
fp, top_instance_name, circuit_lib, signal_init_circuit_model, fp, top_instance_name, circuit_lib, signal_init_circuit_model,
signal_init_circuit_ports.at(signal_init_circuit_model), module_manager, signal_init_circuit_ports.at(signal_init_circuit_model), module_manager,
top_module, primitive_module, deposit_random_values); top_module, primitive_module, deposit_random_values);
} }
} }

2
yosys

@ -1 +1 @@
Subproject commit 91fbd58980e87ad5dc0a5d37c049ffaf5ab243dd Subproject commit 1e42b4f0f9cc1d2f4097ea632a93be3473b0c2f7