/* * 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 CHIPDB_H #define CHIPDB_H #include "archdefs.h" #include "nextpnr_namespaces.h" #include "relptr.h" NEXTPNR_NAMESPACE_BEGIN /* !!! Everything in this section must be kept in sync !!! * !!! with fpga_interchange/chip_info.py !!! * * When schema changes, bump version number in chip_info.py and * kExpectedChipInfoVersion */ static constexpr int32_t kExpectedChipInfoVersion = 15; NPNR_PACKED_STRUCT(struct BelConnectedPinsPOD { int32_t pin1; int32_t pin2; }); // Flattened site indexing. // // To enable flat BelId.z spaces, every tile and sites within that tile are // flattened. // // This has implications on BelId's, WireId's and PipId's. // The flattened site space works as follows: // - Objects that belong to the tile are first. BELs are always part of Sites, // so no BEL objects are in this category. // - All site alternative modes are exposed as a "full" site. // - Each site appends it's BEL's, wires (site wires) and PIP's. // - Sites add two types of pips. Sites will add pip data first for site // pips, and then for site pin edges. // 1. The first type is site pips, which connect site wires to other site // wires. // 2. The second type is site pin edges, which connect site wires to tile // wires (or vise-versa). NPNR_PACKED_STRUCT(struct BelInfoPOD { int32_t name; // bel name (in site) constid int32_t type; // Type name constid int32_t bel_bucket; // BEL bucket constid. int32_t num_bel_wires; RelPtr ports; // port name constid RelPtr types; // port type (IN/OUT/BIDIR) RelPtr wires; // connected wire index in tile, or -1 if NA int16_t site; int16_t site_variant; // some sites have alternative types int16_t category; int8_t synthetic; int8_t lut_element; RelPtr pin_map; // Index into CellMapPOD::cell_bel_map // If this BEL is a site routing BEL with inverting pins, these values // will be [0, num_bel_wires). If this BEL is either not a site routing // BEL or this site routing has no inversion capabilities, then these will // both be -1. int8_t non_inverting_pin; int8_t inverting_pin; int16_t padding; RelSlice connected_pins; }); enum BELCategory { // BEL is a logic element BEL_CATEGORY_LOGIC = 0, // BEL is a site routing mux BEL_CATEGORY_ROUTING = 1, // BEL is a site port, e.g. boundry between site and routing graph. BEL_CATEGORY_SITE_PORT = 2 }; NPNR_PACKED_STRUCT(struct BelPortPOD { int32_t bel_index; int32_t port; }); NPNR_PACKED_STRUCT(struct TileWireInfoPOD { int32_t name; // wire name constid // Pip index inside tile RelSlice pips_uphill; // Pip index inside tile RelSlice pips_downhill; // Bel index inside tile RelSlice bel_pins; int16_t site; // site index in tile int16_t site_variant; // site variant index in tile }); NPNR_PACKED_STRUCT(struct PipInfoPOD { int32_t src_index, dst_index; int16_t site; // site index in tile int16_t site_variant; // site variant index in tile int16_t bel; // BEL this pip belongs to if site pip. int16_t extra_data; RelSlice pseudo_cell_wires; }); NPNR_PACKED_STRUCT(struct ConstraintTagPOD { int32_t tag_prefix; // constid int32_t default_state; // constid RelSlice states; // constid }); NPNR_PACKED_STRUCT(struct LutBelPOD { uint32_t name; // constid RelSlice pins; // constid uint32_t low_bit; uint32_t high_bit; int32_t out_pin; // constid }); NPNR_PACKED_STRUCT(struct LutElementPOD { int32_t width; RelSlice lut_bels; }); NPNR_PACKED_STRUCT(struct TileTypeInfoPOD { int32_t name; // Tile type constid RelSlice bel_data; RelSlice wire_data; RelSlice pip_data; RelSlice tags; RelSlice lut_elements; RelSlice site_types; // constid }); NPNR_PACKED_STRUCT(struct SiteInstInfoPOD { RelPtr name; RelPtr site_name; // Which site type is this site instance? // constid int32_t site_type; }); NPNR_PACKED_STRUCT(struct TileInstInfoPOD { // Name of this tile. RelPtr name; // Index into root.tile_types. int32_t type; // This array is root.tile_types[type].site_types.size() long. // Index into root.sites RelSlice sites; // Number of tile wires; excluding any site-internal wires // which come after general wires and are not stored here // as they will never be nodal // -1 if a tile-local wire; node index if nodal wire RelSlice tile_wire_to_node; // Index into wire_types RelSlice tile_wire_to_type; }); NPNR_PACKED_STRUCT(struct TileWireRefPOD { int32_t tile; int32_t index; }); NPNR_PACKED_STRUCT(struct NodeInfoPOD { RelSlice tile_wires; }); NPNR_PACKED_STRUCT(struct CellBelPinPOD { int32_t cell_pin; // constid int32_t bel_pin; // constid }); NPNR_PACKED_STRUCT(struct ParameterPinsPOD { int32_t key; // constid int32_t value; // constid RelSlice pins; }); NPNR_PACKED_STRUCT(struct CellConstraintPOD { int32_t tag; // Tag index int32_t constraint_type; // Constraint::ConstraintType RelSlice states; // State indicies }); // Cell parameters metadata NPNR_PACKED_STRUCT(struct CellParameterPOD { int32_t cell_type; // constid int32_t parameter; // constid int32_t format; // ParameterFormat enum int32_t default_value; // constid }); NPNR_PACKED_STRUCT(struct CellBelMapPOD { RelSlice common_pins; RelSlice parameter_pins; RelSlice constraints; }); NPNR_PACKED_STRUCT(struct LutCellPOD { int32_t cell; // constid RelSlice input_pins; // constids int32_t parameter; }); NPNR_PACKED_STRUCT(struct CellMapPOD { // Cell names supported in this arch. RelSlice cell_names; // constids // BEL names that are global buffers. RelSlice global_buffers; // constids // Name of BelBuckets. RelSlice cell_bel_buckets; // constids RelSlice cell_bel_map; RelSlice lut_cells; RelSlice cell_parameters; }); NPNR_PACKED_STRUCT(struct PackagePinPOD { int32_t package_pin; // constid int32_t site; // constid int32_t bel; // constid }); NPNR_PACKED_STRUCT(struct PackagePOD { int32_t package; // constid RelSlice pins; }); enum CellPinValue { // leave floating PIN_VALUE_FLOAT = 0, // connect to ground PIN_VALUE_GND = 1, // connect to vcc PIN_VALUE_VCC = 2, }; NPNR_PACKED_STRUCT(struct DefaultCellConnPOD { int32_t pin_name; // constid int32_t value; // CellPinValue }); NPNR_PACKED_STRUCT(struct DefaultCellConnsPOD { int32_t cell_type; // constid RelSlice pins; }); NPNR_PACKED_STRUCT(struct ConstantsPOD { // Cell type and port for the GND and VCC global source. int32_t gnd_cell_name; // constid int32_t gnd_cell_port; // constid int32_t vcc_cell_name; // constid int32_t vcc_cell_port; // constid int32_t gnd_bel_tile; int32_t gnd_bel_index; int32_t gnd_bel_pin; // constid int32_t vcc_bel_tile; int32_t vcc_bel_index; int32_t vcc_bel_pin; // constid // Name to use for the global GND constant net int32_t gnd_net_name; // constid // Name to use for the global VCC constant net int32_t vcc_net_name; // constid // If a choice is available, which constant net should be used? // Can be ''/0 if either constant net are equivilent. int32_t best_constant_net; // constid // Default cell pin connections RelSlice default_conns; }); enum WireCategory { WIRE_CAT_GENERAL = 0, WIRE_CAT_SPECIAL = 1, WIRE_CAT_GLOBAL = 2, }; NPNR_PACKED_STRUCT(struct WireTypePOD { int32_t name; // constid int32_t category; // WireCategory }); NPNR_PACKED_STRUCT(struct GlobalCellPinPOD { int32_t name; // constid int16_t max_hops; // max routing hops to try int8_t guide_placement; int8_t force_routing; }); NPNR_PACKED_STRUCT(struct GlobalCellPOD { int32_t cell_type; RelSlice pins; }); NPNR_PACKED_STRUCT(struct MacroParameterPOD { int32_t key; // constid int32_t value; // constid }); enum MacroParamRuleType { PARAM_MAP_COPY = 0, // copy parameter value PARAM_MAP_SLICE = 1, // take a slice of bits PARAM_MAP_TABLE = 2, // lookup strings in table }; NPNR_PACKED_STRUCT(struct MacroParamMapRulePOD { // name of parameter on parent primitive int32_t prim_param; // constid // name of instance to set parameter on int32_t inst_name; // constid // name of parameter on macro expansion instance int32_t inst_param; // constid // type of mapping to use to derive new value int32_t rule_type; // MacroParamRuleType // for slice mappings, the bits to collect RelSlice slice_bits; // for table mappings, the lookup table to use RelSlice map_table; }); NPNR_PACKED_STRUCT(struct MacroCellInstPOD { int32_t name; // instance name constid int32_t type; // instance type constid // parameters to set on cell RelSlice parameters; }); NPNR_PACKED_STRUCT(struct MacroPortInstPOD { // name of the cell instance the port is on; or 0/'' for top level ports int32_t instance; // name of the port int32_t port; // direction of the port int32_t dir; }); NPNR_PACKED_STRUCT(struct MacroNetPOD { // name of the net int32_t name; // ports on the net RelSlice ports; }); NPNR_PACKED_STRUCT(struct MacroPOD { // macro name int32_t name; // cell instances inside macro RelSlice cell_insts; // nets inside macro RelSlice nets; }); NPNR_PACKED_STRUCT(struct MacroExpansionPOD { // primitive name to match int32_t prim_name; // macro name to expand to int32_t macro_name; // list of parameters to (optionally) match RelSlice param_matches; // how to derive parameters for expansion instances RelSlice param_rules; }); NPNR_PACKED_STRUCT(struct ClusterCellPortPOD { uint32_t cell; uint32_t port; }); NPNR_PACKED_STRUCT(struct ChainablePortPOD { uint32_t cell_source; uint32_t cell_sink; uint32_t bel_source; uint32_t bel_sink; int16_t avg_x_offset; int16_t avg_y_offset; }); NPNR_PACKED_STRUCT(struct ClusterRequiredCellPOD { uint32_t name; uint32_t count; }); NPNR_PACKED_STRUCT(struct ClusterUsedPortPOD { uint32_t name; }); NPNR_PACKED_STRUCT(struct ClusterEdgePOD { uint32_t dir; uint32_t cell_pin; uint32_t other_cell_pin; uint32_t other_cell_type; }); NPNR_PACKED_STRUCT(struct ClusterConnectionsPOD { uint32_t target_idx; RelSlice edges; }); NPNR_PACKED_STRUCT(struct ClusterConnectionGraphPOD { uint32_t idx; uint32_t cell_type; RelSlice connections; RelSlice used_ports; }); NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementEntryPOD { RelSlice bels; }); NPNR_PACKED_STRUCT(struct ClusterPhysicalPlacementsPOD { uint32_t site_type; RelSlice places; }); NPNR_PACKED_STRUCT(struct ClusterPOD { uint32_t name; RelSlice root_cell_types; RelSlice chainable_ports; RelSlice cluster_cells_map; RelSlice required_cells; RelSlice connection_graph; RelSlice physical_placements; uint32_t out_of_site_clusters; uint32_t disallow_other_cells; uint32_t from_macro; }); NPNR_PACKED_STRUCT(struct ChipInfoPOD { RelPtr name; RelPtr generator; int32_t version; int32_t width, height; RelSlice tile_types; RelSlice sites; RelSlice tiles; RelSlice nodes; RelSlice packages; RelSlice wire_types; RelSlice global_cells; // Macro related data RelSlice macros; RelSlice macro_rules; RelSlice clusters; // BEL bucket constids. RelSlice bel_buckets; RelPtr cell_map; RelPtr constants; // Constid string data. RelPtr>> constids; }); /************************ End of chipdb section. ************************/ inline const TileTypeInfoPOD &tile_info(const ChipInfoPOD *chip_info, int32_t tile) { return chip_info->tile_types[chip_info->tiles[tile].type]; } template const TileTypeInfoPOD &loc_info(const ChipInfoPOD *chip_info, Id &id) { return chip_info->tile_types[chip_info->tiles[id.tile].type]; } NPNR_ALWAYS_INLINE inline const BelInfoPOD &bel_info(const ChipInfoPOD *chip_info, BelId bel) { NPNR_ASSERT(bel != BelId()); return loc_info(chip_info, bel).bel_data[bel.index]; } inline const PipInfoPOD &pip_info(const ChipInfoPOD *chip_info, PipId pip) { NPNR_ASSERT(pip != PipId()); return loc_info(chip_info, pip).pip_data[pip.index]; } inline const SiteInstInfoPOD &site_inst_info(const ChipInfoPOD *chip_info, int32_t tile, int32_t site) { return chip_info->sites[chip_info->tiles[tile].sites[site]]; } inline const ClusterPOD &cluster_info(const ChipInfoPOD *chip_info, int32_t cluster) { return chip_info->clusters[cluster]; } enum SyntheticType { NOT_SYNTH = 0, SYNTH_SIGNAL = 1, SYNTH_GND = 2, SYNTH_VCC = 3, }; NEXTPNR_NAMESPACE_END #endif /* CHIPDB_H */