Merge pull request #539 from lnis-uofu/bus_support

Support buses in Verilog testbenches
This commit is contained in:
tangxifan 2022-02-18 16:48:52 -08:00 committed by GitHub
commit feaaeea787
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1437 additions and 88 deletions

View File

@ -0,0 +1,40 @@
.. _file_format_bus_group_file:
Bus Group File (.xml)
=====================
The bus group file aims to show
- How bus ports are flatten by EDA engines, e.g., synthesis.
- What are the pins in post-routing corresponding to the bus ports before synthesis
An example of file is shown as follows.
.. code-block:: xml
<bus_group>
<bus name="i_addr[0:3]">
<pin id="0" name="i_addr_0_"/>
<pin id="1" name="i_addr_1_"/>
<pin id="2" name="i_addr_2_"/>
<pin id="3" name="i_addr_3_"/>
</bus>
</bus_group>
Bus-related Syntax
------------------
.. option:: name="<string>"
The bus port defined before synthesis, e.g., addr[0:3]
Pin-related Syntax
------------------
.. option:: id="<int>"
The index of the current pin in a bus port. The index must be the range of **[LSB, MSB-1]** that are defined in the bus.
.. option:: name="<string>"
The pin name after bus flatten in synthesis results

View File

@ -25,3 +25,5 @@ OpenFPGA widely uses XML format for interchangable files
io_mapping_file io_mapping_file
bitstream_distribution_file bitstream_distribution_file
bus_group_file

View File

@ -68,6 +68,11 @@ write_full_testbench
Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml``
Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`.
.. option:: --bus_group_file <string> or -bgf <string>
Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml``
Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`.
.. option:: --fast_configuration .. option:: --fast_configuration
Enable fast configuration phase for the top-level testbench in order to reduce runtime of simulations. It is applicable to configuration chain, memory bank and frame-based configuration protocols. For configuration chain, when enabled, the zeros at the head of the bitstream will be skipped. For memory bank and frame-based, when enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal. Enable fast configuration phase for the top-level testbench in order to reduce runtime of simulations. It is applicable to configuration chain, memory bank and frame-based configuration protocols. For configuration chain, when enabled, the zeros at the head of the bitstream will be skipped. For memory bank and frame-based, when enabled, all the zero configuration bits will be skipped. So ensure that your memory cells can be correctly reset to zero with a reset signal.
@ -120,6 +125,11 @@ write_preconfigured_fabric_wrapper
Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml``
Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`.
.. option:: --bus_group_file <string> or -bgf <string>
Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml``
Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`.
.. option:: --explicit_port_mapping .. option:: --explicit_port_mapping
Use explicit port mapping when writing the Verilog netlists Use explicit port mapping when writing the Verilog netlists
@ -180,6 +190,11 @@ write_preconfigured_testbench
Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml`` Specify the *Pin Constraints File* (PCF) if you want to custom stimulus in testbenches. For example, ``-pin_constraints_file pin_constraints.xml``
Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`.
.. option:: --bus_group_file <string> or -bgf <string>
Specify the *Bus Group File* (BGF) if you want to group pins to buses. For example, ``-bgf bus_group.xml``
Strongly recommend when input HDL contains bus ports. See detailed file format about :ref:`file_format_bus_group_file`.
.. option:: --explicit_port_mapping .. option:: --explicit_port_mapping
Use explicit port mapping when writing the Verilog netlists Use explicit port mapping when writing the Verilog netlists

View File

@ -11,7 +11,7 @@ To enable various design purposes, OpenFPGA integrates several tools to i.e., FP
.. _fig_openfpga_tools: .. _fig_openfpga_tools:
.. figure:: figures/openfpga_tools.svg .. figure:: figures/openfpga_tools.svg
:scale: 25% :width: 100%
:alt: map to buried treasure :alt: map to buried treasure
OpenFPGA tool suites and design flows OpenFPGA tool suites and design flows

View File

@ -7,3 +7,4 @@ add_subdirectory(libfabrickey)
add_subdirectory(librepackdc) add_subdirectory(librepackdc)
add_subdirectory(libfpgabitstream) add_subdirectory(libfpgabitstream)
add_subdirectory(libpcf) add_subdirectory(libpcf)
add_subdirectory(libbusgroup)

View File

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.9)
project("libbusgroup")
file(GLOB_RECURSE EXEC_SOURCES test/*.cpp)
file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
file(GLOB_RECURSE LIB_HEADERS src/*.h)
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
#Remove test executable from library
list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
#Create the library
add_library(libbusgroup STATIC
${LIB_HEADERS}
${LIB_SOURCES})
target_include_directories(libbusgroup PUBLIC ${LIB_INCLUDE_DIRS})
set_target_properties(libbusgroup PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
#Specify link-time dependancies
target_link_libraries(libbusgroup
libopenfpgautil
libarchopenfpga
libvtrutil
libpugixml
libpugiutil)
#Create the test executable
foreach(testsourcefile ${EXEC_SOURCES})
# Use a simple string replace, to cut off .cpp.
get_filename_component(testname ${testsourcefile} NAME_WE)
add_executable(${testname} ${testsourcefile})
# Make sure the library is linked to each test executable
target_link_libraries(${testname} libbusgroup)
endforeach(testsourcefile ${EXEC_SOURCES})

View File

@ -0,0 +1,8 @@
<bus_group>
<bus name="i_addr[0:3]">
<pin id="0" name="i_addr_0_"/>
<pin id="1" name="i_addr_1_"/>
<pin id="2" name="i_addr_2_"/>
<pin id="3" name="i_addr_3_"/>
</bus>
</bus_group>

View File

@ -0,0 +1,170 @@
#include <algorithm>
#include "vtr_assert.h"
#include "vtr_log.h"
#include "bus_group.h"
namespace openfpga { // Begin namespace openfpga
/************************************************************************
* Member functions for class BusGroup
***********************************************************************/
/************************************************************************
* Constructors
***********************************************************************/
BusGroup::BusGroup() {
return;
}
/************************************************************************
* Public Accessors : aggregates
***********************************************************************/
BusGroup::bus_group_range BusGroup::buses() const {
return vtr::make_range(bus_ids_.begin(), bus_ids_.end());
}
/************************************************************************
* Public Accessors : Basic data query
***********************************************************************/
openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const {
VTR_ASSERT(valid_bus_id(bus_id));
return bus_ports_[bus_id];
}
std::vector<BusPinId> BusGroup::bus_pins(const BusGroupId& bus_id) const {
VTR_ASSERT(valid_bus_id(bus_id));
return bus_pin_ids_[bus_id];
}
int BusGroup::pin_index(const BusPinId& pin_id) const {
VTR_ASSERT(valid_pin_id(pin_id));
return pin_indices_[pin_id];
}
std::string BusGroup::pin_name(const BusPinId& pin_id) const {
VTR_ASSERT(valid_pin_id(pin_id));
return pin_names_[pin_id];
}
BusGroupId BusGroup::find_pin_bus(const std::string& pin_name) const {
std::map<std::string, BusPinId>::const_iterator result = pin_name2id_map_.find(pin_name);
if (result == pin_name2id_map_.end()) {
/* Not found, return an invalid id */
return BusGroupId::INVALID();
}
/* Found, we should get the parent bus */
BusPinId pin_id = result->second;
return pin_parent_bus_ids_[pin_id];
}
BusGroupId BusGroup::find_bus(const std::string& bus_name) const {
std::map<std::string, BusGroupId>::const_iterator result = bus_name2id_map_.find(bus_name);
if (result == bus_name2id_map_.end()) {
/* Not found, return an invalid id */
return BusGroupId::INVALID();
}
/* Found, we should get the parent bus */
return result->second;
}
BusPinId BusGroup::find_pin(const std::string& pin_name) const {
std::map<std::string, BusPinId>::const_iterator result = pin_name2id_map_.find(pin_name);
if (result == pin_name2id_map_.end()) {
/* Not found, return an invalid id */
return BusPinId::INVALID();
}
/* Found, we should get the parent bus */
return result->second;
}
bool BusGroup::empty() const {
return 0 == bus_ids_.size();
}
/************************************************************************
* Public Mutators
***********************************************************************/
void BusGroup::reserve_buses(const size_t& num_buses) {
bus_ids_.reserve(num_buses);
bus_ports_.reserve(num_buses);
bus_pin_ids_.reserve(num_buses);
}
void BusGroup::reserve_pins(const size_t& num_pins) {
pin_ids_.reserve(num_pins);
pin_indices_.reserve(num_pins);
pin_names_.reserve(num_pins);
pin_parent_bus_ids_.reserve(num_pins);
}
BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) {
/* Create a new id */
BusGroupId bus_id = BusGroupId(bus_ids_.size());
bus_ids_.push_back(bus_id);
bus_ports_.push_back(bus_port);
bus_pin_ids_.emplace_back();
/* Register to fast look-up */
auto result = bus_name2id_map_.find(bus_port.get_name());
if (result == bus_name2id_map_.end()) {
bus_name2id_map_[bus_port.get_name()] = bus_id;
} else {
VTR_LOG_ERROR("Duplicated bus name '%s' in bus group", bus_port.get_name().c_str());
exit(1);
}
return bus_id;
}
BusPinId BusGroup::create_pin(const BusGroupId& bus_id, const int& index) {
/* Create a new id */
BusPinId pin_id = BusPinId(pin_ids_.size());
pin_ids_.push_back(pin_id);
pin_indices_.push_back(index);
pin_names_.emplace_back();
/* Register the pin to the bus */
VTR_ASSERT(valid_bus_id(bus_id));
pin_parent_bus_ids_.push_back(bus_id);
/* If the pin index is beyond the range of the bus_pin_ids, resize it */
if (size_t(index) >= bus_pin_ids_[bus_id].size()) {
bus_pin_ids_[bus_id].resize(index + 1);
}
bus_pin_ids_[bus_id][index] = pin_id;
return pin_id;
}
void BusGroup::set_pin_name(const BusPinId& pin_id, const std::string& name) {
VTR_ASSERT(valid_pin_id(pin_id));
pin_names_[pin_id] = name;
/* Register to fast look-up */
auto result = pin_name2id_map_.find(name);
if (result == pin_name2id_map_.end()) {
pin_name2id_map_[name] = pin_id;
} else {
VTR_LOG_ERROR("Duplicated pin name '%s' in bus group", name.c_str());
exit(1);
}
}
/************************************************************************
* Internal invalidators/validators
***********************************************************************/
bool BusGroup::valid_bus_id(const BusGroupId& bus_id) const {
return ( size_t(bus_id) < bus_ids_.size() ) && ( bus_id == bus_ids_[bus_id] );
}
bool BusGroup::valid_pin_id(const BusPinId& pin_id) const {
return ( size_t(pin_id) < pin_ids_.size() ) && ( pin_id == pin_ids_[pin_id] );
}
} // End of namespace openfpga

View File

@ -0,0 +1,125 @@
#ifndef BUS_GROUP_H
#define BUS_GROUP_H
/********************************************************************
* This file include the declaration of pin constraints
*******************************************************************/
#include <string>
#include <map>
#include <array>
/* Headers from vtrutil library */
#include "vtr_vector.h"
/* Headers from openfpgautil library */
#include "openfpga_port.h"
#include "bus_group_fwd.h"
namespace openfpga { // Begin namespace openfpga
/********************************************************************
* A data structure to describe the bus-to-pin mapping
* This data structure may include a number of buses
* each of which has:
* - a unique id and name
* - a number of pins with names and index which are flatten from the bus
*
* Typical usage:
* --------------
* // Create an object of bus group
* BusGroup bus_group;
* // Create a new port
* BasicPort bus_a("BusA", 0, 3)
* // Add a bus
* BusGroupId bus_group_id = bus_group.create_bus(bus_a);
*
*******************************************************************/
class BusGroup {
public: /* Types */
typedef vtr::vector<BusGroupId, BusGroupId>::const_iterator bus_group_iterator;
typedef vtr::vector<BusPinId, BusPinId>::const_iterator bus_pin_iterator;
/* Create range */
typedef vtr::Range<bus_group_iterator> bus_group_range;
typedef vtr::Range<bus_pin_iterator> bus_pin_range;
public: /* Constructors */
BusGroup();
public: /* Accessors: aggregates */
bus_group_range buses() const;
public: /* Public Accessors: Basic data query */
/** Get port information of a bus with a given id */
BasicPort bus_port(const BusGroupId& bus_id) const;
/* Get the pins under a specific bus */
std::vector<BusPinId> bus_pins(const BusGroupId& bus_id) const;
/* Get the index of a pin */
int pin_index(const BusPinId& pin_id) const;
/* Get the name of a pin */
std::string pin_name(const BusPinId& pin_id) const;
/* Find the bus that a pin belongs to */
BusGroupId find_pin_bus(const std::string& pin_name) const;
/* Find the bus id with a given name */
BusGroupId find_bus(const std::string& bus_name) const;
/* Find the pin id with a given name */
BusPinId find_pin(const std::string& pin_name) const;
/* Check if there are any buses */
bool empty() const;
public: /* Public Mutators */
/* Reserve a number of buses to be memory efficent */
void reserve_buses(const size_t& num_buses);
/* Reserve a number of pins to be memory efficent */
void reserve_pins(const size_t& num_pins);
/* Add a bus to storage */
BusGroupId create_bus(const openfpga::BasicPort& bus_port);
/* Add a pin to a bus, with a given index in the bus, e.g., A[1] in A[0:2] */
BusPinId create_pin(const BusGroupId& bus_id, const int& index);
/* Set the name for a pin */
void set_pin_name(const BusPinId& pin_id, const std::string& name);
public: /* Public invalidators/validators */
/* Show if the bus id is a valid for data queries */
bool valid_bus_id(const BusGroupId& bus_id) const;
/* Show if the pin id is a valid for data queries */
bool valid_pin_id(const BusPinId& pin_id) const;
private: /* Internal data */
/* Unique ids for each bus */
vtr::vector<BusGroupId, BusGroupId> bus_ids_;
/* Port information of each bus */
vtr::vector<BusGroupId, BasicPort> bus_ports_;
/* Indices of each pin under each bus */
vtr::vector<BusGroupId, std::vector<BusPinId>> bus_pin_ids_;
/* Unique ids for each pin */
vtr::vector<BusPinId, BusPinId> pin_ids_;
/* Index for each pin */
vtr::vector<BusPinId, int> pin_indices_;
/* Name of each pin under each bus */
vtr::vector<BusPinId, std::string> pin_names_;
/* Parent bus of each pin */
vtr::vector<BusPinId, BusGroupId> pin_parent_bus_ids_;
/* Fast look-up */
std::map<std::string, BusGroupId> bus_name2id_map_;
std::map<std::string, BusPinId> pin_name2id_map_;
};
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,28 @@
/************************************************************************
* A header file for BusGroup class, including critical data declaration
* Please include this file only for using any PinConstraints data structure
* Refer to bus_group.h for more details
***********************************************************************/
/************************************************************************
* Create strong id for BusGroup to avoid illegal type casting
***********************************************************************/
#ifndef BUS_GROUP_FWD_H
#define BUS_GROUP_FWD_H
#include "vtr_strong_id.h"
namespace openfpga { // Begin namespace openfpga
struct bus_group_id_tag;
struct bus_pin_id_tag;
typedef vtr::StrongId<bus_group_id_tag> BusGroupId;
typedef vtr::StrongId<bus_pin_id_tag> BusPinId;
/* Short declaration of class */
class BusGroup;
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,13 @@
#ifndef BUS_GROUP_XML_CONSTANTS_H
#define BUS_GROUP_XML_CONSTANTS_H
/* Constants required by XML parser */
constexpr char* XML_BUS_GROUP_NODE_NAME = "bus_group";
constexpr char* XML_BUS_NODE_NAME = "bus";
constexpr char* XML_BUS_PORT_ATTRIBUTE_NAME = "name";
constexpr char* XML_PIN_NODE_NAME = "pin";
constexpr char* XML_PIN_INDEX_ATTRIBUTE_NAME = "id";
constexpr char* XML_PIN_NAME_ATTRIBUTE_NAME = "name";
#endif

View File

@ -0,0 +1,134 @@
/********************************************************************
* This file includes the top-level function of this library
* which reads an XML of bus group file to the associated
* data structures
*******************************************************************/
#include <string>
/* Headers from pugi XML library */
#include "pugixml.hpp"
#include "pugixml_util.hpp"
/* Headers from vtr util library */
#include "vtr_assert.h"
#include "vtr_time.h"
/* Headers from libopenfpga util library */
#include "openfpga_port_parser.h"
/* Headers from libarchfpga */
#include "arch_error.h"
#include "read_xml_util.h"
#include "bus_group_xml_constants.h"
#include "read_xml_bus_group.h"
namespace openfpga { // Begin namespace openfpga
/********************************************************************
* Parse XML codes of a <pin> to an object of BusGroup
*******************************************************************/
static
void read_xml_pin(pugi::xml_node& xml_pin,
const pugiutil::loc_data& loc_data,
BusGroup& bus_group,
const BusGroupId& bus_id) {
if (false == bus_group.valid_bus_id(bus_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_pin),
"Invalid id of a bus group!\n");
}
int pin_index = get_attribute(xml_pin, XML_PIN_INDEX_ATTRIBUTE_NAME, loc_data).as_int();
std::string pin_name = get_attribute(xml_pin, XML_PIN_NAME_ATTRIBUTE_NAME, loc_data).as_string();
/* Before update storage, check if the pin index is in the range */
BasicPort pin_port(bus_group.bus_port(bus_id).get_name(), pin_index, pin_index);
if (!bus_group.bus_port(bus_id).contained(pin_port)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_pin),
"Pin index is out of range of the bus port width!\n");
}
BusPinId pin_id = bus_group.create_pin(bus_id, pin_index);
bus_group.set_pin_name(pin_id, pin_name);
}
/********************************************************************
* Parse XML codes of a <bus> to an object of BusGroup
*******************************************************************/
static
void read_xml_bus(pugi::xml_node& xml_bus,
const pugiutil::loc_data& loc_data,
BusGroup& bus_group) {
openfpga::PortParser port_parser(get_attribute(xml_bus, XML_BUS_PORT_ATTRIBUTE_NAME, loc_data).as_string());
/* Create a new bus in the storage */
BusGroupId bus_id = bus_group.create_bus(port_parser.port());
if (false == bus_group.valid_bus_id(bus_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_bus),
"Fail to create a bus group!\n");
}
/* Ensure the bus port is valid */
if (!bus_group.bus_port(bus_id).is_valid()) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_bus),
"Bus port is invalid, check LSB and MSB!\n");
}
for (pugi::xml_node xml_pin : xml_bus.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_pin.name() != std::string(XML_PIN_NODE_NAME)) {
bad_tag(xml_pin, loc_data, xml_bus, {XML_PIN_NODE_NAME});
}
read_xml_pin(xml_pin, loc_data, bus_group, bus_id);
}
}
/********************************************************************
* Parse XML codes about <bus_group> to an object of BusGroup
*******************************************************************/
BusGroup read_xml_bus_group(const char* fname) {
vtr::ScopedStartFinishTimer timer("Read Bus Group");
BusGroup bus_group;
/* Parse the file */
pugi::xml_document doc;
pugiutil::loc_data loc_data;
try {
loc_data = pugiutil::load_xml(doc, fname);
pugi::xml_node xml_root = get_single_child(doc, XML_BUS_GROUP_NODE_NAME, loc_data);
size_t num_buses = std::distance(xml_root.children().begin(), xml_root.children().end());
/* Count the total number of pins */
size_t num_pins = 0;
for (pugi::xml_node xml_bus : xml_root.children()) {
num_pins += std::distance(xml_bus.children().begin(), xml_bus.children().end());
}
/* Reserve memory space for the buses */
bus_group.reserve_buses(num_buses);
/* Reserve memory space for the pins */
bus_group.reserve_pins(num_pins);
for (pugi::xml_node xml_bus : xml_root.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_bus.name() != std::string(XML_BUS_NODE_NAME)) {
bad_tag(xml_bus, loc_data, xml_root, {XML_BUS_NODE_NAME});
}
read_xml_bus(xml_bus, loc_data, bus_group);
}
} catch (pugiutil::XmlError& e) {
archfpga_throw(fname, e.line(),
"%s", e.what());
}
return bus_group;
}
} // End of namespace openfpga

View File

@ -0,0 +1,21 @@
#ifndef READ_XML_BUS_GROUP_H
#define READ_XML_BUS_GROUP_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "pugixml_util.hpp"
#include "pugixml.hpp"
#include "bus_group.h"
/********************************************************************
* Function declaration
*******************************************************************/
namespace openfpga { // Begin namespace openfpga
BusGroup read_xml_bus_group(const char* fname);
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,112 @@
/********************************************************************
* This file includes functions that outputs a bus group object to XML format
*******************************************************************/
/* Headers from system goes first */
#include <string>
#include <algorithm>
/* Headers from vtr util library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from openfpga util library */
#include "openfpga_digest.h"
/* Headers from arch openfpga library */
#include "write_xml_utils.h"
/* Headers from pin constraint library */
#include "bus_group_xml_constants.h"
#include "write_xml_bus_group.h"
namespace openfpga { // Begin namespace openfpga
/********************************************************************
* A writer to output a bus to XML format
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
*******************************************************************/
static
int write_xml_bus(std::fstream& fp,
const BusGroup& bus_group,
const BusGroupId& bus_id) {
/* Validate the file stream */
if (false == openfpga::valid_file_stream(fp)) {
return 2;
}
openfpga::write_tab_to_file(fp, 1);
fp << "<" << XML_BUS_NODE_NAME << "";
if (false == bus_group.valid_bus_id(bus_id)) {
return 1;
}
write_xml_attribute(fp, XML_BUS_PORT_ATTRIBUTE_NAME, generate_xml_port_name(bus_group.bus_port(bus_id)).c_str());
fp << ">" << "\n";
/* Output all the pins under this bus */
for (const BusPinId& pin_id : bus_group.bus_pins(bus_id)) {
openfpga::write_tab_to_file(fp, 2);
fp << "<" << XML_PIN_NODE_NAME << "";
write_xml_attribute(fp, XML_PIN_INDEX_ATTRIBUTE_NAME, bus_group.pin_index(pin_id));
write_xml_attribute(fp, XML_PIN_NAME_ATTRIBUTE_NAME, bus_group.pin_name(pin_id).c_str());
fp << "/>" << "\n";
}
openfpga::write_tab_to_file(fp, 1);
fp << "</" << XML_BUS_NODE_NAME << "";
fp << ">" << "\n";
return 0;
}
/********************************************************************
* A writer to output a bus group object to XML format
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
*******************************************************************/
int write_xml_bus_group(const char* fname,
const BusGroup& bus_group) {
vtr::ScopedStartFinishTimer timer("Write Bus Group");
/* Create a file handler */
std::fstream fp;
/* Open the file stream */
fp.open(std::string(fname), std::fstream::out | std::fstream::trunc);
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node */
fp << "<" << XML_BUS_GROUP_NODE_NAME << ">" << "\n";
int err_code = 0;
/* Write each bus */
for (const BusGroupId& bus : bus_group.buses()) {
/* Write bus */
err_code = write_xml_bus(fp, bus_group, bus);
if (0 != err_code) {
return err_code;
}
}
/* Finish writing the root node */
fp << "</" << XML_BUS_GROUP_NODE_NAME << ">" << "\n";
/* Close the file stream */
fp.close();
return err_code;
}
} // End of namespace openfpga

View File

@ -0,0 +1,20 @@
#ifndef WRITE_XML_BUS_GROUP_H
#define WRITE_XML_BUS_GROUP_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "bus_group.h"
/********************************************************************
* Function declaration
*******************************************************************/
namespace openfpga { // Begin namespace openfpga
int write_xml_bus_group(const char* fname,
const BusGroup& bus_group);
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,33 @@
/********************************************************************
* Unit test functions to validate the correctness of
* 1. parser of data structures
* 2. writer of data structures
*******************************************************************/
/* Headers from vtrutils */
#include "vtr_assert.h"
#include "vtr_log.h"
/* Headers from readarchopenfpga */
#include "read_xml_bus_group.h"
#include "write_xml_bus_group.h"
int main(int argc, const char** argv) {
/* Ensure we have only one or two argument */
VTR_ASSERT((2 == argc) || (3 == argc));
/* Parse the circuit library from an XML file */
const openfpga::BusGroup& bus_group = openfpga::read_xml_bus_group(argv[1]);
VTR_LOG("Parsed %lu bus(es) from XML into bus group.\n",
bus_group.buses().size());
/* Output the bus group to an XML file
* This is optional only used when there is a second argument
*/
if (3 <= argc) {
openfpga::write_xml_bus_group(argv[2], bus_group);
VTR_LOG("Write the bus group to an XML file: %s.\n",
argv[2]);
}
}

View File

@ -28,6 +28,7 @@ target_link_libraries(libopenfpga
libini libini
libpcf libpcf
libvtrutil libvtrutil
libbusgroup
libvpr) libvpr)
#Create the test executable #Create the test executable

View File

@ -17,6 +17,9 @@
/* Headers from pcf library */ /* Headers from pcf library */
#include "read_xml_pin_constraints.h" #include "read_xml_pin_constraints.h"
/* Headers from bgf library */
#include "read_xml_bus_group.h"
/* Include global variables of VPR */ /* Include global variables of VPR */
#include "globals.h" #include "globals.h"
@ -79,6 +82,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_bitstream = cmd.option("bitstream"); CommandOptionId opt_bitstream = cmd.option("bitstream");
CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path"); CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path");
CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
CommandOptionId opt_bgf = cmd.option("bus_group_file");
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
CommandOptionId opt_fast_configuration = cmd.option("fast_configuration"); CommandOptionId opt_fast_configuration = cmd.option("fast_configuration");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
@ -112,6 +116,12 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); 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_full_testbench(openfpga_ctx.module_graph(), return fpga_verilog_full_testbench(openfpga_ctx.module_graph(),
openfpga_ctx.bitstream_manager(), openfpga_ctx.bitstream_manager(),
openfpga_ctx.fabric_bitstream(), openfpga_ctx.fabric_bitstream(),
@ -119,6 +129,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx,
g_vpr_ctx.atom(), g_vpr_ctx.atom(),
g_vpr_ctx.placement(), g_vpr_ctx.placement(),
pin_constraints, pin_constraints,
bus_group,
cmd_context.option_value(cmd, opt_bitstream), cmd_context.option_value(cmd, opt_bitstream),
openfpga_ctx.io_location_map(), openfpga_ctx.io_location_map(),
openfpga_ctx.fabric_global_port_info(), openfpga_ctx.fabric_global_port_info(),
@ -138,6 +149,7 @@ int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path"); CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path");
CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); CommandOptionId opt_pcf = cmd.option("pin_constraints_file");
CommandOptionId opt_bgf = cmd.option("bus_group_file");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
CommandOptionId opt_default_net_type = cmd.option("default_net_type"); CommandOptionId opt_default_net_type = cmd.option("default_net_type");
CommandOptionId opt_include_signal_init = cmd.option("include_signal_init"); CommandOptionId opt_include_signal_init = cmd.option("include_signal_init");
@ -171,11 +183,18 @@ int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx,
pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); 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_fabric_wrapper(openfpga_ctx.module_graph(), return fpga_verilog_preconfigured_fabric_wrapper(openfpga_ctx.module_graph(),
openfpga_ctx.bitstream_manager(), openfpga_ctx.bitstream_manager(),
g_vpr_ctx.atom(), g_vpr_ctx.atom(),
g_vpr_ctx.placement(), g_vpr_ctx.placement(),
pin_constraints, pin_constraints,
bus_group,
openfpga_ctx.io_location_map(), openfpga_ctx.io_location_map(),
openfpga_ctx.fabric_global_port_info(), openfpga_ctx.fabric_global_port_info(),
openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.vpr_netlist_annotation(),
@ -192,6 +211,7 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx,
CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_output_dir = cmd.option("file");
CommandOptionId opt_pcf = cmd.option("pin_constraints_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_fabric_netlist = cmd.option("fabric_netlist_file_path");
CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path");
CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping");
@ -222,9 +242,16 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx,
pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); 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(), return fpga_verilog_preconfigured_testbench(openfpga_ctx.module_graph(),
g_vpr_ctx.atom(), g_vpr_ctx.atom(),
pin_constraints, pin_constraints,
bus_group,
openfpga_ctx.fabric_global_port_info(), openfpga_ctx.fabric_global_port_info(),
openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.vpr_netlist_annotation(),
openfpga_ctx.simulation_setting(), openfpga_ctx.simulation_setting(),

View File

@ -89,6 +89,11 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell<Openfpg
shell_cmd.set_option_short_name(pcf_opt, "pcf"); shell_cmd.set_option_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); 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'*/ /* 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"); 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); shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING);
@ -154,6 +159,11 @@ ShellCommandId add_openfpga_write_preconfigured_fabric_wrapper_command(openfpga:
shell_cmd.set_option_short_name(pcf_opt, "pcf"); shell_cmd.set_option_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); 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 '--explicit_port_mapping' */ /* add an option '--explicit_port_mapping' */
shell_cmd.add_option("explicit_port_mapping", false, "use explicit port mapping in verilog netlists"); shell_cmd.add_option("explicit_port_mapping", false, "use explicit port mapping in verilog netlists");
@ -210,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_short_name(pcf_opt, "pcf");
shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); 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'*/ /* 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"); 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); shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING);

View File

@ -159,6 +159,7 @@ int fpga_verilog_full_testbench(const ModuleManager &module_manager,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PlacementContext &place_ctx, const PlacementContext &place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::string& bitstream_file, const std::string& bitstream_file,
const IoLocationMap &io_location_map, const IoLocationMap &io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
@ -188,6 +189,7 @@ int fpga_verilog_full_testbench(const ModuleManager &module_manager,
fabric_global_port_info, fabric_global_port_info,
atom_ctx, place_ctx, atom_ctx, place_ctx,
pin_constraints, pin_constraints,
bus_group,
bitstream_file, bitstream_file,
io_location_map, io_location_map,
netlist_annotation, netlist_annotation,
@ -214,6 +216,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PlacementContext &place_ctx, const PlacementContext &place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const IoLocationMap &io_location_map, const IoLocationMap &io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation, const VprNetlistAnnotation &netlist_annotation,
@ -239,6 +242,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
circuit_lib, fabric_global_port_info, circuit_lib, fabric_global_port_info,
atom_ctx, place_ctx, atom_ctx, place_ctx,
pin_constraints, pin_constraints,
bus_group,
io_location_map, io_location_map,
netlist_annotation, netlist_annotation,
netlist_name, netlist_name,
@ -257,6 +261,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation, const VprNetlistAnnotation &netlist_annotation,
const SimulationSetting &simulation_setting, const SimulationSetting &simulation_setting,
@ -282,6 +287,7 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
module_manager, module_manager,
fabric_global_port_info, fabric_global_port_info,
pin_constraints, pin_constraints,
bus_group,
simulation_setting, simulation_setting,
options); options);

View File

@ -24,6 +24,7 @@
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
#include "vpr_netlist_annotation.h" #include "vpr_netlist_annotation.h"
#include "memory_bank_shift_register_banks.h" #include "memory_bank_shift_register_banks.h"
#include "bus_group.h"
#include "fabric_verilog_options.h" #include "fabric_verilog_options.h"
#include "verilog_testbench_options.h" #include "verilog_testbench_options.h"
@ -52,6 +53,7 @@ int fpga_verilog_full_testbench(const ModuleManager& module_manager,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::string& bitstream_file, const std::string& bitstream_file,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
@ -66,6 +68,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PlacementContext &place_ctx, const PlacementContext &place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const IoLocationMap &io_location_map, const IoLocationMap &io_location_map,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation, const VprNetlistAnnotation &netlist_annotation,
@ -76,6 +79,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage
int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const FabricGlobalPortInfo &fabric_global_port_info, const FabricGlobalPortInfo &fabric_global_port_info,
const VprNetlistAnnotation &netlist_annotation, const VprNetlistAnnotation &netlist_annotation,
const SimulationSetting &simulation_setting, const SimulationSetting &simulation_setting,

View File

@ -109,6 +109,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& explicit_port_mapping) { const bool& explicit_port_mapping) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -116,22 +117,16 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp,
/* Instanciate benchmark */ /* Instanciate benchmark */
print_verilog_comment(fp, std::string("----- Reference Benchmark Instanication -------")); print_verilog_comment(fp, std::string("----- Reference Benchmark Instanication -------"));
/* Do NOT use explicit port mapping here:
* VPR added a prefix of "out_" to the output ports of input benchmark
*/
std::vector<std::string> prefix_to_remove;
prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX));
prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX));
print_verilog_testbench_benchmark_instance(fp, reference_verilog_top_name, print_verilog_testbench_benchmark_instance(fp, reference_verilog_top_name,
std::string(BENCHMARK_INSTANCE_NAME), std::string(BENCHMARK_INSTANCE_NAME),
std::string(), std::string(),
std::string(), std::string(),
std::string(), std::string(),
prefix_to_remove,
std::string(BENCHMARK_PORT_POSTFIX), std::string(BENCHMARK_PORT_POSTFIX),
std::vector<std::string>(), std::vector<std::string>(),
atom_ctx, netlist_annotation, atom_ctx, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
explicit_port_mapping); explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------")); print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -149,29 +144,24 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& explicit_port_mapping) { const bool& explicit_port_mapping) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
print_verilog_comment(fp, std::string("----- FPGA fabric instanciation -------")); print_verilog_comment(fp, std::string("----- FPGA fabric instanciation -------"));
/* VPR added a prefix of "out_" to the output ports of input benchmark */
std::vector<std::string> prefix_to_remove;
prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX));
prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX));
/* Always use explicit port mapping */ /* Always use explicit port mapping */
print_verilog_testbench_benchmark_instance(fp, std::string(circuit_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX)), print_verilog_testbench_benchmark_instance(fp, std::string(circuit_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX)),
std::string(FPGA_INSTANCE_NAME), std::string(FPGA_INSTANCE_NAME),
std::string(), std::string(),
std::string(), std::string(),
std::string(), std::string(),
prefix_to_remove,
std::string(FPGA_PORT_POSTFIX), std::string(FPGA_PORT_POSTFIX),
std::vector<std::string>(), std::vector<std::string>(),
atom_ctx, netlist_annotation, atom_ctx, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
explicit_port_mapping); explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End FPGA Fabric Instanication -------")); print_verilog_comment(fp, std::string("----- End FPGA Fabric Instanication -------"));
@ -288,6 +278,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
const ModuleManager& module_manager, const ModuleManager& module_manager,
const FabricGlobalPortInfo& global_ports, const FabricGlobalPortInfo& global_ports,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const SimulationSetting& simulation_parameters, const SimulationSetting& simulation_parameters,
const VerilogTestbenchOption &options) { 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("'"); 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 +307,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
print_verilog_random_testbench_fpga_instance(fp, circuit_name, print_verilog_random_testbench_fpga_instance(fp, circuit_name,
atom_ctx, netlist_annotation, atom_ctx, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
options.explicit_port_mapping()); options.explicit_port_mapping());
/* Call defined benchmark */ /* Call defined benchmark */
@ -323,6 +315,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name,
print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name, print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name,
atom_ctx, netlist_annotation, atom_ctx, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
options.explicit_port_mapping()); options.explicit_port_mapping());
} }

View File

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

View File

@ -38,7 +38,8 @@ static
void print_verilog_preconfig_top_module_ports(std::fstream &fp, void print_verilog_preconfig_top_module_ports(std::fstream &fp,
const std::string &circuit_name, const std::string &circuit_name,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const VprNetlistAnnotation &netlist_annotation) { const VprNetlistAnnotation &netlist_annotation,
const BusGroup& bus_group) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
@ -47,14 +48,15 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp,
fp << "module " << circuit_name << std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX); fp << "module " << circuit_name << std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX);
fp << " (" << std::endl; fp << " (" << std::endl;
/* Add module ports */
size_t port_counter = 0;
/* Port type-to-type mapping */ /* Port type-to-type mapping */
std::map<AtomBlockType, enum e_dump_verilog_port_type> port_type2type_map; std::map<AtomBlockType, enum e_dump_verilog_port_type> port_type2type_map;
port_type2type_map[AtomBlockType::INPAD] = VERILOG_PORT_INPUT; port_type2type_map[AtomBlockType::INPAD] = VERILOG_PORT_INPUT;
port_type2type_map[AtomBlockType::OUTPAD] = VERILOG_PORT_OUTPUT; port_type2type_map[AtomBlockType::OUTPAD] = VERILOG_PORT_OUTPUT;
/* Ports to be added, this is to avoid any bus port */
std::vector<BasicPort> port_list;
std::vector<AtomBlockType> port_types;
/* Print all the I/Os of the circuit implementation to be tested*/ /* Print all the I/Os of the circuit implementation to be tested*/
for (const AtomBlockId &atom_blk : atom_ctx.nlist.blocks()) { for (const AtomBlockId &atom_blk : atom_ctx.nlist.blocks()) {
/* We only care I/O logical blocks !*/ /* We only care I/O logical blocks !*/
@ -62,8 +64,8 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp,
continue; 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); std::string block_name = atom_ctx.nlist.block_name(atom_blk);
/* The block may be renamed as it contains special characters which violate Verilog syntax */
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
@ -82,12 +84,38 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp,
} }
} }
/* 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_list.end() == std::find(port_list.begin(), port_list.end(), bus_group.bus_port(bus_id))) {
port_list.push_back(bus_group.bus_port(bus_id));
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
continue;
}
/* Both input and output ports have only size of 1 */
BasicPort module_port(std::string(block_name), 1);
port_list.push_back(module_port);
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
/* After collecting all the ports, now print the port mapping */
size_t port_counter = 0;
for (size_t iport = 0; iport < port_list.size(); ++iport) {
BasicPort module_port = port_list[iport];
AtomBlockType port_type = port_types[iport];
if (0 < port_counter) { if (0 < port_counter) {
fp << "," << std::endl; fp << "," << std::endl;
} }
/* Both input and output ports have only size of 1 */
BasicPort module_port(std::string(block_name), 1); fp << generate_verilog_port(port_type2type_map[port_type], module_port);
fp << generate_verilog_port(port_type2type_map[atom_ctx.nlist.block_type(atom_blk)], module_port);
/* Update port counter */ /* Update port counter */
port_counter++; port_counter++;
@ -434,6 +462,7 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager,
const AtomContext &atom_ctx, const AtomContext &atom_ctx,
const PlacementContext &place_ctx, const PlacementContext &place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const IoLocationMap &io_location_map, const IoLocationMap &io_location_map,
const VprNetlistAnnotation &netlist_annotation, const VprNetlistAnnotation &netlist_annotation,
const std::string &circuit_name, const std::string &circuit_name,
@ -461,7 +490,7 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager,
options.default_net_type()); options.default_net_type());
/* Print module declaration and ports */ /* Print module declaration and ports */
print_verilog_preconfig_top_module_ports(fp, circuit_name, atom_ctx, netlist_annotation); print_verilog_preconfig_top_module_ports(fp, circuit_name, atom_ctx, netlist_annotation, bus_group);
/* Find the top_module */ /* Find the top_module */
ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name()); ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name());
@ -488,16 +517,13 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager,
} }
/* Connect I/Os to benchmark I/Os or constant driver */ /* Connect I/Os to benchmark I/Os or constant driver */
std::vector<std::string> prefix_to_remove;
prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX));
prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX));
print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module, print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module,
atom_ctx, place_ctx, io_location_map, atom_ctx, place_ctx, io_location_map,
netlist_annotation, netlist_annotation,
bus_group,
std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX),
std::string(), std::string(),
std::string(), std::string(),
prefix_to_remove,
std::vector<std::string>(), std::vector<std::string>(),
(size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE);

View File

@ -14,6 +14,7 @@
#include "io_location_map.h" #include "io_location_map.h"
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
#include "config_protocol.h" #include "config_protocol.h"
#include "bus_group.h"
#include "vpr_netlist_annotation.h" #include "vpr_netlist_annotation.h"
#include "verilog_testbench_options.h" #include "verilog_testbench_options.h"
@ -32,6 +33,7 @@ int print_verilog_preconfig_top_module(const ModuleManager& module_manager,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const std::string& circuit_name, const std::string& circuit_name,

View File

@ -22,6 +22,7 @@
#include "module_manager_utils.h" #include "module_manager_utils.h"
#include "fabric_global_port_info_utils.h" #include "fabric_global_port_info_utils.h"
#include "openfpga_atom_netlist_utils.h"
#include "verilog_constants.h" #include "verilog_constants.h"
#include "verilog_writer_utils.h" #include "verilog_writer_utils.h"
@ -79,19 +80,22 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
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& input_port_postfix,
const std::vector<std::string>& output_port_prefix_to_remove,
const std::string& output_port_postfix, const std::string& output_port_postfix,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& use_explicit_port_map) { const bool& use_explicit_port_map) {
/* Validate the file stream */ /* Validate the file stream */
valid_file_stream(fp); valid_file_stream(fp);
fp << "\t" << module_name << " " << instance_name << "(" << std::endl; 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()) { for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) {
/* Bypass non-I/O atom blocks ! */ /* Bypass non-I/O atom blocks ! */
if ( (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk)) if ( (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk))
@ -105,62 +109,129 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
/* The first port does not need a comma */ /* Note that VPR added a prefix "out_" or "out:" to the name of output blocks
if(0 < port_counter){ * We can remove this when specified through input argument
fp << "," << std::endl; */
} if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
/* Input port follows the logical block name while output port requires a special postfix */ block_name = remove_atom_block_name_prefix(block_name);
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 << "(";
} }
/* 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 */
port_names.push_back(block_name);
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
/* Print out the instance with port mapping */
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 << "(";
}
/* For bus ports, include a complete list of pins */
BusGroupId bus_id = bus_group.find_bus(port_names[iport]);
if (bus_id) {
fp << "{";
int pin_counter = 0;
/* Include all the pins */
for (const BusPinId& pin : bus_group.bus_pins(bus_id)) {
if (0 < pin_counter) {
fp << ", ";
}
/* Polarity of some input may have to be inverted, as defined in pin constraints /* 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 * 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) * 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 * 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)) { if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(bus_group.pin_name(pin))) {
fp << "~"; fp << "~";
} }
fp << bus_group.pin_name(pin);
/* For clock ports, skip postfix */ /* For clock ports, skip postfix */
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(), port_names[iport])) {
fp << block_name; fp << input_port_postfix;
} else {
fp << block_name << input_port_postfix;
} }
if (true == use_explicit_port_map) {
fp << ")"; pin_counter++;
} }
fp << "}";
} else { } else {
VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)); /* Polarity of some input may have to be inverted, as defined in pin constraints
fp << "\t\t"; * For example, the reset signal of the benchmark is active low
/* Note that VPR added a prefix "out_" or "out:" to the name of output blocks * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* We can remove this when specified through input argument * However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/ */
std::string output_block_name = block_name; if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) {
for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { fp << "~";
if (!prefix_to_remove.empty()) {
if (0 == output_block_name.find(prefix_to_remove)) {
output_block_name.erase(0, prefix_to_remove.length());
break;
} }
fp << port_names[iport];
/* For clock ports, skip postfix */
if (clock_port_names.end() == std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) {
fp << input_port_postfix;
} }
} }
if (true == use_explicit_port_map) { if (true == use_explicit_port_map) {
fp << "." << output_block_name << module_output_port_postfix << "("; fp << ")";
}
} else {
VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == port_types[iport]);
if (true == use_explicit_port_map) {
fp << "." << port_names[iport] << module_output_port_postfix << "(";
}
/* For bus ports, include a complete list of pins */
BusGroupId bus_id = bus_group.find_bus(port_names[iport]);
if (bus_id) {
fp << "{";
int pin_counter = 0;
/* Include all the pins */
for (const BusPinId& pin : bus_group.bus_pins(bus_id)) {
if (0 < pin_counter) {
fp << ", ";
}
fp << bus_group.pin_name(pin) << output_port_postfix;
pin_counter++;
}
fp << "}";
} else {
fp << port_names[iport] << output_port_postfix;
} }
fp << block_name << output_port_postfix;
if (true == use_explicit_port_map) { if (true == use_explicit_port_map) {
fp << ")"; fp << ")";
} }
} }
/* Update the counter */ /* Update the counter */
port_counter++; port_counter++;
} }
fp << "\t);" << std::endl; fp << "\n\t);" << std::endl;
} }
/******************************************************************** /********************************************************************
@ -177,10 +248,10 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, 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>& output_port_prefix_to_remove,
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 */
@ -276,13 +347,8 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
/* Note that VPR added a prefix to the name of output blocks /* Note that VPR added a prefix to the name of output blocks
* We can remove this when specified through input argument * We can remove this when specified through input argument
*/ */
for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
if (!prefix_to_remove.empty()) { block_name = remove_atom_block_name_prefix(block_name);
if (0 == block_name.find(prefix_to_remove)) {
block_name.erase(0, prefix_to_remove.length());
break;
}
}
} }
/* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1 /* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1
@ -290,6 +356,18 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
* due to verification context! Here, we give full customization on naming * due to verification context! Here, we give full customization on naming
*/ */
BasicPort benchmark_io_port; BasicPort benchmark_io_port;
/* If this benchmark pin belongs to any bus group, use the bus pin instead */
BusGroupId bus_id = bus_group.find_pin_bus(block_name);
BusPinId bus_pin_id = bus_group.find_pin(block_name);
if (bus_id) {
block_name = bus_group.bus_port(bus_id).get_name();
VTR_ASSERT_SAFE(bus_pin_id);
benchmark_io_port.set_width(bus_group.pin_index(bus_pin_id), bus_group.pin_index(bus_pin_id));
} else {
benchmark_io_port.set_width(1);
}
if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) { if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) {
/* If the port is a clock, do not add a postfix */ /* If the port is a clock, do not add a postfix */
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)) {
@ -297,13 +375,11 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
} else { } else {
benchmark_io_port.set_name(std::string(block_name + io_input_port_name_postfix)); benchmark_io_port.set_name(std::string(block_name + io_input_port_name_postfix));
} }
benchmark_io_port.set_width(1);
print_verilog_comment(fp, std::string("----- Blif Benchmark input " + block_name + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----")); print_verilog_comment(fp, std::string("----- Blif Benchmark input " + block_name + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----"));
print_verilog_wire_connection(fp, module_mapped_io_port, benchmark_io_port, false); print_verilog_wire_connection(fp, module_mapped_io_port, 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(std::string(block_name + io_output_port_name_postfix)); benchmark_io_port.set_name(std::string(block_name + io_output_port_name_postfix));
benchmark_io_port.set_width(1);
print_verilog_comment(fp, std::string("----- Blif Benchmark output " + block_name + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----")); print_verilog_comment(fp, std::string("----- Blif Benchmark output " + block_name + " is mapped to FPGA IOPAD " + module_mapped_io_port.get_name() + "[" + std::to_string(io_index) + "] -----"));
print_verilog_wire_connection(fp, benchmark_io_port, module_mapped_io_port, false); print_verilog_wire_connection(fp, benchmark_io_port, module_mapped_io_port, false);
} }
@ -487,6 +563,7 @@ void print_verilog_testbench_check(std::fstream& fp,
} }
if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) { if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
block_name = remove_atom_block_name_prefix(block_name);
fp << "\t\t\tif(!(" << block_name << fpga_port_postfix; fp << "\t\t\tif(!(" << block_name << fpga_port_postfix;
fp << " === " << block_name << benchmark_port_postfix; fp << " === " << block_name << benchmark_port_postfix;
fp << ") && !(" << block_name << benchmark_port_postfix; fp << ") && !(" << block_name << benchmark_port_postfix;
@ -514,6 +591,7 @@ void print_verilog_testbench_check(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
block_name = remove_atom_block_name_prefix(block_name);
fp << "\talways@(posedge " << block_name << check_flag_port_postfix << ") begin" << std::endl; fp << "\talways@(posedge " << block_name << check_flag_port_postfix << ") begin" << std::endl;
fp << "\t\tif(" << block_name << check_flag_port_postfix << ") begin" << std::endl; fp << "\t\tif(" << block_name << check_flag_port_postfix << ") begin" << std::endl;
@ -621,6 +699,9 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
block_name = remove_atom_block_name_prefix(block_name);
}
/* Bypass clock ports because their stimulus cannot be random */ /* 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)) {
@ -656,6 +737,7 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
block_name = remove_atom_block_name_prefix(block_name);
/* Each logical block assumes a single-width port */ /* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1);
@ -690,6 +772,9 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) {
block_name = remove_atom_block_name_prefix(block_name);
}
/* Bypass clock ports because their stimulus cannot be random */ /* 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)) {
@ -785,6 +870,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
block_name = remove_atom_block_name_prefix(block_name);
/* Each logical block assumes a single-width port */ /* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + fpga_output_port_postfix), 1); BasicPort output_port(std::string(block_name + fpga_output_port_postfix), 1);
@ -811,6 +897,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
block_name = remove_atom_block_name_prefix(block_name);
/* Each logical block assumes a single-width port */ /* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + benchmark_output_port_postfix), 1); BasicPort output_port(std::string(block_name + benchmark_output_port_postfix), 1);
@ -833,6 +920,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp,
if (true == netlist_annotation.is_block_renamed(atom_blk)) { if (true == netlist_annotation.is_block_renamed(atom_blk)) {
block_name = netlist_annotation.block_name(atom_blk); block_name = netlist_annotation.block_name(atom_blk);
} }
block_name = remove_atom_block_name_prefix(block_name);
/* Each logical block assumes a single-width port */ /* Each logical block assumes a single-width port */
BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1);

View File

@ -17,6 +17,7 @@
#include "simulation_setting.h" #include "simulation_setting.h"
#include "fabric_global_port_info.h" #include "fabric_global_port_info.h"
#include "pin_constraints.h" #include "pin_constraints.h"
#include "bus_group.h"
/******************************************************************** /********************************************************************
* Function declaration * Function declaration
@ -38,12 +39,12 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
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& input_port_postfix,
const std::vector<std::string>& output_port_prefix_to_remove,
const std::string& output_port_postfix, const std::string& output_port_postfix,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const bool& use_explicit_port_map); const bool& use_explicit_port_map);
void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
@ -53,10 +54,10 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, 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>& output_port_prefix_to_remove,
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);

View File

@ -937,6 +937,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::vector<std::string>& clock_port_names, const std::vector<std::string>& clock_port_names,
const bool& explicit_port_mapping) { const bool& explicit_port_mapping) {
/* Validate the file stream */ /* Validate the file stream */
@ -945,22 +946,16 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp,
/* Instanciate benchmark */ /* Instanciate benchmark */
print_verilog_comment(fp, std::string("----- Reference Benchmark Instanication -------")); print_verilog_comment(fp, std::string("----- Reference Benchmark Instanication -------"));
/* Do NOT use explicit port mapping here:
* VPR added a prefix of "out_" to the output ports of input benchmark
*/
std::vector<std::string> prefix_to_remove;
prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX));
prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX));
print_verilog_testbench_benchmark_instance(fp, reference_verilog_top_name, print_verilog_testbench_benchmark_instance(fp, reference_verilog_top_name,
std::string(TOP_TESTBENCH_REFERENCE_INSTANCE_NAME), std::string(TOP_TESTBENCH_REFERENCE_INSTANCE_NAME),
std::string(), std::string(),
std::string(), std::string(),
std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX),
prefix_to_remove,
std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX),
clock_port_names, clock_port_names,
atom_ctx, netlist_annotation, atom_ctx, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
explicit_port_mapping); explicit_port_mapping);
print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------")); print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------"));
@ -1924,6 +1919,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::string& bitstream_file, const std::string& bitstream_file,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,
@ -2064,10 +2060,10 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module, print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module,
atom_ctx, place_ctx, io_location_map, atom_ctx, place_ctx, io_location_map,
netlist_annotation, netlist_annotation,
BusGroup(),
std::string(), std::string(),
std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX),
std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX),
std::vector<std::string>(),
clock_port_names, clock_port_names,
(size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE);
@ -2078,6 +2074,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
atom_ctx, atom_ctx,
netlist_annotation, netlist_annotation,
pin_constraints, pin_constraints,
bus_group,
clock_port_names, clock_port_names,
explicit_port_mapping); explicit_port_mapping);
} }

View File

@ -19,6 +19,7 @@
#include "simulation_setting.h" #include "simulation_setting.h"
#include "memory_bank_shift_register_banks.h" #include "memory_bank_shift_register_banks.h"
#include "verilog_testbench_options.h" #include "verilog_testbench_options.h"
#include "bus_group.h"
/******************************************************************** /********************************************************************
* Function declaration * Function declaration
@ -37,6 +38,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager,
const AtomContext& atom_ctx, const AtomContext& atom_ctx,
const PlacementContext& place_ctx, const PlacementContext& place_ctx,
const PinConstraints& pin_constraints, const PinConstraints& pin_constraints,
const BusGroup& bus_group,
const std::string& bitstream_file, const std::string& bitstream_file,
const IoLocationMap& io_location_map, const IoLocationMap& io_location_map,
const VprNetlistAnnotation& netlist_annotation, const VprNetlistAnnotation& netlist_annotation,

View File

@ -11,6 +11,7 @@
/* Headers from vtrutil library */ /* Headers from vtrutil library */
#include "atom_netlist_utils.h" #include "atom_netlist_utils.h"
#include "openfpga_reserved_words.h"
#include "openfpga_atom_netlist_utils.h" #include "openfpga_atom_netlist_utils.h"
/* begin namespace openfpga */ /* begin namespace openfpga */
@ -38,4 +39,27 @@ std::vector<std::string> find_atom_netlist_clock_port_names(const AtomNetlist& a
return clock_names; return clock_names;
} }
/********************************************************************
* Remove the prefix that is added to the name of a output block (by VPR)
*******************************************************************/
std::string remove_atom_block_name_prefix(const std::string& block_name) {
/* VPR added a prefix of "out_" to the output ports of input benchmark */
std::vector<std::string> prefix_to_remove;
prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX));
prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX));
std::string ret_block_name = block_name;
for (const std::string& cur_prefix_to_remove : prefix_to_remove) {
if (!cur_prefix_to_remove.empty()) {
if (0 == ret_block_name.find(cur_prefix_to_remove)) {
ret_block_name.erase(0, cur_prefix_to_remove.length());
break;
}
}
}
return ret_block_name;
}
} /* end namespace openfpga */ } /* end namespace openfpga */

View File

@ -19,6 +19,8 @@ namespace openfpga {
std::vector<std::string> find_atom_netlist_clock_port_names(const AtomNetlist& atom_nlist, std::vector<std::string> find_atom_netlist_clock_port_names(const AtomNetlist& atom_nlist,
const VprNetlistAnnotation& netlist_annotation); const VprNetlistAnnotation& netlist_annotation);
std::string remove_atom_block_name_prefix(const std::string& block_name);
} /* end namespace openfpga */ } /* end namespace openfpga */
#endif #endif

View File

@ -39,3 +39,4 @@ synth -run check
# Clean and output blif # Clean and output blif
opt_clean -purge opt_clean -purge
write_blif rewritten_${OUTPUT_BLIF} write_blif rewritten_${OUTPUT_BLIF}
write_verilog ${OUTPUT_VERILOG}

View File

@ -0,0 +1,64 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - 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
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_PORT_MAPPING} --include_signal_init --bitstream fabric_bitstream.bit --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bus_group_file ${OPENFPGA_BUS_GROUP_FILE}
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -0,0 +1,65 @@
# Run VPR for the 'and' design
#--write_rr_graph example_rr_graph.xml
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal
# Read OpenFPGA architecture definition
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
# Read OpenFPGA simulation settings
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
# Annotate the OpenFPGA architecture to VPR data base
# to debug use --verbose options
link_openfpga_arch --sort_gsb_chan_node_in_edges
# Check and correct any naming conflicts in the BLIF netlist
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
# Apply fix-up to clustering nets based on routing results
pb_pin_fixup --verbose
# Apply fix-up to Look-Up Table truth tables based on packing results
lut_truth_table_fixup
# Build the module graph
# - Enabled compression on routing architecture modules
# - Enable pin duplication on grid modules
build_fabric --compress_routing #--verbose
# Write the fabric hierarchy of module graph to a file
# This is used by hierarchical PnR flows
write_fabric_hierarchy --file ./fabric_hierarchy.txt
# Repack the netlist to physical pbs
# This must be done before bitstream generator and testbench generation
# Strongly recommend it is done after all the fix-up have been applied
repack #--verbose
# Build the bitstream
# - Output the fabric-independent bitstream to a file
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
# Build fabric-dependent bitstream
build_fabric_bitstream --verbose
# Write fabric-dependent bitstream
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
# Write the Verilog netlist for FPGA fabric
# - Enable the use of explicit port mapping in Verilog netlist
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --verbose
# Write the Verilog testbench for FPGA fabric
# - We suggest the use of same output directory as fabric Verilog netlists
# - Must specify the reference benchmark file if you want to output any testbenches
# - 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
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC ${OPENFPGA_VERILOG_PORT_MAPPING} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bus_group_file ${OPENFPGA_BUS_GROUP_FILE}
write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} ${OPENFPGA_VERILOG_PORT_MAPPING} --pin_constraints_file ${OPENFPGA_PIN_CONSTRAINTS_FILE} --bus_group_file ${OPENFPGA_BUS_GROUP_FILE}
# Finish and exit OpenFPGA
exit
# Note :
# To run verification at the end of the flow maintain source in ./SRC directory

View File

@ -166,3 +166,9 @@ run-task basic_tests/write_gsb/write_gsb_to_xml --debug --show_thread_logs
run-task basic_tests/write_gsb/write_gsb_to_xml_compress_routing --debug --show_thread_logs run-task basic_tests/write_gsb/write_gsb_to_xml_compress_routing --debug --show_thread_logs
run-task basic_tests/write_gsb/write_unique_gsb_to_xml --debug --show_thread_logs run-task basic_tests/write_gsb/write_unique_gsb_to_xml --debug --show_thread_logs
run-task basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing --debug --show_thread_logs run-task basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing --debug --show_thread_logs
echo -e "Testing bus group features";
run-task basic_tests/bus_group/preconfig_testbench_explicit_mapping --debug --show_thread_logs
run-task basic_tests/bus_group/preconfig_testbench_implicit_mapping --debug --show_thread_logs
run-task basic_tests/bus_group/full_testbench_explicit_mapping --debug --show_thread_logs
run-task basic_tests/bus_group/full_testbench_implicit_mapping --debug --show_thread_logs

View File

@ -0,0 +1,12 @@
<bus_group>
<bus name="result[0:7]">
<pin id="0" name="result_7_"/>
<pin id="1" name="result_6_"/>
<pin id="2" name="result_5_"/>
<pin id="3" name="result_4_"/>
<pin id="4" name="result_3_"/>
<pin id="5" name="result_2_"/>
<pin id="6" name="result_1_"/>
<pin id="7" name="result_0_"/>
</bus>
</bus_group>

View File

@ -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>

View File

@ -0,0 +1,47 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = false
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_verilog_port_mapping=--explicit_port_mapping
openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
[SYNTHESIS_PARAM]
# Yosys script parameters
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v
bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v
bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt
bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36
bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys
bench0_top = counter
bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,12 @@
<bus_group>
<bus name="result[0:7]">
<pin id="0" name="result_7_"/>
<pin id="1" name="result_6_"/>
<pin id="2" name="result_5_"/>
<pin id="3" name="result_4_"/>
<pin id="4" name="result_3_"/>
<pin id="5" name="result_2_"/>
<pin id="6" name="result_1_"/>
<pin id="7" name="result_0_"/>
</bus>
</bus_group>

View File

@ -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>

View File

@ -0,0 +1,47 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = false
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_verilog_port_mapping=
openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
[SYNTHESIS_PARAM]
# Yosys script parameters
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v
bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v
bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt
bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36
bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys
bench0_top = counter
bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,12 @@
<bus_group>
<bus name="result[0:7]">
<pin id="0" name="result_7_"/>
<pin id="1" name="result_6_"/>
<pin id="2" name="result_5_"/>
<pin id="3" name="result_4_"/>
<pin id="4" name="result_3_"/>
<pin id="5" name="result_2_"/>
<pin id="6" name="result_1_"/>
<pin id="7" name="result_0_"/>
</bus>
</bus_group>

View File

@ -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>

View File

@ -0,0 +1,48 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = false
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_verilog_port_mapping=--explicit_port_mapping
openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
[SYNTHESIS_PARAM]
# Yosys script parameters
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v
bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v
bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt
bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36
bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys
bench0_top = counter
bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -0,0 +1,12 @@
<bus_group>
<bus name="result[0:7]">
<pin id="0" name="result_7_"/>
<pin id="1" name="result_6_"/>
<pin id="2" name="result_5_"/>
<pin id="3" name="result_4_"/>
<pin id="4" name="result_3_"/>
<pin id="5" name="result_2_"/>
<pin id="6" name="result_1_"/>
<pin id="7" name="result_0_"/>
</bus>
</bus_group>

View File

@ -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>

View File

@ -0,0 +1,48 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = false
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_dpram8K_dsp36_fracff_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_verilog_port_mapping=
openfpga_bus_group_file=${PATH:TASK_DIR}/config/counter8_bus_group.xml
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_8bit_async_reset/counter.v
[SYNTHESIS_PARAM]
# Yosys script parameters
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_cell_sim.v
bench_yosys_dff_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_fracff_40nm_dff_map.v
bench_yosys_bram_map_rules_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram.txt
bench_yosys_bram_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_bram_map.v
bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k6_frac_N10_tileable_adder_chain_dpram8K_dsp36_40nm_dsp_map.v
bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_36x36
bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dff_flow.ys
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys
bench0_top = counter
bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=