Merge pull request #985 from antmicro/interchange-lut-constants
[interchange] Tying unused LUT inputs according to architecture
This commit is contained in:
commit
4ecbf6c6e9
@ -301,6 +301,12 @@ void Arch::init()
|
|||||||
for (size_t tile_type = 0; tile_type < chip_info->tile_types.size(); ++tile_type) {
|
for (size_t tile_type = 0; tile_type < chip_info->tile_types.size(); ++tile_type) {
|
||||||
pseudo_pip_data.init_tile_type(getCtx(), tile_type);
|
pseudo_pip_data.init_tile_type(getCtx(), tile_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warn if there is no preferred constant net defined in the architecture
|
||||||
|
IdString const_net_name(getCtx()->chip_info->constants->best_constant_net);
|
||||||
|
if (const_net_name == IdString()) {
|
||||||
|
log_warning("The architecture does not specify preferred constant net. Using VCC as default.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -874,17 +880,31 @@ static void prepare_sites_for_routing(Context *ctx)
|
|||||||
|
|
||||||
// Fixup LUT vcc pins.
|
// Fixup LUT vcc pins.
|
||||||
IdString vcc_net_name(ctx->chip_info->constants->vcc_net_name);
|
IdString vcc_net_name(ctx->chip_info->constants->vcc_net_name);
|
||||||
|
IdString gnd_net_name(ctx->chip_info->constants->gnd_net_name);
|
||||||
|
|
||||||
|
IdString const_net_name(ctx->chip_info->constants->best_constant_net);
|
||||||
|
NPNR_ASSERT(const_net_name == IdString() || const_net_name == vcc_net_name || const_net_name == gnd_net_name);
|
||||||
|
|
||||||
|
// FIXME: Use VCC if the architecture does not device the best constant
|
||||||
|
if (const_net_name == IdString()) {
|
||||||
|
const_net_name = vcc_net_name;
|
||||||
|
}
|
||||||
|
|
||||||
for (BelId bel : ctx->getBels()) {
|
for (BelId bel : ctx->getBels()) {
|
||||||
CellInfo *cell = ctx->getBoundBelCell(bel);
|
CellInfo *cell = ctx->getBoundBelCell(bel);
|
||||||
if (cell == nullptr) {
|
if (cell == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->lut_cell.vcc_pins.empty()) {
|
for (const auto &it : cell->lut_cell.pin_connections) {
|
||||||
|
const auto &bel_pin = it.first;
|
||||||
|
const auto &conn = it.second;
|
||||||
|
|
||||||
|
// Connected to an active signal or unconnected
|
||||||
|
if (conn == LutCell::PinConnection::Signal || conn == LutCell::PinConnection::Unconnected) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bel_pin : cell->lut_cell.vcc_pins) {
|
|
||||||
// We can't rely on bel pins not clashing with cell names (for Xilinx they use different naming schemes, for
|
// We can't rely on bel pins not clashing with cell names (for Xilinx they use different naming schemes, for
|
||||||
// Nexus they are the same) so add a prefix to the bel pin name to disambiguate it
|
// Nexus they are the same) so add a prefix to the bel pin name to disambiguate it
|
||||||
IdString cell_pin = ctx->id(stringf("%s_PHYS", ctx->nameOf(bel_pin)));
|
IdString cell_pin = ctx->id(stringf("%s_PHYS", ctx->nameOf(bel_pin)));
|
||||||
@ -896,17 +916,37 @@ static void prepare_sites_for_routing(Context *ctx)
|
|||||||
|
|
||||||
#ifdef DEBUG_LUT_MAPPING
|
#ifdef DEBUG_LUT_MAPPING
|
||||||
if (ctx->verbose) {
|
if (ctx->verbose) {
|
||||||
log_info("%s must be tied to VCC, tying now\n", ctx->nameOfWire(lut_pin_wire));
|
log_info("%s must be tied to %s, tying now\n", ctx->nameOfWire(lut_pin_wire),
|
||||||
|
LutCell::nameOfPinConnection(conn).c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
IdString tie_net_name;
|
||||||
|
switch (conn) {
|
||||||
|
case LutCell::PinConnection::Vcc:
|
||||||
|
tie_net_name = vcc_net_name;
|
||||||
|
break;
|
||||||
|
case LutCell::PinConnection::Gnd:
|
||||||
|
tie_net_name = gnd_net_name;
|
||||||
|
break;
|
||||||
|
case LutCell::PinConnection::Const:
|
||||||
|
tie_net_name = const_net_name;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Should never happen
|
||||||
|
NPNR_ASSERT_FALSE(
|
||||||
|
stringf("Invalid LUT cell pin connection '%s'", LutCell::nameOfPinConnection(conn).c_str())
|
||||||
|
.c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto result = cell->ports.emplace(cell_pin, port_info);
|
auto result = cell->ports.emplace(cell_pin, port_info);
|
||||||
if (result.second) {
|
if (result.second) {
|
||||||
cell->cell_bel_pins[cell_pin].push_back(bel_pin);
|
cell->cell_bel_pins[cell_pin].push_back(bel_pin);
|
||||||
ctx->connectPort(vcc_net_name, cell->name, cell_pin);
|
ctx->connectPort(tie_net_name, cell->name, cell_pin);
|
||||||
cell->const_ports.emplace(cell_pin);
|
cell->const_ports.emplace(cell_pin);
|
||||||
} else {
|
} else {
|
||||||
NPNR_ASSERT(result.first->second.net == ctx->getNetByAlias(vcc_net_name));
|
NPNR_ASSERT(result.first->second.net == ctx->getNetByAlias(tie_net_name));
|
||||||
auto result2 = cell->cell_bel_pins.emplace(cell_pin, std::vector<IdString>({bel_pin}));
|
auto result2 = cell->cell_bel_pins.emplace(cell_pin, std::vector<IdString>({bel_pin}));
|
||||||
NPNR_ASSERT(result2.first->second.at(0) == bel_pin);
|
NPNR_ASSERT(result2.first->second.at(0) == bel_pin);
|
||||||
NPNR_ASSERT(result2.first->second.size() == 1);
|
NPNR_ASSERT(result2.first->second.size() == 1);
|
||||||
|
@ -47,14 +47,6 @@ bool rotate_and_merge_lut_equation(std::vector<LogicLevel> *result, const LutBel
|
|||||||
// This address line is 0, so don't translate this bit to the cell
|
// This address line is 0, so don't translate this bit to the cell
|
||||||
// address.
|
// address.
|
||||||
if ((bel_address & (1 << bel_pin_idx)) == 0) {
|
if ((bel_address & (1 << bel_pin_idx)) == 0) {
|
||||||
// This pin is unused, so the line will be tied high, this
|
|
||||||
// address is unreachable.
|
|
||||||
//
|
|
||||||
// FIXME: The assumption is that unused pins are tied VCC.
|
|
||||||
// This is not generally true.
|
|
||||||
//
|
|
||||||
// Use Arch::prefered_constant_net_type to determine what
|
|
||||||
// constant net should be used for unused pins.
|
|
||||||
if ((used_pins & (1 << bel_pin_idx)) == 0) {
|
if ((used_pins & (1 << bel_pin_idx)) == 0) {
|
||||||
address_reachable = false;
|
address_reachable = false;
|
||||||
break;
|
break;
|
||||||
@ -132,6 +124,26 @@ struct LutPin
|
|||||||
bool operator<(const LutPin &other) const { return max_pin < other.max_pin; }
|
bool operator<(const LutPin &other) const { return max_pin < other.max_pin; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string LutCell::nameOfPinConnection(LutCell::PinConnection conn)
|
||||||
|
{
|
||||||
|
switch (conn) {
|
||||||
|
case PinConnection::Unconnected:
|
||||||
|
return std::string("unconnected");
|
||||||
|
case PinConnection::Gnd:
|
||||||
|
return std::string("Gnd");
|
||||||
|
case PinConnection::Vcc:
|
||||||
|
return std::string("Vcc");
|
||||||
|
case PinConnection::Const:
|
||||||
|
return std::string("Const");
|
||||||
|
case PinConnection::Signal:
|
||||||
|
return std::string("Signal");
|
||||||
|
default:
|
||||||
|
// Should never happen
|
||||||
|
NPNR_ASSERT_FALSE("Invalid value of LutCell::PinConnection");
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t LutMapper::check_wires(const Context *ctx) const
|
uint32_t LutMapper::check_wires(const Context *ctx) const
|
||||||
{
|
{
|
||||||
// Unlike the 3 argument version of check_wires, this version needs to
|
// Unlike the 3 argument version of check_wires, this version needs to
|
||||||
@ -184,12 +196,7 @@ uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: The assumption is that unused pins are tied VCC.
|
uint32_t pin_mask = 0;
|
||||||
// This is not generally true.
|
|
||||||
//
|
|
||||||
// Use Arch::prefered_constant_net_type to determine what
|
|
||||||
// constant net should be used for unused pins.
|
|
||||||
uint32_t vcc_mask = 0;
|
|
||||||
|
|
||||||
DynamicBitarray<> wire_equation;
|
DynamicBitarray<> wire_equation;
|
||||||
wire_equation.resize(2);
|
wire_equation.resize(2);
|
||||||
@ -248,11 +255,11 @@ uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_
|
|||||||
|
|
||||||
bool good_for_wire = valid_pin_for_wire && !invalid_pin_for_wire;
|
bool good_for_wire = valid_pin_for_wire && !invalid_pin_for_wire;
|
||||||
if (!good_for_wire) {
|
if (!good_for_wire) {
|
||||||
vcc_mask |= (1 << pin_idx);
|
pin_mask |= (1 << pin_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vcc_mask;
|
return pin_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping,
|
bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping,
|
||||||
@ -381,26 +388,18 @@ bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not all LUT inputs are used
|
// Not all LUT inputs are used
|
||||||
uint32_t vcc_pins = 0;
|
uint32_t pin_mask = 0;
|
||||||
if (cells.size() != element.lut_bels.size()) {
|
if (cells.size() != element.lut_bels.size()) {
|
||||||
// Look to see if wires can be run from element inputs to unused
|
pin_mask = check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins, blocked_luts);
|
||||||
// outputs. If not, block the BEL pin by tying to VCC.
|
}
|
||||||
//
|
|
||||||
// FIXME: The assumption is that unused pins are tied VCC.
|
|
||||||
// This is not generally true.
|
|
||||||
//
|
|
||||||
// Use Arch::prefered_constant_net_type to determine what
|
|
||||||
// constant net should be used for unused pins.
|
|
||||||
vcc_pins = check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins, blocked_luts);
|
|
||||||
#if defined(DEBUG_LUT_ROTATION)
|
#if defined(DEBUG_LUT_ROTATION)
|
||||||
log_info("vcc_pins = 0x%x", vcc_pins);
|
log_info("Cell bindings:\n");
|
||||||
for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
|
for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
|
||||||
CellInfo *cell = cells[cell_idx];
|
CellInfo *cell = cells[cell_idx];
|
||||||
log(", %s => %s", ctx->nameOfBel(cell->bel), cell->name.c_str(ctx));
|
log_info(" - %s => %s\n", ctx->nameOfBel(cell->bel), cell->name.c_str(ctx));
|
||||||
}
|
}
|
||||||
log("\n");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in the LUT mapping result
|
// Fill in the LUT mapping result
|
||||||
|
|
||||||
@ -422,28 +421,39 @@ bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult *lut_mapping
|
|||||||
cell.belPins[cellPin] = belPin;
|
cell.belPins[cellPin] = belPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell.lutCell.vcc_pins.clear();
|
cell.lutCell.pin_connections.clear();
|
||||||
|
|
||||||
// All LUT inputs used
|
// All LUT inputs used
|
||||||
if (cells.size() == element.lut_bels.size()) {
|
if (cells.size() == element.lut_bels.size()) {
|
||||||
for (size_t bel_pin_idx = 0; bel_pin_idx < lutBel.pins.size(); ++bel_pin_idx) {
|
for (size_t bel_pin_idx = 0; bel_pin_idx < lutBel.pins.size(); ++bel_pin_idx) {
|
||||||
if ((used_pins & (1 << bel_pin_idx)) == 0) {
|
if ((used_pins & (1 << bel_pin_idx)) == 0) {
|
||||||
NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
|
NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
|
||||||
cell.lutCell.vcc_pins.emplace(lutBel.pins.at(bel_pin_idx));
|
cell.lutCell.pin_connections.emplace(lutBel.pins.at(bel_pin_idx), LutCell::PinConnection::Const);
|
||||||
|
} else {
|
||||||
|
cell.lutCell.pin_connections.emplace(lutBel.pins.at(bel_pin_idx), LutCell::PinConnection::Signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only some LUT inputs used
|
// Only some LUT inputs used
|
||||||
else {
|
else {
|
||||||
for (size_t bel_pin_idx = 0; bel_pin_idx < lutBel.pins.size(); ++bel_pin_idx) {
|
for (size_t bel_pin_idx = 0; bel_pin_idx < lutBel.pins.size(); ++bel_pin_idx) {
|
||||||
if ((vcc_pins & (1 << bel_pin_idx)) != 0) {
|
if ((pin_mask & (1 << bel_pin_idx)) != 0) {
|
||||||
NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
|
NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
|
||||||
auto pin = lutBel.pins.at(bel_pin_idx);
|
auto pin = lutBel.pins.at(bel_pin_idx);
|
||||||
cell.lutCell.vcc_pins.emplace(pin);
|
cell.lutCell.pin_connections.emplace(pin, LutCell::PinConnection::Const);
|
||||||
|
} else {
|
||||||
|
cell.lutCell.pin_connections.emplace(lutBel.pins.at(bel_pin_idx), LutCell::PinConnection::Signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG_LUT_ROTATION)
|
||||||
|
log_info("Pin connections for LUT cell %s:\n", cellInfo->name.c_str(ctx));
|
||||||
|
for (const auto &it : cell.lutCell.pin_connections) {
|
||||||
|
log_info(" - %s : %s\n", it.first.c_str(ctx), LutCell::nameOfPinConnection(it.second).c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lut_mapping->cells.push_back(cell);
|
lut_mapping->cells.push_back(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +466,7 @@ void check_equation(const LutCell &lut_cell, const dict<IdString, IdString> &cel
|
|||||||
std::vector<int8_t> pin_map;
|
std::vector<int8_t> pin_map;
|
||||||
pin_map.resize(lut_bel.pins.size(), -1);
|
pin_map.resize(lut_bel.pins.size(), -1);
|
||||||
|
|
||||||
NPNR_ASSERT(lut_cell.pins.size() < std::numeric_limits<decltype(pin_map)::value_type>::max());
|
NPNR_ASSERT(lut_cell.pins.size() < (size_t)std::numeric_limits<decltype(pin_map)::value_type>::max());
|
||||||
|
|
||||||
for (size_t cell_pin_idx = 0; cell_pin_idx < lut_cell.pins.size(); ++cell_pin_idx) {
|
for (size_t cell_pin_idx = 0; cell_pin_idx < lut_cell.pins.size(); ++cell_pin_idx) {
|
||||||
IdString cell_pin = lut_cell.pins[cell_pin_idx];
|
IdString cell_pin = lut_cell.pins[cell_pin_idx];
|
||||||
|
@ -42,11 +42,22 @@ enum LogicLevel
|
|||||||
|
|
||||||
struct LutCell
|
struct LutCell
|
||||||
{
|
{
|
||||||
|
enum class PinConnection
|
||||||
|
{
|
||||||
|
Unconnected,
|
||||||
|
Gnd,
|
||||||
|
Vcc,
|
||||||
|
Const,
|
||||||
|
Signal
|
||||||
|
};
|
||||||
|
|
||||||
// LUT cell pins for equation, LSB first.
|
// LUT cell pins for equation, LSB first.
|
||||||
std::vector<IdString> pins;
|
std::vector<IdString> pins;
|
||||||
pool<IdString> lut_pins;
|
pool<IdString> lut_pins;
|
||||||
pool<IdString> vcc_pins;
|
dict<IdString, PinConnection> pin_connections;
|
||||||
DynamicBitarray<> equation;
|
DynamicBitarray<> equation;
|
||||||
|
|
||||||
|
static const std::string nameOfPinConnection(PinConnection conn);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LutBel
|
struct LutBel
|
||||||
|
@ -133,8 +133,20 @@ SiteArch::SiteArch(const SiteInformation *site_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create list of out of site sources and sinks.
|
// Create list of out of site sources and sinks.
|
||||||
|
|
||||||
bool have_vcc_pins = false;
|
bool have_vcc_pins = false;
|
||||||
|
bool have_gnd_pins = false;
|
||||||
|
|
||||||
|
IdString vcc_net_name(ctx->chip_info->constants->vcc_net_name);
|
||||||
|
IdString gnd_net_name(ctx->chip_info->constants->gnd_net_name);
|
||||||
|
|
||||||
|
IdString const_net_name(ctx->chip_info->constants->best_constant_net);
|
||||||
|
NPNR_ASSERT(const_net_name == IdString() || const_net_name == vcc_net_name || const_net_name == gnd_net_name);
|
||||||
|
|
||||||
|
// FIXME: Use VCC if the architecture does not device the best constant
|
||||||
|
if (const_net_name == IdString()) {
|
||||||
|
const_net_name = vcc_net_name;
|
||||||
|
}
|
||||||
|
|
||||||
for (CellInfo *cell : site_info->cells_in_site) {
|
for (CellInfo *cell : site_info->cells_in_site) {
|
||||||
for (const auto &pin_pair : cell->cell_bel_pins) {
|
for (const auto &pin_pair : cell->cell_bel_pins) {
|
||||||
if (!cell->ports.count(pin_pair.first))
|
if (!cell->ports.count(pin_pair.first))
|
||||||
@ -145,8 +157,18 @@ SiteArch::SiteArch(const SiteInformation *site_info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cell->lut_cell.vcc_pins.empty()) {
|
for (const auto &conn : cell->lut_cell.pin_connections) {
|
||||||
|
if (conn.second == LutCell::PinConnection::Vcc) {
|
||||||
have_vcc_pins = true;
|
have_vcc_pins = true;
|
||||||
|
} else if (conn.second == LutCell::PinConnection::Gnd) {
|
||||||
|
have_gnd_pins = true;
|
||||||
|
} else if (conn.second == LutCell::PinConnection::Const) {
|
||||||
|
if (const_net_name == vcc_net_name) {
|
||||||
|
have_vcc_pins = true;
|
||||||
|
} else if (const_net_name == gnd_net_name) {
|
||||||
|
have_gnd_pins = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,10 +261,9 @@ SiteArch::SiteArch(const SiteInformation *site_info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString vcc_net_name(ctx->chip_info->constants->vcc_net_name);
|
|
||||||
NetInfo *vcc_net = ctx->nets.at(vcc_net_name).get();
|
NetInfo *vcc_net = ctx->nets.at(vcc_net_name).get();
|
||||||
auto iter = nets.find(vcc_net);
|
auto vcc_iter = nets.find(vcc_net);
|
||||||
if (iter == nets.end() && have_vcc_pins) {
|
if (vcc_iter == nets.end() && have_vcc_pins) {
|
||||||
// VCC net isn't present, add it.
|
// VCC net isn't present, add it.
|
||||||
SiteNetInfo net_info;
|
SiteNetInfo net_info;
|
||||||
net_info.net = vcc_net;
|
net_info.net = vcc_net;
|
||||||
@ -250,13 +271,53 @@ SiteArch::SiteArch(const SiteInformation *site_info)
|
|||||||
net_info.driver.net = vcc_net;
|
net_info.driver.net = vcc_net;
|
||||||
auto result = nets.emplace(vcc_net, net_info);
|
auto result = nets.emplace(vcc_net, net_info);
|
||||||
NPNR_ASSERT(result.second);
|
NPNR_ASSERT(result.second);
|
||||||
iter = result.first;
|
vcc_iter = result.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetInfo *gnd_net = ctx->nets.at(gnd_net_name).get();
|
||||||
|
auto gnd_iter = nets.find(gnd_net);
|
||||||
|
if (gnd_iter == nets.end() && have_gnd_pins) {
|
||||||
|
// GND net isn't present, add it.
|
||||||
|
SiteNetInfo net_info;
|
||||||
|
net_info.net = gnd_net;
|
||||||
|
net_info.driver.type = SiteWire::OUT_OF_SITE_SOURCE;
|
||||||
|
net_info.driver.net = gnd_net;
|
||||||
|
auto result = nets.emplace(gnd_net, net_info);
|
||||||
|
NPNR_ASSERT(result.second);
|
||||||
|
gnd_iter = result.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CellInfo *cell : site_info->cells_in_site) {
|
for (CellInfo *cell : site_info->cells_in_site) {
|
||||||
for (IdString vcc_pin : cell->lut_cell.vcc_pins) {
|
for (const auto &it : cell->lut_cell.pin_connections) {
|
||||||
SiteWire wire = getBelPinWire(cell->bel, vcc_pin);
|
const auto &pin = it.first;
|
||||||
iter->second.users.emplace(wire);
|
const auto &conn = it.second;
|
||||||
|
|
||||||
|
if (conn == LutCell::PinConnection::Unconnected || conn == LutCell::PinConnection::Signal) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn == LutCell::PinConnection::Vcc) {
|
||||||
|
SiteWire wire = getBelPinWire(cell->bel, pin);
|
||||||
|
vcc_iter->second.users.emplace(wire);
|
||||||
|
} else if (conn == LutCell::PinConnection::Gnd) {
|
||||||
|
SiteWire wire = getBelPinWire(cell->bel, pin);
|
||||||
|
gnd_iter->second.users.emplace(wire);
|
||||||
|
} else if (conn == LutCell::PinConnection::Const) {
|
||||||
|
SiteWire wire = getBelPinWire(cell->bel, pin);
|
||||||
|
if (const_net_name == vcc_net_name) {
|
||||||
|
vcc_iter->second.users.emplace(wire);
|
||||||
|
}
|
||||||
|
if (const_net_name == gnd_net_name) {
|
||||||
|
gnd_iter->second.users.emplace(wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_LUT_MAPPING
|
||||||
|
if (ctx->verbose) {
|
||||||
|
log_info("Tying %s.%s to %s\n", cell->name.c_str(ctx), pin.c_str(ctx),
|
||||||
|
LutCell::nameOfPinConnection(conn).c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,8 +138,8 @@ bool SiteLutMappingResult::apply(const SiteInformation &siteInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LUT data
|
// LUT data
|
||||||
// FIXME: Is there any other info that is being updated than vcc_pins ?
|
// FIXME: Is there any other info that is being updated than pin_connections ?
|
||||||
cellInfo->lut_cell.vcc_pins = std::move(cell.lutCell.vcc_pins);
|
cellInfo->lut_cell.pin_connections = std::move(cell.lutCell.pin_connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user