[FPGA-Verilog] Now instance can output bus ports with all the pins
This commit is contained in:
parent
aa375fd7a4
commit
0d620888ab
|
@ -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));
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,6 +143,37 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
|
|||
if (true == use_explicit_port_map) {
|
||||
fp << "." << port_names[iport] << module_input_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 << ", ";
|
||||
}
|
||||
/* 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 {
|
||||
/* 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)
|
||||
|
@ -151,11 +183,11 @@ void print_verilog_testbench_benchmark_instance(std::fstream& fp,
|
|||
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];
|
||||
} else {
|
||||
fp << port_names[iport] << input_port_postfix;
|
||||
/* 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 << "(";
|
||||
}
|
||||
|
||||
/* 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 << ")";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue