Merge pull request #294 from lnis-uofu/mux_default_path
Support customizable default path in bitstream generation for any interconnect inside pb_type
This commit is contained in:
commit
12f27cf117
|
@ -6,19 +6,35 @@ Bitstream Setting (.xml)
|
|||
An example of bitstream settings is shown as follows.
|
||||
This can define a hard-coded bitstream for a reconfigurable resource in FPGA fabrics.
|
||||
|
||||
.. warning:: Bitstream setting is a feature for power-users. It may cause wrong bitstream to be generated. For example, the hard-coded bitstream is not compatible with LUTs whose nets may be swapped during routing stage (cause a change on the truth table as well as bitstream). It is users's responsibility to ensure correct bitstream.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<openfpga_bitstream_setting>
|
||||
<pb_type name="<string>" source="eblif" content=".param LUT" is_mode_select_bistream="true" bitstream_offset="1"/>
|
||||
<interconnect name="<string>" default_path="<string>"/>
|
||||
</openfpga_bitstream_setting>
|
||||
|
||||
.. option:: pb_type="<string>"
|
||||
pb_type-related Settings
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``pb_type`` name to be constrained, which should be the full path of a ``pb_type`` consistent with VPR's architecture description. For example, ``pb_type="clb.fle[arithmetic].soft_adder.adder_lut4"``
|
||||
The following syntax are applicable to the XML definition tagged by ``pb_type`` in bitstream setting files.
|
||||
|
||||
.. option:: name="<string>"
|
||||
|
||||
The ``pb_type`` name to be constrained, which should be the full path of a ``pb_type`` consistent with VPR's architecture description. For example,
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
pb_type="clb.fle[arithmetic].soft_adder.adder_lut4"
|
||||
|
||||
.. option:: source="<string>"
|
||||
|
||||
The source of the ``pb_type`` bitstream, which could be from a ``.eblif`` file. For example, ``source="eblif"``.
|
||||
The source of the ``pb_type`` bitstream, which could be from a ``.eblif`` file. For example,
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
source="eblif"
|
||||
|
||||
.. option:: content="<string>"
|
||||
|
||||
|
@ -33,5 +49,25 @@ This can define a hard-coded bitstream for a reconfigurable resource in FPGA fab
|
|||
|
||||
Specify the offset to be applied when overloading the bitstream to a target. For example, a LUT may have a 16-bit bitstream. When ``offset=1``, bitstream overloading will skip the first bit and start from the second bit of the 16-bit bitstream.
|
||||
|
||||
.. warning:: Bitstream setting is a feature for power-users. It may cause wrong bitstream to be generated. For example, the hard-coded bitstream is not compatible with LUTs whose nets may be swapped during routing stage (cause a change on the truth table as well as bitstream). It is users's responsibility to ensure correct bitstream.
|
||||
Interconnection-related Settings
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following syntax are applicable to the XML definition tagged by ``interconnect`` in bitstream setting files.
|
||||
|
||||
.. option:: name="<string>"
|
||||
|
||||
The ``interconnect`` name to be constrained, which should be the full path of a ``pb_type`` consistent with VPR's architecture description. For example,
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
pb_type="clb.fle[arithmetic].mux1"
|
||||
|
||||
.. option:: default_path="<string>"
|
||||
|
||||
The default path denotes an input name that is consistent with VPR's architecture description. For example, in VPR architecture, there is a mux defined as
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<mux name="mux1" input="iopad.inpad ff.Q" output="io.inpad"/>
|
||||
|
||||
The default path can be either ``iopad.inpad`` or ``ff.Q`` which corresponds to the first input and the second input respectively.
|
||||
|
|
|
@ -16,6 +16,10 @@ BitstreamSetting::bitstream_pb_type_setting_range BitstreamSetting::pb_type_sett
|
|||
return vtr::make_range(pb_type_setting_ids_.begin(), pb_type_setting_ids_.end());
|
||||
}
|
||||
|
||||
BitstreamSetting::bitstream_interconnect_setting_range BitstreamSetting::interconnect_settings() const {
|
||||
return vtr::make_range(interconnect_setting_ids_.begin(), interconnect_setting_ids_.end());
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
|
@ -61,6 +65,25 @@ size_t BitstreamSetting::bitstream_offset(const BitstreamPbTypeSettingId& pb_typ
|
|||
return bitstream_offsets_[pb_type_setting_id];
|
||||
}
|
||||
|
||||
std::string BitstreamSetting::interconnect_name(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
|
||||
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
|
||||
return interconnect_names_[interconnect_setting_id];
|
||||
}
|
||||
|
||||
std::vector<std::string> BitstreamSetting::parent_pb_type_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
|
||||
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
|
||||
return interconnect_parent_pb_type_names_[interconnect_setting_id];
|
||||
}
|
||||
|
||||
std::vector<std::string> BitstreamSetting::parent_mode_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
|
||||
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
|
||||
return interconnect_parent_mode_names_[interconnect_setting_id];
|
||||
}
|
||||
|
||||
std::string BitstreamSetting::default_path(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
|
||||
VTR_ASSERT(true == valid_bitstream_interconnect_setting_id(interconnect_setting_id));
|
||||
return interconnect_default_paths_[interconnect_setting_id];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Mutators
|
||||
|
@ -95,6 +118,20 @@ void BitstreamSetting::set_bitstream_offset(const BitstreamPbTypeSettingId& pb_t
|
|||
bitstream_offsets_[pb_type_setting_id] = offset;
|
||||
}
|
||||
|
||||
BitstreamInterconnectSettingId BitstreamSetting::add_bitstream_interconnect_setting(const std::string& interconnect_name,
|
||||
const std::vector<std::string>& parent_pb_type_names,
|
||||
const std::vector<std::string>& parent_mode_names,
|
||||
const std::string& default_path) {
|
||||
BitstreamInterconnectSettingId interc_setting_id = BitstreamInterconnectSettingId(interconnect_setting_ids_.size());
|
||||
interconnect_setting_ids_.push_back(interc_setting_id);
|
||||
interconnect_names_.push_back(interconnect_name);
|
||||
interconnect_parent_pb_type_names_.push_back(parent_pb_type_names);
|
||||
interconnect_parent_mode_names_.push_back(parent_mode_names);
|
||||
interconnect_default_paths_.push_back(default_path);
|
||||
|
||||
return interc_setting_id;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public Validators
|
||||
***********************************************************************/
|
||||
|
@ -102,4 +139,8 @@ bool BitstreamSetting::valid_bitstream_pb_type_setting_id(const BitstreamPbTypeS
|
|||
return ( size_t(pb_type_setting_id) < pb_type_setting_ids_.size() ) && ( pb_type_setting_id == pb_type_setting_ids_[pb_type_setting_id] );
|
||||
}
|
||||
|
||||
bool BitstreamSetting::valid_bitstream_interconnect_setting_id(const BitstreamInterconnectSettingId& interconnect_setting_id) const {
|
||||
return ( size_t(interconnect_setting_id) < interconnect_setting_ids_.size() ) && ( interconnect_setting_id == interconnect_setting_ids_[interconnect_setting_id] );
|
||||
}
|
||||
|
||||
} /* namespace openfpga ends */
|
||||
|
|
|
@ -16,6 +16,10 @@ namespace openfpga {
|
|||
|
||||
/********************************************************************
|
||||
* A data structure to describe bitstream settings
|
||||
*
|
||||
* This data structure includes following types of settings:
|
||||
* - Pb type: include definiting hard coded bitstream for pb_types (LUT or configurable pb_type for mode selection)
|
||||
* - Interconnect: include defining default paths for routing multiplexers in pb_types
|
||||
*
|
||||
* Typical usage:
|
||||
* --------------
|
||||
|
@ -27,12 +31,15 @@ namespace openfpga {
|
|||
class BitstreamSetting {
|
||||
public: /* Types */
|
||||
typedef vtr::vector<BitstreamPbTypeSettingId, BitstreamPbTypeSettingId>::const_iterator bitstream_pb_type_setting_iterator;
|
||||
typedef vtr::vector<BitstreamInterconnectSettingId, BitstreamInterconnectSettingId>::const_iterator bitstream_interconnect_setting_iterator;
|
||||
/* Create range */
|
||||
typedef vtr::Range<bitstream_pb_type_setting_iterator> bitstream_pb_type_setting_range;
|
||||
typedef vtr::Range<bitstream_interconnect_setting_iterator> bitstream_interconnect_setting_range;
|
||||
public: /* Constructors */
|
||||
BitstreamSetting();
|
||||
public: /* Accessors: aggregates */
|
||||
bitstream_pb_type_setting_range pb_type_settings() const;
|
||||
bitstream_interconnect_setting_range interconnect_settings() const;
|
||||
public: /* Public Accessors */
|
||||
std::string pb_type_name(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
std::vector<std::string> parent_pb_type_names(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
|
@ -41,6 +48,10 @@ class BitstreamSetting {
|
|||
std::string pb_type_bitstream_content(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
bool is_mode_select_bitstream(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
size_t bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
std::string interconnect_name(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||
std::vector<std::string> parent_pb_type_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||
std::vector<std::string> parent_mode_names(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||
std::string default_path(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||
public: /* Public Mutators */
|
||||
BitstreamPbTypeSettingId add_bitstream_pb_type_setting(const std::string& pb_type_name,
|
||||
const std::vector<std::string>& parent_pb_type_names,
|
||||
|
@ -51,9 +62,19 @@ class BitstreamSetting {
|
|||
const bool& is_mode_select_bitstream);
|
||||
void set_bitstream_offset(const BitstreamPbTypeSettingId& pb_type_setting_id,
|
||||
const size_t& offset);
|
||||
|
||||
BitstreamInterconnectSettingId add_bitstream_interconnect_setting(const std::string& interconnect_name,
|
||||
const std::vector<std::string>& parent_pb_type_names,
|
||||
const std::vector<std::string>& parent_mode_names,
|
||||
const std::string& default_path);
|
||||
public: /* Public Validators */
|
||||
bool valid_bitstream_pb_type_setting_id(const BitstreamPbTypeSettingId& pb_type_setting_id) const;
|
||||
bool valid_bitstream_interconnect_setting_id(const BitstreamInterconnectSettingId& interconnect_setting_id) const;
|
||||
private: /* Internal data */
|
||||
/* Pb type -related settings
|
||||
* - Paths to a pb_type in the pb_graph
|
||||
* - Bitstream source, data_type, offsets etc.
|
||||
*/
|
||||
vtr::vector<BitstreamPbTypeSettingId, BitstreamPbTypeSettingId> pb_type_setting_ids_;
|
||||
vtr::vector<BitstreamPbTypeSettingId, std::string> pb_type_names_;
|
||||
vtr::vector<BitstreamPbTypeSettingId, std::vector<std::string>> parent_pb_type_names_;
|
||||
|
@ -64,6 +85,16 @@ class BitstreamSetting {
|
|||
vtr::vector<BitstreamPbTypeSettingId, bool> is_mode_select_bitstreams_;
|
||||
/* The offset that the bitstream is applied to the original bitstream of a pb_type */
|
||||
vtr::vector<BitstreamPbTypeSettingId, size_t> bitstream_offsets_;
|
||||
|
||||
/* Interconnect-related settings:
|
||||
* - Name of interconnect under a given pb_type
|
||||
* - The default path to be considered for a given interconnect during bitstream generation
|
||||
*/
|
||||
vtr::vector<BitstreamInterconnectSettingId, BitstreamInterconnectSettingId> interconnect_setting_ids_;
|
||||
vtr::vector<BitstreamInterconnectSettingId, std::string> interconnect_names_;
|
||||
vtr::vector<BitstreamInterconnectSettingId, std::vector<std::string>> interconnect_parent_pb_type_names_;
|
||||
vtr::vector<BitstreamInterconnectSettingId, std::vector<std::string>> interconnect_parent_mode_names_;
|
||||
vtr::vector<BitstreamInterconnectSettingId, std::string> interconnect_default_paths_;
|
||||
};
|
||||
|
||||
} /* namespace openfpga ends */
|
||||
|
|
|
@ -13,8 +13,10 @@
|
|||
#include "vtr_strong_id.h"
|
||||
|
||||
struct bitstream_pb_type_setting_id_tag;
|
||||
struct bitstream_interconnect_setting_id_tag;
|
||||
|
||||
typedef vtr::StrongId<bitstream_pb_type_setting_id_tag> BitstreamPbTypeSettingId;
|
||||
typedef vtr::StrongId<bitstream_interconnect_setting_id_tag> BitstreamInterconnectSettingId;
|
||||
|
||||
/* Short declaration of class */
|
||||
class BitstreamSetting;
|
||||
|
|
|
@ -50,6 +50,26 @@ void read_xml_bitstream_pb_type_setting(pugi::xml_node& xml_pb_type,
|
|||
bitstream_setting.set_bitstream_offset(bitstream_pb_type_id, offset);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Parse XML description for a pb_type annotation under a <interconect> XML node
|
||||
*******************************************************************/
|
||||
static
|
||||
void read_xml_bitstream_interconnect_setting(pugi::xml_node& xml_pb_type,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
openfpga::BitstreamSetting& bitstream_setting) {
|
||||
const std::string& name_attr = get_attribute(xml_pb_type, "name", loc_data).as_string();
|
||||
const std::string& default_path_attr = get_attribute(xml_pb_type, "default_path", loc_data).as_string();
|
||||
|
||||
/* Parse the attributes for operating pb_type */
|
||||
openfpga::PbParser operating_pb_parser(name_attr);
|
||||
|
||||
/* Add to bitstream setting */
|
||||
bitstream_setting.add_bitstream_interconnect_setting(operating_pb_parser.leaf(),
|
||||
operating_pb_parser.parents(),
|
||||
operating_pb_parser.modes(),
|
||||
default_path_attr);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Parse XML codes about <openfpga_bitstream_setting> to an object
|
||||
*******************************************************************/
|
||||
|
@ -60,12 +80,19 @@ openfpga::BitstreamSetting read_xml_bitstream_setting(pugi::xml_node& Node,
|
|||
/* Iterate over the children under this node,
|
||||
* each child should be named after <pb_type>
|
||||
*/
|
||||
for (pugi::xml_node xml_pb_type : Node.children()) {
|
||||
for (pugi::xml_node xml_child : Node.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_pb_type.name() != std::string("pb_type")) {
|
||||
bad_tag(xml_pb_type, loc_data, Node, {"pb_type"});
|
||||
if ( (xml_child.name() != std::string("pb_type"))
|
||||
&& (xml_child.name() != std::string("interconnect")) ) {
|
||||
bad_tag(xml_child, loc_data, Node, {"pb_type | interconnect"});
|
||||
}
|
||||
|
||||
if (xml_child.name() == std::string("pb_type")) {
|
||||
read_xml_bitstream_pb_type_setting(xml_child, loc_data, bitstream_setting);
|
||||
} else {
|
||||
VTR_ASSERT_SAFE(xml_child.name() == std::string("interconnect"));
|
||||
read_xml_bitstream_interconnect_setting(xml_child, loc_data, bitstream_setting);
|
||||
}
|
||||
read_xml_bitstream_pb_type_setting(xml_pb_type, loc_data, bitstream_setting);
|
||||
}
|
||||
|
||||
return bitstream_setting;
|
||||
|
|
|
@ -39,6 +39,31 @@ std::string generate_bitstream_setting_pb_type_hierarchy_name(const openfpga::Bi
|
|||
return hie_name;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Generate the full hierarchy name for an interconnect in bitstream setting
|
||||
*******************************************************************/
|
||||
static
|
||||
std::string generate_bitstream_setting_interconnect_hierarchy_name(const openfpga::BitstreamSetting& bitstream_setting,
|
||||
const BitstreamInterconnectSettingId& bitstream_interc_setting_id) {
|
||||
/* Iterate over the parent_pb_type and modes names, they should well match */
|
||||
VTR_ASSERT_SAFE(bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id).size() == bitstream_setting.parent_mode_names(bitstream_interc_setting_id).size());
|
||||
|
||||
std::string hie_name;
|
||||
|
||||
for (size_t i = 0 ; i < bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id).size(); ++i) {
|
||||
hie_name += bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id)[i];
|
||||
hie_name += std::string("[");
|
||||
hie_name += bitstream_setting.parent_mode_names(bitstream_interc_setting_id)[i];
|
||||
hie_name += std::string("]");
|
||||
hie_name += std::string(".");
|
||||
}
|
||||
|
||||
/* Add the leaf pb_type */
|
||||
hie_name += bitstream_setting.interconnect_name(bitstream_interc_setting_id);
|
||||
|
||||
return hie_name;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A writer to output a bitstream pb_type setting to XML format
|
||||
*******************************************************************/
|
||||
|
@ -63,6 +88,27 @@ void write_xml_bitstream_pb_type_setting(std::fstream& fp,
|
|||
fp << "/>" << "\n";
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A writer to output a bitstream interconnect setting to XML format
|
||||
*******************************************************************/
|
||||
static
|
||||
void write_xml_bitstream_interconnect_setting(std::fstream& fp,
|
||||
const char* fname,
|
||||
const openfpga::BitstreamSetting& bitstream_setting,
|
||||
const BitstreamInterconnectSettingId& bitstream_interc_setting_id) {
|
||||
/* Validate the file stream */
|
||||
openfpga::check_file_stream(fname, fp);
|
||||
|
||||
fp << "\t" << "<pb_type";
|
||||
|
||||
/* Generate the full hierarchy name of the pb_type */
|
||||
write_xml_attribute(fp, "name", generate_bitstream_setting_interconnect_hierarchy_name(bitstream_setting, bitstream_interc_setting_id).c_str());
|
||||
|
||||
write_xml_attribute(fp, "default_path", bitstream_setting.default_path(bitstream_interc_setting_id).c_str());
|
||||
|
||||
fp << "/>" << "\n";
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* A writer to output a bitstream setting to XML format
|
||||
*******************************************************************/
|
||||
|
@ -76,11 +122,16 @@ void write_xml_bitstream_setting(std::fstream& fp,
|
|||
*/
|
||||
fp << "<openfpga_bitstream_setting>" << "\n";
|
||||
|
||||
/* Write clock settings */
|
||||
/* Write pb_type -related settings */
|
||||
for (const auto& bitstream_pb_type_setting_id : bitstream_setting.pb_type_settings()) {
|
||||
write_xml_bitstream_pb_type_setting(fp, fname, bitstream_setting, bitstream_pb_type_setting_id);
|
||||
}
|
||||
|
||||
/* Write interconnect -related settings */
|
||||
for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) {
|
||||
write_xml_bitstream_interconnect_setting(fp, fname, bitstream_setting, bitstream_interc_setting_id);
|
||||
}
|
||||
|
||||
/* Write the root node <openfpga_bitstream_setting> */
|
||||
fp << "</openfpga_bitstream_setting>" << "\n";
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_tokenizer.h"
|
||||
|
||||
#include "pb_type_utils.h"
|
||||
#include "annotate_bitstream_setting.h"
|
||||
|
||||
|
@ -23,9 +26,10 @@ namespace openfpga {
|
|||
* - Find the pb_type and link to the bitstream source
|
||||
* - Find the pb_type and link to the bitstream content
|
||||
*******************************************************************/
|
||||
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation) {
|
||||
static
|
||||
int annotate_bitstream_pb_type_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation) {
|
||||
|
||||
for (const auto& bitstream_pb_type_setting_id : bitstream_setting.pb_type_settings()) {
|
||||
/* Get the full name of pb_type */
|
||||
|
@ -95,4 +99,135 @@ int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
|
|||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Annotate bitstream setting based on VPR device information
|
||||
* - Find the interconnect and link to the default path id
|
||||
*******************************************************************/
|
||||
static
|
||||
int annotate_bitstream_interconnect_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
const VprDeviceAnnotation& vpr_device_annotation,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation) {
|
||||
|
||||
for (const auto& bitstream_interc_setting_id : bitstream_setting.interconnect_settings()) {
|
||||
/* Get the full name of pb_type */
|
||||
std::vector<std::string> target_pb_type_names;
|
||||
std::vector<std::string> target_pb_mode_names;
|
||||
|
||||
target_pb_type_names = bitstream_setting.parent_pb_type_names(bitstream_interc_setting_id);
|
||||
target_pb_mode_names = bitstream_setting.parent_mode_names(bitstream_interc_setting_id);
|
||||
/* Kick out the last mode so that we can use an existing function search the pb_type in graph */
|
||||
std::string expected_physical_mode_name = target_pb_mode_names.back();
|
||||
target_pb_mode_names.pop_back();
|
||||
|
||||
std::string interconnect_name = bitstream_setting.interconnect_name(bitstream_interc_setting_id);
|
||||
std::string expected_input_path = bitstream_setting.default_path(bitstream_interc_setting_id);
|
||||
|
||||
/* Pb type information are located at the logic_block_types in the device context of VPR
|
||||
* We iterate over the vectors and find the pb_type matches the parent_pb_type_name
|
||||
*/
|
||||
bool link_success = false;
|
||||
|
||||
for (const t_logical_block_type& lb_type : vpr_device_ctx.logical_block_types) {
|
||||
/* By pass nullptr for pb_type head */
|
||||
if (nullptr == lb_type.pb_type) {
|
||||
continue;
|
||||
}
|
||||
/* Check the name of the top-level pb_type, if it does not match, we can bypass */
|
||||
if (target_pb_type_names[0] != std::string(lb_type.pb_type->name)) {
|
||||
continue;
|
||||
}
|
||||
/* Match the name in the top-level, we go further to search the pb_type in the graph */
|
||||
t_pb_type* target_pb_type = try_find_pb_type_with_given_path(lb_type.pb_type, target_pb_type_names,
|
||||
target_pb_mode_names);
|
||||
if (nullptr == target_pb_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Found one, build annotation */
|
||||
t_mode* physical_mode = vpr_device_annotation.physical_mode(target_pb_type);
|
||||
|
||||
VTR_ASSERT(nullptr != physical_mode);
|
||||
/* Ensure that the annotation is only applicable to physical mode */
|
||||
if (std::string(physical_mode->name) != expected_physical_mode_name) {
|
||||
VTR_LOG_ERROR("The physical mode '%s' under pb_type '%s' does not match in the bitstream setting '%s'!\n",
|
||||
physical_mode->name,
|
||||
target_pb_type->name,
|
||||
expected_physical_mode_name.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Find the interconnect name under the physical mode of a physical pb_type */
|
||||
t_interconnect* pb_interc = find_pb_mode_interconnect(physical_mode, interconnect_name.c_str());
|
||||
|
||||
if (nullptr == pb_interc) {
|
||||
VTR_LOG_ERROR("Unable to find interconnect '%s' under physical mode '%s' of pb_type '%s'!\n",
|
||||
interconnect_name.c_str(),
|
||||
physical_mode->name,
|
||||
target_pb_type->name);
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* Find the default path and spot the path id from the input string recorded */
|
||||
StringToken input_string_tokenizer(std::string(pb_interc->input_string));
|
||||
std::vector<std::string> input_paths = input_string_tokenizer.split(' ');
|
||||
size_t input_path_id = input_paths.size();
|
||||
for (size_t ipath = 0; ipath < input_paths.size(); ++ipath) {
|
||||
if (expected_input_path == input_paths[ipath]) {
|
||||
input_path_id = ipath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If the input_path id is invalid, error out! */
|
||||
if (input_path_id == input_paths.size()) {
|
||||
VTR_LOG_ERROR("Invalid default path '%s' for interconnect '%s' which inputs are '%s'\n",
|
||||
expected_input_path.c_str(),
|
||||
interconnect_name.c_str(),
|
||||
pb_interc->input_string);
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
vpr_bitstream_annotation.set_interconnect_default_path_id(pb_interc, input_path_id);
|
||||
|
||||
link_success = true;
|
||||
}
|
||||
|
||||
/* If fail to link bitstream setting to architecture, error out immediately */
|
||||
if (false == link_success) {
|
||||
VTR_LOG_ERROR("Fail to find an interconnect '%s' with default path '%s', which is defined in bitstream setting from VPR architecture description\n",
|
||||
interconnect_name.c_str(),
|
||||
expected_input_path.c_str());
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_EXEC_SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Annotate bitstream setting based on VPR device information
|
||||
* - Fill pb_type -related mapping
|
||||
* - Fill interconnect -related mapping
|
||||
*******************************************************************/
|
||||
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
const VprDeviceAnnotation& vpr_device_annotation,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation) {
|
||||
|
||||
int status = CMD_EXEC_SUCCESS;
|
||||
|
||||
status = annotate_bitstream_pb_type_setting(bitstream_setting,
|
||||
vpr_device_ctx,
|
||||
vpr_bitstream_annotation);
|
||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = annotate_bitstream_interconnect_setting(bitstream_setting,
|
||||
vpr_device_ctx, vpr_device_annotation,
|
||||
vpr_bitstream_annotation);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace openfpga {
|
|||
|
||||
int annotate_bitstream_setting(const BitstreamSetting& bitstream_setting,
|
||||
const DeviceContext& vpr_device_ctx,
|
||||
const VprDeviceAnnotation& vpr_device_annotation,
|
||||
VprBitstreamAnnotation& vpr_bitstream_annotation);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
#include "mux_bitstream_constants.h"
|
||||
|
||||
/* namespace openfpga begins */
|
||||
namespace openfpga {
|
||||
|
@ -78,6 +79,16 @@ size_t VprBitstreamAnnotation::pb_type_mode_select_bitstream_offset(t_pb_type* p
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t VprBitstreamAnnotation::interconnect_default_path_id(t_interconnect* interconnect) const {
|
||||
auto result = interconnect_default_path_ids_.find(interconnect);
|
||||
if (result != interconnect_default_path_ids_.end()) {
|
||||
return result->second;
|
||||
}
|
||||
|
||||
/* Not found, return an invalid input id */
|
||||
return DEFAULT_PATH_ID;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public mutators
|
||||
***********************************************************************/
|
||||
|
@ -111,4 +122,9 @@ void VprBitstreamAnnotation::set_pb_type_mode_select_bitstream_offset(t_pb_type*
|
|||
mode_select_bitstream_offsets_[pb_type] = offset;
|
||||
}
|
||||
|
||||
void VprBitstreamAnnotation::set_interconnect_default_path_id(t_interconnect* interconnect,
|
||||
const size_t& default_path_id) {
|
||||
interconnect_default_path_ids_[interconnect] = default_path_id;
|
||||
}
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
|
|
@ -38,6 +38,7 @@ class VprBitstreamAnnotation {
|
|||
e_bitstream_source_type pb_type_mode_select_bitstream_source(t_pb_type* pb_type) const;
|
||||
std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const;
|
||||
size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const;
|
||||
size_t interconnect_default_path_id(t_interconnect* interconnect) const;
|
||||
public: /* Public mutators */
|
||||
void set_pb_type_bitstream_source(t_pb_type* pb_type,
|
||||
const e_bitstream_source_type& bitstream_source);
|
||||
|
@ -52,6 +53,8 @@ class VprBitstreamAnnotation {
|
|||
const std::string& bitstream_content);
|
||||
void set_pb_type_mode_select_bitstream_offset(t_pb_type* pb_type,
|
||||
const size_t& offset);
|
||||
void set_interconnect_default_path_id(t_interconnect* interconnect,
|
||||
const size_t& default_path_id);
|
||||
private: /* Internal data */
|
||||
/* For regular bitstreams */
|
||||
/* A look up for pb type to find bitstream source type */
|
||||
|
@ -68,6 +71,12 @@ class VprBitstreamAnnotation {
|
|||
std::map<t_pb_type*, std::string> mode_select_bitstream_contents_;
|
||||
/* Offset to be applied to mode-select bitstream */
|
||||
std::map<t_pb_type*, size_t> mode_select_bitstream_offsets_;
|
||||
|
||||
/* A look up for interconnect to find default path indices
|
||||
* Note: this is different from the default path in bitstream setting which is the index
|
||||
* of inputs in the context of the interconnect input string
|
||||
*/
|
||||
std::map<t_interconnect*, size_t> interconnect_default_path_ids_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
|
|
@ -177,7 +177,9 @@ int link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
/* Build bitstream annotation based on bitstream settings */
|
||||
if (CMD_EXEC_FATAL_ERROR == annotate_bitstream_setting(openfpga_ctx.bitstream_setting(),
|
||||
g_vpr_ctx.device(),
|
||||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.mutable_vpr_bitstream_annotation())) {
|
||||
|
||||
return CMD_EXEC_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ BitstreamManager build_device_bitstream(const VprContext& vpr_ctx,
|
|||
openfpga_ctx.vpr_device_annotation(),
|
||||
openfpga_ctx.vpr_clustering_annotation(),
|
||||
openfpga_ctx.vpr_placement_annotation(),
|
||||
openfpga_ctx.vpr_bitstream_annotation(),
|
||||
verbose);
|
||||
VTR_LOGV(verbose, "Done\n");
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ void build_physical_block_pin_interc_bitstream(BitstreamManager& bitstream_manag
|
|||
const MuxLibrary& mux_lib,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const PhysicalPb& physical_pb,
|
||||
t_pb_graph_pin* des_pb_graph_pin,
|
||||
t_mode* physical_mode) {
|
||||
|
@ -197,6 +198,12 @@ void build_physical_block_pin_interc_bitstream(BitstreamManager& bitstream_manag
|
|||
}
|
||||
}
|
||||
|
||||
/* Overwrite the default path if defined in bitstream annotation */
|
||||
if ( (size_t(DEFAULT_PATH_ID) == mux_input_pin_id)
|
||||
&& (mux_input_pin_id != bitstream_annotation.interconnect_default_path_id(cur_interc)) ) {
|
||||
mux_input_pin_id = bitstream_annotation.interconnect_default_path_id(cur_interc);
|
||||
}
|
||||
|
||||
/* Generate bitstream depend on both technology and structure of this MUX */
|
||||
std::vector<bool> mux_bitstream = build_mux_bitstream(circuit_lib, mux_model, mux_lib, datapath_mux_size, mux_input_pin_id);
|
||||
|
||||
|
@ -266,6 +273,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
|
|||
const MuxLibrary& mux_lib,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
t_pb_graph_node* physical_pb_graph_node,
|
||||
const PhysicalPb& physical_pb,
|
||||
const e_circuit_pb_port_type& pb_port_type,
|
||||
|
@ -276,7 +284,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
|
|||
for (int ipin = 0; ipin < physical_pb_graph_node->num_input_pins[iport]; ++ipin) {
|
||||
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
physical_pb,
|
||||
&(physical_pb_graph_node->input_pins[iport][ipin]),
|
||||
physical_mode);
|
||||
|
@ -288,7 +296,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
|
|||
for (int ipin = 0; ipin < physical_pb_graph_node->num_output_pins[iport]; ++ipin) {
|
||||
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
physical_pb,
|
||||
&(physical_pb_graph_node->output_pins[iport][ipin]),
|
||||
physical_mode);
|
||||
|
@ -300,7 +308,7 @@ void build_physical_block_interc_port_bitstream(BitstreamManager& bitstream_mana
|
|||
for (int ipin = 0; ipin < physical_pb_graph_node->num_clock_pins[iport]; ++ipin) {
|
||||
build_physical_block_pin_interc_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
physical_pb,
|
||||
&(physical_pb_graph_node->clock_pins[iport][ipin]),
|
||||
physical_mode);
|
||||
|
@ -327,6 +335,7 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
|
|||
const MuxLibrary& mux_lib,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
t_pb_graph_node* physical_pb_graph_node,
|
||||
const PhysicalPb& physical_pb,
|
||||
t_mode* physical_mode) {
|
||||
|
@ -348,7 +357,7 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
|
|||
*/
|
||||
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
physical_pb_graph_node, physical_pb,
|
||||
CIRCUIT_PB_PORT_OUTPUT, physical_mode);
|
||||
|
||||
|
@ -367,13 +376,13 @@ void build_physical_block_interc_bitstream(BitstreamManager& bitstream_manager,
|
|||
/* For each child_pb_graph_node input pins*/
|
||||
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
child_pb_graph_node, physical_pb,
|
||||
CIRCUIT_PB_PORT_INPUT, physical_mode);
|
||||
/* For clock pins, we should do the same work */
|
||||
build_physical_block_interc_port_bitstream(bitstream_manager, parent_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx, device_annotation,
|
||||
atom_ctx, device_annotation, bitstream_annotation,
|
||||
child_pb_graph_node, physical_pb,
|
||||
CIRCUIT_PB_PORT_CLOCK, physical_mode);
|
||||
}
|
||||
|
@ -534,6 +543,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
const MuxLibrary& mux_lib,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const e_side& border_side,
|
||||
const PhysicalPb& physical_pb,
|
||||
const PhysicalPbId& pb_id,
|
||||
|
@ -578,7 +588,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
rec_build_physical_block_bitstream(bitstream_manager, pb_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation,
|
||||
device_annotation, bitstream_annotation,
|
||||
border_side,
|
||||
physical_pb, child_pb,
|
||||
&(physical_pb_graph_node->child_pb_graph_nodes[physical_mode->index][ipb][jpb]),
|
||||
|
@ -623,7 +633,7 @@ void rec_build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
build_physical_block_interc_bitstream(bitstream_manager, pb_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation,
|
||||
device_annotation, bitstream_annotation,
|
||||
physical_pb_graph_node, physical_pb,
|
||||
physical_mode);
|
||||
}
|
||||
|
@ -644,6 +654,7 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprClusteringAnnotation& cluster_annotation,
|
||||
const VprPlacementAnnotation& place_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& grid_coord,
|
||||
const e_side& border_side) {
|
||||
|
@ -692,7 +703,8 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
rec_build_physical_block_bitstream(bitstream_manager, grid_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation, border_side,
|
||||
device_annotation, bitstream_annotation,
|
||||
border_side,
|
||||
PhysicalPb(), PhysicalPbId::INVALID(),
|
||||
lb_type->pb_graph_head, z);
|
||||
} else {
|
||||
|
@ -707,7 +719,8 @@ void build_physical_block_bitstream(BitstreamManager& bitstream_manager,
|
|||
rec_build_physical_block_bitstream(bitstream_manager, grid_configurable_block,
|
||||
module_manager, circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation, border_side,
|
||||
device_annotation, bitstream_annotation,
|
||||
border_side,
|
||||
phy_pb, top_pb_id, pb_graph_head, z);
|
||||
}
|
||||
}
|
||||
|
@ -731,6 +744,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
|
|||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprClusteringAnnotation& cluster_annotation,
|
||||
const VprPlacementAnnotation& place_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const bool& verbose) {
|
||||
|
||||
VTR_LOGV(verbose, "Generating bitstream for core grids...");
|
||||
|
@ -753,7 +767,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
|
|||
circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation, cluster_annotation,
|
||||
place_annotation,
|
||||
place_annotation, bitstream_annotation,
|
||||
grids, grid_coord, NUM_SIDES);
|
||||
}
|
||||
}
|
||||
|
@ -780,7 +794,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
|
|||
circuit_lib, mux_lib,
|
||||
atom_ctx,
|
||||
device_annotation, cluster_annotation,
|
||||
place_annotation,
|
||||
place_annotation, bitstream_annotation,
|
||||
grids, io_coordinate, io_side);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_clustering_annotation.h"
|
||||
#include "vpr_placement_annotation.h"
|
||||
#include "vpr_bitstream_annotation.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
|
@ -32,6 +33,7 @@ void build_grid_bitstream(BitstreamManager& bitstream_manager,
|
|||
const VprDeviceAnnotation& device_annotation,
|
||||
const VprClusteringAnnotation& cluster_annotation,
|
||||
const VprPlacementAnnotation& place_annotation,
|
||||
const VprBitstreamAnnotation& bitstream_annotation,
|
||||
const bool& verbose);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
# Run VPR for the 'and' design
|
||||
#--write_rr_graph example_rr_graph.xml
|
||||
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT}
|
||||
|
||||
# Read OpenFPGA architecture definition
|
||||
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
|
||||
|
||||
# Read OpenFPGA simulation settings
|
||||
read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE}
|
||||
|
||||
# Read OpenFPGA bitstream settings
|
||||
read_openfpga_bitstream_setting -f ${OPENFPGA_BITSTREAM_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.xml --format xml
|
||||
|
||||
# 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 --print_user_defined_template --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_verilog_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --print_top_testbench --print_preconfig_top_testbench --print_simulation_ini ./SimulationDeck/simulation_deck.ini --include_signal_init --support_icarus_simulator #--explicit_port_mapping
|
||||
|
||||
# Write the SDC files for PnR backend
|
||||
# - Turn on every options here
|
||||
write_pnr_sdc --file ./SDC
|
||||
|
||||
# Write SDC to disable timing for configure ports
|
||||
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
|
||||
|
||||
# Write the SDC to run timing analysis for a mapped FPGA fabric
|
||||
write_analysis_sdc --file ./SDC_analysis
|
||||
|
||||
# Finish and exit OpenFPGA
|
||||
exit
|
||||
|
||||
# Note :
|
||||
# To run verification at the end of the flow maintain source in ./SRC directory
|
|
@ -11,7 +11,6 @@ echo -e "FPGA-Bitstream regression tests";
|
|||
echo -e "Testing bitstream generation for an auto-sized device";
|
||||
run-task fpga_bitstream/generate_bitstream/device_auto --debug --show_thread_logs
|
||||
|
||||
|
||||
echo -e "Testing bitstream generation for an 48x48 FPGA device";
|
||||
run-task fpga_bitstream/generate_bitstream/device_48x48 --debug --show_thread_logs
|
||||
|
||||
|
@ -23,3 +22,6 @@ run-task fpga_bitstream/load_external_architecture_bitstream --debug --show_thre
|
|||
|
||||
echo -e "Testing repacker capability in identifying wire LUTs";
|
||||
run-task fpga_bitstream/repack_wire_lut --debug --show_thread_logs
|
||||
|
||||
echo -e "Testing overloading default paths for programmable interconnect when generating bitstream";
|
||||
run-task fpga_bitstream/overload_mux_default_path --debug --show_thread_logs
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<openfpga_bitstream_setting>
|
||||
<interconnect name="io[physical].mux1" default_path="ff.Q"/>
|
||||
</openfpga_bitstream_setting>
|
|
@ -0,0 +1,37 @@
|
|||
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||
# 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 = 1*60
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[OpenFPGA_SHELL]
|
||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_global_tile_clock_bitstream_setting_example_script.openfpga
|
||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_bitstream_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/fpga_bitstream/overload_mux_default_path/config/bitstream_annotation.xml
|
||||
openfpga_vpr_device_layout=2x2
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml
|
||||
|
||||
[BENCHMARKS]
|
||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
|
||||
|
||||
[SYNTHESIS_PARAM]
|
||||
bench0_top = and2_pipelined
|
||||
bench0_chan_width = 300
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
vpr_fpga_verilog_formal_verification_top_netlist=
|
Loading…
Reference in New Issue