From a722438fa3ab89dc1fe360483905c9d66e9cbec2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 29 Jan 2020 12:27:55 -0700 Subject: [PATCH] add mode bits binding to pb_type annotation --- openfpga/src/base/annotate_pb_types.cpp | 116 +++++++++++++++++++ openfpga/src/base/vpr_pb_type_annotation.cpp | 20 ++++ openfpga/src/base/vpr_pb_type_annotation.h | 4 +- 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/openfpga/src/base/annotate_pb_types.cpp b/openfpga/src/base/annotate_pb_types.cpp index 064fc2cc0..7095855e0 100644 --- a/openfpga/src/base/annotate_pb_types.cpp +++ b/openfpga/src/base/annotate_pb_types.cpp @@ -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 target_pb_type_names; + std::vector 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); } diff --git a/openfpga/src/base/vpr_pb_type_annotation.cpp b/openfpga/src/base/vpr_pb_type_annotation.cpp index 867f40794..435f46be7 100644 --- a/openfpga/src/base/vpr_pb_type_annotation.cpp +++ b/openfpga/src/base/vpr_pb_type_annotation.cpp @@ -105,6 +105,15 @@ CircuitPortId VprPbTypeAnnotation::pb_circuit_port(t_port* pb_port) const { return pb_circuit_ports_.at(pb_port); } +std::vector VprPbTypeAnnotation::pb_type_mode_bits(t_pb_type* pb_type) const { + /* Ensure that the pb_type is in the list */ + std::map>::const_iterator it = pb_type_mode_bits_.find(pb_type); + if (it == pb_type_mode_bits_.end()) { + /* Return an empty vector */ + return std::vector(); + } + 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& mode_bits) { + /* Warn any override attempt */ + std::map>::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*/ diff --git a/openfpga/src/base/vpr_pb_type_annotation.h b/openfpga/src/base/vpr_pb_type_annotation.h index fb0fec934..24535ee4a 100644 --- a/openfpga/src/base/vpr_pb_type_annotation.h +++ b/openfpga/src/base/vpr_pb_type_annotation.h @@ -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 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& mode_bits); private: /* Internal data */ /* Pair a regular pb_type to its physical pb_type */ std::map 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> pb_type_mode_bits_; + std::map> pb_type_mode_bits_; /* Pair a pb_port to its physical pb_port * Note: