Merge pull request #45 from YosysHQ/constids
Get rid of PortPin and BelType
This commit is contained in:
commit
b326b03a52
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +300,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)) {
|
||||||
@ -423,7 +423,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);
|
||||||
@ -451,7 +451,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;
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
72
ecp5/arch.cc
72
ecp5/arch.cc
@ -43,50 +43,13 @@ static std::tuple<int, int, std::string> split_identifier_name(const std::string
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
IdString Arch::belTypeToId(BelType type) const
|
|
||||||
{
|
|
||||||
if (type == TYPE_TRELLIS_SLICE)
|
|
||||||
return id("TRELLIS_SLICE");
|
|
||||||
if (type == TYPE_TRELLIS_IO)
|
|
||||||
return id("TRELLIS_IO");
|
|
||||||
return IdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
BelType Arch::belTypeFromId(IdString type) const
|
|
||||||
{
|
|
||||||
if (type == id("TRELLIS_SLICE"))
|
|
||||||
return TYPE_TRELLIS_SLICE;
|
|
||||||
if (type == id("TRELLIS_IO"))
|
|
||||||
return TYPE_TRELLIS_IO;
|
|
||||||
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 "constids.inc"
|
||||||
#include "portpins.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(); }
|
||||||
@ -129,14 +92,6 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
|
|
||||||
if (!package_info)
|
if (!package_info)
|
||||||
log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
|
log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
|
||||||
|
|
||||||
id_trellis_slice = id("TRELLIS_SLICE");
|
|
||||||
id_clk = id("CLK");
|
|
||||||
id_lsr = id("LSR");
|
|
||||||
id_clkmux = id("CLKMUX");
|
|
||||||
id_lsrmux = id("LSRMUX");
|
|
||||||
id_srmode = id("SRMODE");
|
|
||||||
id_mode = id("MODE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -209,7 +164,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
|
|||||||
return br;
|
return br;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
|
WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
||||||
{
|
{
|
||||||
WireId ret;
|
WireId ret;
|
||||||
|
|
||||||
@ -218,7 +173,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
|
|||||||
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
||||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
const BelWirePOD *bel_wires = locInfo(bel)->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++)
|
||||||
if (bel_wires[i].port == pin) {
|
if (bel_wires[i].port == pin.index) {
|
||||||
ret.location = bel.location + bel_wires[i].rel_wire_loc;
|
ret.location = bel.location + bel_wires[i].rel_wire_loc;
|
||||||
ret.index = bel_wires[i].wire_index;
|
ret.index = bel_wires[i].wire_index;
|
||||||
break;
|
break;
|
||||||
@ -227,7 +182,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortType Arch::getBelPinType(BelId bel, PortPin pin) const
|
PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
|
|
||||||
@ -235,7 +190,7 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
|
|||||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
const BelWirePOD *bel_wires = locInfo(bel)->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++)
|
||||||
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);
|
||||||
|
|
||||||
return PORT_INOUT;
|
return PORT_INOUT;
|
||||||
@ -374,16 +329,19 @@ BelId Arch::getPioByFunctionName(const std::string &name) const
|
|||||||
return BelId();
|
return BelId();
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
||||||
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires;
|
||||||
const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get();
|
const BelWirePOD *bel_wires = locInfo(bel)->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);
|
IdString id;
|
||||||
|
id.index = bel_wires[i].port;
|
||||||
|
ret.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -446,7 +404,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
|||||||
int z = locInfo(bel)->bel_data[bel.index].z;
|
int z = locInfo(bel)->bel_data[bel.index].z;
|
||||||
auto bel_type = getBelType(bel);
|
auto bel_type = getBelType(bel);
|
||||||
|
|
||||||
if (bel_type == TYPE_TRELLIS_SLICE) {
|
if (bel_type == id_TRELLIS_SLICE) {
|
||||||
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;
|
||||||
@ -457,7 +415,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
|||||||
ret.push_back(el);
|
ret.push_back(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bel_type == TYPE_TRELLIS_IO) {
|
if (bel_type == id_TRELLIS_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;
|
||||||
|
30
ecp5/arch.h
30
ecp5/arch.h
@ -50,13 +50,13 @@ template <typename T> struct RelPtr
|
|||||||
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
NPNR_PACKED_STRUCT(struct BelWirePOD {
|
||||||
LocationPOD rel_wire_loc;
|
LocationPOD rel_wire_loc;
|
||||||
int32_t wire_index;
|
int32_t wire_index;
|
||||||
PortPin port;
|
int32_t port;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||||
RelPtr<char> name;
|
RelPtr<char> name;
|
||||||
BelType type;
|
int32_t type;
|
||||||
int32_t z;
|
int32_t z;
|
||||||
int32_t num_bel_wires;
|
int32_t num_bel_wires;
|
||||||
RelPtr<BelWirePOD> bel_wires;
|
RelPtr<BelWirePOD> bel_wires;
|
||||||
@ -65,7 +65,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
|||||||
NPNR_PACKED_STRUCT(struct BelPortPOD {
|
NPNR_PACKED_STRUCT(struct BelPortPOD {
|
||||||
LocationPOD rel_bel_loc;
|
LocationPOD rel_bel_loc;
|
||||||
int32_t bel_index;
|
int32_t bel_index;
|
||||||
PortPin port;
|
int32_t port;
|
||||||
});
|
});
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct PipInfoPOD {
|
NPNR_PACKED_STRUCT(struct PipInfoPOD {
|
||||||
@ -239,7 +239,7 @@ struct BelPinIterator
|
|||||||
BelPin ret;
|
BelPin ret;
|
||||||
ret.bel.index = ptr->bel_index;
|
ret.bel.index = ptr->bel_index;
|
||||||
ret.bel.location = wire_loc + ptr->rel_bel_loc;
|
ret.bel.location = wire_loc + ptr->rel_bel_loc;
|
||||||
ret.pin = ptr->port;
|
ret.pin.index = ptr->port;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -417,11 +417,6 @@ struct Arch : BaseCtx
|
|||||||
ArchArgs archArgs() const { return args; }
|
ArchArgs archArgs() const { return args; }
|
||||||
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 chip_info->width; };
|
int getGridDimX() const { return chip_info->width; };
|
||||||
@ -518,13 +513,15 @@ struct Arch : BaseCtx
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
BelType getBelType(BelId bel) const
|
IdString getBelType(BelId bel) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(bel != BelId());
|
NPNR_ASSERT(bel != BelId());
|
||||||
return locInfo(bel)->bel_data[bel.index].type;
|
IdString id;
|
||||||
|
id.index = locInfo(bel)->bel_data[bel.index].type;
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireId getBelPinWire(BelId bel, PortPin pin) const;
|
WireId getBelPinWire(BelId bel, IdString pin) const;
|
||||||
|
|
||||||
BelPinRange getWireBelPins(WireId wire) const
|
BelPinRange getWireBelPins(WireId wire) const
|
||||||
{
|
{
|
||||||
@ -537,7 +534,7 @@ struct Arch : BaseCtx
|
|||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PortPin> getBelPins(BelId bel) const;
|
std::vector<IdString> getBelPins(BelId bel) const;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
@ -786,7 +783,7 @@ struct Arch : BaseCtx
|
|||||||
std::string getPioFunctionName(BelId bel) const;
|
std::string getPioFunctionName(BelId bel) const;
|
||||||
BelId getPioByFunctionName(const std::string &name) const;
|
BelId getPioByFunctionName(const std::string &name) const;
|
||||||
|
|
||||||
PortType getBelPinType(BelId bel, PortPin pin) const;
|
PortType getBelPinType(BelId bel, IdString pin) const;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
@ -862,11 +859,6 @@ struct Arch : BaseCtx
|
|||||||
}
|
}
|
||||||
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
|
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString id_trellis_slice;
|
|
||||||
IdString id_clk, id_lsr;
|
|
||||||
IdString id_clkmux, id_lsrmux;
|
|
||||||
IdString id_srmode, id_mode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -40,21 +40,21 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
|
|||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto cell : cells) {
|
for (auto cell : cells) {
|
||||||
if (first) {
|
if (first) {
|
||||||
clk_sig = port_or_nullptr(cell, id_clk);
|
clk_sig = port_or_nullptr(cell, id_CLK);
|
||||||
lsr_sig = port_or_nullptr(cell, id_lsr);
|
lsr_sig = port_or_nullptr(cell, id_LSR);
|
||||||
CLKMUX = str_or_default(cell->params, id_clkmux, "CLK");
|
CLKMUX = str_or_default(cell->params, id_CLKMUX, "CLK");
|
||||||
LSRMUX = str_or_default(cell->params, id_lsrmux, "LSR");
|
LSRMUX = str_or_default(cell->params, id_LSRMUX, "LSR");
|
||||||
SRMODE = str_or_default(cell->params, id_srmode, "CE_OVER_LSR");
|
SRMODE = str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR");
|
||||||
} else {
|
} else {
|
||||||
if (port_or_nullptr(cell, id_clk) != clk_sig)
|
if (port_or_nullptr(cell, id_CLK) != clk_sig)
|
||||||
return false;
|
return false;
|
||||||
if (port_or_nullptr(cell, id_lsr) != lsr_sig)
|
if (port_or_nullptr(cell, id_LSR) != lsr_sig)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_clkmux, "CLK") != CLKMUX)
|
if (str_or_default(cell->params, id_CLKMUX, "CLK") != CLKMUX)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_lsrmux, "LSR") != LSRMUX)
|
if (str_or_default(cell->params, id_LSRMUX, "LSR") != LSRMUX)
|
||||||
return false;
|
return false;
|
||||||
if (str_or_default(cell->params, id_srmode, "CE_OVER_LSR") != SRMODE)
|
if (str_or_default(cell->params, id_SRMODE, "CE_OVER_LSR") != SRMODE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
@ -64,7 +64,7 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
|
|||||||
|
|
||||||
bool Arch::isBelLocationValid(BelId bel) const
|
bool Arch::isBelLocationValid(BelId bel) const
|
||||||
{
|
{
|
||||||
if (getBelType(bel) == TYPE_TRELLIS_SLICE) {
|
if (getBelType(bel) == id_TRELLIS_SLICE) {
|
||||||
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)) {
|
||||||
@ -85,8 +85,8 @@ 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_trellis_slice) {
|
if (cell->type == id_TRELLIS_SLICE) {
|
||||||
NPNR_ASSERT(getBelType(bel) == TYPE_TRELLIS_SLICE);
|
NPNR_ASSERT(getBelType(bel) == id_TRELLIS_SLICE);
|
||||||
|
|
||||||
std::vector<const CellInfo *> bel_cells;
|
std::vector<const CellInfo *> bel_cells;
|
||||||
Loc bel_loc = getBelLocation(bel);
|
Loc bel_loc = getBelLocation(bel);
|
||||||
|
@ -39,13 +39,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)
|
||||||
@ -53,7 +46,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");
|
||||||
@ -71,7 +64,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");
|
||||||
|
|
||||||
|
@ -40,13 +40,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)); }
|
||||||
@ -61,13 +54,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
|
||||||
|
@ -51,21 +51,17 @@ struct DelayInfo
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
enum BelType : int32_t
|
enum ConstIds
|
||||||
{
|
{
|
||||||
TYPE_NONE,
|
ID_NONE
|
||||||
TYPE_TRELLIS_SLICE,
|
#define X(t) , ID_##t
|
||||||
TYPE_TRELLIS_IO
|
#include "constids.inc"
|
||||||
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct LocationPOD { int16_t x, y; });
|
NPNR_PACKED_STRUCT(struct LocationPOD { int16_t x, y; });
|
||||||
|
|
||||||
@ -209,11 +205,4 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType> : hash<int>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
@ -44,3 +44,9 @@ X(I)
|
|||||||
X(O)
|
X(O)
|
||||||
X(T)
|
X(T)
|
||||||
X(B)
|
X(B)
|
||||||
|
|
||||||
|
X(TRELLIS_SLICE)
|
||||||
|
X(TRELLIS_IO)
|
||||||
|
X(CLKMUX)
|
||||||
|
X(LSRMUX)
|
||||||
|
X(SRMODE)
|
@ -25,9 +25,9 @@ if (MSVC)
|
|||||||
foreach (dev ${devices})
|
foreach (dev ${devices})
|
||||||
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
|
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
|
||||||
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
|
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
|
||||||
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/portpins.inc)
|
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
|
||||||
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
|
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
|
||||||
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_PORTS_INC} ${dev} > ${DEV_CC_BBA_DB}
|
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
|
||||||
DEPENDS ${DB_PY}
|
DEPENDS ${DB_PY}
|
||||||
)
|
)
|
||||||
add_custom_command(OUTPUT ${DEV_CC_DB}
|
add_custom_command(OUTPUT ${DEV_CC_DB}
|
||||||
@ -45,9 +45,9 @@ else()
|
|||||||
foreach (dev ${devices})
|
foreach (dev ${devices})
|
||||||
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
|
set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
|
||||||
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
|
set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
|
||||||
set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/portpins.inc)
|
set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
|
||||||
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
|
add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
|
||||||
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_PORTS_INC} ${dev} > ${DEV_CC_BBA_DB}.new
|
COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${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 ${DB_PY}
|
DEPENDS ${DB_PY}
|
||||||
)
|
)
|
||||||
|
@ -11,7 +11,7 @@ tiletype_names = dict()
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description="import ECP5 routing and bels from Project Trellis")
|
parser = argparse.ArgumentParser(description="import ECP5 routing and bels from Project Trellis")
|
||||||
parser.add_argument("device", type=str, help="target device")
|
parser.add_argument("device", type=str, help="target device")
|
||||||
parser.add_argument("-p", "--portspins", type=str, help="path to portpins.inc")
|
parser.add_argument("-p", "--constids", type=str, help="path to constids.inc")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ def get_tiletype_index(name):
|
|||||||
return idx
|
return idx
|
||||||
|
|
||||||
|
|
||||||
portpins = dict()
|
constids = dict()
|
||||||
|
|
||||||
|
|
||||||
class BinaryBlobAssembler:
|
class BinaryBlobAssembler:
|
||||||
@ -78,12 +78,6 @@ class BinaryBlobAssembler:
|
|||||||
def pop(self):
|
def pop(self):
|
||||||
print("pop")
|
print("pop")
|
||||||
|
|
||||||
bel_types = {
|
|
||||||
"NONE": 0,
|
|
||||||
"SLICE": 1,
|
|
||||||
"PIO": 2
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_bel_index(ddrg, loc, name):
|
def get_bel_index(ddrg, loc, name):
|
||||||
loctype = ddrg.locationTypes[ddrg.typeAtLocation[loc]]
|
loctype = ddrg.locationTypes[ddrg.typeAtLocation[loc]]
|
||||||
idx = 0
|
idx = 0
|
||||||
@ -181,7 +175,7 @@ def write_database(dev_name, chip, ddrg, endianness):
|
|||||||
for bp in wire.belPins:
|
for bp in wire.belPins:
|
||||||
write_loc(bp.bel.rel, "rel_bel_loc")
|
write_loc(bp.bel.rel, "rel_bel_loc")
|
||||||
bba.u32(bp.bel.id, "bel_index")
|
bba.u32(bp.bel.id, "bel_index")
|
||||||
bba.u32(portpins[ddrg.to_str(bp.pin)], "port")
|
bba.u32(constids[ddrg.to_str(bp.pin)], "port")
|
||||||
bba.l("loc%d_wires" % idx, "WireInfoPOD")
|
bba.l("loc%d_wires" % idx, "WireInfoPOD")
|
||||||
for wire_idx in range(len(loctype.wires)):
|
for wire_idx in range(len(loctype.wires)):
|
||||||
wire = loctype.wires[wire_idx]
|
wire = loctype.wires[wire_idx]
|
||||||
@ -200,13 +194,13 @@ def write_database(dev_name, chip, ddrg, endianness):
|
|||||||
for pin in bel.wires:
|
for pin in bel.wires:
|
||||||
write_loc(pin.wire.rel, "rel_wire_loc")
|
write_loc(pin.wire.rel, "rel_wire_loc")
|
||||||
bba.u32(pin.wire.id, "wire_index")
|
bba.u32(pin.wire.id, "wire_index")
|
||||||
bba.u32(portpins[ddrg.to_str(pin.pin)], "port")
|
bba.u32(constids[ddrg.to_str(pin.pin)], "port")
|
||||||
bba.u32(int(pin.dir), "dir")
|
bba.u32(int(pin.dir), "dir")
|
||||||
bba.l("loc%d_bels" % idx, "BelInfoPOD")
|
bba.l("loc%d_bels" % idx, "BelInfoPOD")
|
||||||
for bel_idx in range(len(loctype.bels)):
|
for bel_idx in range(len(loctype.bels)):
|
||||||
bel = loctype.bels[bel_idx]
|
bel = loctype.bels[bel_idx]
|
||||||
bba.s(ddrg.to_str(bel.name), "name")
|
bba.s(ddrg.to_str(bel.name), "name")
|
||||||
bba.u32(bel_types[ddrg.to_str(bel.type)], "type")
|
bba.u32(constids[ddrg.to_str(bel.type)], "type")
|
||||||
bba.u32(bel.z, "z")
|
bba.u32(bel.z, "z")
|
||||||
bba.u32(len(bel.wires), "num_bel_wires")
|
bba.u32(len(bel.wires), "num_bel_wires")
|
||||||
bba.r("loc%d_bel%d_wires" % (idx, bel_idx), "bel_wires")
|
bba.r("loc%d_bel%d_wires" % (idx, bel_idx), "bel_wires")
|
||||||
@ -305,7 +299,7 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Read port pin file
|
# Read port pin file
|
||||||
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(")", " ")
|
||||||
@ -314,8 +308,12 @@ def main():
|
|||||||
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["SLICE"] = constids["TRELLIS_SLICE"]
|
||||||
|
constids["PIO"] = constids["TRELLIS_IO"]
|
||||||
|
|
||||||
# print("Initialising chip...")
|
# print("Initialising chip...")
|
||||||
chip = pytrellis.Chip(dev_names[args.device])
|
chip = pytrellis.Chip(dev_names[args.device])
|
||||||
|
@ -238,15 +238,15 @@ CellInfo *Arch::getConflictingBelCell(BelId bel) const { return bels.at(bel).bou
|
|||||||
|
|
||||||
const std::vector<BelId> &Arch::getBels() const { return bel_ids; }
|
const std::vector<BelId> &Arch::getBels() const { return bel_ids; }
|
||||||
|
|
||||||
BelType Arch::getBelType(BelId bel) const { return bels.at(bel).type; }
|
IdString Arch::getBelType(BelId bel) const { return bels.at(bel).type; }
|
||||||
|
|
||||||
WireId Arch::getBelPinWire(BelId bel, PortPin pin) const { return bels.at(bel).pins.at(pin).wire; }
|
WireId Arch::getBelPinWire(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).wire; }
|
||||||
|
|
||||||
PortType Arch::getBelPinType(BelId bel, PortPin pin) const { return bels.at(bel).pins.at(pin).type; }
|
PortType Arch::getBelPinType(BelId bel, IdString pin) const { return bels.at(bel).pins.at(pin).type; }
|
||||||
|
|
||||||
std::vector<PortPin> Arch::getBelPins(BelId bel) const
|
std::vector<IdString> Arch::getBelPins(BelId bel) const
|
||||||
{
|
{
|
||||||
std::vector<PortPin> ret;
|
std::vector<IdString> ret;
|
||||||
for (auto &it : bels.at(bel).pins)
|
for (auto &it : bels.at(bel).pins)
|
||||||
ret.push_back(it.first);
|
ret.push_back(it.first);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -130,12 +130,6 @@ struct Arch : BaseCtx
|
|||||||
ArchArgs archArgs() const { return args; }
|
ArchArgs archArgs() const { return args; }
|
||||||
IdString archArgsToId(ArchArgs args) const { return id("none"); }
|
IdString archArgsToId(ArchArgs args) const { return id("none"); }
|
||||||
|
|
||||||
IdString belTypeToId(BelType type) const { return type; }
|
|
||||||
IdString portPinToId(PortPin type) const { return type; }
|
|
||||||
|
|
||||||
BelType belTypeFromId(IdString id) const { return id; }
|
|
||||||
PortPin portPinFromId(IdString id) const { return id; }
|
|
||||||
|
|
||||||
int getGridDimX() const { return gridDimX; }
|
int getGridDimX() const { return gridDimX; }
|
||||||
int getGridDimY() const { return gridDimY; }
|
int getGridDimY() const { return gridDimY; }
|
||||||
int getTileDimZ(int x, int y) const { return tileDimZ[x][y]; }
|
int getTileDimZ(int x, int y) const { return tileDimZ[x][y]; }
|
||||||
@ -153,10 +147,10 @@ struct Arch : BaseCtx
|
|||||||
CellInfo *getBoundBelCell(BelId bel) const;
|
CellInfo *getBoundBelCell(BelId bel) const;
|
||||||
CellInfo *getConflictingBelCell(BelId bel) const;
|
CellInfo *getConflictingBelCell(BelId bel) const;
|
||||||
const std::vector<BelId> &getBels() const;
|
const std::vector<BelId> &getBels() const;
|
||||||
BelType getBelType(BelId bel) const;
|
IdString getBelType(BelId bel) const;
|
||||||
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;
|
||||||
|
|
||||||
WireId getWireByName(IdString name) const;
|
WireId getWireByName(IdString name) const;
|
||||||
IdString getWireName(WireId wire) const;
|
IdString getWireName(WireId wire) const;
|
||||||
|
@ -46,9 +46,6 @@ struct DelayInfo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IdString BelType;
|
|
||||||
typedef IdString PortPin;
|
|
||||||
|
|
||||||
typedef IdString BelId;
|
typedef IdString BelId;
|
||||||
typedef IdString WireId;
|
typedef IdString WireId;
|
||||||
typedef IdString PipId;
|
typedef IdString PipId;
|
||||||
|
@ -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);
|
||||||
|
231
ice40/arch.cc
231
ice40/arch.cc
@ -32,102 +32,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 "constids.inc"
|
||||||
#include "portpins.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(); }
|
||||||
@ -182,29 +93,6 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
wire_to_net.resize(chip_info->num_wires);
|
wire_to_net.resize(chip_info->num_wires);
|
||||||
pip_to_net.resize(chip_info->num_pips);
|
pip_to_net.resize(chip_info->num_pips);
|
||||||
switches_locked.resize(chip_info->num_switches);
|
switches_locked.resize(chip_info->num_switches);
|
||||||
|
|
||||||
// Initialise regularly used IDStrings for performance
|
|
||||||
id_glb_buf_out = id("GLOBAL_BUFFER_OUTPUT");
|
|
||||||
id_icestorm_lc = id("ICESTORM_LC");
|
|
||||||
id_sb_io = id("SB_IO");
|
|
||||||
id_sb_gb = id("SB_GB");
|
|
||||||
id_cen = id("CEN");
|
|
||||||
id_clk = id("CLK");
|
|
||||||
id_sr = id("SR");
|
|
||||||
id_i0 = id("I0");
|
|
||||||
id_i1 = id("I1");
|
|
||||||
id_i2 = id("I2");
|
|
||||||
id_i3 = id("I3");
|
|
||||||
id_dff_en = id("DFF_ENABLE");
|
|
||||||
id_carry_en = id("CARRY_ENABLE");
|
|
||||||
id_neg_clk = id("NEG_CLK");
|
|
||||||
id_cin = id("CIN");
|
|
||||||
id_cout = id("COUT");
|
|
||||||
id_o = id("O");
|
|
||||||
id_lo = id("LO");
|
|
||||||
id_icestorm_ram = id("ICESTORM_RAM");
|
|
||||||
id_rclk = id("RCLK");
|
|
||||||
id_wclk = id("WCLK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -310,7 +198,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());
|
||||||
|
|
||||||
@ -319,16 +207,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;
|
||||||
@ -338,7 +226,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;
|
||||||
|
|
||||||
@ -349,7 +237,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;
|
||||||
}
|
}
|
||||||
@ -358,11 +246,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;
|
||||||
@ -372,9 +260,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());
|
||||||
|
|
||||||
@ -382,7 +270,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;
|
||||||
}
|
}
|
||||||
@ -644,7 +532,7 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
|
|||||||
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
|
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
|
||||||
{
|
{
|
||||||
const auto &driver = net_info->driver;
|
const auto &driver = net_info->driver;
|
||||||
if (driver.port == id_cout && sink.port == id_cin) {
|
if (driver.port == id_COUT && sink.port == id_CIN) {
|
||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
auto driver_loc = getBelLocation(driver.cell->bel);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto sink_loc = getBelLocation(sink.cell->bel);
|
||||||
if (driver_loc.y == sink_loc.y)
|
if (driver_loc.y == sink_loc.y)
|
||||||
@ -822,7 +710,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;
|
||||||
@ -835,7 +723,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;
|
||||||
@ -848,7 +736,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;
|
||||||
@ -869,15 +757,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
|
||||||
@ -894,70 +779,70 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
|
|||||||
// Get the port class, also setting clockPort to associated clock if applicable
|
// Get the port class, also setting clockPort to associated clock if applicable
|
||||||
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const
|
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const
|
||||||
{
|
{
|
||||||
if (cell->type == id_icestorm_lc) {
|
if (cell->type == id_ICESTORM_LC) {
|
||||||
if (port == id_clk)
|
if (port == id_CLK)
|
||||||
return TMG_CLOCK_INPUT;
|
return TMG_CLOCK_INPUT;
|
||||||
if (port == id_cin)
|
if (port == id_CIN)
|
||||||
return TMG_COMB_INPUT;
|
return TMG_COMB_INPUT;
|
||||||
if (port == id_cout || port == id_lo)
|
if (port == id_COUT || port == id_LO)
|
||||||
return TMG_COMB_OUTPUT;
|
return TMG_COMB_OUTPUT;
|
||||||
if (cell->lcInfo.dffEnable) {
|
if (cell->lcInfo.dffEnable) {
|
||||||
clockPort = id_clk;
|
clockPort = id_CLK;
|
||||||
if (port == id_o)
|
if (port == id_O)
|
||||||
return TMG_REGISTER_OUTPUT;
|
return TMG_REGISTER_OUTPUT;
|
||||||
else
|
else
|
||||||
return TMG_REGISTER_INPUT;
|
return TMG_REGISTER_INPUT;
|
||||||
} else {
|
} else {
|
||||||
if (port == id_o)
|
if (port == id_O)
|
||||||
return TMG_COMB_OUTPUT;
|
return TMG_COMB_OUTPUT;
|
||||||
else
|
else
|
||||||
return TMG_COMB_INPUT;
|
return TMG_COMB_INPUT;
|
||||||
}
|
}
|
||||||
} else if (cell->type == id_icestorm_ram) {
|
} else if (cell->type == id_ICESTORM_RAM) {
|
||||||
|
|
||||||
if (port == id_rclk || port == id_wclk)
|
if (port == id_RCLK || port == id_WCLK)
|
||||||
return TMG_CLOCK_INPUT;
|
return TMG_CLOCK_INPUT;
|
||||||
|
|
||||||
if (port.str(this)[0] == 'R')
|
if (port.str(this)[0] == 'R')
|
||||||
clockPort = id_rclk;
|
clockPort = id_RCLK;
|
||||||
else
|
else
|
||||||
clockPort = id_wclk;
|
clockPort = id_WCLK;
|
||||||
|
|
||||||
if (cell->ports.at(port).type == PORT_OUT)
|
if (cell->ports.at(port).type == PORT_OUT)
|
||||||
return TMG_REGISTER_OUTPUT;
|
return TMG_REGISTER_OUTPUT;
|
||||||
else
|
else
|
||||||
return TMG_REGISTER_INPUT;
|
return TMG_REGISTER_INPUT;
|
||||||
} else if (cell->type == id("ICESTORM_DSP") || cell->type == id("ICESTORM_SPRAM")) {
|
} else if (cell->type == id_ICESTORM_DSP || cell->type == id_ICESTORM_SPRAM) {
|
||||||
clockPort = id_clk;
|
clockPort = id_CLK;
|
||||||
if (port == id_clk)
|
if (port == id_CLK)
|
||||||
return TMG_CLOCK_INPUT;
|
return TMG_CLOCK_INPUT;
|
||||||
else if (cell->ports.at(port).type == PORT_OUT)
|
else if (cell->ports.at(port).type == PORT_OUT)
|
||||||
return TMG_REGISTER_OUTPUT;
|
return TMG_REGISTER_OUTPUT;
|
||||||
else
|
else
|
||||||
return TMG_REGISTER_INPUT;
|
return TMG_REGISTER_INPUT;
|
||||||
} else if (cell->type == id_sb_io) {
|
} else if (cell->type == id_SB_IO) {
|
||||||
if (port == id("D_IN_0") || port == id("D_IN_1"))
|
if (port == id_D_IN_0 || port == id_D_IN_1)
|
||||||
return TMG_STARTPOINT;
|
return TMG_STARTPOINT;
|
||||||
if (port == id("D_OUT_0") || port == id("D_OUT_1") || port == id("OUTPUT_ENABLE"))
|
if (port == id_D_OUT_0 || port == id_D_OUT_1 || port == id_OUTPUT_ENABLE)
|
||||||
return TMG_ENDPOINT;
|
return TMG_ENDPOINT;
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
} else if (cell->type == id("ICESTORM_PLL")) {
|
} else if (cell->type == id_ICESTORM_PLL) {
|
||||||
if (port == id("PLLOUT_A") || port == id("PLLOUT_B"))
|
if (port == id_PLLOUT_A || port == id_PLLOUT_B)
|
||||||
return TMG_GEN_CLOCK;
|
return TMG_GEN_CLOCK;
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
} else if (cell->type == id("ICESTORM_LFOSC")) {
|
} else if (cell->type == id_ICESTORM_LFOSC) {
|
||||||
if (port == id("CLKLF"))
|
if (port == id_CLKLF)
|
||||||
return TMG_GEN_CLOCK;
|
return TMG_GEN_CLOCK;
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
} else if (cell->type == id("ICESTORM_HFOSC")) {
|
} else if (cell->type == id_ICESTORM_HFOSC) {
|
||||||
if (port == id("CLKHF"))
|
if (port == id_CLKHF)
|
||||||
return TMG_GEN_CLOCK;
|
return TMG_GEN_CLOCK;
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
} else if (cell->type == id_sb_gb) {
|
} else if (cell->type == id_SB_GB) {
|
||||||
if (port == id_glb_buf_out)
|
if (port == id_GLOBAL_BUFFER_OUTPUT)
|
||||||
return TMG_COMB_OUTPUT;
|
return TMG_COMB_OUTPUT;
|
||||||
return TMG_COMB_INPUT;
|
return TMG_COMB_INPUT;
|
||||||
} else if (cell->type == id("SB_WARMBOOT")) {
|
} else if (cell->type == id_SB_WARMBOOT) {
|
||||||
return TMG_ENDPOINT;
|
return TMG_ENDPOINT;
|
||||||
}
|
}
|
||||||
log_error("no timing info for port '%s' of cell type '%s'\n", port.c_str(this), cell->type.c_str(this));
|
log_error("no timing info for port '%s' of cell type '%s'\n", port.c_str(this), cell->type.c_str(this));
|
||||||
@ -967,7 +852,7 @@ bool Arch::isGlobalNet(const NetInfo *net) const
|
|||||||
{
|
{
|
||||||
if (net == nullptr)
|
if (net == nullptr)
|
||||||
return false;
|
return false;
|
||||||
return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out;
|
return net->driver.cell != nullptr && net->driver.port == id_GLOBAL_BUFFER_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign arch arg info
|
// Assign arch arg info
|
||||||
@ -994,22 +879,22 @@ 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_ENABLE);
|
||||||
cell->lcInfo.carryEnable = bool_or_default(cell->params, id_carry_en);
|
cell->lcInfo.carryEnable = bool_or_default(cell->params, id_CARRY_ENABLE);
|
||||||
cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk);
|
cell->lcInfo.negClk = bool_or_default(cell->params, id_NEG_CLK);
|
||||||
cell->lcInfo.clk = get_net_or_empty(cell, id_clk);
|
cell->lcInfo.clk = get_net_or_empty(cell, id_CLK);
|
||||||
cell->lcInfo.cen = get_net_or_empty(cell, id_cen);
|
cell->lcInfo.cen = get_net_or_empty(cell, id_CEN);
|
||||||
cell->lcInfo.sr = get_net_or_empty(cell, id_sr);
|
cell->lcInfo.sr = get_net_or_empty(cell, id_SR);
|
||||||
cell->lcInfo.inputCount = 0;
|
cell->lcInfo.inputCount = 0;
|
||||||
if (get_net_or_empty(cell, id_i0))
|
if (get_net_or_empty(cell, id_I0))
|
||||||
cell->lcInfo.inputCount++;
|
cell->lcInfo.inputCount++;
|
||||||
if (get_net_or_empty(cell, id_i1))
|
if (get_net_or_empty(cell, id_I1))
|
||||||
cell->lcInfo.inputCount++;
|
cell->lcInfo.inputCount++;
|
||||||
if (get_net_or_empty(cell, id_i2))
|
if (get_net_or_empty(cell, id_I2))
|
||||||
cell->lcInfo.inputCount++;
|
cell->lcInfo.inputCount++;
|
||||||
if (get_net_or_empty(cell, id_i3))
|
if (get_net_or_empty(cell, id_I3))
|
||||||
cell->lcInfo.inputCount++;
|
cell->lcInfo.inputCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
ice40/arch.h
43
ice40/arch.h
@ -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;
|
||||||
});
|
});
|
||||||
@ -414,12 +414,6 @@ struct Arch : BaseCtx
|
|||||||
ArchArgs archArgs() const { return args; }
|
ArchArgs archArgs() const { return args; }
|
||||||
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; }
|
||||||
@ -444,7 +438,7 @@ struct Arch : BaseCtx
|
|||||||
NPNR_ASSERT(bel_to_cell[bel.index] == nullptr);
|
NPNR_ASSERT(bel_to_cell[bel.index] == nullptr);
|
||||||
|
|
||||||
bel_to_cell[bel.index] = cell;
|
bel_to_cell[bel.index] = cell;
|
||||||
bel_carry[bel.index] = (cell->type == id_icestorm_lc && cell->lcInfo.carryEnable);
|
bel_carry[bel.index] = (cell->type == id_ICESTORM_LC && cell->lcInfo.carryEnable);
|
||||||
cell->bel = bel;
|
cell->bel = bel;
|
||||||
cell->belStrength = strength;
|
cell->belStrength = strength;
|
||||||
refreshUiBel(bel);
|
refreshUiBel(bel);
|
||||||
@ -499,17 +493,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;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
@ -817,21 +811,12 @@ struct Arch : BaseCtx
|
|||||||
void assignArchInfo();
|
void assignArchInfo();
|
||||||
void assignCellInfo(CellInfo *cell);
|
void assignCellInfo(CellInfo *cell);
|
||||||
|
|
||||||
IdString id_glb_buf_out;
|
|
||||||
IdString id_icestorm_lc, id_sb_io, id_sb_gb;
|
|
||||||
IdString id_cen, id_clk, id_sr;
|
|
||||||
IdString id_i0, id_i1, id_i2, id_i3;
|
|
||||||
IdString id_dff_en, id_carry_en, id_neg_clk;
|
|
||||||
IdString id_cin, id_cout;
|
|
||||||
IdString id_o, id_lo;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
@ -91,8 +91,8 @@ 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);
|
||||||
@ -105,16 +105,16 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
|||||||
|
|
||||||
bel_cells.push_back(cell);
|
bel_cells.push_back(cell);
|
||||||
return logicCellsCompatible(bel_cells);
|
return logicCellsCompatible(bel_cells);
|
||||||
} else if (cell->type == id_sb_io) {
|
} else if (cell->type == id_SB_IO) {
|
||||||
// Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to.
|
// Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to.
|
||||||
|
|
||||||
// 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)) {
|
||||||
@ -137,10 +137,10 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getBelPackagePin(bel) != "";
|
return getBelPackagePin(bel) != "";
|
||||||
} 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_GLOBAL_BUFFER_OUTPUT).net != nullptr);
|
||||||
const NetInfo *net = cell->ports.at(id_glb_buf_out).net;
|
const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).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;
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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,8 +55,10 @@ 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:
|
||||||
|
if line.startswith("//"):
|
||||||
|
continue
|
||||||
line = line.replace("(", " ")
|
line = line.replace("(", " ")
|
||||||
line = line.replace(")", " ")
|
line = line.replace(")", " ")
|
||||||
line = line.split()
|
line = line.split()
|
||||||
@ -65,8 +66,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 +119,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 +588,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 +764,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 +789,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 +804,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 +942,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 +1012,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 +1242,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")
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// pin and port names
|
||||||
X(I0)
|
X(I0)
|
||||||
X(I1)
|
X(I1)
|
||||||
X(I2)
|
X(I2)
|
||||||
@ -412,3 +413,25 @@ X(POWEROFF)
|
|||||||
X(SLEEP)
|
X(SLEEP)
|
||||||
X(STANDBY)
|
X(STANDBY)
|
||||||
X(WREN)
|
X(WREN)
|
||||||
|
|
||||||
|
// cell and bel types
|
||||||
|
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)
|
||||||
|
|
||||||
|
// cell parameters
|
||||||
|
X(DFF_ENABLE)
|
||||||
|
X(CARRY_ENABLE)
|
||||||
|
X(NEG_CLK)
|
@ -192,7 +192,7 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
|||||||
auto driver_loc = getBelLocation(driver.cell->bel);
|
auto driver_loc = getBelLocation(driver.cell->bel);
|
||||||
auto sink_loc = getBelLocation(sink.cell->bel);
|
auto sink_loc = getBelLocation(sink.cell->bel);
|
||||||
|
|
||||||
if (driver.port == id_cout) {
|
if (driver.port == id_COUT) {
|
||||||
if (driver_loc.y == sink_loc.y)
|
if (driver_loc.y == sink_loc.y)
|
||||||
return 0;
|
return 0;
|
||||||
return 250;
|
return 250;
|
||||||
|
@ -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}
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user