Merge branch 'gridapi' into 'master'
Gridapi See merge request SymbioticEDA/nextpnr!11
This commit is contained in:
commit
0d6f6f410d
@ -27,6 +27,8 @@
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
#ifndef NEXTPNR_H
|
#ifndef NEXTPNR_H
|
||||||
#define NEXTPNR_H
|
#define NEXTPNR_H
|
||||||
|
|
||||||
@ -158,8 +160,30 @@ struct GraphicElement
|
|||||||
std::string text;
|
std::string text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Loc
|
||||||
|
{
|
||||||
|
int x = -1, y = -1, z = -1;
|
||||||
|
|
||||||
|
bool operator==(const Loc &other) const { return (x == other.x) && (y == other.y) && (z == other.z); }
|
||||||
|
bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z == other.z); }
|
||||||
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX Loc>
|
||||||
|
{
|
||||||
|
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Loc &obj) const noexcept
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, hash<int>()(obj.x));
|
||||||
|
boost::hash_combine(seed, hash<int>()(obj.y));
|
||||||
|
boost::hash_combine(seed, hash<int>()(obj.z));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
#include "archdefs.h"
|
#include "archdefs.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
@ -29,8 +29,8 @@ void Arch::addWire(IdString name, int x, int y)
|
|||||||
NPNR_ASSERT(wires.count(name) == 0);
|
NPNR_ASSERT(wires.count(name) == 0);
|
||||||
WireInfo &wi = wires[name];
|
WireInfo &wi = wires[name];
|
||||||
wi.name = name;
|
wi.name = name;
|
||||||
wi.grid_x = x;
|
wi.x = x;
|
||||||
wi.grid_y = y;
|
wi.y = y;
|
||||||
|
|
||||||
wire_ids.push_back(name);
|
wire_ids.push_back(name);
|
||||||
}
|
}
|
||||||
@ -62,18 +62,28 @@ void Arch::addAlias(IdString name, IdString srcWire, IdString dstWire, DelayInfo
|
|||||||
pip_ids.push_back(name);
|
pip_ids.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arch::addBel(IdString name, IdString type, int x, int y, bool gb)
|
void Arch::addBel(IdString name, IdString type, int x, int y, int z, bool gb)
|
||||||
{
|
{
|
||||||
|
Loc loc;
|
||||||
|
loc.x = x;
|
||||||
|
loc.y = y;
|
||||||
|
loc.z = z;
|
||||||
|
|
||||||
NPNR_ASSERT(bels.count(name) == 0);
|
NPNR_ASSERT(bels.count(name) == 0);
|
||||||
|
NPNR_ASSERT(bel_by_loc.count(loc) == 0);
|
||||||
BelInfo &bi = bels[name];
|
BelInfo &bi = bels[name];
|
||||||
bi.name = name;
|
bi.name = name;
|
||||||
bi.type = type;
|
bi.type = type;
|
||||||
bi.grid_x = x;
|
bi.x = x;
|
||||||
bi.grid_y = y;
|
bi.y = y;
|
||||||
|
bi.z = z;
|
||||||
bi.gb = gb;
|
bi.gb = gb;
|
||||||
|
|
||||||
bel_ids.push_back(name);
|
bel_ids.push_back(name);
|
||||||
bel_ids_by_type[type].push_back(name);
|
bel_ids_by_type[type].push_back(name);
|
||||||
|
|
||||||
|
bel_by_loc[loc] = name;
|
||||||
|
bels_by_tile[x][y].push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arch::addBelInput(IdString bel, IdString name, IdString wire)
|
void Arch::addBelInput(IdString bel, IdString name, IdString wire)
|
||||||
@ -348,8 +358,8 @@ const std::vector<GroupId> &Arch::getGroupGroups(GroupId group) const { return g
|
|||||||
|
|
||||||
void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
|
void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
|
||||||
{
|
{
|
||||||
x = bels.at(bel).grid_x;
|
x = bels.at(bel).x;
|
||||||
y = bels.at(bel).grid_y;
|
y = bels.at(bel).y;
|
||||||
gb = bels.at(bel).gb;
|
gb = bels.at(bel).gb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,8 +367,8 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
|||||||
{
|
{
|
||||||
const WireInfo &s = wires.at(src);
|
const WireInfo &s = wires.at(src);
|
||||||
const WireInfo &d = wires.at(dst);
|
const WireInfo &d = wires.at(dst);
|
||||||
int dx = abs(s.grid_x - d.grid_x);
|
int dx = abs(s.x - d.x);
|
||||||
int dy = abs(s.grid_y - d.grid_y);
|
int dy = abs(s.y - d.y);
|
||||||
return (dx + dy) * grid_distance_to_delay;
|
return (dx + dy) * grid_distance_to_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ struct WireInfo
|
|||||||
BelPin uphill_bel_pin;
|
BelPin uphill_bel_pin;
|
||||||
std::vector<BelPin> downhill_bel_pins;
|
std::vector<BelPin> downhill_bel_pins;
|
||||||
DecalXY decalxy;
|
DecalXY decalxy;
|
||||||
int grid_x, grid_y;
|
int x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PinInfo
|
struct PinInfo
|
||||||
@ -59,7 +59,7 @@ struct BelInfo
|
|||||||
IdString name, type, bound_cell;
|
IdString name, type, bound_cell;
|
||||||
std::unordered_map<IdString, PinInfo> pins;
|
std::unordered_map<IdString, PinInfo> pins;
|
||||||
DecalXY decalxy;
|
DecalXY decalxy;
|
||||||
int grid_x, grid_y;
|
int x, y, z;
|
||||||
bool gb;
|
bool gb;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,6 +85,9 @@ struct Arch : BaseCtx
|
|||||||
std::vector<IdString> bel_ids, wire_ids, pip_ids;
|
std::vector<IdString> bel_ids, wire_ids, pip_ids;
|
||||||
std::unordered_map<IdString, std::vector<IdString>> bel_ids_by_type;
|
std::unordered_map<IdString, std::vector<IdString>> bel_ids_by_type;
|
||||||
|
|
||||||
|
std::unordered_map<Loc, BelId> bel_by_loc;
|
||||||
|
std::unordered_map<int, std::unordered_map<int, std::vector<BelId>>> bels_by_tile;
|
||||||
|
|
||||||
std::unordered_map<DecalId, std::vector<GraphicElement>> decal_graphics;
|
std::unordered_map<DecalId, std::vector<GraphicElement>> decal_graphics;
|
||||||
DecalXY frame_decalxy;
|
DecalXY frame_decalxy;
|
||||||
|
|
||||||
@ -94,7 +97,7 @@ struct Arch : BaseCtx
|
|||||||
void addPip(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay);
|
void addPip(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay);
|
||||||
void addAlias(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay);
|
void addAlias(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay);
|
||||||
|
|
||||||
void addBel(IdString name, IdString type, int x, int y, bool gb);
|
void addBel(IdString name, IdString type, int x, int y, int z, bool gb);
|
||||||
void addBelInput(IdString bel, IdString name, IdString wire);
|
void addBelInput(IdString bel, IdString name, IdString wire);
|
||||||
void addBelOutput(IdString bel, IdString name, IdString wire);
|
void addBelOutput(IdString bel, IdString name, IdString wire);
|
||||||
void addBelInout(IdString bel, IdString name, IdString wire);
|
void addBelInout(IdString bel, IdString name, IdString wire);
|
||||||
@ -129,6 +132,10 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
BelId getBelByName(IdString name) const;
|
BelId getBelByName(IdString name) const;
|
||||||
IdString getBelName(BelId bel) const;
|
IdString getBelName(BelId bel) const;
|
||||||
|
Loc getBelLocation(BelId bel) const;
|
||||||
|
BelId getBelByLocation(Loc loc) const;
|
||||||
|
std::vector<BelId> getBelsByTile(int x, int y) const;
|
||||||
|
bool getBelGlobalBuf(BelId bel) const;
|
||||||
uint32_t getBelChecksum(BelId bel) const;
|
uint32_t getBelChecksum(BelId bel) const;
|
||||||
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
|
void bindBel(BelId bel, IdString cell, PlaceStrength strength);
|
||||||
void unbindBel(BelId bel);
|
void unbindBel(BelId bel);
|
||||||
|
@ -255,11 +255,52 @@ BelId Arch::getBelByName(IdString name) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BelId Arch::getBelByLocation(Loc loc) const
|
||||||
|
{
|
||||||
|
BelId bel;
|
||||||
|
|
||||||
|
if (bel_by_loc.empty()) {
|
||||||
|
for (int i = 0; i < chip_info->num_bels; i++) {
|
||||||
|
BelId b;
|
||||||
|
b.index = i;
|
||||||
|
bel_by_loc[getBelLocation(b)] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = bel_by_loc.find(loc);
|
||||||
|
if (it != bel_by_loc.end())
|
||||||
|
bel.index = it->second;
|
||||||
|
|
||||||
|
return bel;
|
||||||
|
}
|
||||||
|
|
||||||
|
BelRange Arch::getBelsByTile(int x, int y) const
|
||||||
|
{
|
||||||
|
// In iCE40 chipdb bels at the same tile are consecutive and dense z ordinates are used
|
||||||
|
BelRange br;
|
||||||
|
|
||||||
|
Loc loc;
|
||||||
|
loc.x = x;
|
||||||
|
loc.y = y;
|
||||||
|
loc.z = 0;
|
||||||
|
|
||||||
|
br.b.cursor = Arch::getBelByLocation(loc).index;
|
||||||
|
br.e.cursor = br.b.cursor;
|
||||||
|
|
||||||
|
if (br.e.cursor != -1) {
|
||||||
|
while (br.e.cursor < chip_info->num_bels &&
|
||||||
|
chip_info->bel_data[br.e.cursor].x == x &&
|
||||||
|
chip_info->bel_data[br.e.cursor].y == y)
|
||||||
|
br.e.cursor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
BelRange Arch::getBelsAtSameTile(BelId bel) const
|
BelRange Arch::getBelsAtSameTile(BelId bel) const
|
||||||
{
|
{
|
||||||
BelRange br;
|
BelRange br;
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
// This requires Bels at the same tile are consecutive
|
|
||||||
int x = chip_info->bel_data[bel.index].x;
|
int x = chip_info->bel_data[bel.index].x;
|
||||||
int y = chip_info->bel_data[bel.index].y;
|
int y = chip_info->bel_data[bel.index].y;
|
||||||
int start = bel.index, end = bel.index;
|
int start = bel.index, end = bel.index;
|
||||||
|
22
ice40/arch.h
22
ice40/arch.h
@ -350,6 +350,7 @@ struct Arch : BaseCtx
|
|||||||
mutable std::unordered_map<IdString, int> bel_by_name;
|
mutable std::unordered_map<IdString, int> bel_by_name;
|
||||||
mutable std::unordered_map<IdString, int> wire_by_name;
|
mutable std::unordered_map<IdString, int> wire_by_name;
|
||||||
mutable std::unordered_map<IdString, int> pip_by_name;
|
mutable std::unordered_map<IdString, int> pip_by_name;
|
||||||
|
mutable std::unordered_map<Loc, int> bel_by_loc;
|
||||||
|
|
||||||
std::vector<IdString> bel_to_cell;
|
std::vector<IdString> bel_to_cell;
|
||||||
std::vector<IdString> wire_to_net;
|
std::vector<IdString> wire_to_net;
|
||||||
@ -440,7 +441,24 @@ struct Arch : BaseCtx
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
BelRange getBelsAtSameTile(BelId bel) const;
|
Loc getBelLocation(BelId bel) const
|
||||||
|
{
|
||||||
|
Loc loc;
|
||||||
|
loc.x = chip_info->bel_data[bel.index].x;
|
||||||
|
loc.y = chip_info->bel_data[bel.index].y;
|
||||||
|
loc.z = chip_info->bel_data[bel.index].z;
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
BelId getBelByLocation(Loc loc) const;
|
||||||
|
BelRange getBelsByTile(int x, int y) const;
|
||||||
|
|
||||||
|
bool getBelGlobalBuf(BelId bel) const
|
||||||
|
{
|
||||||
|
return chip_info->bel_data[bel.index].type == TYPE_SB_GB;
|
||||||
|
}
|
||||||
|
|
||||||
|
BelRange getBelsAtSameTile(BelId bel) const NPNR_DEPRECATED;
|
||||||
|
|
||||||
BelType getBelType(BelId bel) const
|
BelType getBelType(BelId bel) const
|
||||||
{
|
{
|
||||||
@ -671,7 +689,7 @@ struct Arch : BaseCtx
|
|||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;
|
void estimatePosition(BelId bel, int &x, int &y, bool &gb) const NPNR_DEPRECATED;
|
||||||
delay_t estimateDelay(WireId src, WireId dst) const;
|
delay_t estimateDelay(WireId src, WireId dst) const;
|
||||||
delay_t getDelayEpsilon() const { return 20; }
|
delay_t getDelayEpsilon() const { return 20; }
|
||||||
delay_t getRipupDelayPenalty() const { return 200; }
|
delay_t getRipupDelayPenalty() const { return 200; }
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
#error Include "archdefs.h" via "nextpnr.h" only.
|
#error Include "archdefs.h" via "nextpnr.h" only.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
typedef int delay_t;
|
typedef int delay_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user