Merge branch 'master' into tutorials
This commit is contained in:
commit
2ff3dc0a0f
|
@ -38,6 +38,28 @@ std::string PinConstraints::net(const PinConstraintId& pin_constraint_id) const
|
||||||
return pin_constraint_nets_[pin_constraint_id];
|
return pin_constraint_nets_[pin_constraint_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PinConstraints::pin_net(const openfpga::BasicPort& pin) const {
|
||||||
|
std::string constrained_net_name;
|
||||||
|
for (const PinConstraintId& pin_constraint : pin_constraints()) {
|
||||||
|
if (pin == pin_constraint_pins_[pin_constraint]) {
|
||||||
|
constrained_net_name = net(pin_constraint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constrained_net_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
openfpga::BasicPort PinConstraints::net_pin(const std::string& net) const {
|
||||||
|
openfpga::BasicPort constrained_pin;
|
||||||
|
for (const PinConstraintId& pin_constraint : pin_constraints()) {
|
||||||
|
if (net == pin_constraint_nets_[pin_constraint]) {
|
||||||
|
constrained_pin = pin(pin_constraint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constrained_pin;
|
||||||
|
}
|
||||||
|
|
||||||
bool PinConstraints::empty() const {
|
bool PinConstraints::empty() const {
|
||||||
return 0 == pin_constraint_ids_.size();
|
return 0 == pin_constraint_ids_.size();
|
||||||
}
|
}
|
||||||
|
@ -70,3 +92,11 @@ PinConstraintId PinConstraints::create_pin_constraint(const openfpga::BasicPort&
|
||||||
bool PinConstraints::valid_pin_constraint_id(const PinConstraintId& pin_constraint_id) const {
|
bool PinConstraints::valid_pin_constraint_id(const PinConstraintId& pin_constraint_id) const {
|
||||||
return ( size_t(pin_constraint_id) < pin_constraint_ids_.size() ) && ( pin_constraint_id == pin_constraint_ids_[pin_constraint_id] );
|
return ( size_t(pin_constraint_id) < pin_constraint_ids_.size() ) && ( pin_constraint_id == pin_constraint_ids_[pin_constraint_id] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PinConstraints::unconstrained_net(const std::string& net) const {
|
||||||
|
return net.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PinConstraints::unmapped_net(const std::string& net) const {
|
||||||
|
return std::string(PIN_CONSTRAINT_OPEN_NET) == net;
|
||||||
|
}
|
||||||
|
|
|
@ -52,11 +52,21 @@ class PinConstraints {
|
||||||
/* Get the net to be constrained */
|
/* Get the net to be constrained */
|
||||||
std::string net(const PinConstraintId& pin_constraint_id) const;
|
std::string net(const PinConstraintId& pin_constraint_id) const;
|
||||||
|
|
||||||
|
/* Find the net that is constrained on a pin
|
||||||
|
* TODO: this function will only return the first net found in the constraint list
|
||||||
|
*/
|
||||||
|
std::string pin_net(const openfpga::BasicPort& pin) const;
|
||||||
|
|
||||||
|
/* Find the pin that a net is constrained to
|
||||||
|
* If not found, the return port will be an invalid BasicPort
|
||||||
|
* TODO: this function will only return the first pin found in the constraint list
|
||||||
|
*/
|
||||||
|
openfpga::BasicPort net_pin(const std::string& net) const;
|
||||||
|
|
||||||
/* Check if there are any pin constraints */
|
/* Check if there are any pin constraints */
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
public: /* Public Mutators */
|
public: /* Public Mutators */
|
||||||
|
|
||||||
/* Reserve a number of design constraints to be memory efficent */
|
/* Reserve a number of design constraints to be memory efficent */
|
||||||
void reserve_pin_constraints(const size_t& num_pin_constraints);
|
void reserve_pin_constraints(const size_t& num_pin_constraints);
|
||||||
|
|
||||||
|
@ -65,7 +75,22 @@ class PinConstraints {
|
||||||
const std::string& net);
|
const std::string& net);
|
||||||
|
|
||||||
public: /* Public invalidators/validators */
|
public: /* Public invalidators/validators */
|
||||||
|
/* Show if the pin constraint id is a valid for data queries */
|
||||||
bool valid_pin_constraint_id(const PinConstraintId& pin_constraint_id) const;
|
bool valid_pin_constraint_id(const PinConstraintId& pin_constraint_id) const;
|
||||||
|
|
||||||
|
/* Show if the net has no constraints (free to map to any pin)
|
||||||
|
* This function is used to identify the net name returned by APIs:
|
||||||
|
* - pin_net()
|
||||||
|
* - net()
|
||||||
|
*/
|
||||||
|
bool unconstrained_net(const std::string& net) const;
|
||||||
|
|
||||||
|
/* Show if the net is defined specifically not to map to any pin
|
||||||
|
* This function is used to identify the net name returned by APIs:
|
||||||
|
* - pin_net()
|
||||||
|
* - net()
|
||||||
|
*/
|
||||||
|
bool unmapped_net(const std::string& net) const;
|
||||||
private: /* Internal data */
|
private: /* Internal data */
|
||||||
/* Unique ids for each design constraint */
|
/* Unique ids for each design constraint */
|
||||||
vtr::vector<PinConstraintId, PinConstraintId> pin_constraint_ids_;
|
vtr::vector<PinConstraintId, PinConstraintId> pin_constraint_ids_;
|
||||||
|
|
|
@ -203,6 +203,8 @@ int fpga_verilog_testbench(const ModuleManager &module_manager,
|
||||||
random_top_testbench_file_path,
|
random_top_testbench_file_path,
|
||||||
atom_ctx,
|
atom_ctx,
|
||||||
netlist_annotation,
|
netlist_annotation,
|
||||||
|
module_manager,
|
||||||
|
fabric_global_port_info,
|
||||||
pin_constraints,
|
pin_constraints,
|
||||||
simulation_setting,
|
simulation_setting,
|
||||||
options.explicit_port_mapping());
|
options.explicit_port_mapping());
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "openfpga_atom_netlist_utils.h"
|
#include "openfpga_atom_netlist_utils.h"
|
||||||
#include "simulation_utils.h"
|
#include "simulation_utils.h"
|
||||||
|
#include "fabric_global_port_info_utils.h"
|
||||||
|
|
||||||
#include "verilog_constants.h"
|
#include "verilog_constants.h"
|
||||||
#include "verilog_writer_utils.h"
|
#include "verilog_writer_utils.h"
|
||||||
|
@ -168,6 +169,82 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp,
|
||||||
fp << std::endl;
|
fp << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Generate random stimulus for the reset port
|
||||||
|
* This function is designed to drive the reset port of a benchmark module
|
||||||
|
* The reset signal will be
|
||||||
|
* - enabled in the 1st clock cycle
|
||||||
|
* - disabled in the rest of clock cycles
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_random_testbench_reset_stimuli(std::fstream& fp,
|
||||||
|
const AtomContext& atom_ctx,
|
||||||
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
|
const std::vector<std::string>& clock_port_names,
|
||||||
|
const BasicPort& clock_port) {
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
|
print_verilog_comment(fp, "----- Begin reset signal generation -----");
|
||||||
|
|
||||||
|
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
|
||||||
|
/* Bypass non-input atom blocks ! */
|
||||||
|
if (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bypass clock ports because their stimulus cannot be random */
|
||||||
|
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bypass any constained net that are mapped to a global port of the FPGA fabric
|
||||||
|
* because their stimulus cannot be random
|
||||||
|
*/
|
||||||
|
if (false == port_is_fabric_global_reset_port(global_ports, module_manager, pin_constraints.net_pin(block_name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generete stimuli for this net which is how reset signal works */
|
||||||
|
BasicPort reset_port(block_name, 1);
|
||||||
|
size_t initial_value = 1;
|
||||||
|
if (1 == global_ports.global_port_default_value(find_fabric_global_port(global_ports, module_manager, pin_constraints.net_pin(block_name)))) {
|
||||||
|
initial_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp << "initial" << std::endl;
|
||||||
|
fp << "\tbegin" << std::endl;
|
||||||
|
fp << "\t";
|
||||||
|
std::vector<size_t> initial_values(reset_port.get_width(), initial_value);
|
||||||
|
fp << "\t";
|
||||||
|
fp << generate_verilog_port_constant_values(reset_port, initial_values);
|
||||||
|
fp << ";" << std::endl;
|
||||||
|
|
||||||
|
/* Flip the reset at the second negative edge of the clock port
|
||||||
|
* So the generic reset stimuli is applicable to both synchronous reset and asynchronous reset
|
||||||
|
* This is because the reset is activated in a complete clock cycle
|
||||||
|
* This gaurantees that even for synchronous reset, the reset can be sensed in the 1st rising/falling
|
||||||
|
* edge of the clock signal
|
||||||
|
*/
|
||||||
|
fp << "\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, clock_port) << ");" << std::endl;
|
||||||
|
fp << "\t@(negedge " << generate_verilog_port(VERILOG_PORT_CONKT, clock_port) << ");" << std::endl;
|
||||||
|
print_verilog_wire_connection(fp, reset_port, reset_port, true);
|
||||||
|
fp << "\tend" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_verilog_comment(fp, "----- End reset signal generation -----");
|
||||||
|
|
||||||
|
fp << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* Top-level function in this file:
|
* Top-level function in this file:
|
||||||
* Create a Verilog testbench using random input vectors
|
* Create a Verilog testbench using random input vectors
|
||||||
|
@ -197,6 +274,8 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
|
||||||
const std::string& verilog_fname,
|
const std::string& verilog_fname,
|
||||||
const AtomContext& atom_ctx,
|
const AtomContext& atom_ctx,
|
||||||
const VprNetlistAnnotation& netlist_annotation,
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
const PinConstraints& pin_constraints,
|
const PinConstraints& pin_constraints,
|
||||||
const SimulationSetting& simulation_parameters,
|
const SimulationSetting& simulation_parameters,
|
||||||
const bool& explicit_port_mapping) {
|
const bool& explicit_port_mapping) {
|
||||||
|
@ -240,8 +319,23 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
|
||||||
pin_constraints,
|
pin_constraints,
|
||||||
simulation_parameters,
|
simulation_parameters,
|
||||||
clock_ports);
|
clock_ports);
|
||||||
|
/* TODO: use the first clock now because we do not have information how the reset is
|
||||||
|
* correlated to clock ports. Once we have such information, the limitation should be removed!
|
||||||
|
*/
|
||||||
|
print_verilog_random_testbench_reset_stimuli(fp,
|
||||||
|
atom_ctx,
|
||||||
|
netlist_annotation,
|
||||||
|
module_manager,
|
||||||
|
global_ports,
|
||||||
|
pin_constraints,
|
||||||
|
clock_port_names,
|
||||||
|
clock_ports[0]);
|
||||||
|
|
||||||
print_verilog_testbench_random_stimuli(fp, atom_ctx,
|
print_verilog_testbench_random_stimuli(fp, atom_ctx,
|
||||||
netlist_annotation,
|
netlist_annotation,
|
||||||
|
module_manager,
|
||||||
|
global_ports,
|
||||||
|
pin_constraints,
|
||||||
clock_port_names,
|
clock_port_names,
|
||||||
std::string(CHECKFLAG_PORT_POSTFIX),
|
std::string(CHECKFLAG_PORT_POSTFIX),
|
||||||
clock_ports);
|
clock_ports);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
#include "pin_constraints.h"
|
#include "pin_constraints.h"
|
||||||
|
#include "module_manager.h"
|
||||||
|
#include "fabric_global_port_info.h"
|
||||||
#include "simulation_setting.h"
|
#include "simulation_setting.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -20,6 +22,8 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
|
||||||
const std::string& verilog_fname,
|
const std::string& verilog_fname,
|
||||||
const AtomContext& atom_ctx,
|
const AtomContext& atom_ctx,
|
||||||
const VprNetlistAnnotation& netlist_annotation,
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
const PinConstraints& pin_constraints,
|
const PinConstraints& pin_constraints,
|
||||||
const SimulationSetting& simulation_parameters,
|
const SimulationSetting& simulation_parameters,
|
||||||
const bool& explicit_port_mapping);
|
const bool& explicit_port_mapping);
|
||||||
|
|
|
@ -135,16 +135,10 @@ int print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp,
|
||||||
BasicPort module_clock_pin(module_global_port.get_name(), module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]);
|
BasicPort module_clock_pin(module_global_port.get_name(), module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]);
|
||||||
|
|
||||||
/* If the clock port name is in the pin constraints, we should wire it to the constrained pin */
|
/* If the clock port name is in the pin constraints, we should wire it to the constrained pin */
|
||||||
std::string constrained_net_name;
|
std::string constrained_net_name = pin_constraints.pin_net(module_clock_pin);
|
||||||
for (const PinConstraintId& pin_constraint : pin_constraints.pin_constraints()) {
|
|
||||||
if (module_clock_pin == pin_constraints.pin(pin_constraint)) {
|
|
||||||
constrained_net_name = pin_constraints.net(pin_constraint);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If constrained to an open net or there is no clock in the benchmark, we assign it to a default value */
|
/* If constrained to an open net or there is no clock in the benchmark, we assign it to a default value */
|
||||||
if ( (std::string(PIN_CONSTRAINT_OPEN_NET) == constrained_net_name)
|
if ( (true == pin_constraints.unmapped_net(constrained_net_name))
|
||||||
|| (true == benchmark_clock_port_names.empty())) {
|
|| (true == benchmark_clock_port_names.empty())) {
|
||||||
std::vector<size_t> default_values(1, fabric_global_ports.global_port_default_value(global_port_id));
|
std::vector<size_t> default_values(1, fabric_global_ports.global_port_default_value(global_port_id));
|
||||||
print_verilog_wire_constant_values(fp, module_clock_pin, default_values);
|
print_verilog_wire_constant_values(fp, module_clock_pin, default_values);
|
||||||
|
@ -152,7 +146,7 @@ int print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string clock_name_to_connect;
|
std::string clock_name_to_connect;
|
||||||
if (!constrained_net_name.empty()) {
|
if (!pin_constraints.unconstrained_net(constrained_net_name)) {
|
||||||
clock_name_to_connect = constrained_net_name;
|
clock_name_to_connect = constrained_net_name;
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, we must have a clear one-to-one clock net corresponding!!! */
|
/* Otherwise, we must have a clear one-to-one clock net corresponding!!! */
|
||||||
|
@ -173,8 +167,27 @@ int print_verilog_preconfig_top_module_connect_global_ports(std::fstream &fp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For other ports, give an default value */
|
/* For other ports, give an default value */
|
||||||
std::vector<size_t> default_values(module_global_port.get_width(), fabric_global_ports.global_port_default_value(global_port_id));
|
for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); ++pin_id) {
|
||||||
print_verilog_wire_constant_values(fp, module_global_port, default_values);
|
BasicPort module_global_pin(module_global_port.get_name(),
|
||||||
|
module_global_port.pins()[pin_id],
|
||||||
|
module_global_port.pins()[pin_id]);
|
||||||
|
|
||||||
|
/* If the global port name is in the pin constraints, we should wire it to the constrained pin */
|
||||||
|
std::string constrained_net_name = pin_constraints.pin_net(module_global_pin);
|
||||||
|
|
||||||
|
/* - If constrained to a given net in the benchmark, we connect the global pin to the net
|
||||||
|
* - If constrained to an open net in the benchmark, we assign it to a default value
|
||||||
|
*/
|
||||||
|
if ( (false == pin_constraints.unconstrained_net(constrained_net_name))
|
||||||
|
&& (false == pin_constraints.unmapped_net(constrained_net_name))) {
|
||||||
|
BasicPort benchmark_pin(constrained_net_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), 1);
|
||||||
|
print_verilog_wire_connection(fp, module_global_pin, benchmark_pin, false);
|
||||||
|
} else {
|
||||||
|
VTR_ASSERT_SAFE(std::string(PIN_CONSTRAINT_OPEN_NET) == constrained_net_name);
|
||||||
|
std::vector<size_t> default_values(module_global_pin.get_width(), fabric_global_ports.global_port_default_value(global_port_id));
|
||||||
|
print_verilog_wire_constant_values(fp, module_global_pin, default_values);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_verilog_comment(fp, std::string("----- End Connect Global ports of FPGA top module -----"));
|
print_verilog_comment(fp, std::string("----- End Connect Global ports of FPGA top module -----"));
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "verilog_port_types.h"
|
#include "verilog_port_types.h"
|
||||||
|
|
||||||
#include "module_manager_utils.h"
|
#include "module_manager_utils.h"
|
||||||
|
#include "fabric_global_port_info_utils.h"
|
||||||
|
|
||||||
#include "verilog_constants.h"
|
#include "verilog_constants.h"
|
||||||
#include "verilog_writer_utils.h"
|
#include "verilog_writer_utils.h"
|
||||||
|
@ -537,6 +538,9 @@ void print_verilog_testbench_clock_stimuli(std::fstream& fp,
|
||||||
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||||
const AtomContext& atom_ctx,
|
const AtomContext& atom_ctx,
|
||||||
const VprNetlistAnnotation& netlist_annotation,
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
const std::vector<std::string>& clock_port_names,
|
const std::vector<std::string>& clock_port_names,
|
||||||
const std::string& check_flag_port_postfix,
|
const std::string& check_flag_port_postfix,
|
||||||
const std::vector<BasicPort>& clock_ports) {
|
const std::vector<BasicPort>& clock_ports) {
|
||||||
|
@ -560,11 +564,18 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||||
block_name = netlist_annotation.block_name(atom_blk);
|
block_name = netlist_annotation.block_name(atom_blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bypass clock ports */
|
/* Bypass clock ports because their stimulus cannot be random */
|
||||||
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bypass any constained net that are mapped to a global port of the FPGA fabric
|
||||||
|
* because their stimulus cannot be random
|
||||||
|
*/
|
||||||
|
if (true == port_is_fabric_global_reset_port(global_ports, module_manager, pin_constraints.net_pin(block_name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: find the clock inputs will be initialized later */
|
/* TODO: find the clock inputs will be initialized later */
|
||||||
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
||||||
fp << "\t\t" << block_name << " <= 1'b0;" << std::endl;
|
fp << "\t\t" << block_name << " <= 1'b0;" << std::endl;
|
||||||
|
@ -620,11 +631,18 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||||
block_name = netlist_annotation.block_name(atom_blk);
|
block_name = netlist_annotation.block_name(atom_blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bypass clock ports */
|
/* Bypass clock ports because their stimulus cannot be random */
|
||||||
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bypass any constained net that are mapped to a global port of the FPGA fabric
|
||||||
|
* because their stimulus cannot be random
|
||||||
|
*/
|
||||||
|
if (true == port_is_fabric_global_reset_port(global_ports, module_manager, pin_constraints.net_pin(block_name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: find the clock inputs will be initialized later */
|
/* TODO: find the clock inputs will be initialized later */
|
||||||
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
|
||||||
fp << "\t\t" << block_name << " <= $random;" << std::endl;
|
fp << "\t\t" << block_name << " <= $random;" << std::endl;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
#include "io_location_map.h"
|
#include "io_location_map.h"
|
||||||
#include "vpr_netlist_annotation.h"
|
#include "vpr_netlist_annotation.h"
|
||||||
|
#include "fabric_global_port_info.h"
|
||||||
#include "pin_constraints.h"
|
#include "pin_constraints.h"
|
||||||
#include "simulation_setting.h"
|
#include "simulation_setting.h"
|
||||||
|
|
||||||
|
@ -84,6 +85,9 @@ void print_verilog_testbench_clock_stimuli(std::fstream& fp,
|
||||||
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
void print_verilog_testbench_random_stimuli(std::fstream& fp,
|
||||||
const AtomContext& atom_ctx,
|
const AtomContext& atom_ctx,
|
||||||
const VprNetlistAnnotation& netlist_annotation,
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
const std::vector<std::string>& clock_port_names,
|
const std::vector<std::string>& clock_port_names,
|
||||||
const std::string& check_flag_port_postfix,
|
const std::string& check_flag_port_postfix,
|
||||||
const std::vector<BasicPort>& clock_ports);
|
const std::vector<BasicPort>& clock_ports);
|
||||||
|
|
|
@ -47,7 +47,6 @@ constexpr char* TOP_TESTBENCH_PROG_TASK_NAME = "prog_cycle_task";
|
||||||
|
|
||||||
constexpr char* TOP_TESTBENCH_SIM_START_PORT_NAME = "sim_start";
|
constexpr char* TOP_TESTBENCH_SIM_START_PORT_NAME = "sim_start";
|
||||||
|
|
||||||
constexpr int TOP_TESTBENCH_MAGIC_NUMBER_FOR_SIMULATION_TIME = 200;
|
|
||||||
constexpr char* TOP_TESTBENCH_ERROR_COUNTER = "nb_error";
|
constexpr char* TOP_TESTBENCH_ERROR_COUNTER = "nb_error";
|
||||||
|
|
||||||
constexpr char* TOP_TB_RESET_PORT_NAME = "greset";
|
constexpr char* TOP_TB_RESET_PORT_NAME = "greset";
|
||||||
|
@ -258,21 +257,17 @@ void print_verilog_top_testbench_config_protocol_port(std::fstream& fp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Wire the global ports of FPGA fabric to local wires
|
* Wire the global clock ports of FPGA fabric to local wires
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
void print_verilog_top_testbench_global_clock_ports_stimuli(std::fstream& fp,
|
||||||
const ModuleManager& module_manager,
|
const ModuleManager& module_manager,
|
||||||
const ModuleId& top_module,
|
const ModuleId& top_module,
|
||||||
const FabricGlobalPortInfo& fabric_global_port_info,
|
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
const SimulationSetting& simulation_parameters,
|
const SimulationSetting& simulation_parameters) {
|
||||||
const bool& active_global_prog_reset,
|
|
||||||
const bool& active_global_prog_set) {
|
|
||||||
/* Validate the file stream */
|
/* Validate the file stream */
|
||||||
valid_file_stream(fp);
|
valid_file_stream(fp);
|
||||||
|
|
||||||
print_verilog_comment(fp, std::string("----- Begin connecting global ports of FPGA fabric to stimuli -----"));
|
|
||||||
|
|
||||||
/* Connect global clock ports to operating or programming clock signal */
|
/* Connect global clock ports to operating or programming clock signal */
|
||||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||||
if (false == fabric_global_port_info.global_port_is_clock(fabric_global_port)) {
|
if (false == fabric_global_port_info.global_port_is_clock(fabric_global_port)) {
|
||||||
|
@ -317,6 +312,18 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Wire the global config done ports of FPGA fabric to local wires
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_global_config_done_ports_stimuli(std::fstream& fp,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const ModuleId& top_module,
|
||||||
|
const FabricGlobalPortInfo& fabric_global_port_info) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
/* Connect global configuration done ports to configuration done signal */
|
/* Connect global configuration done ports to configuration done signal */
|
||||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||||
|
@ -341,6 +348,20 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
stimuli_config_done_port,
|
stimuli_config_done_port,
|
||||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Wire the global reset ports of FPGA fabric to local wires
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_global_reset_ports_stimuli(std::fstream& fp,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const ModuleId& top_module,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
|
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const bool& active_global_prog_reset) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
/* Connect global reset ports to operating or programming reset signal */
|
/* Connect global reset ports to operating or programming reset signal */
|
||||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||||
|
@ -373,20 +394,58 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
stimuli_reset_port.set_name(std::string(TOP_TB_RESET_PORT_NAME));
|
stimuli_reset_port.set_name(std::string(TOP_TB_RESET_PORT_NAME));
|
||||||
stimuli_reset_port.set_width(1);
|
stimuli_reset_port.set_width(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicPort module_global_port_info = module_manager.module_port(top_module, module_global_port);
|
||||||
|
|
||||||
|
for (size_t pin_id = 0; pin_id < module_global_port_info.pins().size(); ++pin_id) {
|
||||||
|
BasicPort module_global_pin(module_global_port_info.get_name(),
|
||||||
|
module_global_port_info.pins()[pin_id],
|
||||||
|
module_global_port_info.pins()[pin_id]);
|
||||||
|
|
||||||
|
/* Regular reset port can be mapped by a net from user design */
|
||||||
|
if (false == fabric_global_port_info.global_port_is_prog(fabric_global_port)) {
|
||||||
|
/* If the global port name is in the pin constraints, we should wire it to the constrained pin */
|
||||||
|
std::string constrained_net_name = pin_constraints.pin_net(module_global_pin);
|
||||||
|
|
||||||
|
/* - If constrained to a given net in the benchmark, we connect the global pin to the net */
|
||||||
|
if ( (false == pin_constraints.unconstrained_net(constrained_net_name))
|
||||||
|
&& (false == pin_constraints.unmapped_net(constrained_net_name))) {
|
||||||
|
BasicPort benchmark_pin(constrained_net_name, 1);
|
||||||
|
print_verilog_wire_connection(fp, module_global_pin,
|
||||||
|
benchmark_pin,
|
||||||
|
false);
|
||||||
|
continue; /* Finish the net assignment for this reset pin */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Wire the port to the input stimuli:
|
/* Wire the port to the input stimuli:
|
||||||
* The wiring will be inverted if the default value of the global port is 1
|
* The wiring will be inverted if the default value of the global port is 1
|
||||||
* Otherwise, the wiring will not be inverted!
|
* Otherwise, the wiring will not be inverted!
|
||||||
*/
|
*/
|
||||||
if (true == activate) {
|
if (true == activate) {
|
||||||
print_verilog_wire_connection(fp, module_manager.module_port(top_module, module_global_port),
|
print_verilog_wire_connection(fp, module_global_pin,
|
||||||
stimuli_reset_port,
|
stimuli_reset_port,
|
||||||
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
1 == fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||||
} else {
|
} else {
|
||||||
VTR_ASSERT_SAFE(false == activate);
|
VTR_ASSERT_SAFE(false == activate);
|
||||||
print_verilog_wire_constant_values(fp, module_manager.module_port(top_module, module_global_port),
|
print_verilog_wire_constant_values(fp, module_global_pin,
|
||||||
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Wire the global set ports of FPGA fabric to local wires
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_global_set_ports_stimuli(std::fstream& fp,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const ModuleId& top_module,
|
||||||
|
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const bool& active_global_prog_set) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
/* Connect global set ports to operating or programming set signal */
|
/* Connect global set ports to operating or programming set signal */
|
||||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||||
|
@ -438,6 +497,18 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
std::vector<size_t>(1, fabric_global_port_info.global_port_default_value(fabric_global_port)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Wire the regular global ports of FPGA fabric to local wires
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_regular_global_ports_stimuli(std::fstream& fp,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const ModuleId& top_module,
|
||||||
|
const FabricGlobalPortInfo& fabric_global_port_info) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
/* For the rest of global ports, wire them to constant signals */
|
/* For the rest of global ports, wire them to constant signals */
|
||||||
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
for (const FabricGlobalPortId& fabric_global_port : fabric_global_port_info.global_ports()) {
|
||||||
|
@ -478,6 +549,55 @@ void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
std::vector<size_t> default_values(module_port.get_width(), fabric_global_port_info.global_port_default_value(fabric_global_port));
|
std::vector<size_t> default_values(module_port.get_width(), fabric_global_port_info.global_port_default_value(fabric_global_port));
|
||||||
print_verilog_wire_constant_values(fp, module_port, default_values);
|
print_verilog_wire_constant_values(fp, module_port, default_values);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Wire the global ports of FPGA fabric to local wires
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_global_ports_stimuli(std::fstream& fp,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const ModuleId& top_module,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
|
const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const SimulationSetting& simulation_parameters,
|
||||||
|
const bool& active_global_prog_reset,
|
||||||
|
const bool& active_global_prog_set) {
|
||||||
|
/* Validate the file stream */
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
|
print_verilog_comment(fp, std::string("----- Begin connecting global ports of FPGA fabric to stimuli -----"));
|
||||||
|
|
||||||
|
print_verilog_top_testbench_global_clock_ports_stimuli(fp,
|
||||||
|
module_manager,
|
||||||
|
top_module,
|
||||||
|
fabric_global_port_info,
|
||||||
|
simulation_parameters);
|
||||||
|
|
||||||
|
print_verilog_top_testbench_global_config_done_ports_stimuli(fp,
|
||||||
|
module_manager,
|
||||||
|
top_module,
|
||||||
|
fabric_global_port_info);
|
||||||
|
|
||||||
|
|
||||||
|
print_verilog_top_testbench_global_reset_ports_stimuli(fp,
|
||||||
|
module_manager,
|
||||||
|
top_module,
|
||||||
|
pin_constraints,
|
||||||
|
fabric_global_port_info,
|
||||||
|
active_global_prog_reset);
|
||||||
|
|
||||||
|
print_verilog_top_testbench_global_set_ports_stimuli(fp,
|
||||||
|
module_manager,
|
||||||
|
top_module,
|
||||||
|
fabric_global_port_info,
|
||||||
|
active_global_prog_set);
|
||||||
|
|
||||||
|
|
||||||
|
print_verilog_top_testbench_regular_global_ports_stimuli(fp,
|
||||||
|
module_manager,
|
||||||
|
top_module,
|
||||||
|
fabric_global_port_info);
|
||||||
|
|
||||||
print_verilog_comment(fp, std::string("----- End connecting global ports of FPGA fabric to stimuli -----"));
|
print_verilog_comment(fp, std::string("----- End connecting global ports of FPGA fabric to stimuli -----"));
|
||||||
}
|
}
|
||||||
|
@ -1810,6 +1930,54 @@ void print_verilog_top_testbench_bitstream(std::fstream& fp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Connect proper stimuli to the reset port
|
||||||
|
* This function is designed to drive the reset port of a benchmark module
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
void print_verilog_top_testbench_reset_stimuli(std::fstream& fp,
|
||||||
|
const AtomContext& atom_ctx,
|
||||||
|
const VprNetlistAnnotation& netlist_annotation,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const FabricGlobalPortInfo& global_ports,
|
||||||
|
const PinConstraints& pin_constraints,
|
||||||
|
const std::vector<std::string>& clock_port_names) {
|
||||||
|
valid_file_stream(fp);
|
||||||
|
|
||||||
|
print_verilog_comment(fp, "----- Begin reset signal generation -----");
|
||||||
|
|
||||||
|
for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
|
||||||
|
/* Bypass non-input atom blocks ! */
|
||||||
|
if (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bypass clock ports because their stimulus cannot be random */
|
||||||
|
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bypass any constained net that are mapped to a global port of the FPGA fabric
|
||||||
|
* because their stimulus cannot be random
|
||||||
|
*/
|
||||||
|
if (false == port_is_fabric_global_reset_port(global_ports, module_manager, pin_constraints.net_pin(block_name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect stimuli to greset with an optional inversion, depending on the default value */
|
||||||
|
BasicPort reset_port(block_name, 1);
|
||||||
|
print_verilog_wire_connection(fp, reset_port,
|
||||||
|
BasicPort(TOP_TB_RESET_PORT_NAME, 1),
|
||||||
|
1 == global_ports.global_port_default_value(find_fabric_global_port(global_ports, module_manager, pin_constraints.net_pin(block_name))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Add auto-check codes for the full testbench
|
* Add auto-check codes for the full testbench
|
||||||
* in particular for the configuration phase:
|
* in particular for the configuration phase:
|
||||||
|
@ -1994,6 +2162,7 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
||||||
/* Generate stimuli for global ports or connect them to existed signals */
|
/* Generate stimuli for global ports or connect them to existed signals */
|
||||||
print_verilog_top_testbench_global_ports_stimuli(fp,
|
print_verilog_top_testbench_global_ports_stimuli(fp,
|
||||||
module_manager, top_module,
|
module_manager, top_module,
|
||||||
|
pin_constraints,
|
||||||
global_ports,
|
global_ports,
|
||||||
simulation_parameters,
|
simulation_parameters,
|
||||||
active_global_prog_reset,
|
active_global_prog_reset,
|
||||||
|
@ -2042,9 +2211,20 @@ void print_verilog_top_testbench(const ModuleManager& module_manager,
|
||||||
top_module);
|
top_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add stimuli for reset, set, clock and iopad signals */
|
/* Add stimuli for reset, set, clock and iopad signals */
|
||||||
|
print_verilog_top_testbench_reset_stimuli(fp,
|
||||||
|
atom_ctx,
|
||||||
|
netlist_annotation,
|
||||||
|
module_manager,
|
||||||
|
global_ports,
|
||||||
|
pin_constraints,
|
||||||
|
clock_port_names);
|
||||||
print_verilog_testbench_random_stimuli(fp, atom_ctx,
|
print_verilog_testbench_random_stimuli(fp, atom_ctx,
|
||||||
netlist_annotation,
|
netlist_annotation,
|
||||||
|
module_manager,
|
||||||
|
global_ports,
|
||||||
|
pin_constraints,
|
||||||
clock_port_names,
|
clock_port_names,
|
||||||
std::string(TOP_TESTBENCH_CHECKFLAG_PORT_POSTFIX),
|
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)));
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
#include "vtr_log.h"
|
#include "vtr_log.h"
|
||||||
|
|
||||||
|
#include "openfpga_naming.h"
|
||||||
|
|
||||||
#include "fabric_global_port_info_utils.h"
|
#include "fabric_global_port_info_utils.h"
|
||||||
|
|
||||||
/* begin namespace openfpga */
|
/* begin namespace openfpga */
|
||||||
|
@ -58,4 +60,51 @@ std::vector<FabricGlobalPortId> find_fabric_global_programming_set_ports(const F
|
||||||
return global_prog_set_ports;
|
return global_prog_set_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Identify if a port is in the list of fabric global port
|
||||||
|
* and its functionality is a reset port which is not used for programming FPGAs
|
||||||
|
*******************************************************************/
|
||||||
|
bool port_is_fabric_global_reset_port(const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const BasicPort& port) {
|
||||||
|
/* Find the top_module: the fabric global ports are always part of the ports of the top module */
|
||||||
|
ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name());
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(top_module));
|
||||||
|
|
||||||
|
for (const FabricGlobalPortId& fabric_global_port_id : fabric_global_port_info.global_ports()) {
|
||||||
|
if ( (false == fabric_global_port_info.global_port_is_reset(fabric_global_port_id))
|
||||||
|
|| (true == fabric_global_port_info.global_port_is_prog(fabric_global_port_id))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicPort module_global_port = module_manager.module_port(top_module, fabric_global_port_info.global_module_port(fabric_global_port_id));
|
||||||
|
if ( (true == module_global_port.mergeable(port))
|
||||||
|
&& (true == module_global_port.contained(port)) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Find a global port with a given name
|
||||||
|
*******************************************************************/
|
||||||
|
FabricGlobalPortId find_fabric_global_port(const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const BasicPort& port) {
|
||||||
|
/* Find the top_module: the fabric global ports are always part of the ports of the top module */
|
||||||
|
ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name());
|
||||||
|
VTR_ASSERT(true == module_manager.valid_module_id(top_module));
|
||||||
|
|
||||||
|
for (const FabricGlobalPortId& fabric_global_port_id : fabric_global_port_info.global_ports()) {
|
||||||
|
BasicPort module_global_port = module_manager.module_port(top_module, fabric_global_port_info.global_module_port(fabric_global_port_id));
|
||||||
|
if ( (true == module_global_port.mergeable(port))
|
||||||
|
&& (true == module_global_port.contained(port)) ) {
|
||||||
|
return fabric_global_port_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FabricGlobalPortId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "fabric_global_port_info.h"
|
#include "fabric_global_port_info.h"
|
||||||
|
#include "module_manager.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Function declaration
|
* Function declaration
|
||||||
|
@ -18,6 +19,14 @@ std::vector<FabricGlobalPortId> find_fabric_global_programming_reset_ports(const
|
||||||
|
|
||||||
std::vector<FabricGlobalPortId> find_fabric_global_programming_set_ports(const FabricGlobalPortInfo& fabric_global_port_info);
|
std::vector<FabricGlobalPortId> find_fabric_global_programming_set_ports(const FabricGlobalPortInfo& fabric_global_port_info);
|
||||||
|
|
||||||
|
bool port_is_fabric_global_reset_port(const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const BasicPort& port);
|
||||||
|
|
||||||
|
FabricGlobalPortId find_fabric_global_port(const FabricGlobalPortInfo& fabric_global_port_info,
|
||||||
|
const ModuleManager& module_manager,
|
||||||
|
const BasicPort& port);
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,7 +55,7 @@ write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --pri
|
||||||
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
||||||
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
||||||
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
||||||
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator
|
write_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE}
|
||||||
|
|
||||||
# Write the SDC files for PnR backend
|
# Write the SDC files for PnR backend
|
||||||
# - Turn on every options here
|
# - Turn on every options here
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<pin_constraints>
|
||||||
|
<!-- For a given .blif file, we want to assign
|
||||||
|
- the reset signal to the op_reset[0] port of the FPGA fabric
|
||||||
|
-->
|
||||||
|
<set_io pin="op_reset[0]" net="reset"/>
|
||||||
|
</pin_constraints>
|
||||||
|
|
|
@ -19,6 +19,7 @@ fpga_flow=yosys_vpr
|
||||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
|
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
|
||||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_cc_openfpga.xml
|
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N4_fracff_40nm_cc_openfpga.xml
|
||||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||||
|
openfpga_pin_constraints_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/k4_series/k4n4_fracff/config/pin_constraints.xml
|
||||||
# Yosys script parameters
|
# Yosys script parameters
|
||||||
yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v
|
yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_sim.v
|
||||||
yosys_dff_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v
|
yosys_dff_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_dff_map.v
|
||||||
|
|
Loading…
Reference in New Issue