Get rid of PortPin and BelType (ice40, generic, docs)

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-08-08 17:01:18 +02:00
parent 8553573d24
commit e03ae50e21
18 changed files with 152 additions and 308 deletions

View File

@ -55,18 +55,18 @@ void replace_port(CellInfo *old_cell, IdString old_name, CellInfo *rep_cell, IdS
void print_utilisation(const Context *ctx) void print_utilisation(const Context *ctx)
{ {
// Sort by Bel type // Sort by Bel type
std::map<BelType, int> used_types; std::map<IdString, int> used_types;
for (auto &cell : ctx->cells) { for (auto &cell : ctx->cells) {
used_types[ctx->belTypeFromId(cell.second.get()->type)]++; used_types[cell.second.get()->type]++;
} }
std::map<BelType, int> available_types; std::map<IdString, int> available_types;
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
available_types[ctx->getBelType(bel)]++; available_types[ctx->getBelType(bel)]++;
} }
log_break(); log_break();
log_info("Device utilisation:\n"); log_info("Device utilisation:\n");
for (auto type : available_types) { for (auto type : available_types) {
IdString type_id = ctx->belTypeToId(type.first); IdString type_id = type.first;
int used_bels = get_or_default(used_types, type.first, 0); int used_bels = get_or_default(used_types, type.first, 0);
log_info("\t%20s: %5d/%5d %5d%%\n", type_id.c_str(ctx), used_bels, type.second, 100 * used_bels / type.second); log_info("\t%20s: %5d/%5d %5d%%\n", type_id.c_str(ctx), used_bels, type.second, 100 * used_bels / type.second);
} }

View File

@ -67,7 +67,7 @@ WireId Context::getNetinfoSourceWire(const NetInfo *net_info) const
if (driver_port_it != net_info->driver.cell->pins.end()) if (driver_port_it != net_info->driver.cell->pins.end())
driver_port = driver_port_it->second; driver_port = driver_port_it->second;
return getBelPinWire(src_bel, portPinFromId(driver_port)); return getBelPinWire(src_bel, driver_port);
} }
WireId Context::getNetinfoSinkWire(const NetInfo *net_info, const PortRef &user_info) const WireId Context::getNetinfoSinkWire(const NetInfo *net_info, const PortRef &user_info) const
@ -84,7 +84,7 @@ WireId Context::getNetinfoSinkWire(const NetInfo *net_info, const PortRef &user_
if (user_port_it != user_info.cell->pins.end()) if (user_port_it != user_info.cell->pins.end())
user_port = user_port_it->second; user_port = user_port_it->second;
return getBelPinWire(dst_bel, portPinFromId(user_port)); return getBelPinWire(dst_bel, user_port);
} }
delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &user_info) const delay_t Context::getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &user_info) const

View File

@ -100,13 +100,13 @@ struct Context;
struct IdString struct IdString
{ {
int index = 0; int index;
static void initialize_arch(const BaseCtx *ctx); static void initialize_arch(const BaseCtx *ctx);
static void initialize_add(const BaseCtx *ctx, const char *s, int idx); static void initialize_add(const BaseCtx *ctx, const char *s, int idx);
IdString() {} constexpr IdString(int index = 0) : index(index) {}
void set(const BaseCtx *ctx, const std::string &s); void set(const BaseCtx *ctx, const std::string &s);
@ -211,7 +211,7 @@ struct DecalXY
struct BelPin struct BelPin
{ {
BelId bel; BelId bel;
PortPin pin; IdString pin;
}; };
struct CellInfo; struct CellInfo;

View File

@ -115,7 +115,7 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality)
if (cell->bel != BelId()) { if (cell->bel != BelId()) {
ctx->unbindBel(cell->bel); ctx->unbindBel(cell->bel);
} }
BelType targetType = ctx->belTypeFromId(cell->type); IdString targetType = cell->type;
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) { if (ctx->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) {
if (ctx->checkBelAvail(bel)) { if (ctx->checkBelAvail(bel)) {
@ -228,7 +228,7 @@ class ConstraintLegaliseWorker
if (locBel == BelId()) { if (locBel == BelId()) {
return false; return false;
} }
if (ctx->getBelType(locBel) != ctx->belTypeFromId(cell->type)) { if (ctx->getBelType(locBel) != cell->type) {
return false; return false;
} }
if (!ctx->checkBelAvail(locBel)) { if (!ctx->checkBelAvail(locBel)) {

View File

@ -51,7 +51,7 @@ class SAPlacer
int num_bel_types = 0; int num_bel_types = 0;
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
Loc loc = ctx->getBelLocation(bel); Loc loc = ctx->getBelLocation(bel);
BelType type = ctx->getBelType(bel); IdString type = ctx->getBelType(bel);
int type_idx; int type_idx;
if (bel_types.find(type) == bel_types.end()) { if (bel_types.find(type) == bel_types.end()) {
type_idx = num_bel_types++; type_idx = num_bel_types++;
@ -91,17 +91,17 @@ class SAPlacer
loc_name.c_str(), cell->name.c_str(ctx)); loc_name.c_str(), cell->name.c_str(ctx));
} }
BelType bel_type = ctx->getBelType(bel); IdString bel_type = ctx->getBelType(bel);
if (bel_type != ctx->belTypeFromId(cell->type)) { if (bel_type != cell->type) {
log_error("Bel \'%s\' of type \'%s\' does not match cell " log_error("Bel \'%s\' of type \'%s\' does not match cell "
"\'%s\' of type \'%s\'\n", "\'%s\' of type \'%s\'\n",
loc_name.c_str(), ctx->belTypeToId(bel_type).c_str(ctx), cell->name.c_str(ctx), loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
cell->type.c_str(ctx)); cell->type.c_str(ctx));
} }
if (!ctx->isValidBelForCell(cell, bel)) { if (!ctx->isValidBelForCell(cell, bel)) {
log_error("Bel \'%s\' of type \'%s\' is not valid for cell " log_error("Bel \'%s\' of type \'%s\' is not valid for cell "
"\'%s\' of type \'%s\'\n", "\'%s\' of type \'%s\'\n",
loc_name.c_str(), ctx->belTypeToId(bel_type).c_str(ctx), cell->name.c_str(ctx), loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx),
cell->type.c_str(ctx)); cell->type.c_str(ctx));
} }
@ -297,7 +297,7 @@ class SAPlacer
if (cell->bel != BelId()) { if (cell->bel != BelId()) {
ctx->unbindBel(cell->bel); ctx->unbindBel(cell->bel);
} }
BelType targetType = ctx->belTypeFromId(cell->type); IdString targetType = cell->type;
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) == targetType && ctx->isValidBelForCell(cell, bel)) { if (ctx->getBelType(bel) == targetType && ctx->isValidBelForCell(cell, bel)) {
if (ctx->checkBelAvail(bel)) { if (ctx->checkBelAvail(bel)) {
@ -420,7 +420,7 @@ class SAPlacer
// diameter // diameter
BelId random_bel_for_cell(CellInfo *cell) BelId random_bel_for_cell(CellInfo *cell)
{ {
BelType targetType = ctx->belTypeFromId(cell->type); IdString targetType = cell->type;
Loc curr_loc = ctx->getBelLocation(cell->bel); Loc curr_loc = ctx->getBelLocation(cell->bel);
while (true) { while (true) {
int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0); int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0);
@ -448,7 +448,7 @@ class SAPlacer
bool improved = false; bool improved = false;
int n_move, n_accept; int n_move, n_accept;
int diameter = 35, max_x = 1, max_y = 1; int diameter = 35, max_x = 1, max_y = 1;
std::unordered_map<BelType, int> bel_types; std::unordered_map<IdString, int> bel_types;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels; std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
std::unordered_set<BelId> locked_bels; std::unordered_set<BelId> locked_bels;
bool require_legal = false; bool require_legal = false;

View File

@ -28,14 +28,6 @@ delay_t minDelay() const { return delay; }
delay_t maxDelay() const { return delay; } delay_t maxDelay() const { return delay; }
``` ```
### BelType
A type representing a bel type name. `BelType()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash<BelType>`.
### PortPin
A type representing a port or pin name. `PortPin()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash<PortPin>`.
### BelId ### BelId
A type representing a bel name. `BelId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash<BelId>`. A type representing a bel name. `BelId()` must construct a unique null-value. Must provide `==` and `!=` operators and a specialization for `std::hash<BelId>`.
@ -80,22 +72,6 @@ Constructor. ArchArgs is a architecture-specific type (usually a struct also def
Return a string representation of the ArchArgs that was used to construct this object. Return a string representation of the ArchArgs that was used to construct this object.
### IdString belTypeToId(BelType type) const
Convert a `BelType` to an `IdString`.
### IdString portPinToId(PortPin type) const
Convert a `PortPin` to an `IdString`.
### BelType belTypeFromId(IdString id) const
Convert `IdString` to `BelType`.
### PortPin portPinFromId(IdString id) const
Convert `IdString` to `PortPin`.
### int getGridDimX() const ### int getGridDimX() const
Get grid X dimension. All bels must have Y coordinates in the range `0 .. getGridDimX()-1` (inclusive). Get grid X dimension. All bels must have Y coordinates in the range `0 .. getGridDimX()-1` (inclusive).
@ -167,19 +143,19 @@ If the bel is unavailable, and unbinding a single cell would make it available,
Return a list of all bels on the device. Return a list of all bels on the device.
### BelType getBelType(BelId bel) const ### IdString getBelType(BelId bel) const
Return the type of a given bel. Return the type of a given bel.
### WireId getBelPinWire(BelId bel, PortPin pin) const ### WireId getBelPinWire(BelId bel, IdString pin) const
Return the wire connected to the given bel pin. Return the wire connected to the given bel pin.
### PortType getBelPinType(BelId bel, PortPin pin) const ### PortType getBelPinType(BelId bel, IdString pin) const
Return the type (input/output/inout) of the given bel pin. Return the type (input/output/inout) of the given bel pin.
### const\_range\<PortPin\> getBelPins(BelId bel) const ### const\_range\<IdString\> getBelPins(BelId bel) const
Return a list of all pins on that bel. Return a list of all pins on that bel.

View File

@ -405,7 +405,7 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
QtProperty *topItem = addTopLevelProperty("Bel"); QtProperty *topItem = addTopLevelProperty("Bel");
addProperty(topItem, QVariant::String, "Name", c.c_str(ctx)); addProperty(topItem, QVariant::String, "Name", c.c_str(ctx));
addProperty(topItem, QVariant::String, "Type", ctx->belTypeToId(ctx->getBelType(bel)).c_str(ctx)); addProperty(topItem, QVariant::String, "Type", ctx->getBelType(bel).c_str(ctx));
addProperty(topItem, QVariant::Bool, "Available", ctx->checkBelAvail(bel)); addProperty(topItem, QVariant::Bool, "Available", ctx->checkBelAvail(bel));
addProperty(topItem, QVariant::String, "Bound Cell", ctx->nameOf(ctx->getBoundBelCell(bel)), ElementType::CELL); addProperty(topItem, QVariant::String, "Bound Cell", ctx->nameOf(ctx->getBoundBelCell(bel)), ElementType::CELL);
addProperty(topItem, QVariant::String, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)), addProperty(topItem, QVariant::String, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)),
@ -413,8 +413,8 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
QtProperty *belpinsItem = addSubGroup(topItem, "Ports"); QtProperty *belpinsItem = addSubGroup(topItem, "Ports");
for (const auto &item : ctx->getBelPins(bel)) { for (const auto &item : ctx->getBelPins(bel)) {
QtProperty *portInfoItem = addSubGroup(belpinsItem, ctx->portPinToId(item).c_str(ctx)); QtProperty *portInfoItem = addSubGroup(belpinsItem, item.c_str(ctx));
addProperty(portInfoItem, QVariant::String, "Name", ctx->portPinToId(item).c_str(ctx)); addProperty(portInfoItem, QVariant::String, "Name", item.c_str(ctx));
addProperty(portInfoItem, QVariant::Int, "Type", int(ctx->getBelPinType(bel, item))); addProperty(portInfoItem, QVariant::Int, "Type", int(ctx->getBelPinType(bel, item)));
WireId wire = ctx->getBelPinWire(bel, item); WireId wire = ctx->getBelPinWire(bel, item);
addProperty(portInfoItem, QVariant::String, "Wire", ctx->getWireName(wire).c_str(ctx), ElementType::WIRE); addProperty(portInfoItem, QVariant::String, "Wire", ctx->getWireName(wire).c_str(ctx), ElementType::WIRE);
@ -446,7 +446,7 @@ void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelecti
QString belname = ""; QString belname = "";
if (item.bel != BelId()) if (item.bel != BelId())
belname = ctx->getBelName(item.bel).c_str(ctx); belname = ctx->getBelName(item.bel).c_str(ctx);
QString pinname = ctx->portPinToId(item.pin).c_str(ctx); QString pinname = item.pin.c_str(ctx);
QtProperty *dhItem = addSubGroup(belpinsItem, belname + "-" + pinname); QtProperty *dhItem = addSubGroup(belpinsItem, belname + "-" + pinname);
addProperty(dhItem, QVariant::String, "Bel", belname, ElementType::BEL); addProperty(dhItem, QVariant::String, "Bel", belname, ElementType::BEL);

View File

@ -31,100 +31,13 @@ NEXTPNR_NAMESPACE_BEGIN
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
IdString Arch::belTypeToId(BelType type) const
{
if (type == TYPE_ICESTORM_LC)
return id("ICESTORM_LC");
if (type == TYPE_ICESTORM_RAM)
return id("ICESTORM_RAM");
if (type == TYPE_SB_IO)
return id("SB_IO");
if (type == TYPE_SB_GB)
return id("SB_GB");
if (type == TYPE_ICESTORM_PLL)
return id("ICESTORM_PLL");
if (type == TYPE_SB_WARMBOOT)
return id("SB_WARMBOOT");
if (type == TYPE_ICESTORM_DSP)
return id("ICESTORM_DSP");
if (type == TYPE_ICESTORM_HFOSC)
return id("ICESTORM_HFOSC");
if (type == TYPE_ICESTORM_LFOSC)
return id("ICESTORM_LFOSC");
if (type == TYPE_SB_I2C)
return id("SB_I2C");
if (type == TYPE_SB_SPI)
return id("SB_SPI");
if (type == TYPE_IO_I3C)
return id("IO_I3C");
if (type == TYPE_SB_LEDDA_IP)
return id("SB_LEDDA_IP");
if (type == TYPE_SB_RGBA_DRV)
return id("SB_RGBA_DRV");
if (type == TYPE_ICESTORM_SPRAM)
return id("ICESTORM_SPRAM");
return IdString();
}
BelType Arch::belTypeFromId(IdString type) const
{
if (type == id("ICESTORM_LC"))
return TYPE_ICESTORM_LC;
if (type == id("ICESTORM_RAM"))
return TYPE_ICESTORM_RAM;
if (type == id("SB_IO"))
return TYPE_SB_IO;
if (type == id("SB_GB"))
return TYPE_SB_GB;
if (type == id("ICESTORM_PLL"))
return TYPE_ICESTORM_PLL;
if (type == id("SB_WARMBOOT"))
return TYPE_SB_WARMBOOT;
if (type == id("ICESTORM_DSP"))
return TYPE_ICESTORM_DSP;
if (type == id("ICESTORM_HFOSC"))
return TYPE_ICESTORM_HFOSC;
if (type == id("ICESTORM_LFOSC"))
return TYPE_ICESTORM_LFOSC;
if (type == id("SB_I2C"))
return TYPE_SB_I2C;
if (type == id("SB_SPI"))
return TYPE_SB_SPI;
if (type == id("IO_I3C"))
return TYPE_IO_I3C;
if (type == id("SB_LEDDA_IP"))
return TYPE_SB_LEDDA_IP;
if (type == id("SB_RGBA_DRV"))
return TYPE_SB_RGBA_DRV;
if (type == id("ICESTORM_SPRAM"))
return TYPE_ICESTORM_SPRAM;
return TYPE_NONE;
}
// -----------------------------------------------------------------------
void IdString::initialize_arch(const BaseCtx *ctx) void IdString::initialize_arch(const BaseCtx *ctx)
{ {
#define X(t) initialize_add(ctx, #t, PIN_##t); #define X(t) initialize_add(ctx, #t, ID_##t);
#include "portpins.inc" #include "constids.inc"
#undef X #undef X
} }
IdString Arch::portPinToId(PortPin type) const
{
IdString ret;
if (type > 0 && type < PIN_MAXIDX)
ret.index = type;
return ret;
}
PortPin Arch::portPinFromId(IdString type) const
{
if (type.index > 0 && type.index < PIN_MAXIDX)
return PortPin(type.index);
return PIN_NONE;
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); } static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
@ -306,7 +219,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
return br; return br;
} }
PortType Arch::getBelPinType(BelId bel, PortPin pin) const PortType Arch::getBelPinType(BelId bel, IdString pin) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
@ -315,16 +228,16 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
if (num_bel_wires < 7) { if (num_bel_wires < 7) {
for (int i = 0; i < num_bel_wires; i++) { for (int i = 0; i < num_bel_wires; i++) {
if (bel_wires[i].port == pin) if (bel_wires[i].port == pin.index)
return PortType(bel_wires[i].type); return PortType(bel_wires[i].type);
} }
} else { } else {
int b = 0, e = num_bel_wires - 1; int b = 0, e = num_bel_wires - 1;
while (b <= e) { while (b <= e) {
int i = (b + e) / 2; int i = (b + e) / 2;
if (bel_wires[i].port == pin) if (bel_wires[i].port == pin.index)
return PortType(bel_wires[i].type); return PortType(bel_wires[i].type);
if (bel_wires[i].port > pin) if (bel_wires[i].port > pin.index)
e = i - 1; e = i - 1;
else else
b = i + 1; b = i + 1;
@ -334,7 +247,7 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
return PORT_INOUT; return PORT_INOUT;
} }
WireId Arch::getBelPinWire(BelId bel, PortPin pin) const WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{ {
WireId ret; WireId ret;
@ -345,7 +258,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
if (num_bel_wires < 7) { if (num_bel_wires < 7) {
for (int i = 0; i < num_bel_wires; i++) { for (int i = 0; i < num_bel_wires; i++) {
if (bel_wires[i].port == pin) { if (bel_wires[i].port == pin.index) {
ret.index = bel_wires[i].wire_index; ret.index = bel_wires[i].wire_index;
break; break;
} }
@ -354,11 +267,11 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
int b = 0, e = num_bel_wires - 1; int b = 0, e = num_bel_wires - 1;
while (b <= e) { while (b <= e) {
int i = (b + e) / 2; int i = (b + e) / 2;
if (bel_wires[i].port == pin) { if (bel_wires[i].port == pin.index) {
ret.index = bel_wires[i].wire_index; ret.index = bel_wires[i].wire_index;
break; break;
} }
if (bel_wires[i].port > pin) if (bel_wires[i].port > pin.index)
e = i - 1; e = i - 1;
else else
b = i + 1; b = i + 1;
@ -368,9 +281,9 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
return ret; return ret;
} }
std::vector<PortPin> Arch::getBelPins(BelId bel) const std::vector<IdString> Arch::getBelPins(BelId bel) const
{ {
std::vector<PortPin> ret; std::vector<IdString> ret;
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
@ -378,7 +291,7 @@ std::vector<PortPin> Arch::getBelPins(BelId bel) const
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++) for (int i = 0; i < num_bel_wires; i++)
ret.push_back(bel_wires[i].port); ret.push_back(IdString(bel_wires[i].port));
return ret; return ret;
} }
@ -814,7 +727,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
auto bel_type = getBelType(bel); auto bel_type = getBelType(bel);
if (bel_type == TYPE_ICESTORM_LC) { if (bel_type == id_ICESTORM_LC) {
GraphicElement el; GraphicElement el;
el.type = GraphicElement::TYPE_BOX; el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@ -827,7 +740,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el); ret.push_back(el);
} }
if (bel_type == TYPE_SB_IO) { if (bel_type == id_SB_IO) {
GraphicElement el; GraphicElement el;
el.type = GraphicElement::TYPE_BOX; el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE; el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@ -840,7 +753,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el); ret.push_back(el);
} }
if (bel_type == TYPE_ICESTORM_RAM) { if (bel_type == id_ICESTORM_RAM) {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
GraphicElement el; GraphicElement el;
el.type = GraphicElement::TYPE_BOX; el.type = GraphicElement::TYPE_BOX;
@ -861,15 +774,12 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
{ {
BelType type = belTypeFromId(cell->type);
for (int i = 0; i < chip_info->num_timing_cells; i++) { for (int i = 0; i < chip_info->num_timing_cells; i++) {
const auto &tc = chip_info->cell_timing[i]; const auto &tc = chip_info->cell_timing[i];
if (tc.type == type) { if (tc.type == cell->type.index) {
PortPin fromPin = portPinFromId(fromPort);
PortPin toPin = portPinFromId(toPort);
for (int j = 0; j < tc.num_paths; j++) { for (int j = 0; j < tc.num_paths; j++) {
const auto &path = tc.path_delays[j]; const auto &path = tc.path_delays[j];
if (path.from_port == fromPin && path.to_port == toPin) { if (path.from_port == fromPort.index && path.to_port == toPort.index) {
if (fast_part) if (fast_part)
delay.delay = path.fast_delay; delay.delay = path.fast_delay;
else else
@ -937,8 +847,8 @@ void Arch::assignArchInfo()
void Arch::assignCellInfo(CellInfo *cell) void Arch::assignCellInfo(CellInfo *cell)
{ {
cell->belType = belTypeFromId(cell->type); cell->belType = cell->type;
if (cell->type == id_icestorm_lc) { if (cell->type == id_ICESTORM_LC) {
cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en); cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en);
cell->lcInfo.carryEnable = bool_or_default(cell->params, id_carry_en); cell->lcInfo.carryEnable = bool_or_default(cell->params, id_carry_en);
cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk); cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk);

View File

@ -44,14 +44,14 @@ template <typename T> struct RelPtr
}; };
NPNR_PACKED_STRUCT(struct BelWirePOD { NPNR_PACKED_STRUCT(struct BelWirePOD {
PortPin port; int32_t port;
int32_t type; int32_t type;
int32_t wire_index; int32_t wire_index;
}); });
NPNR_PACKED_STRUCT(struct BelInfoPOD { NPNR_PACKED_STRUCT(struct BelInfoPOD {
RelPtr<char> name; RelPtr<char> name;
BelType type; int32_t type;
int32_t num_bel_wires; int32_t num_bel_wires;
RelPtr<BelWirePOD> bel_wires; RelPtr<BelWirePOD> bel_wires;
int8_t x, y, z; int8_t x, y, z;
@ -60,7 +60,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
NPNR_PACKED_STRUCT(struct BelPortPOD { NPNR_PACKED_STRUCT(struct BelPortPOD {
int32_t bel_index; int32_t bel_index;
PortPin port; int32_t port;
}); });
NPNR_PACKED_STRUCT(struct PipInfoPOD { NPNR_PACKED_STRUCT(struct PipInfoPOD {
@ -200,8 +200,8 @@ NPNR_PACKED_STRUCT(struct BelConfigPOD {
}); });
NPNR_PACKED_STRUCT(struct CellPathDelayPOD { NPNR_PACKED_STRUCT(struct CellPathDelayPOD {
PortPin from_port; int32_t from_port;
PortPin to_port; int32_t to_port;
int32_t fast_delay; int32_t fast_delay;
int32_t slow_delay; int32_t slow_delay;
}); });
@ -413,12 +413,6 @@ struct Arch : BaseCtx
IdString archId() const { return id("ice40"); } IdString archId() const { return id("ice40"); }
IdString archArgsToId(ArchArgs args) const; IdString archArgsToId(ArchArgs args) const;
IdString belTypeToId(BelType type) const;
BelType belTypeFromId(IdString id) const;
IdString portPinToId(PortPin type) const;
PortPin portPinFromId(IdString id) const;
// ------------------------------------------------- // -------------------------------------------------
int getGridDimX() const { return 34; } int getGridDimX() const { return 34; }
@ -498,17 +492,17 @@ struct Arch : BaseCtx
BelId getBelByLocation(Loc loc) const; BelId getBelByLocation(Loc loc) const;
BelRange getBelsByTile(int x, int y) const; BelRange getBelsByTile(int x, int y) const;
bool getBelGlobalBuf(BelId bel) const { return chip_info->bel_data[bel.index].type == TYPE_SB_GB; } bool getBelGlobalBuf(BelId bel) const { return chip_info->bel_data[bel.index].type == ID_SB_GB; }
BelType getBelType(BelId bel) const IdString getBelType(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
return chip_info->bel_data[bel.index].type; return IdString(chip_info->bel_data[bel.index].type);
} }
WireId getBelPinWire(BelId bel, PortPin pin) const; WireId getBelPinWire(BelId bel, IdString pin) const;
PortType getBelPinType(BelId bel, PortPin pin) const; PortType getBelPinType(BelId bel, IdString pin) const;
std::vector<PortPin> getBelPins(BelId bel) const; std::vector<IdString> getBelPins(BelId bel) const;
// ------------------------------------------------- // -------------------------------------------------
@ -826,11 +820,11 @@ struct Arch : BaseCtx
IdString id_icestorm_ram, id_rclk, id_wclk; IdString id_icestorm_ram, id_rclk, id_wclk;
// ------------------------------------------------- // -------------------------------------------------
BelPin getIOBSharingPLLPin(BelId pll, PortPin pll_pin) const BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const
{ {
auto wire = getBelPinWire(pll, pll_pin); auto wire = getBelPinWire(pll, pll_pin);
for (auto src_bel : getWireBelPins(wire)) { for (auto src_bel : getWireBelPins(wire)) {
if (getBelType(src_bel.bel) == TYPE_SB_IO && src_bel.pin == PIN_D_IN_0) { if (getBelType(src_bel.bel) == id_SB_IO && src_bel.pin == id_D_IN_0) {
return src_bel; return src_bel;
} }
} }

View File

@ -32,7 +32,7 @@ bool Arch::logicCellsCompatible(const std::vector<const CellInfo *> &cells) cons
int locals_count = 0; int locals_count = 0;
for (auto cell : cells) { for (auto cell : cells) {
NPNR_ASSERT(cell->belType == TYPE_ICESTORM_LC); NPNR_ASSERT(cell->belType == id_ICESTORM_LC);
if (cell->lcInfo.dffEnable) { if (cell->lcInfo.dffEnable) {
if (!dffs_exist) { if (!dffs_exist) {
dffs_exist = true; dffs_exist = true;
@ -70,7 +70,7 @@ bool Arch::logicCellsCompatible(const std::vector<const CellInfo *> &cells) cons
bool Arch::isBelLocationValid(BelId bel) const bool Arch::isBelLocationValid(BelId bel) const
{ {
if (getBelType(bel) == TYPE_ICESTORM_LC) { if (getBelType(bel) == id_ICESTORM_LC) {
std::vector<const CellInfo *> bel_cells; std::vector<const CellInfo *> bel_cells;
Loc bel_loc = getBelLocation(bel); Loc bel_loc = getBelLocation(bel);
for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
@ -92,7 +92,7 @@ bool Arch::isBelLocationValid(BelId bel) const
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{ {
if (cell->type == id_icestorm_lc) { if (cell->type == id_icestorm_lc) {
NPNR_ASSERT(getBelType(bel) == TYPE_ICESTORM_LC); NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC);
std::vector<const CellInfo *> bel_cells; std::vector<const CellInfo *> bel_cells;
Loc bel_loc = getBelLocation(bel); Loc bel_loc = getBelLocation(bel);
@ -110,11 +110,11 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
// Find shared PLL by looking for driving bel siblings from D_IN_0 // Find shared PLL by looking for driving bel siblings from D_IN_0
// that are a PLL clock output. // that are a PLL clock output.
auto wire = getBelPinWire(bel, PIN_D_IN_0); auto wire = getBelPinWire(bel, id_D_IN_0);
PortPin pll_bel_pin; IdString pll_bel_pin;
BelId pll_bel; BelId pll_bel;
for (auto pin : getWireBelPins(wire)) { for (auto pin : getWireBelPins(wire)) {
if (pin.pin == PIN_PLLOUT_A || pin.pin == PIN_PLLOUT_B) { if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) {
pll_bel = pin.bel; pll_bel = pin.bel;
pll_bel_pin = pin.pin; pll_bel_pin = pin.pin;
break; break;
@ -126,7 +126,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
// Is a PLL placed in this PLL bel? // Is a PLL placed in this PLL bel?
if (pll_cell != nullptr) { if (pll_cell != nullptr) {
// Is the shared port driving a net? // Is the shared port driving a net?
auto pi = pll_cell->ports[portPinToId(pll_bel_pin)]; auto pi = pll_cell->ports[pll_bel_pin];
if (pi.net != nullptr) { if (pi.net != nullptr) {
// Are we perhaps a PAD INPUT Bel that can be placed here? // Are we perhaps a PAD INPUT Bel that can be placed here?
if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) {
@ -140,7 +140,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
} else if (cell->type == id_sb_gb) { } else if (cell->type == id_sb_gb) {
NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr); NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr);
const NetInfo *net = cell->ports.at(id_glb_buf_out).net; const NetInfo *net = cell->ports.at(id_glb_buf_out).net;
IdString glb_net = getWireName(getBelPinWire(bel, PIN_GLOBAL_BUFFER_OUTPUT)); IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT));
int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); int glb_id = std::stoi(std::string("") + glb_net.str(this).back());
if (net->is_reset && net->is_enable) if (net->is_reset && net->is_enable)
return false; return false;

View File

@ -49,13 +49,6 @@ void arch_wrap_python()
class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin); class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
enum_<PortPin>("PortPin")
#define X(t) .value("PIN_" #t, PIN_##t)
#include "portpins.inc"
;
#undef X
auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>()); auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init) auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
.def("checksum", &Context::checksum) .def("checksum", &Context::checksum)
@ -63,7 +56,7 @@ void arch_wrap_python()
.def("place", &Context::place) .def("place", &Context::place)
.def("route", &Context::route); .def("route", &Context::route);
fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<BelType>, fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<IdString>,
conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType"); conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType");
fn_wrapper_1a<Context, decltype(&Context::checkBelAvail), &Context::checkBelAvail, pass_through<bool>, fn_wrapper_1a<Context, decltype(&Context::checkBelAvail), &Context::checkBelAvail, pass_through<bool>,
conv_from_str<BelId>>::def_wrap(ctx_cls, "checkBelAvail"); conv_from_str<BelId>>::def_wrap(ctx_cls, "checkBelAvail");
@ -81,7 +74,7 @@ void arch_wrap_python()
"getBels"); "getBels");
fn_wrapper_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>, fn_wrapper_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>,
conv_from_str<BelId>, conv_from_str<PortPin>>::def_wrap(ctx_cls, "getBelPinWire"); conv_from_str<BelId>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getBelPinWire");
fn_wrapper_1a<Context, decltype(&Context::getWireBelPins), &Context::getWireBelPins, wrap_context<BelPinRange>, fn_wrapper_1a<Context, decltype(&Context::getWireBelPins), &Context::getWireBelPins, wrap_context<BelPinRange>,
conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireBelPins"); conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireBelPins");

View File

@ -41,13 +41,6 @@ template <> struct string_converter<BelId>
} }
}; };
template <> struct string_converter<BelType>
{
BelType from_str(Context *ctx, std::string name) { return ctx->belTypeFromId(ctx->id(name)); }
std::string to_str(Context *ctx, BelType typ) { return ctx->belTypeToId(typ).str(ctx); }
};
template <> struct string_converter<WireId> template <> struct string_converter<WireId>
{ {
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); } WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
@ -62,13 +55,6 @@ template <> struct string_converter<PipId>
std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); } std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); }
}; };
template <> struct string_converter<PortPin>
{
PortPin from_str(Context *ctx, std::string name) { return ctx->portPinFromId(ctx->id(name)); }
std::string to_str(Context *ctx, PortPin id) { return ctx->portPinToId(id).str(ctx); }
};
} // namespace PythonConversion } // namespace PythonConversion
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -48,34 +48,17 @@ struct DelayInfo
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
enum BelType : int32_t enum ConstIds
{ {
TYPE_NONE, ID_NONE
TYPE_ICESTORM_LC, #define X(t) , ID_##t
TYPE_ICESTORM_RAM, #include "constids.inc"
TYPE_SB_IO, #undef X
TYPE_SB_GB,
TYPE_ICESTORM_PLL,
TYPE_SB_WARMBOOT,
TYPE_ICESTORM_DSP,
TYPE_ICESTORM_HFOSC,
TYPE_ICESTORM_LFOSC,
TYPE_SB_I2C,
TYPE_SB_SPI,
TYPE_IO_I3C,
TYPE_SB_LEDDA_IP,
TYPE_SB_RGBA_DRV,
TYPE_ICESTORM_SPRAM,
}; };
enum PortPin : int32_t #define X(t) static constexpr auto id_##t = IdString(ID_##t);
{ #include "constids.inc"
PIN_NONE,
#define X(t) PIN_##t,
#include "portpins.inc"
#undef X #undef X
PIN_MAXIDX
};
struct BelId struct BelId
{ {
@ -151,7 +134,7 @@ struct NetInfo;
struct ArchCellInfo struct ArchCellInfo
{ {
BelType belType = TYPE_NONE; IdString belType;
union union
{ {
struct struct
@ -186,14 +169,6 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PipId>
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &pip) const noexcept { return hash<int>()(pip.index); } std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &pip) const noexcept { return hash<int>()(pip.index); }
}; };
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType> : hash<int>
{
};
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int>
{
};
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId> template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId>
{ {
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept

View File

@ -300,12 +300,12 @@ void write_asc(const Context *ctx, std::ostream &out)
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC]; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC];
BelId sw_bel; BelId sw_bel;
sw_bel.index = sw_bel_idx; sw_bel.index = sw_bel_idx;
NPNR_ASSERT(ctx->getBelType(sw_bel) == TYPE_ICESTORM_LC); NPNR_ASSERT(ctx->getBelType(sw_bel) == id_ICESTORM_LC);
if (ci.wire_data[ctx->getPipDstWire(pip).index].type == WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT) if (ci.wire_data[ctx->getPipDstWire(pip).index].type == WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT)
continue; // Permutation pips continue; // Permutation pips
BelPin output = get_one_bel_pin(ctx, ctx->getPipDstWire(pip)); BelPin output = get_one_bel_pin(ctx, ctx->getPipDstWire(pip));
NPNR_ASSERT(output.bel == sw_bel && output.pin == PIN_O); NPNR_ASSERT(output.bel == sw_bel && output.pin == id_O);
unsigned lut_init; unsigned lut_init;
WireId permWire; WireId permWire;
@ -382,7 +382,7 @@ void write_asc(const Context *ctx, std::ostream &out)
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
unused.insert(i); unused.insert(i);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
WireId lut_wire = ctx->getBelPinWire(bel, PortPin(PIN_I0 + i)); WireId lut_wire = ctx->getBelPinWire(bel, IdString(ID_I0 + i));
for (auto pip : ctx->getPipsUphill(lut_wire)) { for (auto pip : ctx->getPipsUphill(lut_wire)) {
if (ctx->getBoundPipNet(pip) != nullptr) { if (ctx->getBoundPipNet(pip) != nullptr) {
std::string name = ci.wire_data[ctx->getPipSrcWire(pip).index].name.get(); std::string name = ci.wire_data[ctx->getPipSrcWire(pip).index].name.get();
@ -458,8 +458,8 @@ void write_asc(const Context *ctx, std::ostream &out)
NPNR_ASSERT(iez != -1); NPNR_ASSERT(iez != -1);
bool input_en = false; bool input_en = false;
if ((ctx->wire_to_net[ctx->getBelPinWire(bel, PIN_D_IN_0).index] != nullptr) || if ((ctx->wire_to_net[ctx->getBelPinWire(bel, id_D_IN_0).index] != nullptr) ||
(ctx->wire_to_net[ctx->getBelPinWire(bel, PIN_D_IN_1).index] != nullptr)) { (ctx->wire_to_net[ctx->getBelPinWire(bel, id_D_IN_1).index] != nullptr)) {
input_en = true; input_en = true;
} }
@ -578,10 +578,10 @@ void write_asc(const Context *ctx, std::ostream &out)
// Get IO Bel that this PLL port goes through by finding sibling // Get IO Bel that this PLL port goes through by finding sibling
// Bel driving the same wire via PIN_D_IN_0. // Bel driving the same wire via PIN_D_IN_0.
auto wire = ctx->getBelPinWire(cell.second->bel, ctx->portPinFromId(port.second.name)); auto wire = ctx->getBelPinWire(cell.second->bel, port.second.name);
BelId io_bel; BelId io_bel;
for (auto pin : ctx->getWireBelPins(wire)) { for (auto pin : ctx->getWireBelPins(wire)) {
if (pin.pin == PIN_D_IN_0) { if (pin.pin == id_D_IN_0) {
io_bel = pin.bel; io_bel = pin.bel;
break; break;
} }
@ -618,7 +618,7 @@ void write_asc(const Context *ctx, std::ostream &out)
} }
// Set config bits in unused IO and RAM // Set config bits in unused IO and RAM
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->bel_to_cell[bel.index] == nullptr && ctx->getBelType(bel) == TYPE_SB_IO) { if (ctx->bel_to_cell[bel.index] == nullptr && ctx->getBelType(bel) == id_SB_IO) {
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
const BelInfoPOD &beli = ci.bel_data[bel.index]; const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z; int x = beli.x, y = beli.y, z = beli.z;
@ -633,7 +633,7 @@ void write_asc(const Context *ctx, std::ostream &out)
set_ie_bit_logical(ctx, ti, config.at(iey).at(iex), "IoCtrl.IE_" + std::to_string(iez), true); set_ie_bit_logical(ctx, ti, config.at(iey).at(iex), "IoCtrl.IE_" + std::to_string(iez), true);
set_ie_bit_logical(ctx, ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false); set_ie_bit_logical(ctx, ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false);
} }
} else if (ctx->bel_to_cell[bel.index] == nullptr && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { } else if (ctx->bel_to_cell[bel.index] == nullptr && ctx->getBelType(bel) == id_ICESTORM_RAM) {
const BelInfoPOD &beli = ci.bel_data[bel.index]; const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y; int x = beli.x, y = beli.y;
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB]; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB];
@ -877,7 +877,7 @@ bool read_asc(Context *ctx, std::istream &in)
} }
} }
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) == TYPE_ICESTORM_LC) { if (ctx->getBelType(bel) == id_ICESTORM_LC) {
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC]; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC];
const BelInfoPOD &beli = ci.bel_data[bel.index]; const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z; int x = beli.x, y = beli.y, z = beli.z;
@ -900,7 +900,7 @@ bool read_asc(Context *ctx, std::istream &in)
// TODO: Add port mapping to nets and assign values of properties // TODO: Add port mapping to nets and assign values of properties
} }
} }
if (ctx->getBelType(bel) == TYPE_SB_IO) { if (ctx->getBelType(bel) == id_SB_IO) {
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
const BelInfoPOD &beli = ci.bel_data[bel.index]; const BelInfoPOD &beli = ci.bel_data[bel.index];
int x = beli.x, y = beli.y, z = beli.z; int x = beli.x, y = beli.y, z = beli.z;
@ -929,35 +929,35 @@ bool read_asc(Context *ctx, std::istream &in)
for (auto belpin : ctx->getWireBelPins(wire)) { for (auto belpin : ctx->getWireBelPins(wire)) {
if (ctx->checkBelAvail(belpin.bel)) { if (ctx->checkBelAvail(belpin.bel)) {
if (ctx->getBelType(belpin.bel) == TYPE_ICESTORM_LC) { if (ctx->getBelType(belpin.bel) == id_ICESTORM_LC) {
std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LC")); std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LC"));
IdString name = created->name; IdString name = created->name;
ctx->cells[name] = std::move(created); ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK); ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets // TODO: Add port mapping to nets
} }
if (ctx->getBelType(belpin.bel) == TYPE_SB_IO) { if (ctx->getBelType(belpin.bel) == id_SB_IO) {
std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_IO")); std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_IO"));
IdString name = created->name; IdString name = created->name;
ctx->cells[name] = std::move(created); ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK); ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets // TODO: Add port mapping to nets
} }
if (ctx->getBelType(belpin.bel) == TYPE_SB_GB) { if (ctx->getBelType(belpin.bel) == id_SB_GB) {
std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_GB")); std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_GB"));
IdString name = created->name; IdString name = created->name;
ctx->cells[name] = std::move(created); ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK); ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets // TODO: Add port mapping to nets
} }
if (ctx->getBelType(belpin.bel) == TYPE_SB_WARMBOOT) { if (ctx->getBelType(belpin.bel) == id_SB_WARMBOOT) {
std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_WARMBOOT")); std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("SB_WARMBOOT"));
IdString name = created->name; IdString name = created->name;
ctx->cells[name] = std::move(created); ctx->cells[name] = std::move(created);
ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK); ctx->bindBel(belpin.bel, ctx->cells[name].get(), STRENGTH_WEAK);
// TODO: Add port mapping to nets // TODO: Add port mapping to nets
} }
if (ctx->getBelType(belpin.bel) == TYPE_ICESTORM_LFOSC) { if (ctx->getBelType(belpin.bel) == id_ICESTORM_LFOSC) {
std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC")); std::unique_ptr<CellInfo> created = create_ice_cell(ctx, ctx->id("ICESTORM_LFOSC"));
IdString name = created->name; IdString name = created->name;
ctx->cells[name] = std::move(created); ctx->cells[name] = std::move(created);
@ -972,7 +972,7 @@ bool read_asc(Context *ctx, std::istream &in)
for (auto &cell : ctx->cells) { for (auto &cell : ctx->cells) {
if (cell.second->bel != BelId()) { if (cell.second->bel != BelId()) {
for (auto &port : cell.second->ports) { for (auto &port : cell.second->ports) {
PortPin pin = ctx->portPinFromId(port.first); IdString pin = port.first;
WireId wire = ctx->getBelPinWire(cell.second->bel, pin); WireId wire = ctx->getBelPinWire(cell.second->bel, pin);
if (wire != WireId()) { if (wire != WireId()) {
NetInfo *net = ctx->getBoundWireNet(wire); NetInfo *net = ctx->getBoundWireNet(wire);

View File

@ -7,7 +7,7 @@ import argparse
parser = argparse.ArgumentParser(description="convert ICE40 chip database") parser = argparse.ArgumentParser(description="convert ICE40 chip database")
parser.add_argument("filename", type=str, help="chipdb input filename") parser.add_argument("filename", type=str, help="chipdb input filename")
parser.add_argument("-p", "--portspins", type=str, help="path to portpins.inc") parser.add_argument("-p", "--constids", type=str, help="path to constids.inc")
parser.add_argument("-g", "--gfxh", type=str, help="path to gfx.h") parser.add_argument("-g", "--gfxh", type=str, help="path to gfx.h")
parser.add_argument("--fast", type=str, help="path to timing data for fast part") parser.add_argument("--fast", type=str, help="path to timing data for fast part")
parser.add_argument("--slow", type=str, help="path to timing data for slow part") parser.add_argument("--slow", type=str, help="path to timing data for slow part")
@ -45,8 +45,7 @@ wire_xy = dict()
cbit_re = re.compile(r'B(\d+)\[(\d+)\]') cbit_re = re.compile(r'B(\d+)\[(\d+)\]')
portpins = dict() constids = dict()
beltypes = dict()
tiletypes = dict() tiletypes = dict()
wiretypes = dict() wiretypes = dict()
@ -56,7 +55,7 @@ wire_segments = dict()
fast_timings = None fast_timings = None
slow_timings = None slow_timings = None
with open(args.portspins) as f: with open(args.constids) as f:
for line in f: for line in f:
line = line.replace("(", " ") line = line.replace("(", " ")
line = line.replace(")", " ") line = line.replace(")", " ")
@ -65,8 +64,19 @@ with open(args.portspins) as f:
continue continue
assert len(line) == 2 assert len(line) == 2
assert line[0] == "X" assert line[0] == "X"
idx = len(portpins) + 1 idx = len(constids) + 1
portpins[line[1]] = idx constids[line[1]] = idx
constids["PLL"] = constids["ICESTORM_PLL"]
constids["WARMBOOT"] = constids["SB_WARMBOOT"]
constids["MAC16"] = constids["ICESTORM_DSP"]
constids["HFOSC"] = constids["ICESTORM_HFOSC"]
constids["LFOSC"] = constids["ICESTORM_LFOSC"]
constids["I2C"] = constids["SB_I2C"]
constids["SPI"] = constids["SB_SPI"]
constids["LEDDA_IP"] = constids["SB_LEDDA_IP"]
constids["RGBA_DRV"] = constids["SB_RGBA_DRV"]
constids["SPRAM"] = constids["ICESTORM_SPRAM"]
with open(args.gfxh) as f: with open(args.gfxh) as f:
state = 0 state = 0
@ -107,22 +117,6 @@ if args.fast is not None:
if args.slow is not None: if args.slow is not None:
slow_timings = read_timings(args.slow) slow_timings = read_timings(args.slow)
beltypes["ICESTORM_LC"] = 1
beltypes["ICESTORM_RAM"] = 2
beltypes["SB_IO"] = 3
beltypes["SB_GB"] = 4
beltypes["PLL"] = 5
beltypes["WARMBOOT"] = 6
beltypes["MAC16"] = 7
beltypes["HFOSC"] = 8
beltypes["LFOSC"] = 9
beltypes["I2C"] = 10
beltypes["SPI"] = 11
beltypes["IO_I3C"] = 12
beltypes["LEDDA_IP"] = 13
beltypes["RGBA_DRV"] = 14
beltypes["SPRAM"] = 15
tiletypes["NONE"] = 0 tiletypes["NONE"] = 0
tiletypes["LOGIC"] = 1 tiletypes["LOGIC"] = 1
tiletypes["IO"] = 2 tiletypes["IO"] = 2
@ -592,13 +586,13 @@ def add_bel_input(bel, wire, port):
if wire not in wire_belports: if wire not in wire_belports:
wire_belports[wire] = set() wire_belports[wire] = set()
wire_belports[wire].add((bel, port)) wire_belports[wire].add((bel, port))
bel_wires[bel].append((portpins[port], 0, wire)) bel_wires[bel].append((constids[port], 0, wire))
def add_bel_output(bel, wire, port): def add_bel_output(bel, wire, port):
if wire not in wire_belports: if wire not in wire_belports:
wire_belports[wire] = set() wire_belports[wire] = set()
wire_belports[wire].add((bel, port)) wire_belports[wire].add((bel, port))
bel_wires[bel].append((portpins[port], 1, wire)) bel_wires[bel].append((constids[port], 1, wire))
def add_bel_lc(x, y, z): def add_bel_lc(x, y, z):
bel = len(bel_name) bel = len(bel_name)
@ -768,7 +762,7 @@ def add_bel_ec(ec):
extra_cell_config[bel].append(entry) extra_cell_config[bel].append(entry)
cell_timings = {} cell_timings = {}
tmport_to_portpin = { tmport_to_constids = {
"posedge:clk": "CLK", "posedge:clk": "CLK",
"ce": "CEN", "ce": "CEN",
"sr": "SR", "sr": "SR",
@ -793,14 +787,14 @@ tmport_to_portpin = {
} }
for i in range(16): for i in range(16):
tmport_to_portpin["RDATA[%d]" % i] = "RDATA_%d" % i tmport_to_constids["RDATA[%d]" % i] = "RDATA_%d" % i
tmport_to_portpin["WDATA[%d]" % i] = "WDATA_%d" % i tmport_to_constids["WDATA[%d]" % i] = "WDATA_%d" % i
tmport_to_portpin["MASK[%d]" % i] = "MASK_%d" % i tmport_to_constids["MASK[%d]" % i] = "MASK_%d" % i
tmport_to_portpin["DATAOUT[%d]" % i] = "DATAOUT_%d" % i tmport_to_constids["DATAOUT[%d]" % i] = "DATAOUT_%d" % i
for i in range(11): for i in range(11):
tmport_to_portpin["RADDR[%d]" % i] = "RADDR_%d" % i tmport_to_constids["RADDR[%d]" % i] = "RADDR_%d" % i
tmport_to_portpin["WADDR[%d]" % i] = "WADDR_%d" % i tmport_to_constids["WADDR[%d]" % i] = "WADDR_%d" % i
def add_cell_timingdata(bel_type, timing_cell, fast_db, slow_db): def add_cell_timingdata(bel_type, timing_cell, fast_db, slow_db):
timing_entries = [] timing_entries = []
@ -808,9 +802,9 @@ def add_cell_timingdata(bel_type, timing_cell, fast_db, slow_db):
for key in database.keys(): for key in database.keys():
skey = key.split(".") skey = key.split(".")
if skey[0] == timing_cell: if skey[0] == timing_cell:
if skey[1] in tmport_to_portpin and skey[2] in tmport_to_portpin: if skey[1] in tmport_to_constids and skey[2] in tmport_to_constids:
iport = tmport_to_portpin[skey[1]] iport = tmport_to_constids[skey[1]]
oport = tmport_to_portpin[skey[2]] oport = tmport_to_constids[skey[2]]
fastdel = fast_db[key] if fast_db is not None else 0 fastdel = fast_db[key] if fast_db is not None else 0
slowdel = slow_db[key] if slow_db is not None else 0 slowdel = slow_db[key] if slow_db is not None else 0
timing_entries.append((iport, oport, fastdel, slowdel)) timing_entries.append((iport, oport, fastdel, slowdel))
@ -946,7 +940,7 @@ for bel in range(len(bel_name)):
bba.l("bel_data_%s" % dev_name, "BelInfoPOD") bba.l("bel_data_%s" % dev_name, "BelInfoPOD")
for bel in range(len(bel_name)): for bel in range(len(bel_name)):
bba.s(bel_name[bel], "name") bba.s(bel_name[bel], "name")
bba.u32(beltypes[bel_type[bel]], "type") bba.u32(constids[bel_type[bel]], "type")
bba.u32(len(bel_wires[bel]), "num_bel_wires") bba.u32(len(bel_wires[bel]), "num_bel_wires")
bba.r("bel_wires_%d" % bel, "bel_wires") bba.r("bel_wires_%d" % bel, "bel_wires")
bba.u8(bel_pos[bel][0], "x") bba.u8(bel_pos[bel][0], "x")
@ -1016,7 +1010,7 @@ for wire in range(num_wires):
bba.l("wire%d_bels" % wire, "BelPortPOD") bba.l("wire%d_bels" % wire, "BelPortPOD")
for belport in sorted(wire_belports[wire]): for belport in sorted(wire_belports[wire]):
bba.u32(belport[0], "bel_index") bba.u32(belport[0], "bel_index")
bba.u32(portpins[belport[1]], "port") bba.u32(constids[belport[1]], "port")
else: else:
num_bel_pins = 0 num_bel_pins = 0
@ -1246,18 +1240,18 @@ for info in packageinfo:
bba.r(info[2], "pins") bba.r(info[2], "pins")
for cell, timings in sorted(cell_timings.items()): for cell, timings in sorted(cell_timings.items()):
beltype = beltypes[cell] beltype = constids[cell]
bba.l("cell_paths_%d" % beltype, "CellPathDelayPOD") bba.l("cell_paths_%d" % beltype, "CellPathDelayPOD")
for entry in timings: for entry in timings:
fromport, toport, fast, slow = entry fromport, toport, fast, slow = entry
bba.u32(portpins[fromport], "from_port") bba.u32(constids[fromport], "from_port")
bba.u32(portpins[toport], "to_port") bba.u32(constids[toport], "to_port")
bba.u32(fast, "fast_delay") bba.u32(fast, "fast_delay")
bba.u32(slow, "slow_delay") bba.u32(slow, "slow_delay")
bba.l("cell_timings_%s" % dev_name, "CellTimingPOD") bba.l("cell_timings_%s" % dev_name, "CellTimingPOD")
for cell, timings in sorted(cell_timings.items()): for cell, timings in sorted(cell_timings.items()):
beltype = beltypes[cell] beltype = constids[cell]
bba.u32(beltype, "type") bba.u32(beltype, "type")
bba.u32(len(timings), "num_paths") bba.u32(len(timings), "num_paths")
bba.r("cell_paths_%d" % beltype, "path_delays") bba.r("cell_paths_%d" % beltype, "path_delays")

View File

@ -412,3 +412,19 @@ X(POWEROFF)
X(SLEEP) X(SLEEP)
X(STANDBY) X(STANDBY)
X(WREN) X(WREN)
X(ICESTORM_LC)
X(ICESTORM_RAM)
X(SB_IO)
X(SB_GB)
X(ICESTORM_PLL)
X(SB_WARMBOOT)
X(ICESTORM_DSP)
X(ICESTORM_HFOSC)
X(ICESTORM_LFOSC)
X(SB_I2C)
X(SB_SPI)
X(IO_I3C)
X(SB_LEDDA_IP)
X(SB_RGBA_DRV)
X(ICESTORM_SPRAM)

View File

@ -32,10 +32,10 @@ if (MSVC)
set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba) set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin)
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
add_custom_command(OUTPUT ${DEV_CC_BBA_DB} add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB} COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}
DEPENDS ${DEV_TXT_DB} ${DB_PY} DEPENDS ${DEV_TXT_DB} ${DB_PY}
) )
add_custom_command(OUTPUT ${DEV_CC_DB} add_custom_command(OUTPUT ${DEV_CC_DB}
@ -64,10 +64,10 @@ else()
set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba) set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc)
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
add_custom_command(OUTPUT ${DEV_CC_BBA_DB} add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new
COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB} COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
DEPENDS ${DEV_TXT_DB} ${DB_PY} DEPENDS ${DEV_TXT_DB} ${DB_PY}
) )

View File

@ -755,13 +755,13 @@ static void pack_special(Context *ctx)
bool constrained = false; bool constrained = false;
if (packed->attrs.find(ctx->id("BEL")) == packed->attrs.end()) { if (packed->attrs.find(ctx->id("BEL")) == packed->attrs.end()) {
for (auto bel : ctx->getBels()) { for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) != TYPE_ICESTORM_PLL) if (ctx->getBelType(bel) != id_ICESTORM_PLL)
continue; continue;
// A PAD PLL must have its' PACKAGEPIN on the SB_IO that's shared // A PAD PLL must have its' PACKAGEPIN on the SB_IO that's shared
// with PLLOUT_A. // with PLLOUT_A.
if (is_pad) { if (is_pad) {
auto pll_sb_io_belpin = ctx->getIOBSharingPLLPin(bel, PIN_PLLOUT_A); auto pll_sb_io_belpin = ctx->getIOBSharingPLLPin(bel, id_PLLOUT_A);
NPNR_ASSERT(pad_packagepin_net != nullptr); NPNR_ASSERT(pad_packagepin_net != nullptr);
auto pll_packagepin_driver = pad_packagepin_net->driver; auto pll_packagepin_driver = pad_packagepin_net->driver;
NPNR_ASSERT(pll_packagepin_driver.cell != nullptr); NPNR_ASSERT(pll_packagepin_driver.cell != nullptr);
@ -846,7 +846,7 @@ static void pack_special(Context *ctx)
} }
// Find wire that will be driven by this port. // Find wire that will be driven by this port.
const auto pll_out_wire = ctx->getBelPinWire(pll_bel, ctx->portPinFromId(port.name)); const auto pll_out_wire = ctx->getBelPinWire(pll_bel, port.name);
NPNR_ASSERT(pll_out_wire.index != -1); NPNR_ASSERT(pll_out_wire.index != -1);
// Now, constrain all LUTs on the output of the signal to be at // Now, constrain all LUTs on the output of the signal to be at