add mode bits binding to pb_type annotation

This commit is contained in:
tangxifan 2020-01-29 12:27:55 -07:00
parent 24b180b298
commit a722438fa3
3 changed files with 139 additions and 1 deletions

View File

@ -1011,6 +1011,118 @@ void link_vpr_pb_interconnect_to_circuit_model_implicit_annotation(const DeviceC
}
}
/********************************************************************
* This function will bind mode selection bits to a primitive pb_type
* in the vpr_pb_type_annotation
*******************************************************************/
static
bool link_primitive_pb_type_to_mode_bits(t_pb_type* primitive_pb_type,
const PbTypeAnnotation& pb_type_annotation,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
/* Error out if this is not a primitive pb_type */
if (false == is_primitive_pb_type(primitive_pb_type)) {
VTR_LOG_ERROR("Mode selection is only applicable to primitive pb_type while pb_type '%s' is not primitve !\n",
primitive_pb_type->name);
return false;
}
/* Update the annotation */
vpr_pb_type_annotation.add_pb_type_mode_bits(primitive_pb_type, pb_type_annotation.mode_bits());
return true;
}
/********************************************************************
* This function will link
* - pb_type to mode bits by following
* the explicit definition in OpenFPGA architecture XML
*
* Note:
* - This function should be executed only AFTER
* the physical mode and physical pb_type annotation is completed
* the physical pb_type circuit model annotation is completed
*******************************************************************/
static
void link_vpr_pb_type_to_mode_bits_explicit_annotation(const DeviceContext& vpr_device_ctx,
const Arch& openfpga_arch,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
/* Walk through the pb_type annotation stored in the openfpga arch */
for (const PbTypeAnnotation& pb_type_annotation : openfpga_arch.pb_type_annotations) {
if (true == pb_type_annotation.mode_bits().empty()) {
continue;
}
/* Convert the vector of integer to string */
std::string mode_bits_str;
for (const size_t& bit : pb_type_annotation.mode_bits()) {
mode_bits_str += std::to_string(bit);
}
/* Collect the information about the full hierarchy of physical pb_type to be annotated */
std::vector<std::string> target_pb_type_names;
std::vector<std::string> target_pb_mode_names;
if (true == pb_type_annotation.is_operating_pb_type()) {
target_pb_type_names = pb_type_annotation.operating_parent_pb_type_names();
target_pb_type_names.push_back(pb_type_annotation.operating_pb_type_name());
target_pb_mode_names = pb_type_annotation.operating_parent_mode_names();
}
if (true == pb_type_annotation.is_physical_pb_type()) {
target_pb_type_names = pb_type_annotation.physical_parent_pb_type_names();
target_pb_type_names.push_back(pb_type_annotation.physical_pb_type_name());
target_pb_mode_names = pb_type_annotation.physical_parent_mode_names();
}
/* We must have at least one pb_type in the list */
VTR_ASSERT_SAFE(0 < target_pb_type_names.size());
/* 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 operating as well as
* physical pb_types 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;
}
/* Only try to bind pb_type to circuit model when it is defined by users */
if (true == link_primitive_pb_type_to_mode_bits(target_pb_type,
pb_type_annotation, vpr_pb_type_annotation)) {
/* Give a message */
VTR_LOG("Bind physical pb_type '%s' to mode selection bits '%s'\n",
target_pb_type->name,
mode_bits_str.c_str());
link_success = true;
break;
}
}
if (false == link_success) {
/* Not found, error out! */
VTR_LOG_ERROR("Unable to bind pb_type '%s' to mode_selection bits '%s'!\n",
target_pb_type_names.back().c_str(),
mode_bits_str.c_str());
return;
}
}
}
/********************************************************************
* Top-level function to link openfpga architecture to VPR, including:
* - physical pb_type
@ -1069,6 +1181,10 @@ void annotate_pb_types(const DeviceContext& vpr_device_ctx,
/* TODO: check the circuit model annotation */
/* Link physical pb_type to mode_bits */
VTR_LOG("\n");
VTR_LOG("Building annotation between physical pb_types and mode selection bits...\n");
link_vpr_pb_type_to_mode_bits_explicit_annotation(vpr_device_ctx, openfpga_arch,
vpr_pb_type_annotation);
}

View File

@ -105,6 +105,15 @@ CircuitPortId VprPbTypeAnnotation::pb_circuit_port(t_port* pb_port) const {
return pb_circuit_ports_.at(pb_port);
}
std::vector<size_t> VprPbTypeAnnotation::pb_type_mode_bits(t_pb_type* pb_type) const {
/* Ensure that the pb_type is in the list */
std::map<t_pb_type*, std::vector<size_t>>::const_iterator it = pb_type_mode_bits_.find(pb_type);
if (it == pb_type_mode_bits_.end()) {
/* Return an empty vector */
return std::vector<size_t>();
}
return pb_type_mode_bits_.at(pb_type);
}
/************************************************************************
* Public mutators
@ -201,4 +210,15 @@ void VprPbTypeAnnotation::add_pb_circuit_port(t_port* pb_port, const CircuitPort
pb_circuit_ports_[pb_port] = circuit_port;
}
void VprPbTypeAnnotation::add_pb_type_mode_bits(t_pb_type* pb_type, const std::vector<size_t>& mode_bits) {
/* Warn any override attempt */
std::map<t_pb_type*, std::vector<size_t>>::const_iterator it = pb_type_mode_bits_.find(pb_type);
if (it != pb_type_mode_bits_.end()) {
VTR_LOG_WARN("Override the mode bits mapping for pb_type '%s'!\n",
pb_type->name);
}
pb_type_mode_bits_[pb_type] = mode_bits;
}
} /* End namespace openfpga*/

View File

@ -38,6 +38,7 @@ class VprPbTypeAnnotation {
CircuitModelId interconnect_circuit_model(t_interconnect* pb_interconnect) const;
e_interconnect interconnect_physical_type(t_interconnect* pb_interconnect) const;
CircuitPortId pb_circuit_port(t_port* pb_port) const;
std::vector<size_t> pb_type_mode_bits(t_pb_type* pb_type) const;
public: /* Public mutators */
void add_pb_type_physical_mode(t_pb_type* pb_type, t_mode* physical_mode);
void add_physical_pb_type(t_pb_type* operating_pb_type, t_pb_type* physical_pb_type);
@ -47,6 +48,7 @@ class VprPbTypeAnnotation {
void add_interconnect_circuit_model(t_interconnect* pb_interconnect, const CircuitModelId& circuit_model);
void add_interconnect_physical_type(t_interconnect* pb_interconnect, const e_interconnect& physical_type);
void add_pb_circuit_port(t_port* pb_port, const CircuitPortId& circuit_port);
void add_pb_type_mode_bits(t_pb_type* pb_type, const std::vector<size_t>& mode_bits);
private: /* Internal data */
/* Pair a regular pb_type to its physical pb_type */
std::map<t_pb_type*, t_pb_type*> physical_pb_types_;
@ -82,7 +84,7 @@ class VprPbTypeAnnotation {
* - if the pb_type is an operating pb_type, the mode bits will be applied
* when the operating pb_type is used by packer
*/
std::map<t_pb_type*, std::vector<bool>> pb_type_mode_bits_;
std::map<t_pb_type*, std::vector<size_t>> pb_type_mode_bits_;
/* Pair a pb_port to its physical pb_port
* Note: