make source more inline with ecp5

This commit is contained in:
Miodrag Milanovic 2023-03-30 18:18:52 +02:00 committed by myrtle
parent 62ace58204
commit ca3d32e5ac
4 changed files with 263 additions and 163 deletions

View File

@ -201,27 +201,6 @@ BelId Arch::getBelByName(IdStringList name) const
return BelId();
}
BelId Arch::getBelByLocation(Loc loc) const
{
BelId ret;
if (loc.x >= chip_info->width || loc.y >= chip_info->height)
return BelId();
ret.location.x = loc.x;
ret.location.y = loc.y;
const TileTypePOD *loci = tile_info(ret);
for (int i = 0; i < loci->bel_data.ssize(); i++) {
if (loci->bel_data[i].z == loc.z) {
ret.index = i;
return ret;
}
}
return BelId();
}
BelRange Arch::getBelsByTile(int x, int y) const
{
BelRange br;
@ -239,24 +218,21 @@ BelRange Arch::getBelsByTile(int x, int y) const
return br;
}
bool Arch::getBelGlobalBuf(BelId bel) const { return false; }
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
WireId ret;
NPNR_ASSERT(bel != BelId());
for (auto &bw : tile_info(bel)->bel_data[bel.index].bel_wires)
if (bw.port == pin.index) {
WireId ret;
ret.location.x = bw.rel_wire_loc.x;
ret.location.y = bw.rel_wire_loc.y;
ret.index = bw.wire_index;
return ret;
break;
}
return WireId();
return ret;
}
PortType Arch::getBelPinType(BelId bel, IdString pin) const
@ -270,35 +246,6 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
return PORT_INOUT;
}
std::vector<IdString> Arch::getBelPins(BelId bel) const
{
std::vector<IdString> ret;
NPNR_ASSERT(bel != BelId());
for (auto &bw : tile_info(bel)->bel_data[bel.index].bel_wires) {
IdString id;
id.index = bw.port;
ret.push_back(id);
}
return ret;
}
// ---------------------------------------------------------------
BelId Arch::getPackagePinBel(const std::string &pin) const
{
for (auto &ppin : package_info->pin_data) {
if (ppin.name.get() == pin) {
BelId bel;
bel.location = ppin.abs_loc;
bel.index = ppin.bel_index;
return bel;
}
}
return BelId();
}
// ---------------------------------------------------------------
WireId Arch::getWireByName(IdStringList name) const
@ -362,6 +309,56 @@ IdStringList Arch::getPipName(PipId pip) const
// ---------------------------------------------------------------
BelId Arch::get_package_pin_bel(const std::string &pin) const
{
for (auto &ppin : package_info->pin_data) {
if (ppin.name.get() == pin) {
BelId bel;
bel.location = ppin.abs_loc;
bel.index = ppin.bel_index;
return bel;
}
}
return BelId();
}
std::vector<IdString> Arch::getBelPins(BelId bel) const
{
std::vector<IdString> ret;
NPNR_ASSERT(bel != BelId());
for (auto &bw : tile_info(bel)->bel_data[bel.index].bel_wires) {
IdString id;
id.index = bw.port;
ret.push_back(id);
}
return ret;
}
BelId Arch::getBelByLocation(Loc loc) const
{
BelId ret;
if (loc.x >= chip_info->width || loc.y >= chip_info->height)
return BelId();
ret.location.x = loc.x;
ret.location.y = loc.y;
const TileTypePOD *loci = tile_info(ret);
for (int i = 0; i < loci->bel_data.ssize(); i++) {
if (loci->bel_data[i].z == loc.z) {
ret.index = i;
return ret;
}
}
return BelId();
}
// ---------------------------------------------------------------
delay_t Arch::estimateDelay(WireId src, WireId dst) const
{
// Taxicab distance multiplied by pipDelay (0.01) and fake wireDelay (0.01).
@ -370,6 +367,16 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
return (abs(dst.location.x - src.location.x) + abs(dst.location.y - src.location.y)) * (0.01 + 0.01);
}
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
BoundingBox bb;
bb.x0 = std::min(src.location.x, dst.location.x);
bb.y0 = std::min(src.location.y, dst.location.y);
bb.x1 = std::max(src.location.x, dst.location.x);
bb.y1 = std::max(src.location.y, dst.location.y);
return bb;
}
delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
{
NPNR_UNUSED(src_pin);
@ -383,16 +390,6 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
(0.01 + 0.01);
}
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
{
BoundingBox bb;
bb.x0 = std::min(src.location.x, dst.location.x);
bb.y0 = std::min(src.location.y, dst.location.y);
bb.x1 = std::max(src.location.x, dst.location.x);
bb.y1 = std::max(src.location.y, dst.location.y);
return bb;
}
// ---------------------------------------------------------------
bool Arch::place()
@ -508,6 +505,16 @@ DecalXY Arch::getPipDecal(PipId pip) const
return decalxy;
};
DecalXY Arch::getGroupDecal(GroupId group) const
{
DecalXY decalxy;
decalxy.decal.type = DecalId::TYPE_GROUP;
decalxy.decal.location = group.location;
decalxy.decal.z = group.type;
decalxy.decal.active = true;
return decalxy;
}
// ---------------------------------------------------------------
const std::string Arch::defaultPlacer = "heap";
@ -517,8 +524,6 @@ const std::vector<std::string> Arch::availablePlacers = {"sa", "heap"};
const std::string Arch::defaultRouter = "router1";
const std::vector<std::string> Arch::availableRouters = {"router1", "router2"};
bool Arch::cells_compatible(const CellInfo **cells, int count) const { return false; }
std::vector<std::pair<std::string, std::string>> Arch::get_tiles_at_loc(int row, int col)
{
std::vector<std::pair<std::string, std::string>> ret;
@ -531,6 +536,72 @@ std::vector<std::pair<std::string, std::string>> Arch::get_tiles_at_loc(int row,
// -----------------------------------------------------------------------
GroupId Arch::getGroupByName(IdStringList name) const
{
for (auto g : getGroups())
if (getGroupName(g) == name)
return g;
return GroupId();
}
IdStringList Arch::getGroupName(GroupId group) const
{
std::string suffix;
switch (group.type) {
case GroupId::TYPE_SWITCHBOX:
suffix = "switchbox";
break;
default:
return IdStringList();
}
std::array<IdString, 3> ids{x_ids.at(group.location.x), y_ids.at(group.location.y), id(suffix)};
return IdStringList(ids);
}
std::vector<GroupId> Arch::getGroups() const
{
std::vector<GroupId> ret;
for (int y = 1; y < chip_info->height - 1; y++) {
for (int x = 1; x < chip_info->width - 1; x++) {
GroupId group;
group.type = GroupId::TYPE_SWITCHBOX;
group.location.x = x;
group.location.y = y;
ret.push_back(group);
}
}
return ret;
}
std::vector<BelId> Arch::getGroupBels(GroupId group) const
{
std::vector<BelId> ret;
return ret;
}
std::vector<WireId> Arch::getGroupWires(GroupId group) const
{
std::vector<WireId> ret;
return ret;
}
std::vector<PipId> Arch::getGroupPips(GroupId group) const
{
std::vector<PipId> ret;
return ret;
}
std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
{
std::vector<GroupId> ret;
return ret;
}
// -----------------------------------------------------------------------
std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) const
{
std::vector<std::pair<IdString, std::string>> ret;

View File

@ -149,8 +149,6 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
/************************ End of chipdb section. ************************/
// Iterators
// Iterate over Bels across tiles.
struct BelIterator
{
const ChipInfoPOD *chip;
@ -200,7 +198,8 @@ struct BelRange
BelIterator end() const { return e; }
};
// Iterate over Downstream/Upstream Bels for a Wire.
// -----------------------------------------------------------------------
struct BelPinIterator
{
const BelPortPOD *ptr = nullptr;
@ -225,7 +224,8 @@ struct BelPinRange
BelPinIterator end() const { return e; }
};
// Iterator over Wires across tiles.
// -----------------------------------------------------------------------
struct WireIterator
{
const ChipInfoPOD *chip;
@ -275,7 +275,8 @@ struct WireRange
WireIterator end() const { return e; }
};
// Iterator over Pips across tiles.
// -----------------------------------------------------------------------
struct AllPipIterator
{
const ChipInfoPOD *chip;
@ -325,7 +326,8 @@ struct AllPipRange
AllPipIterator end() const { return e; }
};
// Iterate over Downstream/Upstream Pips for a Wire.
// -----------------------------------------------------------------------
struct PipIterator
{
@ -383,11 +385,6 @@ struct Arch : BaseArch<ArchRanges>
mutable dict<IdStringList, PipId> pip_by_name;
// fast access to X and Y IdStrings for building object names
std::vector<IdString> x_ids, y_ids;
// inverse of the above for name->object mapping
dict<IdString, int> id_to_x, id_to_y;
enum class LutPermRule
{
NONE,
@ -397,6 +394,9 @@ struct Arch : BaseArch<ArchRanges>
std::vector<LutPermRule> lutperm_allowed;
bool disable_router_lutperm = false;
// For fast, incremental validity checking of split SLICE
// BEL z-position lookup, x-ored with (index in tile) << 2
enum LogicBELType
{
BEL_COMB = 0,
@ -427,8 +427,6 @@ struct Arch : BaseArch<ArchRanges>
~TileStatus() { delete lts; }
};
mutable std::vector<TileStatus> tile_status;
// faster replacements for base_pip2net, base_wire2net
// indexed by get_pip_vecidx()
std::vector<NetInfo *> pip2net;
@ -440,53 +438,49 @@ struct Arch : BaseArch<ArchRanges>
std::vector<int32_t> pip_tile_vecidx;
std::vector<int32_t> wire_tile_vecidx;
// Helpers
template <typename Id> const TileTypePOD *tile_info(Id &id) const
{
return &(chip_info->tiles[id.location.y * chip_info->width + id.location.x]);
}
// fast access to X and Y IdStrings for building object names
std::vector<IdString> x_ids, y_ids;
// inverse of the above for name->object mapping
dict<IdString, int> id_to_x, id_to_y;
int get_bel_flat_index(BelId bel) const
{
return (bel.location.y * chip_info->width + bel.location.x) * max_loc_bels + bel.index;
}
template <typename Id> inline int tile_index(Id id) const
{
return id.location.y * chip_info->width + id.location.x;
}
// ---------------------------------------------------------------
// Common Arch API. Every arch must provide the following methods.
// General
ArchArgs args;
Arch(ArchArgs args);
static void list_devices();
std::string getChipName() const override;
// Extra helper
std::string get_full_chip_name() const;
IdString archId() const override { return id_machxo2; }
ArchArgs archArgs() const override { return args; }
IdString archArgsToId(ArchArgs args) const override;
static const int max_loc_bels = 20;
// -------------------------------------------------
int getGridDimX() const override { return chip_info->width; }
int getGridDimY() const override { return chip_info->height; }
int getTileBelDimZ(int x, int y) const override { return max_loc_bels; }
static const int max_loc_bels = 32;
int getGridDimX() const override { return chip_info->width; };
int getGridDimY() const override { return chip_info->height; };
int getTileBelDimZ(int, int) const override { return max_loc_bels; };
// TODO: Make more precise? The CENTER MUX having config bits across
// tiles can complicate this?
int getTilePipDimZ(int x, int y) const override { return 2; }
int getTilePipDimZ(int, int) const override { return 2; };
char getNameDelimiter() const override { return '/'; }
// Bels
// -------------------------------------------------
BelId getBelByName(IdStringList name) const override;
template <typename Id> const TileTypePOD *tile_info(Id &id) const
{
return &(chip_info->tiles[id.location.y * chip_info->width + id.location.x]);
}
template <typename Id> inline int tile_index(Id id) const
{
return id.location.y * chip_info->width + id.location.x;
}
IdStringList getBelName(BelId bel) const override
{
NPNR_ASSERT(bel != BelId());
@ -563,7 +557,8 @@ struct Arch : BaseArch<ArchRanges>
BelId getBelByLocation(Loc loc) const override;
BelRange getBelsByTile(int x, int y) const override;
bool getBelGlobalBuf(BelId bel) const override;
bool getBelGlobalBuf(BelId bel) const override { return false; }
bool checkBelAvail(BelId bel) const override
{
@ -608,13 +603,22 @@ struct Arch : BaseArch<ArchRanges>
}
WireId getBelPinWire(BelId bel, IdString pin) const override;
PortType getBelPinType(BelId bel, IdString pin) const override;
BelPinRange getWireBelPins(WireId wire) const override
{
BelPinRange range;
NPNR_ASSERT(wire != WireId());
range.b.ptr = tile_info(wire)->wire_data[wire.index].bel_pins.begin();
range.b.wire_loc = wire.location;
range.e.ptr = tile_info(wire)->wire_data[wire.index].bel_pins.end();
range.e.wire_loc = wire.location;
return range;
}
std::vector<IdString> getBelPins(BelId bel) const override;
// Package
BelId getPackagePinBel(const std::string &pin) const;
// -------------------------------------------------
// Wires
WireId getWireByName(IdStringList name) const override;
IdStringList getWireName(WireId wire) const override
@ -694,17 +698,6 @@ struct Arch : BaseArch<ArchRanges>
return range;
}
BelPinRange getWireBelPins(WireId wire) const override
{
BelPinRange range;
NPNR_ASSERT(wire != WireId());
range.b.ptr = tile_info(wire)->wire_data[wire.index].bel_pins.begin();
range.b.wire_loc = wire.location;
range.e.ptr = tile_info(wire)->wire_data[wire.index].bel_pins.end();
range.e.wire_loc = wire.location;
return range;
}
IdString get_wire_basename(WireId wire) const { return id(tile_info(wire)->wire_data[wire.index].name.get()); }
WireId get_wire_by_loc_basename(Location loc, std::string basename) const
@ -720,7 +713,8 @@ struct Arch : BaseArch<ArchRanges>
return WireId();
}
// Pips
// -------------------------------------------------
PipId getPipByName(IdStringList name) const override;
IdStringList getPipName(PipId pip) const override;
@ -809,18 +803,6 @@ struct Arch : BaseArch<ArchRanges>
return range;
}
Loc getPipLocation(PipId pip) const override
{
Loc loc;
loc.x = pip.location.x;
loc.y = pip.location.y;
// FIXME: Some Pip's config bits span across tiles. Will Z
// be affected by this?
loc.z = 0;
return loc;
}
WireId getPipSrcWire(PipId pip) const override
{
WireId wire;
@ -863,9 +845,6 @@ struct Arch : BaseArch<ArchRanges>
return range;
}
// Extra Pip helpers.
int8_t get_pip_class(PipId pip) const { return tile_info(pip)->pip_data[pip.index].pip_type; }
std::string get_pip_tilename(PipId pip) const
{
auto &tileloc = chip_info->tile_info[pip.location.y * chip_info->width + pip.location.x];
@ -881,32 +860,65 @@ struct Arch : BaseArch<ArchRanges>
return chip_info->tiletype_names[tile_info(pip)->pip_data[pip.index].tile_type].get();
}
// Delay
Loc getPipLocation(PipId pip) const override
{
Loc loc;
loc.x = pip.location.x;
loc.y = pip.location.y;
loc.z = 0;
return loc;
}
int8_t get_pip_class(PipId pip) const { return tile_info(pip)->pip_data[pip.index].pip_type; }
BelId get_package_pin_bel(const std::string &pin) const;
//std::string get_bel_package_pin(BelId bel) const;
//int get_pio_bel_bank(BelId bel) const;
// For getting GCLK, PLL, Vref, etc, pins
//std::string get_pio_function_name(BelId bel) const;
//BelId get_pio_by_function_name(const std::string &name) const;
PortType getBelPinType(BelId bel, IdString pin) const override;
// -------------------------------------------------
GroupId getGroupByName(IdStringList name) const override;
IdStringList getGroupName(GroupId group) const override;
std::vector<GroupId> getGroups() const override;
std::vector<BelId> getGroupBels(GroupId group) const override;
std::vector<WireId> getGroupWires(GroupId group) const override;
std::vector<PipId> getGroupPips(GroupId group) const override;
std::vector<GroupId> getGroupGroups(GroupId group) const override;
// -------------------------------------------------
delay_t estimateDelay(WireId src, WireId dst) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
delay_t getDelayEpsilon() const override { return 0.001; }
delay_t getRipupDelayPenalty() const override { return 0.015; }
float getDelayNS(delay_t v) const override { return v; }
delay_t getDelayFromNS(float ns) const override { return ns; }
uint32_t getDelayChecksum(delay_t v) const override { return v; }
//bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override;
BoundingBox getRouteBoundingBox(WireId src, WireId dst) const override;
// -------------------------------------------------
// Flow
bool pack() override;
bool place() override;
bool route() override;
// Graphics
// -------------------------------------------------
std::vector<GraphicElement> getDecalGraphics(DecalId decal) const override;
DecalXY getBelDecal(BelId bel) const override;
DecalXY getWireDecal(WireId wire) const override;
DecalXY getPipDecal(PipId pip) const override;
DecalXY getGroupDecal(GroupId group) const override;
// Placer
// -------------------------------------------------
// Placement validity checks
bool isBelLocationValid(BelId bel, bool explain_invalid = false) const override;
// Helper function for above
@ -915,15 +927,6 @@ struct Arch : BaseArch<ArchRanges>
void assign_arch_info_for_cell(CellInfo *ci);
void assignArchInfo() override;
static const std::string defaultPlacer;
static const std::vector<std::string> availablePlacers;
static const std::string defaultRouter;
static const std::vector<std::string> availableRouters;
// ---------------------------------------------------------------
// Internal usage
bool cells_compatible(const CellInfo **cells, int count) const;
std::vector<std::pair<std::string, std::string>> get_tiles_at_loc(int row, int col);
std::string get_tile_by_type_loc(int row, int col, std::string type) const
{
@ -956,6 +959,16 @@ struct Arch : BaseArch<ArchRanges>
}
NPNR_ASSERT_FALSE_STR("no tile with type " + type);
}
static const std::string defaultPlacer;
static const std::vector<std::string> availablePlacers;
static const std::string defaultRouter;
static const std::vector<std::string> availableRouters;
mutable std::vector<TileStatus> tile_status;
// -------------------------------------------------
};
NEXTPNR_NAMESPACE_END

View File

@ -30,6 +30,8 @@ NEXTPNR_NAMESPACE_BEGIN
typedef float delay_t;
// -----------------------------------------------------------------------
// https://bugreports.qt.io/browse/QTBUG-80789
#ifndef Q_MOC_RUN
@ -107,6 +109,22 @@ struct PipId
unsigned int hash() const { return mkhash(location.hash(), index); }
};
typedef IdString BelBucketId;
struct GroupId
{
enum : int8_t
{
TYPE_NONE,
TYPE_SWITCHBOX
} type = TYPE_NONE;
Location location;
bool operator==(const GroupId &other) const { return (type == other.type) && (location == other.location); }
bool operator!=(const GroupId &other) const { return (type != other.type) || (location != other.location); }
unsigned int hash() const { return mkhash(location.hash(), int(type)); }
};
struct DecalId
{
enum
@ -131,14 +149,13 @@ struct DecalId
unsigned int hash() const { return mkhash(location.hash(), mkhash(z, int(type))); }
};
typedef IdString GroupId;
typedef IdString BelBucketId;
typedef IdString ClusterId;
struct ArchNetInfo
{
};
typedef IdString ClusterId;
struct CellInfo;
struct NetInfo;
struct ArchCellInfo : BaseClusterInfo
@ -197,5 +214,4 @@ struct ArchCellInfo : BaseClusterInfo
};
NEXTPNR_NAMESPACE_END
#endif /* MACHXO2_ARCHDEFS_H */

View File

@ -381,7 +381,7 @@ class Ecp5Packer
auto loc_attr = trio->attrs.find(id_LOC);
if (loc_attr != trio->attrs.end()) {
std::string pin = loc_attr->second.as_string();
BelId pinBel = ctx->getPackagePinBel(pin);
BelId pinBel = ctx->get_package_pin_bel(pin);
if (pinBel == BelId()) {
log_error("IO pin '%s' constrained to pin '%s', which does not exist for package '%s'.\n",
trio->name.c_str(ctx), pin.c_str(), ctx->package_name);