add mode bits binding to pb_type annotation
This commit is contained in:
parent
24b180b298
commit
a722438fa3
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue