[FPGA-Verilog] Now instance can output bus ports with all the pins

This commit is contained in:
tangxifan 2022-02-18 12:03:26 -08:00
parent aa375fd7a4
commit 0d620888ab
4 changed files with 96 additions and 27 deletions

View File

@ -59,6 +59,16 @@ BusGroupId BusGroup::find_pin_bus(const std::string& pin_name) const {
return pin_parent_bus_ids_[pin_id];
}
BusGroupId BusGroup::find_bus(const std::string& bus_name) const {
std::map<std::string, BusGroupId>::const_iterator result = bus_name2id_map_.find(bus_name);
if (result == bus_name2id_map_.end()) {
/* Not found, return an invalid id */
return BusGroupId::INVALID();
}
/* Found, we should get the parent bus */
return result->second;
}
BusPinId BusGroup::find_pin(const std::string& pin_name) const {
std::map<std::string, BusPinId>::const_iterator result = pin_name2id_map_.find(pin_name);
if (result == pin_name2id_map_.end()) {
@ -97,30 +107,40 @@ BusGroupId BusGroup::create_bus(const openfpga::BasicPort& bus_port) {
bus_ports_.push_back(bus_port);
bus_pin_ids_.emplace_back();
/* Register to fast look-up */
auto result = bus_name2id_map_.find(bus_port.get_name());
if (result == bus_name2id_map_.end()) {
bus_name2id_map_[bus_port.get_name()] = bus_id;
} else {
VTR_LOG_ERROR("Duplicated bus name '%s' in bus group", bus_port.get_name().c_str());
exit(1);
}
return bus_id;
}
BusPinId BusGroup::create_pin(const BusGroupId& bus_id) {
BusPinId BusGroup::create_pin(const BusGroupId& bus_id, const int& index) {
/* Create a new id */
BusPinId pin_id = BusPinId(pin_ids_.size());
pin_ids_.push_back(pin_id);
pin_indices_.emplace_back();
pin_indices_.push_back(index);
pin_names_.emplace_back();
/* Register the pin to the bus */
VTR_ASSERT(valid_bus_id(bus_id));
pin_parent_bus_ids_.push_back(bus_id);
bus_pin_ids_[bus_id].push_back(pin_id);
/* If the pin index is beyond the range of the bus_pin_ids, resize it */
if (size_t(index) > bus_pin_ids_[bus_id].size()) {
bus_pin_ids_[bus_id].resize(index + 1);
}
bus_pin_ids_[bus_id][index] = pin_id;
return pin_id;
}
void BusGroup::set_pin_index(const BusPinId& pin_id, const int& index) {
VTR_ASSERT(valid_pin_id(pin_id));
pin_indices_[pin_id] = index;
}
void BusGroup::set_pin_name(const BusPinId& pin_id, const std::string& name) {
VTR_ASSERT(valid_pin_id(pin_id));

View File

@ -62,6 +62,9 @@ class BusGroup {
/* Find the bus that a pin belongs to */
BusGroupId find_pin_bus(const std::string& pin_name) const;
/* Find the bus id with a given name */
BusGroupId find_bus(const std::string& bus_name) const;
/* Find the pin id with a given name */
BusPinId find_pin(const std::string& pin_name) const;
@ -78,11 +81,8 @@ class BusGroup {
/* Add a bus to storage */
BusGroupId create_bus(const openfpga::BasicPort& bus_port);
/* Add a pin to a bus */
BusPinId create_pin(const BusGroupId& bus_id);
/* Set the index for a pin */
void set_pin_index(const BusPinId& pin_id, const int& index);
/* Add a pin to a bus, with a given index in the bus, e.g., A[1] in A[0:2] */
BusPinId create_pin(const BusGroupId& bus_id, const int& index);
/* Set the name for a pin */
void set_pin_name(const BusPinId& pin_id, const std::string& name);
@ -117,6 +117,7 @@ class BusGroup {
vtr::vector<BusPinId, BusGroupId> pin_parent_bus_ids_;
/* Fast look-up */
std::map<std::string, BusGroupId> bus_name2id_map_;
std::map<std::string, BusPinId> pin_name2id_map_;
};

View File

@ -48,8 +48,7 @@ void read_xml_pin(pugi::xml_node& xml_pin,
"Pin index is out of range of the bus port width!\n");
}
BusPinId pin_id = bus_group.create_pin(bus_id);
bus_group.set_pin_index(pin_id, pin_index);
BusPinId pin_id = bus_group.create_pin(bus_id, pin_index);
bus_group.set_pin_name(pin_id, pin_name);
}

View File

@ -130,6 +130,7 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
port_types.push_back(atom_ctx.nlist.block_type(atom_blk));
}
/* Print out the instance with port mapping */
size_t port_counter = 0;
for (size_t iport = 0; iport < port_names.size(); ++iport) {
/* The first port does not need a comma */
@ -142,20 +143,51 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
if (true == use_explicit_port_map) {
fp << "." << port_names[iport] << module_input_port_postfix << "(";
}
/* Polarity of some input may have to be inverted, as defined in pin constraints
* For example, the reset signal of the benchmark is active low
* while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/
if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) {
fp << "~";
}
/* For clock ports, skip postfix */
if (clock_port_names.end() != std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) {
fp << port_names[iport];
/* For bus ports, include a complete list of pins */
BusGroupId bus_id = bus_group.find_bus(port_names[iport]);
if (bus_id) {
fp << "{";
int pin_counter = 0;
/* Include all the pins */
for (const BusPinId& pin : bus_group.bus_pins(bus_id)) {
if (0 < pin_counter) {
fp << ", ";
}
/* Polarity of some input may have to be inverted, as defined in pin constraints
* For example, the reset signal of the benchmark is active low
* while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/
if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(bus_group.pin_name(pin))) {
fp << "~";
}
fp << bus_group.pin_name(pin);
/* For clock ports, skip postfix */
if (clock_port_names.end() == std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) {
fp << input_port_postfix;
}
pin_counter++;
}
fp << "}";
} else {
fp << port_names[iport] << input_port_postfix;
/* Polarity of some input may have to be inverted, as defined in pin constraints
* For example, the reset signal of the benchmark is active low
* while the reset signal of the FPGA fabric is active high (inside FPGA, the reset signal will be inverted)
* However, to ensure correct stimuli to the benchmark, we have to invert the signal
*/
if (PinConstraints::LOGIC_HIGH == pin_constraints.net_default_value(port_names[iport])) {
fp << "~";
}
fp << port_names[iport];
/* For clock ports, skip postfix */
if (clock_port_names.end() == std::find(clock_port_names.begin(), clock_port_names.end(), port_names[iport])) {
fp << input_port_postfix;
}
}
if (true == use_explicit_port_map) {
@ -179,7 +211,24 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
if (true == use_explicit_port_map) {
fp << "." << output_block_name << module_output_port_postfix << "(";
}
fp << port_names[iport] << output_port_postfix;
/* For bus ports, include a complete list of pins */
BusGroupId bus_id = bus_group.find_bus(port_names[iport]);
if (bus_id) {
fp << "{";
int pin_counter = 0;
/* Include all the pins */
for (const BusPinId& pin : bus_group.bus_pins(bus_id)) {
if (0 < pin_counter) {
fp << ", ";
}
fp << bus_group.pin_name(pin) << output_port_postfix;
pin_counter++;
}
fp << "}";
} else {
fp << port_names[iport] << output_port_postfix;
}
if (true == use_explicit_port_map) {
fp << ")";
}