/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2021 Symbiflow Authors * * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef SITE_ARCH_IMPL_H #define SITE_ARCH_IMPL_H #include "context.h" #include "site_arch.h" NEXTPNR_NAMESPACE_BEGIN inline const ChipInfoPOD &SiteInformation::chip_info() const { return *ctx->chip_info; } inline bool SiteInformation::is_wire_in_site(WireId wire) const { if (wire.tile != tile) { return false; } return ctx->wire_info(wire).site == site; } inline bool SiteInformation::is_bel_in_site(BelId bel) const { if (bel.tile != tile) { return false; } return bel_info(ctx->chip_info, bel).site == site; } inline bool SiteInformation::is_pip_part_of_site(PipId pip) const { if (pip.tile != tile) { return false; } const auto &tile_type_data = ctx->chip_info->tile_types[tile_type]; const auto &pip_data = tile_type_data.pip_data[pip.index]; return pip_data.site == site; } inline bool SiteInformation::is_site_port(PipId pip) const { const auto &tile_type_data = ctx->chip_info->tile_types[tile_type]; const auto &pip_data = tile_type_data.pip_data[pip.index]; if (pip_data.site == -1) { return false; } auto &bel_data = tile_type_data.bel_data[pip_data.bel]; return bel_data.category == BEL_CATEGORY_SITE_PORT; } inline SiteWire SiteWire::make(const SiteInformation *site_info, WireId site_wire) { NPNR_ASSERT(site_info->is_wire_in_site(site_wire)); SiteWire out; out.type = SITE_WIRE; out.wire = site_wire; return out; } inline SiteWire SiteWire::make_site_port(const SiteInformation *site_info, PipId pip, bool dst_wire) { const auto &tile_type_data = site_info->chip_info().tile_types[site_info->tile_type]; const auto &pip_data = tile_type_data.pip_data[pip.index]; // This pip should definitely be part of this site NPNR_ASSERT(pip_data.site == site_info->site); SiteWire out; const auto &src_data = tile_type_data.wire_data[pip_data.src_index]; const auto &dst_data = tile_type_data.wire_data[pip_data.dst_index]; if (dst_wire) { if (src_data.site == site_info->site) { NPNR_ASSERT(dst_data.site == -1); out.type = SITE_PORT_SINK; out.pip = pip; out.wire = canonical_wire(&site_info->chip_info(), pip.tile, pip_data.dst_index); } else { NPNR_ASSERT(src_data.site == -1); NPNR_ASSERT(dst_data.site == site_info->site); out.type = SITE_WIRE; out.wire.tile = pip.tile; out.wire.index = pip_data.dst_index; } } else { if (src_data.site == site_info->site) { NPNR_ASSERT(dst_data.site == -1); out.type = SITE_WIRE; out.wire.tile = pip.tile; out.wire.index = pip_data.src_index; } else { NPNR_ASSERT(src_data.site == -1); NPNR_ASSERT(dst_data.site == site_info->site