aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/arch.h
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-02-17 10:16:45 +0000
committerGitHub <noreply@github.com>2021-02-17 10:16:45 +0000
commitda1ecf0813cb07a65bc1ca498d0f9c896cc3a675 (patch)
tree5b9625b3852b79acb73ae55cd39078b18ab29019 /fpga_interchange/arch.h
parenta77ceec5cf5603542d87724d9fdc51d48fa29327 (diff)
parent26a187e5ebcd1bdb6e079a91e25b610dc603aab2 (diff)
downloadnextpnr-da1ecf0813cb07a65bc1ca498d0f9c896cc3a675.tar.gz
nextpnr-da1ecf0813cb07a65bc1ca498d0f9c896cc3a675.tar.bz2
nextpnr-da1ecf0813cb07a65bc1ca498d0f9c896cc3a675.zip
Merge pull request #586 from litghost/add_cell_bel_mapping_only
Add Cell -> BEL Pin maps to FPGA interchange arch.
Diffstat (limited to 'fpga_interchange/arch.h')
-rw-r--r--fpga_interchange/arch.h111
1 files changed, 105 insertions, 6 deletions
diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h
index 80eada4e..638855cd 100644
--- a/fpga_interchange/arch.h
+++ b/fpga_interchange/arch.h
@@ -67,7 +67,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
int16_t category;
int16_t padding;
- RelPtr<int8_t> valid_cells; // Bool array, length of number_cells.
+ RelPtr<int32_t> pin_map; // Index into CellMapPOD::cell_bel_map
});
enum BELCategory
@@ -109,6 +109,12 @@ NPNR_PACKED_STRUCT(struct PipInfoPOD {
int16_t extra_data;
});
+NPNR_PACKED_STRUCT(struct ConstraintTagPOD {
+ int32_t tag_prefix; // constid
+ int32_t default_state; // constid
+ RelSlice<int32_t> states; // constid
+});
+
NPNR_PACKED_STRUCT(struct TileTypeInfoPOD {
int32_t name; // Tile type constid
@@ -119,10 +125,13 @@ NPNR_PACKED_STRUCT(struct TileTypeInfoPOD {
RelSlice<TileWireInfoPOD> wire_data;
RelSlice<PipInfoPOD> pip_data;
+
+ RelSlice<ConstraintTagPOD> tags;
});
NPNR_PACKED_STRUCT(struct SiteInstInfoPOD {
RelPtr<char> name;
+ RelPtr<char> site_name;
// Which site type is this site instance?
// constid
@@ -138,7 +147,7 @@ NPNR_PACKED_STRUCT(struct TileInstInfoPOD {
// This array is root.tile_types[type].number_sites long.
// Index into root.sites
- RelPtr<int32_t> sites;
+ RelSlice<int32_t> sites;
// Number of tile wires; excluding any site-internal wires
// which come after general wires and are not stored here
@@ -154,10 +163,46 @@ NPNR_PACKED_STRUCT(struct TileWireRefPOD {
NPNR_PACKED_STRUCT(struct NodeInfoPOD { RelSlice<TileWireRefPOD> 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<CellBelPinPOD> pins;
+});
+
+NPNR_PACKED_STRUCT(struct CellConstraintPOD {
+ int32_t tag; // Tag index
+ int32_t constraint_type; // Constraint::ConstraintType
+ RelSlice<int32_t> states; // State indicies
+});
+
+NPNR_PACKED_STRUCT(struct CellBelMapPOD {
+ RelSlice<CellBelPinPOD> common_pins;
+ RelSlice<ParameterPinsPOD> parameter_pins;
+ RelSlice<CellConstraintPOD> constraints;
+});
+
NPNR_PACKED_STRUCT(struct CellMapPOD {
// Cell names supported in this arch.
RelSlice<int32_t> cell_names; // constids
RelSlice<int32_t> cell_bel_buckets; // constids
+
+ RelSlice<CellBelMapPOD> cell_bel_map;
+});
+
+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<PackagePinPOD> pins;
});
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
@@ -171,6 +216,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelSlice<SiteInstInfoPOD> sites;
RelSlice<TileInstInfoPOD> tiles;
RelSlice<NodeInfoPOD> nodes;
+ RelSlice<PackagePOD> packages;
// BEL bucket constids.
RelSlice<int32_t> bel_buckets;
@@ -667,7 +713,7 @@ struct ArchRanges
using TileBelsRangeT = BelRange;
using BelAttrsRangeT = std::vector<std::pair<IdString, std::string>>;
using BelPinsRangeT = IdStringRange;
- using CellBelPinRangeT = std::array<IdString, 1>;
+ using CellBelPinRangeT = const std::vector<IdString> &;
// Wires
using AllWiresRangeT = WireRange;
using DownhillPipRangeT = DownhillPipRange;
@@ -695,6 +741,7 @@ struct Arch : ArchAPI<ArchRanges>
{
boost::iostreams::mapped_file_source blob_file;
const ChipInfoPOD *chip_info;
+ int32_t package_index;
mutable std::unordered_map<IdString, int> tile_by_name;
mutable std::unordered_map<IdString, std::pair<int, int>> site_by_name;
@@ -768,12 +815,29 @@ struct Arch : ArchAPI<ArchRanges>
uint32_t getBelChecksum(BelId bel) const override { return bel.index; }
+ void map_cell_pins(CellInfo *cell, int32_t mapping) const;
+ void map_port_pins(BelId bel, CellInfo *cell) const;
+
void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override
{
NPNR_ASSERT(bel != BelId());
NPNR_ASSERT(tileStatus[bel.tile].boundcells[bel.index] == nullptr);
tileStatus[bel.tile].boundcells[bel.index] = cell;
+
+ 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)];
+ NPNR_ASSERT(mapping >= 0);
+
+ if (cell->cell_mapping != mapping) {
+ map_cell_pins(cell, mapping);
+ }
+ } else {
+ map_port_pins(bel, cell);
+ }
cell->bel = bel;
cell->belStrength = strength;
refreshUiBel(bel);
@@ -870,12 +934,15 @@ struct Arch : ArchAPI<ArchRanges>
IdStringRange str_range;
str_range.b.cursor = &ports[0];
- str_range.e.cursor = &ports[num_bel_wires - 1];
+ str_range.e.cursor = &ports[num_bel_wires];
return str_range;
}
- std::array<IdString, 1> getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override { return {pin}; }
+ const std::vector<IdString> &getBelPinsForCellPin(CellInfo *cell_info, IdString pin) const override
+ {
+ return cell_info->cell_bel_pins.at(pin);
+ }
// -------------------------------------------------
@@ -1260,6 +1327,12 @@ struct Arch : ArchAPI<ArchRanges>
BelBucketId getBelBucketForCellType(IdString cell_type) const override
{
+ if (io_port_types.count(cell_type)) {
+ BelBucketId bucket;
+ bucket.name = id("IOPORTS");
+ return bucket;
+ }
+
BelBucketId bucket;
const CellMapPOD &cell_map = *chip_info->cell_map;
bucket.name = IdString(cell_map.cell_bel_buckets[get_cell_type_index(cell_type)]);
@@ -1277,7 +1350,11 @@ struct Arch : ArchAPI<ArchRanges>
bool isValidBelForCellType(IdString cell_type, BelId bel) const override
{
- return bel_info(chip_info, bel).valid_cells[get_cell_type_index(cell_type)];
+ if (io_port_types.count(cell_type)) {
+ return pads.count(bel) > 0;
+ } else {
+ return bel_info(chip_info, bel).pin_map[get_cell_type_index(cell_type)] > 0;
+ }
}
// Return true whether all Bels at a given location are valid
@@ -1307,6 +1384,28 @@ struct Arch : ArchAPI<ArchRanges>
void parse_xdc(const std::string &filename);
std::unordered_set<IdString> io_port_types;
+ std::unordered_set<BelId> 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;
};
NEXTPNR_NAMESPACE_END