add pb type port mapping to circuit model ports

This commit is contained in:
tangxifan 2020-01-29 11:24:14 -07:00
parent cf3c5b5c42
commit 399ba8d648
5 changed files with 126 additions and 2 deletions

View File

@ -584,6 +584,69 @@ void check_vpr_physical_pb_type_annotation(const DeviceContext& vpr_device_ctx,
}
}
/********************************************************************
* This function aims to link all the ports defined under a physical
* pb_type to the ports of circuit model in the circuit library
* The binding assumes that pb_type port should be defined with the same name
* as the circuit port
*******************************************************************/
static
bool link_physical_pb_port_to_circuit_port(t_pb_type* physical_pb_type,
const CircuitLibrary& circuit_lib,
const CircuitModelId& circuit_model,
VprPbTypeAnnotation& vpr_pb_type_annotation) {
bool link_success = true;
/* Iterate over the pb_ports
* Note:
* - Not every port defined in the circuit model will appear under the pb_type
* Some circuit ports are just for physical implementation
*/
for (t_port* pb_port : pb_type_ports(physical_pb_type)) {
CircuitPortId circuit_port = circuit_lib.model_port(circuit_model, std::string(pb_port->name));
/* If we cannot find a port with the same name, error out */
if (CircuitPortId::INVALID() == circuit_port) {
VTR_LOG_ERROR("Pb type port '%s' is not found in any port of circuit model '%s'!\n",
pb_port->name, circuit_lib.model_name(circuit_model).c_str());
link_success = false;
continue;
}
/* If the port width does not match, error out */
if ((size_t)(pb_port->num_pins) != circuit_lib.port_size(circuit_port)) {
VTR_LOG_ERROR("Pb type port '%s[%d:%d]' does not match the port '%s[%d:%d]' of circuit model '%s' in size!\n",
pb_port->name,
0, pb_port->num_pins - 1,
circuit_lib.port_prefix(circuit_port).c_str(),
0, circuit_lib.port_size(circuit_port) - 1,
circuit_lib.model_name(circuit_model).c_str());
link_success = false;
continue;
}
/* If the port type does not match, error out */
if (ERR_PORT == circuit_port_require_pb_port_type(circuit_lib.port_type(circuit_port))) {
VTR_LOG_ERROR("Pb type port '%s' type does not match the port type '%s' of circuit model '%s'!\n",
pb_port->name,
circuit_lib.port_prefix(circuit_port).c_str(),
circuit_lib.model_name(circuit_model).c_str());
link_success = false;
continue;
}
/* Reach here, it means that mapping should be ok, update the vpr_pb_type_annotation */
vpr_pb_type_annotation.add_pb_circuit_port(pb_port, circuit_port);
VTR_LOG("Bind pb type '%s' port '%s' to circuit model '%s' port '%s'\n",
physical_pb_type->name,
pb_port->name,
circuit_lib.model_name(circuit_model).c_str(),
circuit_lib.port_prefix(circuit_port).c_str());
}
return link_success;
}
/********************************************************************
* This function aims to link a physical pb_type to a valid circuit model
* in the circuit library
@ -613,7 +676,10 @@ bool link_physical_pb_type_to_circuit_model(t_pb_type* physical_pb_type,
return false;
}
/* TODO: Ensure that the pb_type ports can be matched in the circuit model ports */
/* Ensure that the pb_type ports can be matched in the circuit model ports */
if (false == link_physical_pb_port_to_circuit_port(physical_pb_type, circuit_lib, circuit_model_id, vpr_pb_type_annotation)) {
return false;
}
/* Now the circuit model is valid, update the vpr_pb_type_annotation */
vpr_pb_type_annotation.add_pb_type_circuit_model(physical_pb_type, circuit_model_id);

View File

@ -228,4 +228,30 @@ e_circuit_model_type pb_interconnect_require_circuit_model_type(const e_intercon
return type_mapping.at(pb_interc_type);
}
/********************************************************************
* This function aims to find the required type for a pb_port
* when it is linked to a port of a circuit model
* We start from the view of a circuit port here.
* This is due to circuit port has more types than a pb_type port
* as it is designed for physical implementation
* As such, a few types of circuit port may be directed the same type of pb_type port
* This is done to make the mapping much simpler than doing in the opposite direction
*******************************************************************/
enum PORTS circuit_port_require_pb_port_type(const e_circuit_model_port_type& circuit_port_type) {
std::map<e_circuit_model_port_type, enum PORTS> type_mapping;
/* These circuit model ports may be founed in the pb_type ports */
type_mapping[CIRCUIT_MODEL_PORT_INPUT] = IN_PORT;
type_mapping[CIRCUIT_MODEL_PORT_OUTPUT] = OUT_PORT;
type_mapping[CIRCUIT_MODEL_PORT_INOUT] = INOUT_PORT;
type_mapping[CIRCUIT_MODEL_PORT_CLOCK] = IN_PORT;
/* Other circuit model ports should not be found when mapping to the pb_type ports */
if (type_mapping.end() == type_mapping.find(circuit_port_type)) {
return ERR_PORT;
}
return type_mapping.at(circuit_port_type);
}
} /* end namespace openfpga */

View File

@ -41,6 +41,8 @@ e_interconnect pb_interconnect_physical_type(t_interconnect* pb_interc,
e_circuit_model_type pb_interconnect_require_circuit_model_type(const e_interconnect& pb_interc_type);
enum PORTS circuit_port_require_pb_port_type(const e_circuit_model_port_type& circuit_port_type);
} /* end namespace openfpga */
#endif

View File

@ -89,12 +89,23 @@ e_interconnect VprPbTypeAnnotation::interconnect_physical_type(t_interconnect* p
/* Ensure that the pb_type is in the list */
std::map<t_interconnect*, e_interconnect>::const_iterator it = interconnect_physical_types_.find(pb_interconnect);
if (it == interconnect_physical_types_.end()) {
/* Return an invalid circuit model id */
/* Return an invalid interconnect type */
return NUM_INTERC_TYPES;
}
return interconnect_physical_types_.at(pb_interconnect);
}
CircuitPortId VprPbTypeAnnotation::pb_circuit_port(t_port* pb_port) const {
/* Ensure that the pb_type is in the list */
std::map<t_port*, CircuitPortId>::const_iterator it = pb_circuit_ports_.find(pb_port);
if (it == pb_circuit_ports_.end()) {
/* Return an invalid circuit port id */
return CircuitPortId::INVALID();
}
return pb_circuit_ports_.at(pb_port);
}
/************************************************************************
* Public mutators
***********************************************************************/
@ -179,4 +190,15 @@ void VprPbTypeAnnotation::add_interconnect_physical_type(t_interconnect* pb_inte
interconnect_physical_types_[pb_interconnect] = physical_type;
}
void VprPbTypeAnnotation::add_pb_circuit_port(t_port* pb_port, const CircuitPortId& circuit_port) {
/* Warn any override attempt */
std::map<t_port*, CircuitPortId>::const_iterator it = pb_circuit_ports_.find(pb_port);
if (it != pb_circuit_ports_.end()) {
VTR_LOG_WARN("Override the circuit port mapping for pb_type port '%s'!\n",
pb_port->name);
}
pb_circuit_ports_[pb_port] = circuit_port;
}
} /* End namespace openfpga*/

View File

@ -37,6 +37,7 @@ class VprPbTypeAnnotation {
CircuitModelId pb_type_circuit_model(t_pb_type* physical_pb_type) const;
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;
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);
@ -45,6 +46,7 @@ class VprPbTypeAnnotation {
void add_pb_type_circuit_model(t_pb_type* physical_pb_type, const CircuitModelId& circuit_model);
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);
private: /* Internal data */
/* Pair a regular pb_type to its physical pb_type */
std::map<t_pb_type*, t_pb_type*> physical_pb_types_;
@ -94,6 +96,12 @@ class VprPbTypeAnnotation {
*/
std::map<t_port*, BasicPort> physical_pb_port_ranges_;
/* Pair a pb_port to a circuit port in circuit model
* Note:
* - the parent of physical pb_port MUST be a physical pb_type
*/
std::map<t_port*, CircuitPortId> pb_circuit_ports_;
/* Pair a pb_graph_node to a physical pb_graph_node
* Note:
* - the pb_type of physical pb_graph_node must be a physical pb_type