diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index 1c84821fbca..8eeb821a5de 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -795,11 +795,19 @@ struct t_physical_tile_port { bool is_clock; bool is_non_clock_global; int num_pins; - PortEquivalence equivalent = PortEquivalence::NONE; + PortEquivalence equivalent; int index; int absolute_first_pin_index; int port_index_by_type; + + t_physical_tile_port() { + is_clock = false; + is_non_clock_global = false; + + num_pins = 1; + equivalent = PortEquivalence::NONE; + } }; /* Describes the type for a logical block @@ -1807,8 +1815,8 @@ struct t_arch { // for the interchange netlist format, to determine which are the constants // net names and which virtual cell is responsible to generate them. // The information is present in the device database. - std::string gnd_cell; - std::string vcc_cell; + std::pair gnd_cell; + std::pair vcc_cell; std::string gnd_net = "$__gnd_net"; std::string vcc_net = "$__vcc_net"; diff --git a/libs/libarchfpga/src/read_fpga_interchange_arch.cpp b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp index 977ed0bc254..4d56a3f535b 100644 --- a/libs/libarchfpga/src/read_fpga_interchange_arch.cpp +++ b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp @@ -289,6 +289,8 @@ struct ArchReader { process_bels_and_sites(); process_models(); + process_constant_model(); + process_device(); process_layout(); @@ -296,7 +298,10 @@ struct ArchReader { process_segments(); process_sites(); + process_constant_block(); + process_tiles(); + process_constant_tile(); link_physical_logical_types(ptypes_, ltypes_); @@ -314,6 +319,7 @@ struct ArchReader { t_default_fc_spec default_fc_; std::string bel_dedup_suffix_ = "_bel"; + std::string const_block_ = "constant_block"; std::unordered_set take_bels_; std::unordered_set take_sites_; @@ -361,7 +367,7 @@ struct ArchReader { for (auto bel : site.getBels()) if (str(bel.getName()) == bel_name) return bel; - VTR_ASSERT(0); + VTR_ASSERT_MSG(0, "Could not find the BEL reader!\n"); } /** @brief Get the BEL pin reader given its name, site and corresponding BEL */ @@ -373,7 +379,7 @@ struct ArchReader { if (str(pin_reader.getName()) == pin_name) return pin_reader; } - VTR_ASSERT(0); + VTR_ASSERT_MSG(0, "Could not find the BEL pin reader!\n"); } /** @brief Get the BEL name, with an optional deduplication suffix in case its name collides with the site name */ @@ -442,6 +448,86 @@ struct ArchReader { return pad_bels_.count(name) != 0; } + /** @brief Utility function to fill in all the necessary information for the sub_tile + * + * Given a physical tile type and a corresponding sub tile with additional information on the IO pin count + * this function populates all the data structures corresponding to the sub tile, and modifies also the parent + * physical tile type, updating the pin numberings as well as the directs pin mapping for the equivalent sites + * + * Affected data structures: + * - pinloc + * - fc_specs + * - equivalent_sites + * - tile_block_pin_directs_map + **/ + void fill_sub_tile(t_physical_tile_type& type, t_sub_tile& sub_tile, int num_pins, int input_count, int output_count) { + sub_tile.num_phy_pins += num_pins; + type.num_pins += num_pins; + type.num_inst_pins += num_pins; + + type.num_input_pins += input_count; + type.num_output_pins += output_count; + type.num_receivers += input_count; + type.num_drivers += output_count; + + type.pin_width_offset.resize(type.num_pins, 0); + type.pin_height_offset.resize(type.num_pins, 0); + + type.pinloc.resize({1, 1, 4}, std::vector(type.num_pins, false)); + for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) { + for (int pin = 0; pin < type.num_pins; pin++) { + type.pinloc[0][0][side][pin] = true; + type.pin_width_offset[pin] = 0; + type.pin_height_offset[pin] = 0; + } + } + + vtr::bimap directs_map; + + for (int npin = 0; npin < type.num_pins; npin++) { + t_physical_pin physical_pin(npin); + t_logical_pin logical_pin(npin); + + directs_map.insert(logical_pin, physical_pin); + } + + auto ltype = get_type_by_name(sub_tile.name, ltypes_); + sub_tile.equivalent_sites.push_back(ltype); + + type.tile_block_pin_directs_map[ltype->index][sub_tile.index] = directs_map; + + // Assign FC specs + int iblk_pin = 0; + for (const auto& port : sub_tile.ports) { + t_fc_specification fc_spec; + + // FIXME: Use always one segment for the time being. + // Can use the right segment for this IOPIN as soon + // as the RR graph reading from the interchange is complete. + fc_spec.seg_index = 0; + + //Apply type and defaults + if (port.type == IN_PORT) { + fc_spec.fc_type = e_fc_type::IN; + fc_spec.fc_value_type = default_fc_.in_value_type; + fc_spec.fc_value = default_fc_.in_value; + } else { + VTR_ASSERT(port.type == OUT_PORT); + fc_spec.fc_type = e_fc_type::OUT; + fc_spec.fc_value_type = default_fc_.out_value_type; + fc_spec.fc_value = default_fc_.out_value; + } + + //Add all the pins from this port + for (int iport_pin = 0; iport_pin < port.num_pins; ++iport_pin) { + int true_physical_blk_pin = sub_tile.sub_tile_to_tile_pin_indices[iblk_pin++]; + fc_spec.pins.push_back(true_physical_blk_pin); + } + + type.fc_specs.push_back(fc_spec); + } + } + /** @brief Returns an intermediate map representing all the interconnects to be added in a site */ std::unordered_map get_interconnects(Device::SiteType::Reader& site) { // dictionary: @@ -811,14 +897,11 @@ struct ArchReader { void process_constants() { auto consts = ar_.getConstants(); - arch_->gnd_cell = str(consts.getGndCellType()); - arch_->vcc_cell = str(consts.getVccCellType()); + arch_->gnd_cell = std::make_pair(str(consts.getGndCellType()), str(consts.getGndCellPin())); + arch_->vcc_cell = std::make_pair(str(consts.getVccCellType()), str(consts.getVccCellPin())); - if (consts.getGndNetName().isName()) - arch_->gnd_net = str(consts.getGndNetName().getName()); - - if (consts.getVccNetName().isName()) - arch_->vcc_net = str(consts.getVccNetName().getName()); + arch_->gnd_net = consts.getGndNetName().isName() ? str(consts.getGndNetName().getName()) : "$__gnd_net"; + arch_->vcc_net = consts.getVccNetName().isName() ? str(consts.getVccNetName().getName()) : "$__vcc_net"; } /* end preprocessors */ @@ -1413,7 +1496,7 @@ struct ArchReader { auto cell_pin = str(pin_map.first); auto bel_pin = str(pin_map.second); - if (cell_pin == arch_->vcc_cell || cell_pin == arch_->gnd_cell) + if (cell_pin == arch_->vcc_cell.first || cell_pin == arch_->gnd_cell.first) continue; // Assign suffix to bel pin as it is a inout pin which was split in out and in ports @@ -1467,7 +1550,7 @@ struct ArchReader { for (auto pin_map : map.pins) { auto cell_pin = str(pin_map.first); - if (cell_pin == arch_->vcc_cell || cell_pin == arch_->gnd_cell) + if (cell_pin == arch_->vcc_cell.first || cell_pin == arch_->gnd_cell.first) continue; ic_count++; @@ -1487,7 +1570,7 @@ struct ArchReader { auto cell_pin = str(pin_map.first); auto bel_pin = str(pin_map.second); - if (cell_pin == arch_->vcc_cell || cell_pin == arch_->gnd_cell) + if (cell_pin == arch_->vcc_cell.first || cell_pin == arch_->gnd_cell.first) continue; std::smatch regex_matches; @@ -1899,6 +1982,7 @@ struct ArchReader { ptype.is_input_type = ptype.is_output_type = is_io; + // TODO: remove the following once the RR graph generation is fully enabled from the device database ptype.switchblock_locations = vtr::Matrix({{1, 1}}, e_sb_type::FULL); ptype.switchblock_switch_overrides = vtr::Matrix({{1, 1}}, DEFAULT_SWITCH); @@ -1943,18 +2027,12 @@ struct ArchReader { port_name_to_wire_name[std::string(port.name)] = str(pins_to_wires[idx++]); - port.equivalent = PortEquivalence::NONE; - port.num_pins = 1; - sub_tile.sub_tile_to_tile_pin_indices.push_back(type.num_pins + port_idx); port.index = port_idx++; port.absolute_first_pin_index = abs_first_pin_idx++; port.port_index_by_type = port_idx_by_type++; - port.is_clock = false; - port.is_non_clock_global = false; - if (dir == INPUT) { port.type = IN_PORT; icount++; @@ -1968,74 +2046,188 @@ struct ArchReader { } auto pins_size = site.getPins().size(); - sub_tile.num_phy_pins += pins_size; - type.num_pins += pins_size; - type.num_inst_pins += pins_size; - - type.num_input_pins += icount; - type.num_output_pins += ocount; - type.num_receivers += icount; - type.num_drivers += ocount; - - type.pin_width_offset.resize(type.num_pins, 0); - type.pin_height_offset.resize(type.num_pins, 0); - - type.pinloc.resize({1, 1, 4}, std::vector(type.num_pins, false)); - for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) { - for (int pin = 0; pin < type.num_pins; pin++) { - type.pinloc[0][0][side][pin] = true; - type.pin_width_offset[pin] = 0; - type.pin_height_offset[pin] = 0; - } - } + fill_sub_tile(type, sub_tile, pins_size, icount, ocount); - auto ltype = get_type_by_name(sub_tile.name, ltypes_); - vtr::bimap directs_map; + type.sub_tiles.push_back(sub_tile); + } + } - for (int npin = 0; npin < type.num_pins; npin++) { - t_physical_pin physical_pin(npin); - t_logical_pin logical_pin(npin); + /** @brief The constant block is a synthetic tile which is used to assign a virtual + * location in the grid to the constant signals which are than driven to + * all the real constant wires. + * + * The block's diagram can be seen below. The port names are specified in + * the interchange device database, therefore GND and VCC are mainly + * examples in this case. + * + * +---------------+ + * | | + * | +-------+ | + * | | | | + * | | GND +----+--> RR Graph node + * | | | | + * | +-------+ | + * | | + * | | + * | +-------+ | + * | | | | + * | | VCC +----+--> RR Graph node + * | | | | + * | +-------+ | + * | | + * +---------------+ + */ + void process_constant_block() { + std::vector> const_cells{arch_->gnd_cell, arch_->vcc_cell}; - directs_map.insert(logical_pin, physical_pin); - } + // Create constant complex block + t_logical_block_type block; - sub_tile.equivalent_sites.push_back(ltype); - - type.tile_block_pin_directs_map[ltype->index][sub_tile.index] = directs_map; - - // Assign FC specs - int iblk_pin = 0; - for (const auto& port : sub_tile.ports) { - t_fc_specification fc_spec; - - // FIXME: Use always one segment for the time being. - // Can use the right segment for this IOPIN as soon - // as the RR graph reading from the interchange is complete. - fc_spec.seg_index = 0; - - //Apply type and defaults - if (port.type == IN_PORT) { - fc_spec.fc_type = e_fc_type::IN; - fc_spec.fc_value_type = default_fc_.in_value_type; - fc_spec.fc_value = default_fc_.in_value; - } else { - VTR_ASSERT(port.type == OUT_PORT); - fc_spec.fc_type = e_fc_type::OUT; - fc_spec.fc_value_type = default_fc_.out_value_type; - fc_spec.fc_value = default_fc_.out_value; - } + block.name = vtr::strdup(const_block_.c_str()); + block.index = ltypes_.size(); - //Add all the pins from this port - for (int iport_pin = 0; iport_pin < port.num_pins; ++iport_pin) { - int true_physical_blk_pin = sub_tile.sub_tile_to_tile_pin_indices[iblk_pin++]; - fc_spec.pins.push_back(true_physical_blk_pin); - } + auto pb_type = new t_pb_type; + block.pb_type = pb_type; - type.fc_specs.push_back(fc_spec); - } + pb_type->name = vtr::strdup(const_block_.c_str()); + pb_type->num_pb = 1; - type.sub_tiles.push_back(sub_tile); + pb_type->num_modes = 1; + pb_type->modes = new t_mode[pb_type->num_modes]; + + pb_type->num_ports = 2; + pb_type->ports = (t_port*)vtr::calloc(pb_type->num_ports, sizeof(t_port)); + + pb_type->num_output_pins = 2; + pb_type->num_input_pins = 0; + pb_type->num_clock_pins = 0; + pb_type->num_pins = 2; + + auto mode = &pb_type->modes[0]; + mode->parent_pb_type = pb_type; + mode->index = 0; + mode->name = vtr::strdup("default"); + mode->disable_packing = false; + + mode->num_interconnect = 2; + mode->interconnect = new t_interconnect[mode->num_interconnect]; + + mode->num_pb_type_children = 2; + mode->pb_type_children = new t_pb_type[mode->num_pb_type_children]; + + int count = 0; + for (auto const_cell : const_cells) { + auto leaf_pb_type = &mode->pb_type_children[count]; + + std::string leaf_name = const_cell.first; + leaf_pb_type->name = vtr::strdup(leaf_name.c_str()); + leaf_pb_type->num_pb = 1; + leaf_pb_type->parent_mode = mode; + leaf_pb_type->blif_model = nullptr; + + leaf_pb_type->num_output_pins = 1; + leaf_pb_type->num_input_pins = 0; + leaf_pb_type->num_clock_pins = 0; + leaf_pb_type->num_pins = 1; + + int num_ports = 1; + leaf_pb_type->num_ports = num_ports; + leaf_pb_type->ports = (t_port*)vtr::calloc(num_ports, sizeof(t_port)); + leaf_pb_type->blif_model = vtr::strdup(const_cell.first.c_str()); + leaf_pb_type->model = get_model(arch_, const_cell.first); + + leaf_pb_type->ports[0] = get_generic_port(arch_, leaf_pb_type, OUT_PORT, const_cell.second, const_cell.first); + pb_type->ports[count] = get_generic_port(arch_, leaf_pb_type, OUT_PORT, const_cell.first + "_" + const_cell.second); + + std::string istr = leaf_name + "." + const_cell.second; + std::string ostr = const_block_ + "." + const_cell.first + "_" + const_cell.second; + std::string ic_name = const_cell.first; + + auto ic = &mode->interconnect[count]; + + ic->name = vtr::strdup(ic_name.c_str()); + ic->type = DIRECT_INTERC; + ic->parent_mode_index = 0; + ic->parent_mode = mode; + ic->input_string = vtr::strdup(istr.c_str()); + ic->output_string = vtr::strdup(ostr.c_str()); + + count++; } + + ltypes_.push_back(block); + } + + /** @brief Creates the models corresponding to the constant cells that are used in a given interchange device */ + void process_constant_model() { + std::vector> const_cells{arch_->gnd_cell, arch_->vcc_cell}; + + // Create constant models + for (auto const_cell : const_cells) { + t_model* model = new t_model; + model->index = arch_->models->index + 1; + + model->never_prune = true; + model->name = vtr::strdup(const_cell.first.c_str()); + + t_model_ports* model_port = new t_model_ports; + model_port->dir = OUT_PORT; + model_port->name = vtr::strdup(const_cell.second.c_str()); + + model_port->min_size = 1; + model_port->size = 1; + model_port->next = model->outputs; + model->outputs = model_port; + + model->next = arch_->models; + arch_->models = model; + } + } + + /** @brief Creates a synthetic constant tile that will be located in the external layer of the device. + * + * The constant tile has two output ports, one for GND and the other for VCC. The constant tile hosts + * the constant pb type that is generated as well. See process_constant_model and process_constant_block. + */ + void process_constant_tile() { + std::vector> const_cells{arch_->gnd_cell, arch_->vcc_cell}; + // Create constant tile + t_physical_tile_type constant; + constant.name = vtr::strdup(const_block_.c_str()); + constant.index = ptypes_.size(); + constant.width = constant.height = constant.area = 1; + constant.capacity = 1; + constant.is_input_type = constant.is_output_type = false; + + constant.switchblock_locations = vtr::Matrix({{1, 1}}, e_sb_type::FULL); + constant.switchblock_switch_overrides = vtr::Matrix({{1, 1}}, DEFAULT_SWITCH); + + t_sub_tile sub_tile; + sub_tile.index = 0; + sub_tile.name = vtr::strdup(const_block_.c_str()); + int count = 0; + for (auto const_cell : const_cells) { + sub_tile.sub_tile_to_tile_pin_indices.push_back(count); + + t_physical_tile_port port; + port.type = OUT_PORT; + port.num_pins = 1; + + port.name = vtr::strdup((const_cell.first + "_" + const_cell.second).c_str()); + + port.index = port.absolute_first_pin_index = port.port_index_by_type = 0; + + sub_tile.ports.push_back(port); + + count++; + } + + fill_sub_tile(constant, sub_tile, 2, 0, 2); + constant.sub_tiles.push_back(sub_tile); + + setup_pin_classes(&constant); + + ptypes_.push_back(constant); } // Layout Processing @@ -2103,6 +2295,16 @@ struct ArchReader { grid_def.loc_defs.emplace_back(std::move(single)); } + // The constant source tile will be placed at (0, 0) + t_grid_loc_def constant(const_block_, 1); + constant.x.start_expr = std::to_string(1); + constant.y.start_expr = std::to_string(1); + + constant.x.end_expr = constant.x.start_expr + " + w - 1"; + constant.y.end_expr = constant.y.start_expr + " + h - 1"; + + grid_def.loc_defs.emplace_back(std::move(constant)); + arch_->grid_layouts.emplace_back(std::move(grid_def)); } } @@ -2210,7 +2412,7 @@ struct ArchReader { Tdel = get_corner_value(model.getInternalDelay(), "slow", "min"); name << "Tdel" << std::scientific << Tdel; - switch_name = name.str(); + switch_name = name.str() + std::to_string(i); type = entry.first ? SwitchType::MUX : SwitchType::PASS_GATE; } diff --git a/vpr/src/base/read_interchange_netlist.cpp b/vpr/src/base/read_interchange_netlist.cpp index 38f1731197b..c3c323827f4 100644 --- a/vpr/src/base/read_interchange_netlist.cpp +++ b/vpr/src/base/read_interchange_netlist.cpp @@ -57,6 +57,8 @@ struct NetlistReader { outpad_model_ = find_model(MODEL_OUTPUT); main_netlist_.set_block_types(inpad_model_, outpad_model_); + prepare_port_net_maps(); + VTR_LOG("Reading IOs...\n"); read_ios(); VTR_LOG("Reading names...\n"); @@ -78,6 +80,60 @@ struct NetlistReader { LogicalNetlist::Netlist::CellInstance::Reader top_cell_instance_; + std::unordered_map, std::string, vtr::hash_pair>> port_net_maps_; + + /** @brief Preprocesses the port net maps, populating the port_net_maps_ hash map to be later accessed for faster lookups */ + void prepare_port_net_maps() { + auto inst_list = nr_.getInstList(); + auto decl_list = nr_.getCellDecls(); + auto str_list = nr_.getStrList(); + auto port_list = nr_.getPortList(); + auto top_cell = nr_.getCellList()[nr_.getTopInst().getCell()]; + + for (auto net : top_cell.getNets()) { + std::string net_name = str_list[net.getName()]; + + // Rename constant nets to their correct name based on the device architecture + // database + for (auto port : net.getPortInsts()) { + if (port.isExtPort()) + continue; + + auto port_inst = port.getInst(); + auto cell = inst_list[port_inst].getCell(); + if (str_list[decl_list[cell].getName()] == arch_.gnd_cell.first) + net_name = arch_.gnd_net; + + if (str_list[decl_list[cell].getName()] == arch_.vcc_cell.first) + net_name = arch_.vcc_net; + } + + for (auto port : net.getPortInsts()) { + if (!port.isInst()) + continue; + + size_t inst = port.getInst(); + + size_t port_bit = get_port_bit(port); + + auto port_idx = port.getPort(); + int start, end; + std::tie(start, end) = get_bus_range(port_list[port_idx]); + + int bus_size = std::abs(end - start); + + port_bit = start < end ? port_bit : bus_size - port_bit; + + auto pair = std::make_pair(port_idx, port_bit); + std::unordered_map, std::string, vtr::hash_pair> map{{pair, net_name}}; + + auto result = port_net_maps_.emplace(inst, map); + if (!result.second) + result.first->second.emplace(pair, net_name); + } + } + } + void read_ios() { const t_model* input_model = find_model(MODEL_INPUT); const t_model* output_model = find_model(MODEL_OUTPUT); @@ -90,8 +146,11 @@ struct NetlistReader { std::string name = str_list[port.getName()]; auto dir = port.getDir(); - int bus_size, start_bit; - std::tie(bus_size, start_bit) = get_bus_size(port); + int start, end; + std::tie(start, end) = get_bus_range(port); + + int bus_size = std::abs(end - start) + 1; + int start_bit = start < end ? start : end; for (int bit = start_bit; bit < start_bit + bus_size; bit++) { auto port_name = name; @@ -138,7 +197,7 @@ struct NetlistReader { auto port_list = nr_.getPortList(); auto str_list = nr_.getStrList(); - std::vector> insts; + std::vector> insts; for (auto cell_inst : top_cell.getInsts()) { auto cell = decl_list[inst_list[cell_inst].getCell()]; @@ -147,12 +206,14 @@ struct NetlistReader { std::string init_param; std::tie(is_lut, width, init_param) = is_lut_cell(str_list[cell.getName()]); - if (is_lut) - insts.emplace_back(cell_inst, width, init_param); + if (!is_lut) + continue; + + insts.emplace_back(cell_inst, width, init_param); } for (auto inst : insts) { - unsigned int inst_idx; + size_t inst_idx; int lut_width; std::string init_param; std::tie(inst_idx, lut_width, init_param) = inst; @@ -257,24 +318,15 @@ struct NetlistReader { AtomPortId oport_id = main_netlist_.create_port(blk_id, blk_model->outputs); auto cell_lib = decl_list[inst_list[inst_idx].getCell()]; - std::unordered_map port_net_map; - - for (auto net : top_cell.getNets()) { - std::string net_name = str_list[net.getName()]; - for (auto port : net.getPortInsts()) { - if (!port.isInst() || port.getInst() != inst_idx) - continue; - - port_net_map.emplace(port.getPort(), net_name); - } - } - + auto port_net_map = port_net_maps_.at(inst_idx); int inum = 0; for (auto port : cell_lib.getPorts()) { - if (port_net_map.find(port) == port_net_map.end()) + std::pair pair{port, 0}; + + if (port_net_map.find(pair) == port_net_map.end()) continue; - auto net_name = port_net_map.at(port); + auto net_name = port_net_map.at(pair); AtomNetId net_id = main_netlist_.create_net(net_name); auto dir = port_list[port].getDir(); @@ -300,7 +352,7 @@ struct NetlistReader { auto port_list = nr_.getPortList(); auto str_list = nr_.getStrList(); - std::vector> insts; + std::vector> insts; for (auto cell_inst : top_cell.getInsts()) { auto cell = decl_list[inst_list[cell_inst].getCell()]; @@ -331,13 +383,13 @@ struct NetlistReader { inst_name.c_str(), conflicting_model->name, blk_model->name); } - auto port_net_map = get_port_net_map(inst_idx); + auto port_net_map = port_net_maps_.at(inst_idx); auto cell = decl_list[inst_list[inst_idx].getCell()]; - if (str_list[cell.getName()] == arch_.vcc_cell) - inst_name = arch_.vcc_cell; - else if (str_list[cell.getName()] == arch_.gnd_cell) - inst_name = arch_.gnd_cell; + if (str_list[cell.getName()] == arch_.vcc_cell.first) + inst_name = arch_.vcc_cell.first; + else if (str_list[cell.getName()] == arch_.gnd_cell.first) + inst_name = arch_.gnd_cell.first; if (main_netlist_.find_block(inst_name)) continue; @@ -351,9 +403,9 @@ struct NetlistReader { auto port_bit = port_net.first.second; auto net_name = port_net.second; - if (inst_name == arch_.vcc_cell) + if (inst_name == arch_.vcc_cell.first) net_name = arch_.vcc_net; - else if (inst_name == arch_.gnd_cell) + else if (inst_name == arch_.gnd_cell.first) net_name = arch_.gnd_net; auto port = port_list[port_idx]; @@ -431,44 +483,23 @@ struct NetlistReader { return nullptr; } - std::pair get_bus_size(LogicalNetlist::Netlist::Port::Reader port_reader) { + std::pair get_bus_range(LogicalNetlist::Netlist::Port::Reader port_reader) { if (port_reader.isBus()) { int s = port_reader.getBus().getBusStart(); int e = port_reader.getBus().getBusEnd(); - if (e < s) - return std::make_pair(s - e + 1, e); - else - return std::make_pair(e - s + 1, s); + return std::make_pair(s, e); } - return std::make_pair(1, 0); + return std::make_pair(0, 0); } - unsigned int get_port_bit(LogicalNetlist::Netlist::PortInstance::Reader port_inst_reader) { + size_t get_port_bit(LogicalNetlist::Netlist::PortInstance::Reader port_inst_reader) { + size_t port_bit = 0; if (port_inst_reader.getBusIdx().which() == LogicalNetlist::Netlist::PortInstance::BusIdx::IDX) - return port_inst_reader.getBusIdx().getIdx(); - - return 0; - } - - std::unordered_map, std::string, vtr::hash_pair> get_port_net_map(unsigned int inst_idx) { - auto top_cell = nr_.getCellList()[nr_.getTopInst().getCell()]; - auto str_list = nr_.getStrList(); - std::unordered_map, std::string, vtr::hash_pair> map; - for (auto net : top_cell.getNets()) { - std::string net_name = str_list[net.getName()]; - for (auto port : net.getPortInsts()) { - if (!port.isInst() || port.getInst() != inst_idx) - continue; - - unsigned int port_bit = get_port_bit(port); - auto pair = std::make_pair(port.getPort(), port_bit); - map.emplace(pair, net_name); - } - } + port_bit = port_inst_reader.getBusIdx().getIdx(); - return map; + return port_bit; } std::tuple is_lut_cell(std::string cell_name) { diff --git a/vpr/test/test_interchange_device.cpp b/vpr/test/test_interchange_device.cpp index caf5295a1d9..5a0d727558f 100644 --- a/vpr/test/test_interchange_device.cpp +++ b/vpr/test/test_interchange_device.cpp @@ -53,7 +53,7 @@ TEST_CASE("read_interchange_layout", "[vpr]") { REQUIRE(gd.height == 12); REQUIRE(gd.width == 12); - std::unordered_map tile_types({{"PWR", false}, {"IOB", false}, {"CLB", false}}); + std::unordered_map tile_types({{"constant_block", false}, {"IB", false}, {"OB", false}, {"IOB", false}, {"CLB", false}}); for (auto& loc : gd.loc_defs) { auto ret = tile_types.find(loc.block_type); REQUIRE(ret != tile_types.end()); @@ -91,7 +91,7 @@ TEST_CASE("read_interchange_luts", "[vpr]") { const auto& lut_elements = it.second; for (const auto& lut_element : lut_elements) { - REQUIRE(lut_element.lut_bels.size() == 2); + REQUIRE(lut_element.lut_bels.size() == 1); for (auto lut_bel : lut_element.lut_bels) { CHECK(std::find(lut_bels.begin(), lut_bels.end(), lut_bel.name) != lut_bels.end()); @@ -110,7 +110,7 @@ TEST_CASE("read_interchange_tiles", "[vpr]") { FPGAInterchangeReadArch(kArchFile, /*timing_enabled=*/true, &arch, physical_tile_types, logical_block_types); - std::unordered_set ptypes = {"EMPTY", "IOB", "PWR", "CLB"}; + std::unordered_set ptypes = {"EMPTY", "IOB", "IB", "OB", "CLB", "constant_block"}; // Check that there are exactly the expected models for (auto ptype : physical_tile_types) { @@ -134,7 +134,7 @@ TEST_CASE("read_interchange_pb_types", "[vpr]") { FPGAInterchangeReadArch(kArchFile, /*timing_enabled=*/true, &arch, physical_tile_types, logical_block_types); - std::unordered_set ltypes = {"EMPTY", "IOPAD", "SLICE", "POWER"}; + std::unordered_set ltypes = {"EMPTY", "IOPAD", "IPAD", "OPAD", "SLICE", "constant_block"}; std::unordered_map slice_ports = { {"L0_0", PORTS::IN_PORT}, diff --git a/vpr/test/testarch.device b/vpr/test/testarch.device index 92c32afe1c4..335792e8ad6 100644 Binary files a/vpr/test/testarch.device and b/vpr/test/testarch.device differ