From 796428d848f1d66b91f072a56734be9045a81b77 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 14:22:21 -0800 Subject: [PATCH 01/37] [Doc] Add documentation about bus group file format --- .../manual/file_formats/bus_group_file.rst | 48 +++++++++++++++++++ docs/source/manual/file_formats/index.rst | 2 + 2 files changed, 50 insertions(+) create mode 100644 docs/source/manual/file_formats/bus_group_file.rst diff --git a/docs/source/manual/file_formats/bus_group_file.rst b/docs/source/manual/file_formats/bus_group_file.rst new file mode 100644 index 000000000..499db8900 --- /dev/null +++ b/docs/source/manual/file_formats/bus_group_file.rst @@ -0,0 +1,48 @@ +.. _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-related Syntax +------------------ + +.. option:: name="" + + The bus port name defined before synthesis. + +.. option:: lsb="" + + The *Least Significant Bit* (LSB) of the bus + +.. option:: msb="" + + The *Most Significant Bit* (MSB) of the bus + +Pin-related Syntax +------------------ + +.. option:: id="" + + 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="" + + The pin name after bus flatten in synthesis results diff --git a/docs/source/manual/file_formats/index.rst b/docs/source/manual/file_formats/index.rst index 7ed213012..c00f46b6b 100644 --- a/docs/source/manual/file_formats/index.rst +++ b/docs/source/manual/file_formats/index.rst @@ -25,3 +25,5 @@ OpenFPGA widely uses XML format for interchangable files io_mapping_file bitstream_distribution_file + + bus_group_file From f5e0d685cfeed272107b064098118adb73497f22 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 14:29:09 -0800 Subject: [PATCH 02/37] [Doc] Adjust figure width --- docs/source/tutorials/getting_started/tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/tutorials/getting_started/tools.rst b/docs/source/tutorials/getting_started/tools.rst index 7f1b7f850..ebff3c77c 100644 --- a/docs/source/tutorials/getting_started/tools.rst +++ b/docs/source/tutorials/getting_started/tools.rst @@ -11,7 +11,7 @@ To enable various design purposes, OpenFPGA integrates several tools to i.e., FP .. _fig_openfpga_tools: .. figure:: figures/openfpga_tools.svg - :scale: 25% + :width: 100% :alt: map to buried treasure OpenFPGA tool suites and design flows From b44701bc2c6f3cfe78985a712b3d22db5c8b3486 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 15:02:37 -0800 Subject: [PATCH 03/37] [Lib] Adding the 1st version of bus group data structure --- libopenfpga/CMakeLists.txt | 1 + libopenfpga/libbusgroup/CMakeLists.txt | 35 ++++++++++ libopenfpga/libbusgroup/src/bus_group.cpp | 68 ++++++++++++++++++ libopenfpga/libbusgroup/src/bus_group.h | 77 +++++++++++++++++++++ libopenfpga/libbusgroup/src/bus_group_fwd.h | 24 +++++++ 5 files changed, 205 insertions(+) create mode 100644 libopenfpga/libbusgroup/CMakeLists.txt create mode 100644 libopenfpga/libbusgroup/src/bus_group.cpp create mode 100644 libopenfpga/libbusgroup/src/bus_group.h create mode 100644 libopenfpga/libbusgroup/src/bus_group_fwd.h diff --git a/libopenfpga/CMakeLists.txt b/libopenfpga/CMakeLists.txt index 62dc6d596..36bce10b6 100644 --- a/libopenfpga/CMakeLists.txt +++ b/libopenfpga/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(libfabrickey) add_subdirectory(librepackdc) add_subdirectory(libfpgabitstream) add_subdirectory(libpcf) +add_subdirectory(libbusgroup) diff --git a/libopenfpga/libbusgroup/CMakeLists.txt b/libopenfpga/libbusgroup/CMakeLists.txt new file mode 100644 index 000000000..a2cbea164 --- /dev/null +++ b/libopenfpga/libbusgroup/CMakeLists.txt @@ -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}) diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp new file mode 100644 index 000000000..b4c05b7b4 --- /dev/null +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -0,0 +1,68 @@ +#include + +#include "vtr_assert.h" +#include "vtr_log.h" + +#include "bus_group.h" + +/************************************************************************ + * 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 { + /* validate the bus_id */ + VTR_ASSERT(valid_bus_id(bus_id)); + return bus_ports_[bus_id]; +} + +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_indices_.reserve(num_buses); + bus_pin_names_.reserve(num_buses); +} + +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_indices_.emplace_back(); + bus_pin_names_.emplace_back(); + + return bus_id; +} + +/************************************************************************ + * Internal invalidators/validators + ***********************************************************************/ +/* 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] ); +} + diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h new file mode 100644 index 000000000..6f8517fd0 --- /dev/null +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -0,0 +1,77 @@ +#ifndef BUS_GROUP_H +#define BUS_GROUP_H + +/******************************************************************** + * This file include the declaration of pin constraints + *******************************************************************/ +#include +#include +#include + +/* Headers from vtrutil library */ +#include "vtr_vector.h" + +/* Headers from openfpgautil library */ +#include "openfpga_port.h" + +#include "bus_group_fwd.h" + +/******************************************************************** + * 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::const_iterator bus_group_iterator; + /* Create range */ + typedef vtr::Range bus_group_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 */ + openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) 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); + + /* Add a bus to storage */ + BusGroupId create_bus(const openfpga::BasicPort& bus_port); + + public: /* Public invalidators/validators */ + /* Show if the pin constraint id is a valid for data queries */ + bool valid_bus_id(const BusGroupId& bus_id) const; + + private: /* Internal data */ + /* Unique ids for each bus */ + vtr::vector bus_ids_; + + /* Port information of each bus */ + vtr::vector bus_ports_; + + /* Indices of each pin under each bus */ + vtr::vector> bus_pin_indices_; + + /* Name of each pin under each bus */ + vtr::vector> bus_pin_names_; +}; + +#endif diff --git a/libopenfpga/libbusgroup/src/bus_group_fwd.h b/libopenfpga/libbusgroup/src/bus_group_fwd.h new file mode 100644 index 000000000..5f1d6cd25 --- /dev/null +++ b/libopenfpga/libbusgroup/src/bus_group_fwd.h @@ -0,0 +1,24 @@ +/************************************************************************ + * 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" + +struct bus_group_id_tag; +struct bus_pin_id_tag; + +typedef vtr::StrongId BusGroupId; +typedef vtr::StrongId BusPinId; + +/* Short declaration of class */ +class BusGroup; + +#endif From 4a78bcf5d346bb6b3cd7f9b7295ba783b867ff78 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 15:15:05 -0800 Subject: [PATCH 04/37] [Doc] update file format about bus group --- .../manual/file_formats/bus_group_file.rst | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/docs/source/manual/file_formats/bus_group_file.rst b/docs/source/manual/file_formats/bus_group_file.rst index 499db8900..bf14fec4e 100644 --- a/docs/source/manual/file_formats/bus_group_file.rst +++ b/docs/source/manual/file_formats/bus_group_file.rst @@ -12,29 +12,21 @@ An example of file is shown as follows. .. code-block:: xml - - + + - + Bus-related Syntax ------------------ .. option:: name="" - The bus port name defined before synthesis. - -.. option:: lsb="" - - The *Least Significant Bit* (LSB) of the bus - -.. option:: msb="" - - The *Most Significant Bit* (MSB) of the bus + The bus port defined before synthesis, e.g., addr[0:3] Pin-related Syntax ------------------ From 1edaa04715a02e3cac79cd148048b56b9ab47b41 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 15:50:44 -0800 Subject: [PATCH 05/37] [Lib] Adding XML parser for the bus group --- libopenfpga/libbusgroup/src/bus_group.cpp | 37 ++++- libopenfpga/libbusgroup/src/bus_group.h | 29 +++- .../libbusgroup/src/read_xml_bus_group.cpp | 131 ++++++++++++++++++ .../libbusgroup/src/read_xml_bus_group.h | 16 +++ 4 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 libopenfpga/libbusgroup/src/read_xml_bus_group.cpp create mode 100644 libopenfpga/libbusgroup/src/read_xml_bus_group.h diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index b4c05b7b4..3d6682a08 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -46,6 +46,12 @@ void BusGroup::reserve_buses(const size_t& num_buses) { bus_pin_names_.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); +} + BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { /* Create a new id */ BusGroupId bus_id = BusGroupId(bus_ids_.size()); @@ -58,11 +64,40 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { return bus_id; } +BusPinId BasicGroup::create_pin(const BusGroupId& bus_id) { + /* Create a new id */ + BusPinId pin_id = BusPinId(pin_ids_.size()); + + pin_ids_.push_back(pin_id); + + pin_indices_.emplace_back(); + pin_names_.emplace_back(); + + /* Register the pin to the bus */ + VTR_ASSERT(valid_bus_id(bus_id)); + bus_pin_ids_[bus_id].push_back(pin_id); + + return bus_id; +} + +void BusGroup::set_pin_index(const BusPinId& pin_id, const int& index) { + VTR_ASSERT(valid_pin_id(pin_id)); + pin_indices_[pin_id] = index; +} + +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; +} + /************************************************************************ * Internal invalidators/validators ***********************************************************************/ -/* 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] ); +} + diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index 6f8517fd0..ad2393be2 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -36,8 +36,10 @@ class BusGroup { public: /* Types */ typedef vtr::vector::const_iterator bus_group_iterator; + typedef vtr::vector::const_iterator bus_pin_iterator; /* Create range */ typedef vtr::Range bus_group_range; + typedef vtr::Range bus_pin_range; public: /* Constructors */ BusGroup(); public: /* Accessors: aggregates */ @@ -53,13 +55,28 @@ class BusGroup { /* 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 */ + BusPinId create_pin(const BusGroupId& bus_id); + + /* Set the index for a pin */ + void set_pin_index(const BusPinId& pin_id, const int& index); + + /* Set the name for a pin */ + void set_pin_index(const BusPinId& pin_id, const std::string& name); + public: /* Public invalidators/validators */ - /* Show if the pin constraint id is a valid for data queries */ + /* 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 bus_ids_; @@ -68,10 +85,16 @@ class BusGroup { vtr::vector bus_ports_; /* Indices of each pin under each bus */ - vtr::vector> bus_pin_indices_; + vtr::vector> bus_pin_ids_; + + /* Unique ids for each pin */ + vtr::vector pin_ids_; + + /* Index for each pin */ + vtr::vector pin_indices_; /* Name of each pin under each bus */ - vtr::vector> bus_pin_names_; + vtr::vector pin_names_; }; #endif diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp new file mode 100644 index 000000000..f904e5206 --- /dev/null +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp @@ -0,0 +1,131 @@ +/******************************************************************** + * This file includes the top-level function of this library + * which reads an XML of bus group file to the associated + * data structures + *******************************************************************/ +#include + +/* 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 "read_xml_bus_group.h" + +/******************************************************************** + * Parse XML codes of a 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, "id", loc_data).as_int(); + std::string pin_name = get_attribute(xml_pin, "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); + bus_group.set_pin_index(pin_id, pin_index); + bus_group.set_pin_name(pin_id, pin_name); +} + +/******************************************************************** + * Parse XML codes of a 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, "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_pin), + "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("pin")) { + bad_tag(xml_pin, loc_data, xml_root, {"pin"}); + } + read_xml_pin(xml_pin, loc_data, bus_group, bus_id); + } +} + +/******************************************************************** + * Parse XML codes about 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, "bus_group", 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("bus")) { + bad_tag(xml_bus, loc_data, xml_root, {"bus"}); + } + read_xml_bus(xml_bus, loc_data, bus_group); + } + } catch (pugiutil::XmlError& e) { + archfpga_throw(fname, e.line(), + "%s", e.what()); + } + + return bus_group; +} + diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.h b/libopenfpga/libbusgroup/src/read_xml_bus_group.h new file mode 100644 index 000000000..8be1fa04d --- /dev/null +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.h @@ -0,0 +1,16 @@ +#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 + *******************************************************************/ +BusGroup read_xml_bus_group(const char* fname); + +#endif From 76cf4e1662829bc620fd6c6ec01a68cef4c71aa1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 16:17:37 -0800 Subject: [PATCH 06/37] [Lib] Add reader and writer for bus group --- libopenfpga/libbusgroup/src/bus_group.cpp | 16 ++- libopenfpga/libbusgroup/src/bus_group.h | 9 ++ .../libbusgroup/src/bus_group_xml_constants.h | 13 +++ .../libbusgroup/src/read_xml_bus_group.cpp | 17 +-- .../libbusgroup/src/write_xml_bus_group.cpp | 108 ++++++++++++++++++ .../libbusgroup/src/write_xml_bus_group.h | 16 +++ 6 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 libopenfpga/libbusgroup/src/bus_group_xml_constants.h create mode 100644 libopenfpga/libbusgroup/src/write_xml_bus_group.cpp create mode 100644 libopenfpga/libbusgroup/src/write_xml_bus_group.h diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index 3d6682a08..b3f03aef8 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -27,11 +27,25 @@ BusGroup::bus_group_range BusGroup::buses() const { * Public Accessors : Basic data query ***********************************************************************/ openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const { - /* validate the bus_id */ VTR_ASSERT(valid_bus_id(bus_id)); return bus_ports_[bus_id]; } +std::vector 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]; +} + bool BusGroup::empty() const { return 0 == bus_ids_.size(); } diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index ad2393be2..7d8bb717f 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -48,6 +48,15 @@ class BusGroup { /** Get port information of a bus with a given id */ openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const; + /* Get the pins under a specific bus */ + std::vector 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; + /* Check if there are any buses */ bool empty() const; diff --git a/libopenfpga/libbusgroup/src/bus_group_xml_constants.h b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h new file mode 100644 index 000000000..32d92c8e9 --- /dev/null +++ b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h @@ -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 diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp index f904e5206..514414425 100644 --- a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp @@ -20,6 +20,7 @@ #include "arch_error.h" #include "read_xml_util.h" +#include "bus_group_xml_constants.h" #include "read_xml_bus_group.h" /******************************************************************** @@ -35,8 +36,8 @@ void read_xml_pin(pugi::xml_node& xml_pin, "Invalid id of a bus group!\n"); } - int pin_index = get_attribute(xml_pin, "id", loc_data).as_int(); - std::string pin_name = get_attribute(xml_pin, "name", loc_data).as_string(); + 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); @@ -58,7 +59,7 @@ 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, "name", loc_data).as_string()); + 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()); @@ -76,8 +77,8 @@ void read_xml_bus(pugi::xml_node& xml_bus, 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("pin")) { - bad_tag(xml_pin, loc_data, xml_root, {"pin"}); + if (xml_pin.name() != std::string(XML_PIN_NODE_NAME)) { + bad_tag(xml_pin, loc_data, xml_root, {XML_PIN_NODE_NAME}); } read_xml_pin(xml_pin, loc_data, bus_group, bus_id); } @@ -99,7 +100,7 @@ BusGroup read_xml_bus_group(const char* fname) { try { loc_data = pugiutil::load_xml(doc, fname); - pugi::xml_node xml_root = get_single_child(doc, "bus_group", loc_data); + 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()); @@ -116,8 +117,8 @@ BusGroup read_xml_bus_group(const char* fname) { 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("bus")) { - bad_tag(xml_bus, loc_data, xml_root, {"bus"}); + 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); } diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp new file mode 100644 index 000000000..059f7c39c --- /dev/null +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp @@ -0,0 +1,108 @@ +/******************************************************************** + * This file includes functions that outputs a bus group object to XML format + *******************************************************************/ +/* Headers from system goes first */ +#include +#include + +/* 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" + +/******************************************************************** + * 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 << "" << "\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 << "" << "\n"; + + /* Close the file stream */ + fp.close(); + + return err_code; +} diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.h b/libopenfpga/libbusgroup/src/write_xml_bus_group.h new file mode 100644 index 000000000..096c72ec5 --- /dev/null +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.h @@ -0,0 +1,16 @@ +#ifndef WRITE_XML_BUS_GROUP_H +#define WRITE_XML_BUS_GROUP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#include "bus_group.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ +int write_xml_bus_group(const char* fname, + const BusGroup& bus_group); + +#endif From 0d7e9491662ff30bc4f1d0bf76fecec2a181c17f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 16:21:12 -0800 Subject: [PATCH 07/37] [Lib] Add unit test for bus group --- .../libbusgroup/test/xml_io_bus_group.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 libopenfpga/libbusgroup/test/xml_io_bus_group.cpp diff --git a/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp b/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp new file mode 100644 index 000000000..5c5160960 --- /dev/null +++ b/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp @@ -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 = 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) { + write_xml_bus_group(argv[2], bus_group); + VTR_LOG("Write the bus group to an XML file: %s.\n", + argv[2]); + } +} + + From 27627bf5b4ca61e8f183ee755b3f5e902a04995e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 16:22:01 -0800 Subject: [PATCH 08/37] [Lib] Add an example XML for bus group unit tests --- libopenfpga/libbusgroup/example/bus_group_example.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 libopenfpga/libbusgroup/example/bus_group_example.xml diff --git a/libopenfpga/libbusgroup/example/bus_group_example.xml b/libopenfpga/libbusgroup/example/bus_group_example.xml new file mode 100644 index 000000000..2d31fb76a --- /dev/null +++ b/libopenfpga/libbusgroup/example/bus_group_example.xml @@ -0,0 +1,8 @@ + + + + + + + + From 4b3f906f1162363e039e7cc2873526ed34351afc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 17:09:03 -0800 Subject: [PATCH 09/37] [Lib] Fixed all the syntax errors --- libopenfpga/libbusgroup/src/bus_group.cpp | 15 ++++++++------- libopenfpga/libbusgroup/src/bus_group.h | 9 ++++++--- libopenfpga/libbusgroup/src/bus_group_fwd.h | 4 ++++ .../libbusgroup/src/bus_group_xml_constants.h | 12 ++++++------ .../libbusgroup/src/read_xml_bus_group.cpp | 7 +++++-- libopenfpga/libbusgroup/src/read_xml_bus_group.h | 5 +++++ .../libbusgroup/src/write_xml_bus_group.cpp | 4 ++++ libopenfpga/libbusgroup/src/write_xml_bus_group.h | 4 ++++ libopenfpga/libbusgroup/test/xml_io_bus_group.cpp | 4 ++-- 9 files changed, 44 insertions(+), 20 deletions(-) diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index b3f03aef8..403888c75 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -5,6 +5,8 @@ #include "bus_group.h" +namespace openfpga { // Begin namespace openfpga + /************************************************************************ * Member functions for class BusGroup ***********************************************************************/ @@ -56,8 +58,7 @@ bool BusGroup::empty() const { void BusGroup::reserve_buses(const size_t& num_buses) { bus_ids_.reserve(num_buses); bus_ports_.reserve(num_buses); - bus_pin_indices_.reserve(num_buses); - bus_pin_names_.reserve(num_buses); + bus_pin_ids_.reserve(num_buses); } void BusGroup::reserve_pins(const size_t& num_pins) { @@ -71,14 +72,13 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { BusGroupId bus_id = BusGroupId(bus_ids_.size()); bus_ids_.push_back(bus_id); - bus_ports.push_back(bus_port); - bus_pin_indices_.emplace_back(); - bus_pin_names_.emplace_back(); + bus_ports_.push_back(bus_port); + bus_pin_ids_.emplace_back(); return bus_id; } -BusPinId BasicGroup::create_pin(const BusGroupId& bus_id) { +BusPinId BusGroup::create_pin(const BusGroupId& bus_id) { /* Create a new id */ BusPinId pin_id = BusPinId(pin_ids_.size()); @@ -91,7 +91,7 @@ BusPinId BasicGroup::create_pin(const BusGroupId& bus_id) { VTR_ASSERT(valid_bus_id(bus_id)); bus_pin_ids_[bus_id].push_back(pin_id); - return bus_id; + return pin_id; } void BusGroup::set_pin_index(const BusPinId& pin_id, const int& index) { @@ -115,3 +115,4 @@ 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 diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index 7d8bb717f..bb7187fb5 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -16,6 +16,8 @@ #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 @@ -46,7 +48,7 @@ class BusGroup { bus_group_range buses() const; public: /* Public Accessors: Basic data query */ /** Get port information of a bus with a given id */ - openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const; + BasicPort bus_port(const BusGroupId& bus_id) const; /* Get the pins under a specific bus */ std::vector bus_pins(const BusGroupId& bus_id) const; @@ -77,7 +79,7 @@ class BusGroup { void set_pin_index(const BusPinId& pin_id, const int& index); /* Set the name for a pin */ - void set_pin_index(const BusPinId& pin_id, const std::string& name); + 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 */ @@ -91,7 +93,7 @@ class BusGroup { vtr::vector bus_ids_; /* Port information of each bus */ - vtr::vector bus_ports_; + vtr::vector bus_ports_; /* Indices of each pin under each bus */ vtr::vector> bus_pin_ids_; @@ -106,4 +108,5 @@ class BusGroup { vtr::vector pin_names_; }; +} // End of namespace openfpga #endif diff --git a/libopenfpga/libbusgroup/src/bus_group_fwd.h b/libopenfpga/libbusgroup/src/bus_group_fwd.h index 5f1d6cd25..d6cfea772 100644 --- a/libopenfpga/libbusgroup/src/bus_group_fwd.h +++ b/libopenfpga/libbusgroup/src/bus_group_fwd.h @@ -12,6 +12,8 @@ #include "vtr_strong_id.h" +namespace openfpga { // Begin namespace openfpga + struct bus_group_id_tag; struct bus_pin_id_tag; @@ -21,4 +23,6 @@ typedef vtr::StrongId BusPinId; /* Short declaration of class */ class BusGroup; +} // End of namespace openfpga + #endif diff --git a/libopenfpga/libbusgroup/src/bus_group_xml_constants.h b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h index 32d92c8e9..9f27ae978 100644 --- a/libopenfpga/libbusgroup/src/bus_group_xml_constants.h +++ b/libopenfpga/libbusgroup/src/bus_group_xml_constants.h @@ -3,11 +3,11 @@ /* 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" +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 diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp index 514414425..701cbb1bf 100644 --- a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp @@ -23,6 +23,8 @@ #include "bus_group_xml_constants.h" #include "read_xml_bus_group.h" +namespace openfpga { // Begin namespace openfpga + /******************************************************************** * Parse XML codes of a to an object of BusGroup *******************************************************************/ @@ -71,14 +73,14 @@ void read_xml_bus(pugi::xml_node& xml_bus, /* 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_pin), + 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_root, {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); } @@ -130,3 +132,4 @@ BusGroup read_xml_bus_group(const char* fname) { return bus_group; } +} // End of namespace openfpga diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.h b/libopenfpga/libbusgroup/src/read_xml_bus_group.h index 8be1fa04d..7b1c89a06 100644 --- a/libopenfpga/libbusgroup/src/read_xml_bus_group.h +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.h @@ -11,6 +11,11 @@ /******************************************************************** * Function declaration *******************************************************************/ + +namespace openfpga { // Begin namespace openfpga + BusGroup read_xml_bus_group(const char* fname); +} // End of namespace openfpga + #endif diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp index 059f7c39c..219ec9ce6 100644 --- a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp @@ -20,6 +20,8 @@ #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 * @@ -106,3 +108,5 @@ int write_xml_bus_group(const char* fname, return err_code; } + +} // End of namespace openfpga diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.h b/libopenfpga/libbusgroup/src/write_xml_bus_group.h index 096c72ec5..09a51673f 100644 --- a/libopenfpga/libbusgroup/src/write_xml_bus_group.h +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.h @@ -10,7 +10,11 @@ /******************************************************************** * Function declaration *******************************************************************/ +namespace openfpga { // Begin namespace openfpga + int write_xml_bus_group(const char* fname, const BusGroup& bus_group); +} // End of namespace openfpga + #endif diff --git a/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp b/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp index 5c5160960..1f372c311 100644 --- a/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp +++ b/libopenfpga/libbusgroup/test/xml_io_bus_group.cpp @@ -16,7 +16,7 @@ int main(int argc, const char** argv) { VTR_ASSERT((2 == argc) || (3 == argc)); /* Parse the circuit library from an XML file */ - const openfpga::BusGroup& bus_group = read_xml_bus_group(argv[1]); + 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()); @@ -24,7 +24,7 @@ int main(int argc, const char** argv) { * This is optional only used when there is a second argument */ if (3 <= argc) { - write_xml_bus_group(argv[2], bus_group); + openfpga::write_xml_bus_group(argv[2], bus_group); VTR_LOG("Write the bus group to an XML file: %s.\n", argv[2]); } From e60d7d12b7fb593fed8f585f9e24bbd2b04db2e2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 17:12:07 -0800 Subject: [PATCH 10/37] [Lib] Fixed a bug in writer --- libopenfpga/libbusgroup/src/write_xml_bus_group.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp index 219ec9ce6..9d9fdb005 100644 --- a/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/write_xml_bus_group.cpp @@ -56,7 +56,7 @@ int write_xml_bus(std::fstream& fp, 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"; + fp << "/>" << "\n"; } openfpga::write_tab_to_file(fp, 1); From 38601f325b8e0fa5c6be8e500a2f797931305d89 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 17:28:55 -0800 Subject: [PATCH 11/37] [Engine] Add bus group to OpenFPGA core --- openfpga/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga/CMakeLists.txt b/openfpga/CMakeLists.txt index 88b790d89..70b00fa7b 100644 --- a/openfpga/CMakeLists.txt +++ b/openfpga/CMakeLists.txt @@ -28,6 +28,7 @@ target_link_libraries(libopenfpga libini libpcf libvtrutil + libbusgroup libvpr) #Create the test executable From 37d8617a5c35fdda360dbf0d9a674450fd79fc45 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 19:45:37 -0800 Subject: [PATCH 12/37] [Doc] Update due to new options --- .../openfpga_commands/fpga_verilog_commands.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index 9f39f8250..aaebf5f87 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -120,6 +120,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`` Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. + .. option:: --bus_group_file or -bgf + + 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 Use explicit port mapping when writing the Verilog netlists From c96f0d199d25ec40f19d8c7f6001d585ab92f5a1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 23:14:28 -0800 Subject: [PATCH 13/37] [FPGA-Verilog] Adding bus group support in Verilog testbenches --- libopenfpga/libbusgroup/src/bus_group.cpp | 34 ++++++++++++- libopenfpga/libbusgroup/src/bus_group.h | 12 +++++ openfpga/src/base/openfpga_verilog.cpp | 19 +++++++ .../src/base/openfpga_verilog_command.cpp | 10 ++++ openfpga/src/fpga_verilog/verilog_api.cpp | 4 ++ openfpga/src/fpga_verilog/verilog_api.h | 3 ++ .../verilog_preconfig_top_module.cpp | 49 +++++++++++++++---- .../verilog_preconfig_top_module.h | 2 + .../fpga_verilog/verilog_testbench_utils.cpp | 16 +++++- .../fpga_verilog/verilog_testbench_utils.h | 2 + .../fpga_verilog/verilog_top_testbench.cpp | 2 + .../src/fpga_verilog/verilog_top_testbench.h | 2 + 12 files changed, 143 insertions(+), 12 deletions(-) diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index 403888c75..71a433793 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -48,6 +48,27 @@ std::string BusGroup::pin_name(const BusPinId& pin_id) const { return pin_names_[pin_id]; } +BusGroupId BusGroup::find_pin_bus(const std::string& pin_name) const { + std::map::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]; +} + +BusPinId BusGroup::find_pin(const std::string& pin_name) const { + std::map::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(); } @@ -65,6 +86,7 @@ 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) { @@ -89,8 +111,9 @@ BusPinId BusGroup::create_pin(const BusGroupId& bus_id) { /* Register the pin to the bus */ VTR_ASSERT(valid_bus_id(bus_id)); + pin_parent_bus_ids_.push_back(bus_id); bus_pin_ids_[bus_id].push_back(pin_id); - + return pin_id; } @@ -102,6 +125,15 @@ void BusGroup::set_pin_index(const BusPinId& pin_id, const int& index) { 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); + } } /************************************************************************ diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index bb7187fb5..d849f5fd3 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -59,6 +59,12 @@ class BusGroup { /* 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 pin id with a given name */ + BusPinId find_pin(const std::string& pin_name) const; + /* Check if there are any buses */ bool empty() const; @@ -106,6 +112,12 @@ class BusGroup { /* Name of each pin under each bus */ vtr::vector pin_names_; + + /* Parent bus of each pin */ + vtr::vector pin_parent_bus_ids_; + + /* Fast look-up */ + std::map pin_name2id_map_; }; } // End of namespace openfpga diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 7569a14bf..91412be31 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -17,6 +17,9 @@ /* Headers from pcf library */ #include "read_xml_pin_constraints.h" +/* Headers from bgf library */ +#include "read_xml_bus_group.h" + /* Include global variables of VPR */ #include "globals.h" @@ -79,6 +82,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_bitstream = cmd.option("bitstream"); CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path"); 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_fast_configuration = cmd.option("fast_configuration"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); @@ -111,6 +115,12 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, if (true == cmd_context.option_enable(cmd, opt_pcf)) { pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); } + + /* If bug group file are enabled by command options, read the file */ + BusGroup bus_group; + if (true == cmd_context.option_enable(cmd, opt_bgf)) { + bus_group = read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str()); + } return fpga_verilog_full_testbench(openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), @@ -119,6 +129,7 @@ int write_full_testbench(const OpenfpgaContext& openfpga_ctx, g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, + bus_group, cmd_context.option_value(cmd, opt_bitstream), openfpga_ctx.io_location_map(), 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_fabric_netlist = cmd.option("fabric_netlist_file_path"); 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_default_net_type = cmd.option("default_net_type"); CommandOptionId opt_include_signal_init = cmd.option("include_signal_init"); @@ -170,12 +182,19 @@ int write_preconfigured_fabric_wrapper(const OpenfpgaContext& openfpga_ctx, if (true == cmd_context.option_enable(cmd, opt_pcf)) { pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); } + + /* If bug group file are enabled by command options, read the file */ + BusGroup bus_group; + if (true == cmd_context.option_enable(cmd, opt_bgf)) { + bus_group = read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str()); + } return fpga_verilog_preconfigured_fabric_wrapper(openfpga_ctx.module_graph(), openfpga_ctx.bitstream_manager(), g_vpr_ctx.atom(), g_vpr_ctx.placement(), pin_constraints, + bus_group, openfpga_ctx.io_location_map(), openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index 9d0f58eef..fc648e095 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -89,6 +89,11 @@ ShellCommandId add_openfpga_write_full_testbench_command(openfpga::Shell port_type2type_map; port_type2type_map[AtomBlockType::INPAD] = VERILOG_PORT_INPUT; port_type2type_map[AtomBlockType::OUTPAD] = VERILOG_PORT_OUTPUT; + /* Ports to be added, this is to avoid any bus port */ + std::vector port_list; + std::vector port_types; + /* Print all the I/Os of the circuit implementation to be tested*/ for (const AtomBlockId &atom_blk : atom_ctx.nlist.blocks()) { /* We only care I/O logical blocks !*/ @@ -62,11 +64,28 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, continue; } - /* The block may be renamed as it contains special characters which violate Verilog syntax */ std::string block_name = atom_ctx.nlist.block_name(atom_blk); + /* If 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; + } + + /* The block may be renamed as it contains special characters which violate Verilog syntax */ if (true == netlist_annotation.is_block_renamed(atom_blk)) { block_name = netlist_annotation.block_name(atom_blk); } + /* For output block, remove the prefix which is added by VPR */ std::vector output_port_prefix_to_remove; output_port_prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX)); @@ -82,12 +101,22 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, } } + /* 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) { 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[atom_ctx.nlist.block_type(atom_blk)], module_port); + + fp << generate_verilog_port(port_type2type_map[port_type], module_port); /* Update port counter */ port_counter++; @@ -434,6 +463,7 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, const AtomContext &atom_ctx, const PlacementContext &place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const IoLocationMap &io_location_map, const VprNetlistAnnotation &netlist_annotation, const std::string &circuit_name, @@ -461,7 +491,7 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, options.default_net_type()); /* 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 */ ModuleId top_module = module_manager.find_module(generate_fpga_top_module_name()); @@ -494,6 +524,7 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module, atom_ctx, place_ctx, io_location_map, netlist_annotation, + bus_group, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), std::string(), std::string(), diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h index 01bb12f08..39e1d9f28 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.h @@ -14,6 +14,7 @@ #include "io_location_map.h" #include "fabric_global_port_info.h" #include "config_protocol.h" +#include "bus_group.h" #include "vpr_netlist_annotation.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 PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const IoLocationMap& io_location_map, const VprNetlistAnnotation& netlist_annotation, const std::string& circuit_name, diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index 899d6b014..537098a68 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -177,6 +177,7 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, const VprNetlistAnnotation& netlist_annotation, + const BusGroup& bus_group, const std::string& net_name_postfix, const std::string& io_input_port_name_postfix, const std::string& io_output_port_name_postfix, @@ -285,11 +286,24 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, } } + /* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1 * In addition, the input and output ports may have different postfix in naming * due to verification context! Here, we give full customization on naming */ 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 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)) { @@ -297,13 +311,11 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, } else { 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_wire_connection(fp, module_mapped_io_port, benchmark_io_port, false); } else { 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_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_wire_connection(fp, benchmark_io_port, module_mapped_io_port, false); } diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 44816e85b..1a6c106c0 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -17,6 +17,7 @@ #include "simulation_setting.h" #include "fabric_global_port_info.h" #include "pin_constraints.h" +#include "bus_group.h" /******************************************************************** * Function declaration @@ -53,6 +54,7 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, const PlacementContext& place_ctx, const IoLocationMap& io_location_map, const VprNetlistAnnotation& netlist_annotation, + const BusGroup& bus_group, const std::string& net_name_postfix, const std::string& io_input_port_name_postfix, const std::string& io_output_port_name_postfix, diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index d668cb997..ed59bd05f 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -1924,6 +1924,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const std::string& bitstream_file, const IoLocationMap& io_location_map, const VprNetlistAnnotation& netlist_annotation, @@ -2064,6 +2065,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module, atom_ctx, place_ctx, io_location_map, netlist_annotation, + bus_group, std::string(), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.h b/openfpga/src/fpga_verilog/verilog_top_testbench.h index bbad08125..51f71fee7 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.h @@ -19,6 +19,7 @@ #include "simulation_setting.h" #include "memory_bank_shift_register_banks.h" #include "verilog_testbench_options.h" +#include "bus_group.h" /******************************************************************** * Function declaration @@ -37,6 +38,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, const AtomContext& atom_ctx, const PlacementContext& place_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const std::string& bitstream_file, const IoLocationMap& io_location_map, const VprNetlistAnnotation& netlist_annotation, From 6da0ede9b005492820c116edae091cca74dea094 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 17 Feb 2022 23:48:44 -0800 Subject: [PATCH 14/37] [FPGA-Verilog] Adding bus group support to all Verilog testbench generators --- openfpga/src/base/openfpga_verilog.cpp | 8 +++ .../src/base/openfpga_verilog_command.cpp | 5 ++ openfpga/src/fpga_verilog/verilog_api.cpp | 2 + openfpga/src/fpga_verilog/verilog_api.h | 1 + .../verilog_formal_random_top_testbench.cpp | 7 ++ .../verilog_formal_random_top_testbench.h | 2 + .../fpga_verilog/verilog_testbench_utils.cpp | 68 ++++++++++++++----- .../fpga_verilog/verilog_testbench_utils.h | 1 + .../fpga_verilog/verilog_top_testbench.cpp | 3 + 9 files changed, 80 insertions(+), 17 deletions(-) diff --git a/openfpga/src/base/openfpga_verilog.cpp b/openfpga/src/base/openfpga_verilog.cpp index 91412be31..ae154435f 100644 --- a/openfpga/src/base/openfpga_verilog.cpp +++ b/openfpga/src/base/openfpga_verilog.cpp @@ -211,6 +211,7 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, CommandOptionId opt_output_dir = cmd.option("file"); CommandOptionId opt_pcf = cmd.option("pin_constraints_file"); + CommandOptionId opt_bgf = cmd.option("bus_group_file"); CommandOptionId opt_fabric_netlist = cmd.option("fabric_netlist_file_path"); CommandOptionId opt_reference_benchmark = cmd.option("reference_benchmark_file_path"); CommandOptionId opt_explicit_port_mapping = cmd.option("explicit_port_mapping"); @@ -240,10 +241,17 @@ int write_preconfigured_testbench(const OpenfpgaContext& openfpga_ctx, if (true == cmd_context.option_enable(cmd, opt_pcf)) { pin_constraints = read_xml_pin_constraints(cmd_context.option_value(cmd, opt_pcf).c_str()); } + + /* If bug group file are enabled by command options, read the file */ + BusGroup bus_group; + if (true == cmd_context.option_enable(cmd, opt_bgf)) { + bus_group = read_xml_bus_group(cmd_context.option_value(cmd, opt_bgf).c_str()); + } return fpga_verilog_preconfigured_testbench(openfpga_ctx.module_graph(), g_vpr_ctx.atom(), pin_constraints, + bus_group, openfpga_ctx.fabric_global_port_info(), openfpga_ctx.vpr_netlist_annotation(), openfpga_ctx.simulation_setting(), diff --git a/openfpga/src/base/openfpga_verilog_command.cpp b/openfpga/src/base/openfpga_verilog_command.cpp index fc648e095..1cc85333a 100644 --- a/openfpga/src/base/openfpga_verilog_command.cpp +++ b/openfpga/src/base/openfpga_verilog_command.cpp @@ -220,6 +220,11 @@ ShellCommandId add_openfpga_write_preconfigured_testbench_command(openfpga::Shel shell_cmd.set_option_short_name(pcf_opt, "pcf"); shell_cmd.set_option_require_value(pcf_opt, openfpga::OPT_STRING); + /* add an option '--bus_group_file in short '-bgf' */ + CommandOptionId bgf_opt = shell_cmd.add_option("bus_group_file", false, "specify the file path to the group pins to bus"); + shell_cmd.set_option_short_name(bgf_opt, "bgf"); + shell_cmd.set_option_require_value(bgf_opt, openfpga::OPT_STRING); + /* Add an option '--reference_benchmark_file_path'*/ CommandOptionId ref_bm_opt = shell_cmd.add_option("reference_benchmark_file_path", false, "Specify the file path to the reference Verilog netlist. If specified, the testbench will include self-checking codes"); shell_cmd.set_option_require_value(ref_bm_opt, openfpga::OPT_STRING); diff --git a/openfpga/src/fpga_verilog/verilog_api.cpp b/openfpga/src/fpga_verilog/verilog_api.cpp index d123d115f..56086b6cf 100644 --- a/openfpga/src/fpga_verilog/verilog_api.cpp +++ b/openfpga/src/fpga_verilog/verilog_api.cpp @@ -261,6 +261,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, const AtomContext &atom_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const SimulationSetting &simulation_setting, @@ -286,6 +287,7 @@ int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, module_manager, fabric_global_port_info, pin_constraints, + bus_group, simulation_setting, options); diff --git a/openfpga/src/fpga_verilog/verilog_api.h b/openfpga/src/fpga_verilog/verilog_api.h index 3cd249dc1..78cb8288d 100644 --- a/openfpga/src/fpga_verilog/verilog_api.h +++ b/openfpga/src/fpga_verilog/verilog_api.h @@ -79,6 +79,7 @@ int fpga_verilog_preconfigured_fabric_wrapper(const ModuleManager &module_manage int fpga_verilog_preconfigured_testbench(const ModuleManager &module_manager, const AtomContext &atom_ctx, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const FabricGlobalPortInfo &fabric_global_port_info, const VprNetlistAnnotation &netlist_annotation, const SimulationSetting &simulation_setting, diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp index 42bb7886f..d39c198cb 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp @@ -109,6 +109,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const bool& explicit_port_mapping) { /* Validate the file stream */ valid_file_stream(fp); @@ -132,6 +133,7 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp, std::vector(), atom_ctx, netlist_annotation, pin_constraints, + bus_group, explicit_port_mapping); print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------")); @@ -149,6 +151,7 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const bool& explicit_port_mapping) { /* Validate the file stream */ valid_file_stream(fp); @@ -172,6 +175,7 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp, std::vector(), atom_ctx, netlist_annotation, pin_constraints, + bus_group, explicit_port_mapping); print_verilog_comment(fp, std::string("----- End FPGA Fabric Instanication -------")); @@ -288,6 +292,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const SimulationSetting& simulation_parameters, const VerilogTestbenchOption &options) { std::string timer_message = std::string("Write configuration-skip testbench for FPGA top-level Verilog netlist implemented by '") + circuit_name.c_str() + std::string("'"); @@ -316,6 +321,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, print_verilog_random_testbench_fpga_instance(fp, circuit_name, atom_ctx, netlist_annotation, pin_constraints, + bus_group, options.explicit_port_mapping()); /* Call defined benchmark */ @@ -323,6 +329,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, print_verilog_top_random_testbench_benchmark_instance(fp, circuit_name, atom_ctx, netlist_annotation, pin_constraints, + bus_group, options.explicit_port_mapping()); } diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h index d58bae969..e3b092e1c 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.h @@ -11,6 +11,7 @@ #include "fabric_global_port_info.h" #include "simulation_setting.h" #include "verilog_testbench_options.h" +#include "bus_group.h" /******************************************************************** * Function declaration @@ -26,6 +27,7 @@ void print_verilog_random_top_testbench(const std::string& circuit_name, const ModuleManager& module_manager, const FabricGlobalPortInfo& global_ports, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const SimulationSetting& simulation_parameters, const VerilogTestbenchOption &options); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index 537098a68..e804d775f 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -85,13 +85,17 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const bool& use_explicit_port_map) { /* Validate the file stream */ valid_file_stream(fp); fp << "\t" << module_name << " " << instance_name << "(" << std::endl; - size_t port_counter = 0; + /* Consider all the unique port names */ + std::vector port_names; + std::vector port_types; + for (const AtomBlockId& atom_blk : atom_ctx.nlist.blocks()) { /* Bypass non-I/O atom blocks ! */ if ( (AtomBlockType::INPAD != atom_ctx.nlist.block_type(atom_blk)) @@ -105,41 +109,70 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, block_name = netlist_annotation.block_name(atom_blk); } - /* The first port does not need a comma */ - if(0 < port_counter){ - fp << "," << std::endl; + /* If the pin is part of a bus, + * - Check if the bus is already in the list + * - If not, add it to the port list + * - If yes, do nothing and move onto the next port + * If the pin does not belong to any bus + * - Add it to the bus port + */ + BusGroupId bus_id = bus_group.find_pin_bus(block_name); + if (bus_id) { + if (port_names.end() == std::find(port_names.begin(), port_names.end(), bus_group.bus_port(bus_id).get_name())) { + port_names.push_back(bus_group.bus_port(bus_id).get_name()); + port_types.push_back(atom_ctx.nlist.block_type(atom_blk)); + } + continue; } + /* Input port follows the logical block name while output port requires a special postfix */ if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) { - fp << "\t\t"; - if (true == use_explicit_port_map) { - fp << "." << block_name << module_input_port_postfix << "("; - } - + std::string port_name; /* Polarity of some input may have to be inverted, as defined in pin constraints * For example, the reset signal of the benchmark is active low * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) * However, to ensure correct stimuli to the benchmark, we have to invert the signal */ if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(block_name)) { - fp << "~"; + port_name += std::string("~"); } /* For clock ports, skip postfix */ if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) { - fp << block_name; + port_name += block_name; } else { - fp << block_name << input_port_postfix; + port_name += block_name + input_port_postfix; } + port_names.push_back(port_name); + } else { + VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)); + port_names.push_back(block_name); + } + + port_types.push_back(atom_ctx.nlist.block_type(atom_blk)); + } + + size_t port_counter = 0; + for (size_t iport = 0; iport < port_names.size(); ++iport) { + /* The first port does not need a comma */ + if (0 < port_counter){ + fp << "," << std::endl; + } + + fp << "\t\t"; + if (AtomBlockType::INPAD == port_types[iport]) { + if (true == use_explicit_port_map) { + fp << "." << port_names[iport] << module_input_port_postfix << "("; + } + fp << port_names[iport]; if (true == use_explicit_port_map) { fp << ")"; } } else { - VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)); - fp << "\t\t"; + VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == port_types[iport]); /* Note that VPR added a prefix "out_" or "out:" to the name of output blocks * We can remove this when specified through input argument */ - std::string output_block_name = block_name; + std::string output_block_name = port_names[iport]; for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { if (!prefix_to_remove.empty()) { if (0 == output_block_name.find(prefix_to_remove)) { @@ -152,11 +185,12 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, if (true == use_explicit_port_map) { fp << "." << output_block_name << module_output_port_postfix << "("; } - fp << block_name << output_port_postfix; + fp << port_names[iport] << output_port_postfix; if (true == use_explicit_port_map) { fp << ")"; } - } + } + /* Update the counter */ port_counter++; } diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 1a6c106c0..39b269904 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -45,6 +45,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const bool& use_explicit_port_map); void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index ed59bd05f..666c2fa83 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -937,6 +937,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp, const AtomContext& atom_ctx, const VprNetlistAnnotation& netlist_annotation, const PinConstraints& pin_constraints, + const BusGroup& bus_group, const std::vector& clock_port_names, const bool& explicit_port_mapping) { /* Validate the file stream */ @@ -961,6 +962,7 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp, clock_port_names, atom_ctx, netlist_annotation, pin_constraints, + bus_group, explicit_port_mapping); print_verilog_comment(fp, std::string("----- End reference Benchmark Instanication -------")); @@ -2080,6 +2082,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, atom_ctx, netlist_annotation, pin_constraints, + bus_group, clock_port_names, explicit_port_mapping); } From aa375fd7a4582ddb34ad8eb1836ee233d1ea6624 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 11:31:11 -0800 Subject: [PATCH 15/37] [FPGA-Verilog] Fixed a bug due to the use of bus group in testbench generator --- .../fpga_verilog/verilog_testbench_utils.cpp | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index e804d775f..f1799796a 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -126,28 +126,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, } /* Input port follows the logical block name while output port requires a special postfix */ - if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) { - std::string port_name; - /* Polarity of some input may have to be inverted, as defined in pin constraints - * For example, the reset signal of the benchmark is active low - * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) - * However, to ensure correct stimuli to the benchmark, we have to invert the signal - */ - if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(block_name)) { - port_name += std::string("~"); - } - /* For clock ports, skip postfix */ - if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) { - port_name += block_name; - } else { - port_name += block_name + input_port_postfix; - } - port_names.push_back(port_name); - } else { - VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)); - port_names.push_back(block_name); - } - + port_names.push_back(block_name); port_types.push_back(atom_ctx.nlist.block_type(atom_blk)); } @@ -163,7 +142,22 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, if (true == use_explicit_port_map) { fp << "." << port_names[iport] << module_input_port_postfix << "("; } - fp << port_names[iport]; + /* Polarity of some input may have to be inverted, as defined in pin constraints + * For example, the reset signal of the benchmark is active low + * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) + * However, to ensure correct stimuli to the benchmark, we have to invert the signal + */ + if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) { + fp << "~"; + } + + /* For clock ports, skip postfix */ + if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) { + fp << port_names[iport]; + } else { + fp << port_names[iport] << input_port_postfix; + } + if (true == use_explicit_port_map) { fp << ")"; } From 0d620888ab29599446820e3ed9e7e17a9b5cc9ca Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:03:26 -0800 Subject: [PATCH 16/37] [FPGA-Verilog] Now instance can output bus ports with all the pins --- libopenfpga/libbusgroup/src/bus_group.cpp | 34 +++++++-- libopenfpga/libbusgroup/src/bus_group.h | 11 +-- .../libbusgroup/src/read_xml_bus_group.cpp | 3 +- .../fpga_verilog/verilog_testbench_utils.cpp | 75 +++++++++++++++---- 4 files changed, 96 insertions(+), 27 deletions(-) diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index 71a433793..9e191c12f 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -59,6 +59,16 @@ BusGroupId BusGroup::find_pin_bus(const std::string& pin_name) const { return pin_parent_bus_ids_[pin_id]; } +BusGroupId BusGroup::find_bus(const std::string& bus_name) const { + std::map::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::const_iterator result = pin_name2id_map_.find(pin_name); if (result == pin_name2id_map_.end()) { @@ -96,31 +106,41 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) { 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) { +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_.emplace_back(); + 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); - bus_pin_ids_[bus_id].push_back(pin_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_index(const BusPinId& pin_id, const int& index) { - VTR_ASSERT(valid_pin_id(pin_id)); - pin_indices_[pin_id] = index; -} void BusGroup::set_pin_name(const BusPinId& pin_id, const std::string& name) { VTR_ASSERT(valid_pin_id(pin_id)); diff --git a/libopenfpga/libbusgroup/src/bus_group.h b/libopenfpga/libbusgroup/src/bus_group.h index d849f5fd3..da63fb210 100644 --- a/libopenfpga/libbusgroup/src/bus_group.h +++ b/libopenfpga/libbusgroup/src/bus_group.h @@ -62,6 +62,9 @@ class BusGroup { /* 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; @@ -78,11 +81,8 @@ class BusGroup { /* Add a bus to storage */ BusGroupId create_bus(const openfpga::BasicPort& bus_port); - /* Add a pin to a bus */ - BusPinId create_pin(const BusGroupId& bus_id); - - /* Set the index for a pin */ - void set_pin_index(const BusPinId& pin_id, const int& index); + /* 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); @@ -117,6 +117,7 @@ class BusGroup { vtr::vector pin_parent_bus_ids_; /* Fast look-up */ + std::map bus_name2id_map_; std::map pin_name2id_map_; }; diff --git a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp index 701cbb1bf..020aa224b 100644 --- a/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp +++ b/libopenfpga/libbusgroup/src/read_xml_bus_group.cpp @@ -48,8 +48,7 @@ void read_xml_pin(pugi::xml_node& xml_pin, "Pin index is out of range of the bus port width!\n"); } - BusPinId pin_id = bus_group.create_pin(bus_id); - bus_group.set_pin_index(pin_id, pin_index); + BusPinId pin_id = bus_group.create_pin(bus_id, pin_index); bus_group.set_pin_name(pin_id, pin_name); } diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index f1799796a..c1c379366 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -130,6 +130,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, 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 */ @@ -142,20 +143,51 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, if (true == use_explicit_port_map) { fp << "." << port_names[iport] << module_input_port_postfix << "("; } - /* Polarity of some input may have to be inverted, as defined in pin constraints - * For example, the reset signal of the benchmark is active low - * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) - * However, to ensure correct stimuli to the benchmark, we have to invert the signal - */ - if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) { - fp << "~"; - } - /* For clock ports, skip postfix */ - if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) { - fp << port_names[iport]; + /* 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 + * For example, the reset signal of the benchmark is active low + * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) + * However, to ensure correct stimuli to the benchmark, we have to invert the signal + */ + if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(bus_group.pin_name(pin))) { + fp << "~"; + } + + fp << bus_group.pin_name(pin); + + /* 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; + } + + pin_counter++; + } + fp << "}"; } else { - fp << port_names[iport] << input_port_postfix; + /* Polarity of some input may have to be inverted, as defined in pin constraints + * For example, the reset signal of the benchmark is active low + * while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted) + * However, to ensure correct stimuli to the benchmark, we have to invert the signal + */ + if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) { + fp << "~"; + } + + 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) { @@ -179,7 +211,24 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, if (true == use_explicit_port_map) { fp << "." << output_block_name << module_output_port_postfix << "("; } - fp << port_names[iport] << 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; + } if (true == use_explicit_port_map) { fp << ")"; } From 73e6ee964d1159c942cb173dd1584134db752dd5 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:25:34 -0800 Subject: [PATCH 17/37] [Script] Add a new example script showing how to use bus group features --- ...estbench_bus_group_example_script.openfpga | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga diff --git a/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga new file mode 100644 index 000000000..fd5e8d8ad --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga @@ -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 route + +# 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 --activity_file ${ACTIVITY_FILE} --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 From 7176037bc47ded1729e2daa2ae71ff6b26db8b9f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:26:00 -0800 Subject: [PATCH 18/37] [Test] Added a new test about bus group --- .../config/counter8_bus_group.xml | 12 +++++ .../config/pin_constraints_reset.xml | 7 +++ .../config/task.conf | 49 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml new file mode 100644 index 000000000..3263c16d3 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf new file mode 100644 index 000000000..198166769 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf @@ -0,0 +1,49 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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/auto_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;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys +bench_read_verilog_options_common = -nolatches + +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= From 43d852d8a1c0a8fa313b9ce44b2e9f6e78454e0e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:27:25 -0800 Subject: [PATCH 19/37] [Test] Add the bus group test case to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index b8261b501..9cdda1671 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -166,3 +166,6 @@ 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_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 + +echo -e "Testing bus group features"; +run-task basic_tests/bus_group/preconfig_testbench_explicit_mapping --debug --show_thread_logs From a4d5172b7c3104aacaf60021eced22205e71bb18 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:31:29 -0800 Subject: [PATCH 20/37] [Test] Fixed bugs that causes VPR failed --- .../preconfigured_testbench_bus_group_example_script.openfpga | 4 ++-- .../preconfig_testbench_explicit_mapping/config/task.conf | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga index fd5e8d8ad..a85b8e24c 100644 --- a/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/preconfigured_testbench_bus_group_example_script.openfpga @@ -1,6 +1,6 @@ # Run VPR for the 'and' design #--write_rr_graph example_rr_graph.xml -vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal # Read OpenFPGA architecture definition read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} @@ -10,7 +10,7 @@ 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 --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges +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 diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf index 198166769..402126fec 100644 --- a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf @@ -39,7 +39,6 @@ bench_yosys_dsp_map_parameters_common=-D DSP_A_MAXWIDTH=36 -D DSP_B_MAXWIDTH=36 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;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys -bench_read_verilog_options_common = -nolatches bench0_top = counter bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/pin_constraints_reset.xml From 94fea84a4032826ebe8f23183dd46e73958d151a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:36:03 -0800 Subject: [PATCH 21/37] [Lib] Fix a bug in memory allocation --- libopenfpga/libbusgroup/src/bus_group.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libopenfpga/libbusgroup/src/bus_group.cpp b/libopenfpga/libbusgroup/src/bus_group.cpp index 9e191c12f..7aed69215 100644 --- a/libopenfpga/libbusgroup/src/bus_group.cpp +++ b/libopenfpga/libbusgroup/src/bus_group.cpp @@ -133,7 +133,7 @@ BusPinId BusGroup::create_pin(const BusGroupId& bus_id, const int& index) { 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()) { + 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; From 8ba3d06392c587ac8abf89dc4aa4fcc7569c63d0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 12:36:22 -0800 Subject: [PATCH 22/37] [Test] Fixed bugs in simulation settings --- .../preconfig_testbench_explicit_mapping/config/task.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf index 402126fec..d1de85faf 100644 --- a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf @@ -18,7 +18,7 @@ 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/auto_sim_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 From f5dd89bbd91c3e1a5579d1be675d5e3ccc329d4c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 14:08:03 -0800 Subject: [PATCH 23/37] [FPGA-Verilog] Fixed bugs in preconfigured wrapper generator when bus group is used --- .../verilog_preconfig_top_module.cpp | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index 401d7d0b5..dd9d8f0a9 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -65,6 +65,25 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, } 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)) { + block_name = netlist_annotation.block_name(atom_blk); + } + /* For output block, remove the prefix which is added by VPR */ + std::vector output_port_prefix_to_remove; + output_port_prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX)); + output_port_prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX)); + if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) { + for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { + if (!prefix_to_remove.empty()) { + if (0 == block_name.find(prefix_to_remove)) { + block_name.erase(0, prefix_to_remove.length()); + break; + } + } + } + } + /* 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 @@ -81,26 +100,6 @@ void print_verilog_preconfig_top_module_ports(std::fstream &fp, continue; } - /* The block may be renamed as it contains special characters which violate Verilog syntax */ - if (true == netlist_annotation.is_block_renamed(atom_blk)) { - block_name = netlist_annotation.block_name(atom_blk); - } - - /* For output block, remove the prefix which is added by VPR */ - std::vector output_port_prefix_to_remove; - output_port_prefix_to_remove.push_back(std::string(VPR_BENCHMARK_OUT_PORT_PREFIX)); - output_port_prefix_to_remove.push_back(std::string(OPENFPGA_BENCHMARK_OUT_PORT_PREFIX)); - if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) { - for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { - if (!prefix_to_remove.empty()) { - if (0 == block_name.find(prefix_to_remove)) { - block_name.erase(0, prefix_to_remove.length()); - break; - } - } - } - } - /* Both input and output ports have only size of 1 */ BasicPort module_port(std::string(block_name), 1); port_list.push_back(module_port); From a4dc86a33d5c73247208c42e17fbf4f0159c6b96 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 14:30:46 -0800 Subject: [PATCH 24/37] [FPGA-Verilog] Now output atom block name removal has a dedicated function --- .../verilog_formal_random_top_testbench.cpp | 14 --------- .../fpga_verilog/verilog_testbench_utils.cpp | 29 +++++++++---------- .../fpga_verilog/verilog_testbench_utils.h | 1 - .../fpga_verilog/verilog_top_testbench.cpp | 7 ----- .../src/utils/openfpga_atom_netlist_utils.cpp | 24 +++++++++++++++ .../src/utils/openfpga_atom_netlist_utils.h | 2 ++ 6 files changed, 39 insertions(+), 38 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp index d39c198cb..d044064c8 100644 --- a/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_formal_random_top_testbench.cpp @@ -117,18 +117,11 @@ void print_verilog_top_random_testbench_benchmark_instance(std::fstream& fp, /* Instanciate benchmark */ 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 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, std::string(BENCHMARK_INSTANCE_NAME), std::string(), std::string(), std::string(), - prefix_to_remove, std::string(BENCHMARK_PORT_POSTFIX), std::vector(), atom_ctx, netlist_annotation, @@ -158,19 +151,12 @@ void print_verilog_random_testbench_fpga_instance(std::fstream& fp, print_verilog_comment(fp, std::string("----- FPGA fabric instanciation -------")); - /* VPR added a prefix of "out_" to the output ports of input benchmark */ - std::vector 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 */ print_verilog_testbench_benchmark_instance(fp, std::string(circuit_name + std::string(FORMAL_VERIFICATION_TOP_MODULE_POSTFIX)), std::string(FPGA_INSTANCE_NAME), std::string(), std::string(), std::string(), - prefix_to_remove, std::string(FPGA_PORT_POSTFIX), std::vector(), atom_ctx, netlist_annotation, diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index c1c379366..85f32aa98 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -22,6 +22,7 @@ #include "module_manager_utils.h" #include "fabric_global_port_info_utils.h" +#include "openfpga_atom_netlist_utils.h" #include "verilog_constants.h" #include "verilog_writer_utils.h" @@ -79,7 +80,6 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, const std::string& module_input_port_postfix, const std::string& module_output_port_postfix, const std::string& input_port_postfix, - const std::vector& output_port_prefix_to_remove, const std::string& output_port_postfix, const std::vector& clock_port_names, const AtomContext& atom_ctx, @@ -109,6 +109,13 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, block_name = netlist_annotation.block_name(atom_blk); } + /* Note that VPR added a prefix "out_" or "out:" to the name of output blocks + * We can remove this when specified through input argument + */ + if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) { + block_name = remove_atom_block_name_prefix(block_name); + } + /* 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 @@ -195,21 +202,8 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, } } else { VTR_ASSERT_SAFE(AtomBlockType::OUTPAD == port_types[iport]); - /* Note that VPR added a prefix "out_" or "out:" to the name of output blocks - * We can remove this when specified through input argument - */ - std::string output_block_name = port_names[iport]; - for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { - if (!prefix_to_remove.empty()) { - if (0 == output_block_name.find(prefix_to_remove)) { - output_block_name.erase(0, prefix_to_remove.length()); - break; - } - } - } - if (true == use_explicit_port_map) { - fp << "." << output_block_name << module_output_port_postfix << "("; + fp << "." << port_names[iport] << module_output_port_postfix << "("; } /* For bus ports, include a complete list of pins */ @@ -237,7 +231,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, /* Update the counter */ port_counter++; } - fp << "\t);" << std::endl; + fp << "\n\t);" << std::endl; } /******************************************************************** @@ -576,6 +570,7 @@ void print_verilog_testbench_check(std::fstream& fp, } 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 << " === " << block_name << benchmark_port_postfix; fp << ") && !(" << block_name << benchmark_port_postfix; @@ -603,6 +598,7 @@ void print_verilog_testbench_check(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 << "\t\tif(" << block_name << check_flag_port_postfix << ") begin" << std::endl; @@ -874,6 +870,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ BasicPort output_port(std::string(block_name + fpga_output_port_postfix), 1); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 39b269904..1d531cfe0 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -39,7 +39,6 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp, const std::string& module_input_port_postfix, const std::string& module_output_port_postfix, const std::string& input_port_postfix, - const std::vector& output_port_prefix_to_remove, const std::string& output_port_postfix, const std::vector& clock_port_names, const AtomContext& atom_ctx, diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 666c2fa83..57312ac9d 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -946,18 +946,11 @@ void print_verilog_top_testbench_benchmark_instance(std::fstream& fp, /* Instanciate benchmark */ 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 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, std::string(TOP_TESTBENCH_REFERENCE_INSTANCE_NAME), std::string(), std::string(), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), - prefix_to_remove, std::string(TOP_TESTBENCH_REFERENCE_OUTPUT_POSTFIX), clock_port_names, atom_ctx, netlist_annotation, diff --git a/openfpga/src/utils/openfpga_atom_netlist_utils.cpp b/openfpga/src/utils/openfpga_atom_netlist_utils.cpp index 8d1876f90..9539a7c91 100644 --- a/openfpga/src/utils/openfpga_atom_netlist_utils.cpp +++ b/openfpga/src/utils/openfpga_atom_netlist_utils.cpp @@ -11,6 +11,7 @@ /* Headers from vtrutil library */ #include "atom_netlist_utils.h" +#include "openfpga_reserved_words.h" #include "openfpga_atom_netlist_utils.h" /* begin namespace openfpga */ @@ -38,4 +39,27 @@ std::vector find_atom_netlist_clock_port_names(const AtomNetlist& a 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 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 */ diff --git a/openfpga/src/utils/openfpga_atom_netlist_utils.h b/openfpga/src/utils/openfpga_atom_netlist_utils.h index dfa5743a2..3ddad6a93 100644 --- a/openfpga/src/utils/openfpga_atom_netlist_utils.h +++ b/openfpga/src/utils/openfpga_atom_netlist_utils.h @@ -19,6 +19,8 @@ namespace openfpga { std::vector find_atom_netlist_clock_port_names(const AtomNetlist& atom_nlist, const VprNetlistAnnotation& netlist_annotation); +std::string remove_atom_block_name_prefix(const std::string& block_name); + } /* end namespace openfpga */ #endif From c16ea8d0821f4ddd7ba08935d5958f6f90231479 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 14:34:32 -0800 Subject: [PATCH 25/37] [FPGA-Verilog] Fixing bugs in naming wires in verilog testbenches --- openfpga/src/fpga_verilog/verilog_testbench_utils.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index 85f32aa98..d7a2db8a0 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -706,6 +706,9 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) { @@ -741,6 +744,7 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); @@ -775,6 +779,9 @@ void print_verilog_testbench_random_stimuli(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), block_name)) { @@ -897,6 +904,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ BasicPort output_port(std::string(block_name + benchmark_output_port_postfix), 1); @@ -919,6 +927,7 @@ void print_verilog_testbench_shared_ports(std::fstream& fp, if (true == netlist_annotation.is_block_renamed(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 */ BasicPort output_port(std::string(block_name + check_flag_port_postfix), 1); From 401f673f1699ca5bf119dd053a5557a0b2ed0b08 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 14:47:36 -0800 Subject: [PATCH 26/37] [FPGA-Verilog] Streamline codes by using APIs --- .../src/fpga_verilog/verilog_preconfig_top_module.cpp | 4 ---- openfpga/src/fpga_verilog/verilog_testbench_utils.cpp | 11 ++--------- openfpga/src/fpga_verilog/verilog_testbench_utils.h | 1 - openfpga/src/fpga_verilog/verilog_top_testbench.cpp | 1 - 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp index dd9d8f0a9..26ce11c2f 100644 --- a/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp +++ b/openfpga/src/fpga_verilog/verilog_preconfig_top_module.cpp @@ -517,9 +517,6 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, } /* Connect I/Os to benchmark I/Os or constant driver */ - std::vector 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, atom_ctx, place_ctx, io_location_map, netlist_annotation, @@ -527,7 +524,6 @@ int print_verilog_preconfig_top_module(const ModuleManager &module_manager, std::string(FORMAL_VERIFICATION_TOP_MODULE_PORT_POSTFIX), std::string(), std::string(), - prefix_to_remove, std::vector(), (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp index d7a2db8a0..4d19b5e96 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.cpp @@ -252,7 +252,6 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, const std::string& net_name_postfix, const std::string& io_input_port_name_postfix, const std::string& io_output_port_name_postfix, - const std::vector& output_port_prefix_to_remove, const std::vector& clock_port_names, const size_t& unused_io_value) { /* Validate the file stream */ @@ -348,16 +347,10 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, /* Note that VPR added a prefix to the name of output blocks * We can remove this when specified through input argument */ - for (const std::string& prefix_to_remove : output_port_prefix_to_remove) { - if (!prefix_to_remove.empty()) { - if (0 == block_name.find(prefix_to_remove)) { - block_name.erase(0, prefix_to_remove.length()); - break; - } - } + if (AtomBlockType::OUTPAD == atom_ctx.nlist.block_type(atom_blk)) { + block_name = remove_atom_block_name_prefix(block_name); } - /* Create the port for benchmark I/O, due to BLIF benchmark, each I/O always has a size of 1 * In addition, the input and output ports may have different postfix in naming * due to verification context! Here, we give full customization on naming diff --git a/openfpga/src/fpga_verilog/verilog_testbench_utils.h b/openfpga/src/fpga_verilog/verilog_testbench_utils.h index 1d531cfe0..7803be4d0 100644 --- a/openfpga/src/fpga_verilog/verilog_testbench_utils.h +++ b/openfpga/src/fpga_verilog/verilog_testbench_utils.h @@ -58,7 +58,6 @@ void print_verilog_testbench_connect_fpga_ios(std::fstream& fp, const std::string& net_name_postfix, const std::string& io_input_port_name_postfix, const std::string& io_output_port_name_postfix, - const std::vector& output_port_prefix_to_remove, const std::vector& clock_port_names, const size_t& unused_io_value); diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 57312ac9d..8a2163a9c 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -2064,7 +2064,6 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, std::string(), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), - std::vector(), clock_port_names, (size_t)VERILOG_DEFAULT_SIGNAL_INIT_VALUE); From 36543f7f2f3601c812876892fb2c7564af1af745 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 14:54:39 -0800 Subject: [PATCH 27/37] [Script] Support simplified rewriting for Yosys on output verilog --- openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys | 1 + .../preconfig_testbench_explicit_mapping/config/task.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys index 2dd4ab695..9083f7344 100644 --- a/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys @@ -39,3 +39,4 @@ synth -run check # Clean and output blif opt_clean -purge write_blif rewritten_${OUTPUT_BLIF} +write_verilog ${OUTPUT_VERILOG} diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf index d1de85faf..92892a530 100644 --- a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/task.conf @@ -38,7 +38,7 @@ bench_yosys_dsp_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_ 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;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_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 From b4d59fdd1e9cb6c3c8471271ff5f59a3747dc6a9 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:02:08 -0800 Subject: [PATCH 28/37] [Test] Update bus group file due to little and big endian conversion during yosys/vpr --- .../config/counter8_bus_group.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml index 3263c16d3..51dccca71 100644 --- a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_explicit_mapping/config/counter8_bus_group.xml @@ -1,12 +1,12 @@ - - - - - - - - + + + + + + + + From 5ab84e1861860db32e0db9ff0490fdcfd9648273 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:29:33 -0800 Subject: [PATCH 29/37] [Test] Add a new test for bus group --- .../config/counter8_bus_group.xml | 12 +++++ .../config/pin_constraints_reset.xml | 7 +++ .../config/task.conf | 48 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/counter8_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/counter8_bus_group.xml new file mode 100644 index 000000000..51dccca71 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/task.conf new file mode 100644 index 000000000..23af1199a --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/preconfig_testbench_implicit_mapping/config/task.conf @@ -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= From 85c893c94cb4c8aa07db35a05da6a59214aab507 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:30:08 -0800 Subject: [PATCH 30/37] [Test] Add new test to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 9cdda1671..55993d946 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -169,3 +169,4 @@ run-task basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing --debug 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 From 223575cf3e5e80616c2cfdf3ac8f49e509936df1 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:33:29 -0800 Subject: [PATCH 31/37] [Test] Added a new test for bus group on full testbenches --- .../config/counter8_bus_group.xml | 12 +++++ .../config/pin_constraints_reset.xml | 7 +++ .../config/task.conf | 47 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/counter8_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/counter8_bus_group.xml new file mode 100644 index 000000000..51dccca71 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/task.conf new file mode 100644 index 000000000..adfb12dc1 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_explicit_mapping/config/task.conf @@ -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= From c897a64ad570f0846cf0c080abce30ae3fcd516e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:37:42 -0800 Subject: [PATCH 32/37] [Script] Add a new example script to test full testbenches using bus group features --- ...estbench_bus_group_example_script.openfpga | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga diff --git a/openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga new file mode 100644 index 000000000..b44f1a3bd --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/full_testbench_bus_group_example_script.openfpga @@ -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 From fe9e0ff977eafd31022a899190d130d5b1650bfb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:38:53 -0800 Subject: [PATCH 33/37] [Test] Add the new test to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 55993d946..996031140 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -170,3 +170,4 @@ run-task basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing --debug 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 From 790715f46a27f77dce08a8ea08e1581057683ddf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:41:35 -0800 Subject: [PATCH 34/37] [FPGA-Verilog] Fixing bugs when using bus group in full testbench generator --- openfpga/src/fpga_verilog/verilog_top_testbench.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp index 8a2163a9c..689b7f569 100644 --- a/openfpga/src/fpga_verilog/verilog_top_testbench.cpp +++ b/openfpga/src/fpga_verilog/verilog_top_testbench.cpp @@ -2060,7 +2060,7 @@ int print_verilog_full_testbench(const ModuleManager& module_manager, print_verilog_testbench_connect_fpga_ios(fp, module_manager, top_module, atom_ctx, place_ctx, io_location_map, netlist_annotation, - bus_group, + BusGroup(), std::string(), std::string(TOP_TESTBENCH_SHARED_INPUT_POSTFIX), std::string(TOP_TESTBENCH_FPGA_OUTPUT_POSTFIX), From f0ce1e79a3fe887104f3aeedd6a9cf8c90f48a0f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:43:21 -0800 Subject: [PATCH 35/37] [Test] Added a new test to validate bus group in full testbench --- .../config/counter8_bus_group.xml | 12 +++++ .../config/pin_constraints_reset.xml | 7 +++ .../config/task.conf | 47 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/counter8_bus_group.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/pin_constraints_reset.xml create mode 100644 openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/counter8_bus_group.xml b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/counter8_bus_group.xml new file mode 100644 index 000000000..51dccca71 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/counter8_bus_group.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/pin_constraints_reset.xml b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/pin_constraints_reset.xml new file mode 100644 index 000000000..abcf209f6 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/pin_constraints_reset.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/task.conf b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/task.conf new file mode 100644 index 000000000..2ecda7275 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/bus_group/full_testbench_implicit_mapping/config/task.conf @@ -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= From 68644ea0f6608038cfb379b4515753816496db40 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:44:07 -0800 Subject: [PATCH 36/37] [Test] Add the new test to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 996031140..bab6c6256 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -171,3 +171,4 @@ 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 From 811614121060f899e77dd3011037cd5ae8dc7b2b Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 18 Feb 2022 15:46:25 -0800 Subject: [PATCH 37/37] [Doc] Update documentation on the bus group feature --- .../openfpga_commands/fpga_verilog_commands.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst index aaebf5f87..6a872a1d1 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/fpga_verilog_commands.rst @@ -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`` Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. + .. option:: --bus_group_file or -bgf + + 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 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. @@ -185,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`` Strongly recommend for multi-clock simulations. See detailed file format about :ref:`file_format_pin_constraints_file`. + .. option:: --bus_group_file or -bgf + + 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 Use explicit port mapping when writing the Verilog netlists