/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Claire Xenia Wolf * Copyright (C) 2018-19 gatecat * 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 FPGA_INTERCHANGE_ARCH_H #define FPGA_INTERCHANGE_ARCH_H #include #include #include #include "PhysicalNetlist.capnp.h" #include "arch_api.h" #include "constraints.h" #include "nextpnr_types.h" #include "relptr.h" #include "arch_iterators.h" #include "cell_parameters.h" #include "chipdb.h" #include "dedicated_interconnect.h" #include "lookahead.h" #include "pseudo_pip_model.h" #include "site_lut_mapping_cache.h" #include "site_router.h" #include "site_routing_cache.h" NEXTPNR_NAMESPACE_BEGIN struct ArchArgs { std::string chipdb; std::string package; bool rebuild_lookahead; bool dont_write_lookahead; bool disable_lut_mapping_cache; }; struct ArchRanges { using ArchArgsT = ArchArgs; // Bels using AllBelsRangeT = BelRange; using TileBelsRangeT = BelRange; using BelAttrsRangeT = std::vector>; using BelPinsRangeT = IdStringRange; using CellBelPinRangeT = const std::vector &; // Wires using AllWiresRangeT = WireRange; using DownhillPipRangeT = DownhillPipRange; using UphillPipRangeT = UphillPipRange; using WireBelPinRangeT = BelPinRange; using WireAttrsRangeT = std::vector>; // Pips using AllPipsRangeT = AllPipRange; using PipAttrsRangeT = std::vector>; // Groups using AllGroupsRangeT = std::vector; using GroupBelsRangeT = std::vector; using GroupWiresRangeT = std::vector; using GroupPipsRangeT = std::vector; using GroupGroupsRangeT = std::vector; // Decals using DecalGfxRangeT = std::vector; // Placement validity using CellTypeRangeT = const IdStringRange; using BelBucketRangeT = const BelBucketRange; using BucketBelRangeT = FilteredBelRange; }; static constexpr size_t kMaxState = 8; struct TileStatus { std::vector> tags; std::vector boundcells; std::vector sites; PseudoPipModel pseudo_pip_model; }; struct Cluster { uint32_t index; CellInfo *root; std::vector cluster_nodes; dict cell_cluster_node_map; dict>> cluster_node_cells; }; struct Arch : ArchAPI { boost::iostreams::mapped_file_source blob_file; const ChipInfoPOD *chip_info; int32_t package_index; // Guard initialization of "by_name" maps if accessed from multiple // threads on a "const Context *". mutable std::mutex by_name_mutex; mutable dict tile_by_name; mutable dict> site_by_name; dict wire_to_net; dict pip_to_net; DedicatedInterconnect dedicated_interconnect; dict tileStatus; PseudoPipData pseudo_pip_data; ArchArgs args; Arch(ArchArgs args); virtual ~Arch(); void init(); std::string getChipName() const final; IdString archId() const final { return id(chip_info->name.get()); } ArchArgs archArgs() const final { return args; } IdString archArgsToId(ArchArgs args) const final; // ------------------------------------------------- uint32_t get_tile_index(int x, int y) const { return (y * chip_info->width + x); } uint32_t get_tile_index(Loc loc) const { return get_tile_index(loc.x, loc.y); } template void get_tile_x_y(TileIndex tile_index, CoordIndex *x, CoordIndex *y) const { *x = tile_index % chip_info->width; *y = tile_index / chip_info->width; } template void get_tile_loc(TileIndex tile_index, Loc *loc) const { get_tile_x_y(tile_index, &loc->x, &loc->y); } int getGridDimX() const final { return chip_info->width; } int getGridDimY() const final { return chip_info->height; } int getTileBelDimZ(int x, int y) const final { return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].bel_data.size(); } int getTilePipDimZ(int x, int y) const final { return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].site_types.size(); } char getNameDelimiter() const final { return '/'; } std::string get_part() const; // ------------------------------------------------- void setup_byname() const; BelId getBelByName(IdStringList name) const final; IdStringList getBelName(BelId bel) const final { NPNR_ASSERT(bel != BelId()); const SiteInstInfoPOD &site = get_site_inst(bel); std::array ids{id(site.name.get()), IdString(bel_info(chip_info, bel).name)}; return IdStringList(ids); } uint32_t getBelChecksum(BelId bel) const final { return bel.index; } void map_cell_pins(CellInfo *cell, int32_t mapping, bool bind_constants); void map_port_pins(BelId bel, CellInfo *cell) const; TileStatus &get_tile_status(int32_t tile) { auto result = tileStatus.emplace(tile, TileStatus()); if (result.second) { auto &tile_type = chip_info->tile_types[chip_info->tiles[tile].type]; result.first->second.boundcells.resize(tile_type.bel_data.size(), nullptr); result.first->second.tags.resize(default_tags.size()); result.first->second.sites.reserve(tile_type.site_types.size()); for (size_t i = 0; i < tile_type.site_types.size(); ++i) { result.first->second.sites.push_back(SiteRouter(i)); } result.first->second.pseudo_pip_model.init(getCtx(), tile); } return result.first->second; } const SiteRouter &get_site_status(const TileStatus &tile_status, const BelInfoPOD &bel_data) const { return tile_status.sites.at(bel_data.site); } SiteRouter &get_site_status(TileStatus &tile_status, const BelInfoPOD &bel_data) { return tile_status.sites.at(bel_data.site); } BelId get_vcc_bel() const { auto &constants = *chip_info->constants; BelId bel; bel.tile = constants.vcc_bel_tile; bel.index = constants.vcc_bel_index; return bel; } BelId get_gnd_bel() const { auto &constants = *chip_info->constants; BelId bel; bel.tile = constants.gnd_bel_tile; bel.index = constants.gnd_bel_index; return bel; } PhysicalNetlist::PhysNetlist::NetType get_net_type(NetInfo *net) const { NPNR_ASSERT(net != nullptr); IdString gnd_cell_name(chip_info->constants->gnd_cell_name); IdString gnd_cell_port(chip_info->constants->gnd_cell_port); IdString vcc_cell_name(chip_info->constants->vcc_cell_name); IdString vcc_cell_port(chip_info->constants->vcc_cell_port); if (net->driver.cell->type == gnd_cell_name && net->driver.port == gnd_cell_port) { return PhysicalNetlist::PhysNetlist::NetType::GND; } else if (net->driver.cell->type == vcc_cell_name && net->driver.port == vcc_cell_port) { return PhysicalNetlist::PhysNetlist::NetType::VCC; } else { return PhysicalNetlist::PhysNetlist::NetType::SIGNAL; } } void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) final { NPNR_ASSERT(bel != BelId()); TileStatus &tile_status = get_tile_status(bel.tile); NPNR_ASSERT(tile_status.boundcells[bel.index] == nullptr); const auto &bel_data = bel_info(chip_info, bel); NPNR_ASSERT(bel_data.category == BEL_CATEGORY_LOGIC); if (io_port_types.count(cell->type) == 0) { int32_t mapping = bel_info(chip_info, bel).pin_map[get_cell_type_index(cell->type)]; if (mapping < 0) { report_invalid_bel(bel, cell); } NPNR_ASSERT(mapping >= 0); if (cell->cell_mapping != mapping) { map_cell_pins(cell, mapping, /*bind_constants=*/false); } constraints.bindBel(tile_status.tags.data(), get_cell_constraints(bel, cell->type)); // Clean previous cell placement in tile if (cell->bel != BelId()) { TileStatus &prev_tile_status = get_tile_status(cell->bel.tile); NPNR_ASSERT(prev_tile_status.boundcells[cell->bel.index] != nullptr); const auto &prev_bel_data = bel_info(chip_info, cell->bel); NPNR_ASSERT(prev_bel_data.category == BEL_CATEGORY_LOGIC); get_site_status(prev_tile_status, prev_bel_data).unbindBel(cell); prev_tile_status.boundcells[cell->bel.index] = nullptr; constraints.unbindBel(prev_tile_status.tags.data(), get_cell_constraints(cell->bel, cell->type)); } } else { map_port_pins(bel, cell); // FIXME: Probably need to actually constraint io port cell/bel, // but the current BBA emission doesn't support that. This only // really matters if the placer can choose IO port locations. } get_site_status(tile_status, bel_data).bindBel(cell); tile_status.boundcells[bel.index] = cell; cell->bel = bel; cell->belStrength = strength; refreshUiBel(bel); } void unbindBel(BelId bel) final { NPNR_ASSERT(bel != BelId()); TileStatus &tile_status = get_tile_status(bel.tile); NPNR_ASSERT(tile_status.boundcells[bel.index] != nullptr); CellInfo *cell = tile_status.boundcells[bel.index]; tile_status.boundcells[bel.index] = nullptr; cell->bel = BelId(); cell->belStrength = STRENGTH_NONE; // FIXME: Probably need to actually constraint io port cell/bel, // but the current BBA emission doesn't support that. This only // really matters if the placer can choose IO port locations. if (io_port_types.count(cell->type) == 0) { constraints.unbindBel(tile_status.tags.data(), get_cell_constraints(bel, cell->type)); } const auto &bel_data = bel_info(chip_info, bel); get_site_status(tile_status, bel_data).unbindBel(cell); refreshUiBel(bel); } bool checkBelAvail(BelId bel) const final { // FIXME: This could consult the constraint system to see if this BEL // is b
#
# Copyright (C) 2006-2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

INPUT_MODULES_MENU:=Input modules

define KernelPackage/hid
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=HID Devices
  DEPENDS:=+kmod-input-core +kmod-input-evdev
  KCONFIG:=CONFIG_HID CONFIG_HIDRAW=y CONFIG_HID_BATTERY_STRENGTH=y
  FILES:=$(LINUX_DIR)/drivers/hid/hid.ko
  AUTOLOAD:=$(call AutoLoad,61,hid)
endef

define KernelPackage/hid/description
 Kernel modules for HID devices
endef

$(eval $(call KernelPackage,hid))

define KernelPackage/hid-generic
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Generic HID device support
  DEPENDS:=+kmod-hid
  KCONFIG:=CONFIG_HID_GENERIC
  FILES:=$(LINUX_DIR)/drivers/hid/hid-generic.ko
  AUTOLOAD:=$(call AutoProbe,hid-generic)
endef

define KernelPackage/hid/description
 Kernel modules for generic HID device (e.g. keyboards and mice) support
endef

$(eval $(call KernelPackage,hid-generic))

define KernelPackage/input-core
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Input device core
  KCONFIG:=CONFIG_INPUT
  FILES:=$(LINUX_DIR)/drivers/input/input-core.ko
endef

define KernelPackage/input-core/description
 Kernel modules for support of input device
endef

$(eval $(call KernelPackage,input-core))


define KernelPackage/input-evdev
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Input event device
  DEPENDS:=+kmod-input-core
  KCONFIG:=CONFIG_INPUT_EVDEV
  FILES:=$(LINUX_DIR)/drivers/input/evdev.ko
  AUTOLOAD:=$(call AutoLoad,60,evdev)
endef

define KernelPackage/input-evdev/description
 Kernel modules for support of input device events
endef

$(eval $(call KernelPackage,input-evdev))


define KernelPackage/input-gpio-keys
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=GPIO key support
  DEPENDS:= @GPIO_SUPPORT +kmod-input-core
  KCONFIG:= \
	CONFIG_KEYBOARD_GPIO \
	CONFIG_INPUT_KEYBOARD=y
  FILES:=$(LINUX_DIR)/drivers/input/keyboard/gpio_keys.ko
  AUTOLOAD:=$(call AutoProbe,gpio_keys,1)
endef

define KernelPackage/input-gpio-keys/description
 This driver implements support for buttons connected
 to GPIO pins of various CPUs (and some other chips).

 See also gpio-button-hotplug which is an alternative, lower overhead
 implementation that generates uevents instead of kernel input events.
endef

$(eval $(call KernelPackage,input-gpio-keys))


define KernelPackage/input-gpio-keys-polled
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Polled GPIO key support
  DEPENDS:=@GPIO_SUPPORT +kmod-input-polldev
  KCONFIG:= \
	CONFIG_KEYBOARD_GPIO_POLLED \
	CONFIG_INPUT_KEYBOARD=y
  FILES:=$(LINUX_DIR)/drivers/input/keyboard/gpio_keys_polled.ko
  AUTOLOAD:=$(call AutoProbe,gpio_keys_polled,1)
endef

define KernelPackage/input-gpio-keys-polled/description
 Kernel module for support polled GPIO keys input device

 See also gpio-button-hotplug which is an alternative, lower overhead
 implementation that generates uevents instead of kernel input events.
endef

$(eval $(call KernelPackage,input-gpio-keys-polled))


define KernelPackage/input-gpio-encoder
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=GPIO rotary encoder
  DEPENDS:=@GPIO_SUPPORT +kmod-input-core
  KCONFIG:=CONFIG_INPUT_GPIO_ROTARY_ENCODER
  FILES:=$(LINUX_DIR)/drivers/input/misc/rotary_encoder.ko
  AUTOLOAD:=$(call AutoProbe,rotary_encoder)
endef

define KernelPackage/input-gpio-encoder/description
 Kernel module to use rotary encoders connected to GPIO pins
endef

$(eval $(call KernelPackage,input-gpio-encoder))


define KernelPackage/input-joydev
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Joystick device support
  DEPENDS:=+kmod-input-core
  KCONFIG:=CONFIG_INPUT_JOYDEV
  FILES:=$(LINUX_DIR)/drivers/input/joydev.ko
  AUTOLOAD:=$(call AutoProbe,joydev)
endef

define KernelPackage/input-joydev/description
 Kernel module for joystick support
endef

$(eval $(call KernelPackage,input-joydev))


define KernelPackage/input-polldev
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Polled Input device support
  DEPENDS:=+kmod-input-core
  KCONFIG:=CONFIG_INPUT_POLLDEV
  FILES:=$(LINUX_DIR)/drivers/input/input-polldev.ko
endef

define KernelPackage/input-polldev/description
 Kernel module for support of polled input devices
endef

$(eval $(call KernelPackage,input-polldev))


define KernelPackage/input-matrixkmap
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=Input matrix devices support
  DEPENDS:=+kmod-input-core
  KCONFIG:=CONFIG_INPUT_MATRIXKMAP
  FILES:=$(LINUX_DIR)/drivers/input/matrix-keymap.ko
  AUTOLOAD:=$(call AutoProbe,matrix-keymap)
endef

define KernelPackage/input-matrixkmap/description
 Kernel module support for input matrix devices
endef

$(eval $(call KernelPackage,input-matrixkmap))


define KernelPackage/input-touchscreen-ads7846
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens
  DEPENDS:=+kmod-hwmon-core +kmod-input-core +kmod-spi-bitbang
  KCONFIG:= \
	CONFIG_INPUT_TOUCHSCREEN=y \
	CONFIG_TOUCHSCREEN_PROPERTIES=y \
	CONFIG_TOUCHSCREEN_ADS7846
  FILES:=$(LINUX_DIR)/drivers/input/touchscreen/ads7846.ko \
	$(LINUX_DIR)/drivers/input/touchscreen/of_touchscreen.ko
  AUTOLOAD:=$(call AutoProbe,ads7846)
endef

define KernelPackage/input-touchscreen-ads7846/description
  Kernel module for ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens
endef

$(eval $(call KernelPackage,input-touchscreen-ads7846))


define KernelPackage/keyboard-imx
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=IMX keypad support
  DEPENDS:=@(TARGET_mxs||TARGET_imx) +kmod-input-matrixkmap
  KCONFIG:= \
	CONFIG_KEYBOARD_IMX \
	CONFIG_INPUT_KEYBOARD=y
  FILES:=$(LINUX_DIR)/drivers/input/keyboard/imx_keypad.ko
  AUTOLOAD:=$(call AutoProbe,imx_keypad)
endef

define KernelPackage/keyboard-imx/description
 Enable support for IMX keypad port.
endef

$(eval $(call KernelPackage,keyboard-imx))


define KernelPackage/input-uinput
  SUBMENU:=$(INPUT_MODULES_MENU)
  TITLE:=user input module
  DEPENDS:=+kmod-input-core
  KCONFIG:= \
	CONFIG_INPUT_MISC=y \
	CONFIG_INPUT_UINPUT
  FILES:=$(LINUX_DIR)/drivers/input/misc/uinput.ko
  AUTOLOAD:=$(call AutoProbe,uinput)
endef

define KernelPackage/input-uinput/description
  user input modules needed for bluez
endef

$(eval $(call KernelPackage,input-uinput))
el) const { return IdString(loc_info(chip_info, bel).name); } dict sink_locs, source_locs; // ------------------------------------------------- void assignArchInfo() final {} // ------------------------------------------------- static const std::string defaultPlacer; static const std::vector availablePlacers; static const std::string defaultRouter; static const std::vector availableRouters; // ------------------------------------------------- void read_logical_netlist(const std::string &filename); void write_physical_netlist(const std::string &filename) const; void parse_xdc(const std::string &filename); pool io_port_types; pool pads; bool is_site_port(PipId pip) const { const PipInfoPOD &pip_data = pip_info(chip_info, pip); if (pip_data.site == -1) { return false; } BelId bel; bel.tile = pip.tile; bel.index = pip_data.bel; const BelInfoPOD &bel_data = bel_info(chip_info, bel); return bel_data.category == BEL_CATEGORY_SITE_PORT; } // Is the driver and all users of this net located within the same site? // // Returns false if any element of the net is not placed. bool is_net_within_site(const NetInfo &net) const; using ArchConstraints = Constraints; ArchConstraints constraints; std::vector default_tags; bool explain_constraints; struct StateRange { const int32_t *b; const int32_t *e; const int32_t *begin() const { return b; } const int32_t *end() const { return e; } }; struct Constraint : ArchConstraints::Constraint { const CellConstraintPOD *constraint; Constraint(const CellConstraintPOD *constraint) : constraint(constraint) {} size_t tag() const final { return constraint->tag; } ArchConstraints::ConstraintType constraint_type() const final { return Constraints::ConstraintType(constraint->constraint_type); } ArchConstraints::ConstraintStateType state() const final { NPNR_ASSERT(constraint_type() == Constraints::CONSTRAINT_TAG_IMPLIES); NPNR_ASSERT(constraint->states.size() == 1); return constraint->states[0]; } StateRange states() const final { StateRange range; range.b = constraint->states.get(); range.e = range.b + constraint->states.size(); return range; } }; struct ConstraintIterator { const CellConstraintPOD *constraint; ConstraintIterator() {} ConstraintIterator operator++() { ++constraint; return *this; } bool operator!=(const ConstraintIterator &other) const { return constraint != other.constraint; } bool operator==(const ConstraintIterator &other) const { return constraint == other.constraint; } Constraint operator*() const { return Constraint(constraint); } }; struct ConstraintRange { ConstraintIterator b, e; ConstraintIterator begin() const { return b; } ConstraintIterator end() const { return e; } }; uint32_t get_constraint_prototype(BelId bel) const { return chip_info->tiles[bel.tile].type; } ConstraintRange get_cell_constraints(BelId bel, IdString cell_type) const { const auto &bel_data = bel_info(chip_info, bel); NPNR_ASSERT(bel_data.category == BEL_CATEGORY_LOGIC); int32_t mapping = bel_data.pin_map[get_cell_type_index(cell_type)]; NPNR_ASSERT(mapping >= 0); auto &cell_bel_map = chip_info->cell_map->cell_bel_map[mapping]; ConstraintRange range; range.b.constraint = cell_bel_map.constraints.get(); range.e.constraint = range.b.constraint + cell_bel_map.constraints.size(); return range; } const char *get_site_name(int32_t tile, size_t site) const { return site_inst_info(chip_info, tile, site).name.get(); } const char *get_site_name(BelId bel) const { auto &bel_data = bel_info(chip_info, bel); return get_site_name(bel.tile, bel_data.site); } const SiteInstInfoPOD &get_site_inst(BelId bel) const { auto &bel_data = bel_info(chip_info, bel); return site_inst_info(chip_info, bel.tile, bel_data.site); } const SiteInstInfoPOD &get_site_inst(WireId wire) const { auto &wire_data = wire_info(wire); NPNR_ASSERT(wire_data.site != -1); return site_inst_info(chip_info, wire.tile, wire_data.site); } const SiteInstInfoPOD &get_site_inst(PipId pip) const { auto &pip_data = pip_info(chip_info, pip); return site_inst_info(chip_info, pip.tile, pip_data.site); } // Is this bel synthetic (e.g. added during import process)? // // This is generally used for constant networks, but can also be used for // static partitions. bool is_bel_synthetic(BelId bel) const { const BelInfoPOD &bel_data = bel_info(chip_info, bel); return bel_data.synthetic != 0; } // Is this pip synthetic (e.g. added during import process)? // // This is generally used for constant networks, but can also be used for // static partitions. bool is_pip_synthetic(PipId pip) const { auto &pip_data = pip_info(chip_info, pip); if (pip_data.site == -1) { return pip_data.extra_data == -1; } else { BelId bel; bel.tile = pip.tile; bel.index = pip_data.bel; return is_bel_synthetic(bel); } } bool is_same_site(WireId wire_a, WireId wire_b) const { if (wire_a.tile == -1) { return false; } if (wire_a.tile != wire_b.tile) { return false; } auto &wire_a_data = wire_info(wire_a); auto &wire_b_data = wire_info(wire_b); return wire_a_data.site == wire_b_data.site && wire_a_data.site != -1; } bool is_wire_in_site(WireId wire) const { if (wire.tile == -1) { return false; } auto &wire_data = wire_info(wire); return wire_data.site != -1; } // Does this pip always invert its signal? bool is_inverting(PipId pip) const; // Can this pip optional invert its signal? bool can_invert(PipId pip) const; void merge_constant_nets(); void report_invalid_bel(BelId bel, CellInfo *cell) const; std::vector no_pins; IdString gnd_cell_pin; IdString vcc_cell_pin; std::vector> lut_elements; dict lut_cells; // Defines the max number of LUT cells in a site and LUT pins // to allow a correct functioning of the site lut mapping cache int max_lut_cells; int max_lut_pins; // Of the LUT cells, which is used for wires? // Note: May be null in arch's without wire LUT types. Assumption is // that these arch's don't need wire LUT's because the LUT share is simple // enough to avoid it. const LutCellPOD *wire_lut; std::regex raw_bin_constant; std::regex verilog_bin_constant; std::regex verilog_hex_constant; void read_lut_equation(DynamicBitarray<> *equation, const Property &equation_parameter) const; IdString id_GND; IdString id_VCC; Lookahead lookahead; mutable RouteNodeStorage node_storage; mutable SiteRoutingCache site_routing_cache; mutable SiteLutMappingCache site_lut_mapping_cache; bool disallow_site_routing; CellParameters cell_parameters; std::string chipdb_hash; std::string get_chipdb_hash() const; // Masking moves BEL pins from cell_bel_pins to masked_cell_bel_pins for // the purposes routing. The idea is that masked BEL pins are already // handled during site routing, and they shouldn't be visible to the // router. void mask_bel_pins_on_site_wire(NetInfo *net, WireId wire); // This removes pips and wires bound by the site router, and unmasks all // BEL pins masked during site routing. void remove_site_routing(); // This unmasks any BEL pins that were masked when site routing was bound. void unmask_bel_pins(); void explain_bel_status(BelId bel) const; const DefaultCellConnsPOD *get_default_conns(IdString cell_type) const; void pack_default_conns(); dict> macro_to_cells; void expand_macros(); }; NEXTPNR_NAMESPACE_END #endif /* FPGA_INTERCHANGE_ARCH_H */