diff --git a/libopenfpga/libarchopenfpga/arch/sample_arch.xml b/libopenfpga/libarchopenfpga/arch/sample_arch.xml index 8d19fc150..49eccdaa8 100644 --- a/libopenfpga/libarchopenfpga/arch/sample_arch.xml +++ b/libopenfpga/libarchopenfpga/arch/sample_arch.xml @@ -277,6 +277,16 @@ + + + + + + + + + + @@ -301,13 +311,6 @@ - - - - - - - diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp new file mode 100644 index 000000000..dda74520b --- /dev/null +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp @@ -0,0 +1,181 @@ +/************************************************************************ + * Member functions for class PbTypeAnnotation + ***********************************************************************/ +#include "vtr_log.h" +#include "vtr_assert.h" +#include "pb_type_annotation.h" + +/* namespace openfpga begins */ +namespace openfpga { + +/************************************************************************ + * Constructors + ***********************************************************************/ +PbTypeAnnotation::PbTypeAnnotation() { + return; +} + +/************************************************************************ + * Public Accessors + ***********************************************************************/ +std::string PbTypeAnnotation::operating_pb_type_name() const { + return operating_pb_type_name_; +} + +std::vector PbTypeAnnotation::operating_parent_pb_type_names() const { + return operating_parent_pb_type_names_; +} + +std::vector PbTypeAnnotation::operating_parent_mode_names() const { + return operating_parent_mode_names_; +} + +bool PbTypeAnnotation::is_operating_pb_type() const { + return true == operating_pb_type_name_.empty(); +} + + +std::string PbTypeAnnotation::physical_pb_type_name() const { + return physical_pb_type_name_; +} + +std::vector PbTypeAnnotation::physical_parent_pb_type_names() const { + return physical_parent_pb_type_names_; +} + +std::vector PbTypeAnnotation::physical_parent_mode_names() const { + return physical_parent_mode_names_; +} + +bool PbTypeAnnotation::is_physical_pb_type() const { + return true == physical_pb_type_name_.empty(); +} + +std::string PbTypeAnnotation::mode_bits() const { + return mode_bits_; +} + +std::string PbTypeAnnotation::circuit_model_name() const { + return circuit_model_name_; +} + +int PbTypeAnnotation::physical_pb_type_index_factor() const { + return physical_pb_type_index_factor_; +} + +int PbTypeAnnotation::physical_pb_type_index_offset() const { + return physical_pb_type_index_offset_; +} + +BasicPort PbTypeAnnotation::physical_pb_type_ports(const std::string& port_name) const { + std::map::const_iterator it = operating_pb_type_ports_.find(port_name); + if (it == operating_pb_type_ports_.end()) { + /* Return an empty port */ + return BasicPort(); + } + return operating_pb_type_ports_.at(port_name); +} + +int PbTypeAnnotation::physical_pin_rotate_offsets(const std::string& port_name) const { + std::map::const_iterator it = physical_pin_rotate_offsets_.find(port_name); + if (it == physical_pin_rotate_offsets_.end()) { + /* Return a zero offset which is default */ + return 0; + } + return physical_pin_rotate_offsets_.at(port_name); +} + +std::string PbTypeAnnotation::interconnect_circuit_model_name(const std::string& interc_name) const { + std::map::const_iterator it = interconnect_circuit_model_names_.find(interc_name); + if (it == interconnect_circuit_model_names_.end()) { + return std::string(); + } + + return interconnect_circuit_model_names_.at(interc_name); +} + +/************************************************************************ + * Public Mutators + ***********************************************************************/ +void PbTypeAnnotation::set_operating_pb_type_name(const std::string& name) { + operating_pb_type_name_ = name; +} + +void PbTypeAnnotation::set_operating_parent_pb_type_names(const std::vector& names) { + operating_parent_pb_type_names_ = names; +} + +void PbTypeAnnotation::set_operating_parent_mode_names(const std::vector& names) { + operating_parent_mode_names_ = names; +} + +void PbTypeAnnotation::set_physical_pb_type_name(const std::string& name) { + physical_pb_type_name_ = name; +} + +void PbTypeAnnotation::set_physical_parent_pb_type_names(const std::vector& names) { + physical_parent_pb_type_names_ = names; +} + +void PbTypeAnnotation::set_physical_parent_mode_names(const std::vector& names) { + physical_parent_mode_names_ = names; +} + +void PbTypeAnnotation::set_mode_bits(const std::string& mode_bits) { + mode_bits_ = mode_bits; +} + +void PbTypeAnnotation::set_circuit_model_name(const std::string& name) { + VTR_ASSERT(true == is_physical_pb_type()); + circuit_model_name_ = name; +} + +void PbTypeAnnotation::physical_pb_type_index_factor(const int& value) { + VTR_ASSERT(true == is_operating_pb_type()); + physical_pb_type_index_factor_ = value; +} + +void PbTypeAnnotation::physical_pb_type_index_offset(const int& value) { + VTR_ASSERT(true == is_operating_pb_type()); + physical_pb_type_index_offset_ = value; +} + +void PbTypeAnnotation::add_pb_type_port_pair(const std::string& operating_pb_port_name, + const BasicPort& physical_pb_port) { + /* Give a warning if the operating_pb_port_name already exist */ + std::map::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + /* Give a warning if the interconnection name already exist */ + if (it != operating_pb_type_ports_.end()) { + VTR_LOG_WARN("Redefine operating pb type port '%s' with physical pb type port '%s'\n", + operating_pb_port_name.c_str(), physical_pb_port.get_name().c_str()); + } + + operating_pb_type_ports_[operating_pb_port_name] = physical_pb_port; +} + +void PbTypeAnnotation::set_physical_pin_rotate_offset(const std::string& operating_pb_port_name, + const int& physical_pin_rotate_offset) { + std::map::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + /* Give a warning if the interconnection name already exist */ + if (it == operating_pb_type_ports_.end()) { + VTR_LOG_ERROR("Operating pb type port '%s' does not exist! Ignore physical pin rotate offset '%d'\n", + operating_pb_port_name.c_str(), physical_pin_rotate_offset); + return; + } + + physical_pin_rotate_offsets_[operating_pb_port_name] = physical_pin_rotate_offset; +} + +void PbTypeAnnotation::add_interconnect_circuit_model_pair(const std::string& interc_name, + const std::string& circuit_model_name) { + std::map::const_iterator it = interconnect_circuit_model_names_.find(interc_name); + /* Give a warning if the interconnection name already exist */ + if (it != interconnect_circuit_model_names_.end()) { + VTR_LOG_WARN("Redefine interconnect '%s' with circuit model '%s'\n", + interc_name.c_str(), circuit_model_name.c_str()); + } + + interconnect_circuit_model_names_[interc_name] = circuit_model_name; +} + +} /* namespace openfpga ends */ diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h index bad6489b0..e2ca62df6 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h @@ -1,5 +1,5 @@ #ifndef PB_TYPE_ANNOTATION_H -#ifndef PB_TYPE_ANNOTATION_H +#define PB_TYPE_ANNOTATION_H /******************************************************************** * Include header files required by the data structure definition @@ -7,6 +7,8 @@ #include #include +#include "openfpga_port.h" + /* namespace openfpga begins */ namespace openfpga { @@ -27,28 +29,117 @@ namespace openfpga { * to contain the raw data from architecture XML! If you want to link * to other data structures, please create another one in other header files *******************************************************************/ -class PhysicalPbAnnotation { +class PbTypeAnnotation { + public: /* Constructor */ + PbTypeAnnotation(); + public: /* Public accessors */ + std::string operating_pb_type_name() const; + std::vector operating_parent_pb_type_names() const; + std::vector operating_parent_mode_names() const; + bool is_operating_pb_type() const; + std::string physical_pb_type_name() const; + std::vector physical_parent_pb_type_names() const; + std::vector physical_parent_mode_names() const; + bool is_physical_pb_type() const; + std::string mode_bits() const; + std::string circuit_model_name() const; + int physical_pb_type_index_factor() const; + int physical_pb_type_index_offset() const; + BasicPort physical_pb_type_ports(const std::string& port_name) const; + int physical_pin_rotate_offsets(const std::string& port_name) const; + std::string interconnect_circuit_model_name(const std::string& interc_name) const; + public: /* Public mutators */ + void set_operating_pb_type_name(const std::string& name); + void set_operating_parent_pb_type_names(const std::vector& names); + void set_operating_parent_mode_names(const std::vector& names); + void set_physical_pb_type_name(const std::string& name); + void set_physical_parent_pb_type_names(const std::vector& names); + void set_physical_parent_mode_names(const std::vector& names); + void set_mode_bits(const std::string& mode_bits); + void set_circuit_model_name(const std::string& name); + void physical_pb_type_index_factor(const int& value); + void physical_pb_type_index_offset(const int& value); + void add_pb_type_port_pair(const std::string& operating_pb_port_name, + const BasicPort& physical_pb_port); + void set_physical_pin_rotate_offset(const std::string& operating_pb_port_name, + const int& physical_pin_rotate_offset); + void add_interconnect_circuit_model_pair(const std::string& interc_name, + const std::string& circuit_model_name); private: /* Internal data */ /* Binding between physical pb_type and operating pb_type - * both operating and physial pb_type names are the full names + * both operating and physial pb_type names contain the full names * defined in the hierarchy of pb_types * e.g. * clb.fle[frac_logic].frac_lut6 + * ^ + * | + * mode_name + * + * The pb_type name 'frac_lut6' will be stored in + * either operating or physical pb_type_name + * The parent pb_type and mode names will be stored in + * either operating or physical parent_pb_type_name and parent_mode_names + * */ std::string operating_pb_type_name_; + std::vector operating_parent_pb_type_names_; + std::vector operating_parent_mode_names_; + std::string physical_pb_type_name_; + std::vector physical_parent_pb_type_names_; + std::vector physical_parent_mode_names_; + + /* Configuration bits to select an operting mode for the circuit mode name */ std::string mode_bits_; + + /* Circuit mode name linked to a physical pb_type. + * This is only applicable to the physical pb_type + */ std::string circuit_model_name_; + + /* The factor aims to align the indices for pb_type between operating and physical modes, + * especially when an operating mode contains multiple pb_type (num_pb>1) + * that are linked to the same physical pb_type. + * When number of physical_pb_type is larger than 1, + * the index of pb_type will be multipled by the given factor. + * + * For example, a factor of 2 is used to map + * operating pb_type adder[5] with a full path clb.fle[arith].adder[5] + * to physical pb_type adder[10] with a full path clb.fle[physical].adder[10] + */ int physical_pb_type_index_factor_; + + /* The offset aims to align the indices for pb_type between operating and physical modes, + * especially when an operating mode contains multiple pb_type (num_pb>1) + * that are linked to the same physical pb_type. + * When number of physical_pb_type is larger than 1, + * the index of pb_type will be shifted by the given factor. + * + * For example, an offset of 1 is used to map + * operating pb_type adder[0] with a full path clb.fle[arith].adder[0] + * to physical pb_type adder[1] with a full path clb.fle[physical].adder[1] + */ int physical_pb_type_index_offset_; /* Link from the pins under an operating pb_type to physical pb_type */ - std::vector operating_pb_type_pin_names_; - std::vector physical_pb_type_pin_names_; - std::vector physical_pin_rotate_offset_; + std::map operating_pb_type_ports_; + + /* The offset aims to align the pin indices for port of pb_type + * between operating and physical modes, especially when an operating + * mode contains multiple pb_type (num_pb>1) that are linked to + * the same physical pb_type. + * When physical_mode_pin_rotate_offset is larger than zero, + * the pin index of pb_type (whose index is large than 1) + * will be shifted by the given offset. + * + * For example, an offset of 1 is used to map + * operating pb_type adder[0].pin[0] with a full path clb.fle[arith].adder[0] + * to physical pb_type adder[0].pin[1] with a full path clb.fle[physical].adder[0] + */ + std::map physical_pin_rotate_offsets_; /* Link between the interconnects under this pb_type and circuit model names */ - std::vector> interconnect_circuit_model_names_; + std::map interconnect_circuit_model_names_; }; } /* namespace openfpga ends */