add pb type port mapping to circuit model ports
This commit is contained in:
parent
cf3c5b5c42
commit
399ba8d648
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue