add aliases

This commit is contained in:
Pepijn de Vos 2020-11-19 18:28:14 +01:00
parent 9fd85e4fad
commit 401584bf89
2 changed files with 131 additions and 76 deletions

View File

@ -19,8 +19,8 @@
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include "nextpnr.h"
#include "embed.h" #include "embed.h"
#include "nextpnr.h"
#include "placer1.h" #include "placer1.h"
#include "placer_heap.h" #include "placer_heap.h"
#include "router1.h" #include "router1.h"
@ -249,7 +249,8 @@ void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock,
// --------------------------------------------------------------- // ---------------------------------------------------------------
// TODO represent wires more intelligently. // TODO represent wires more intelligently.
IdString Arch::wireToGlobal(int row, int col, const DatabasePOD* db, IdString wire) { IdString Arch::wireToGlobal(int &row, int &col, const DatabasePOD *db, IdString wire)
{
std::string wirename = wire.str(this); std::string wirename = wire.str(this);
char buf[32]; char buf[32];
if (wirename == "VCC" || wirename == "GND") { if (wirename == "VCC" || wirename == "GND") {
@ -262,24 +263,18 @@ IdString Arch::wireToGlobal(int row, int col, const DatabasePOD* db, IdString wi
char direction = wirename[0]; char direction = wirename[0];
int num = std::stoi(wirename.substr(1, 2)); int num = std::stoi(wirename.substr(1, 2));
int segment = std::stoi(wirename.substr(3, 1)); int segment = std::stoi(wirename.substr(3, 1));
int rootrow, rootcol; switch (direction) {
switch (direction)
{
case 'N': case 'N':
rootrow = row + segment; row += segment;
rootcol = col;
break; break;
case 'S': case 'S':
rootrow = row - segment; row -= segment;
rootcol = col;
break; break;
case 'E': case 'E':
rootrow = row; col -= segment;
rootcol = col - segment;
break; break;
case 'W': case 'W':
rootrow = row; col += segment;
rootcol = col + segment;
break; break;
default: default:
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, wirename.c_str()); snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, wirename.c_str());
@ -288,24 +283,25 @@ IdString Arch::wireToGlobal(int row, int col, const DatabasePOD* db, IdString wi
} }
// wires wrap around the edges // wires wrap around the edges
// assumes 0-based indexes // assumes 0-based indexes
if(rootrow < 0) { if (row < 0) {
rootrow = -1-rootrow; row = -1 - row;
direction = 'N'; direction = 'N';
} else if(rootcol < 0) { } else if (col < 0) {
rootcol = -1-rootcol; col = -1 - col;
direction = 'W'; direction = 'W';
} else if(rootrow >= db->rows) { } else if (row >= db->rows) {
rootrow = 2*db->rows-1-rootrow; row = 2 * db->rows - 1 - row;
direction = 'S'; direction = 'S';
} else if(rootcol >= db->cols) { } else if (col >= db->cols) {
rootcol = 2*db->cols-1-rootcol; col = 2 * db->cols - 1 - col;
direction = 'E'; direction = 'E';
} }
snprintf(buf, 32, "R%dC%d_%c%d", rootrow+1, rootcol+1, direction, num); snprintf(buf, 32, "R%dC%d_%c%d", row + 1, col + 1, direction, num);
return id(buf); return id(buf);
} }
PairPOD pairLookup(const PairPOD* list, const size_t len, const int src, const int dest) { PairPOD pairLookup(const PairPOD *list, const size_t len, const int src, const int dest)
{
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
PairPOD pair = list[i]; PairPOD pair = list[i];
if ((src < 0 || pair.src_id == src) && (dest < 0 || pair.dest_id == dest)) { if ((src < 0 || pair.src_id == src) && (dest < 0 || pair.dest_id == dest)) {
@ -315,6 +311,23 @@ PairPOD pairLookup(const PairPOD* list, const size_t len, const int src, const i
return PairPOD(); return PairPOD();
} }
bool destCompare (PairPOD i,PairPOD j) { return (i.dest_id<j.dest_id); }
bool aliasCompare (GlobalAliasPOD i, GlobalAliasPOD j) {
return (i.dest_row<j.dest_row) ||
(i.dest_row==j.dest_row && i.dest_col<j.dest_col) ||
(i.dest_row==j.dest_row && i.dest_col==j.dest_col && i.dest_id<j.dest_id);
}
const GlobalAliasPOD* aliasLookup(const GlobalAliasPOD *first, int len, const GlobalAliasPOD val)
{
auto res = std::lower_bound(first, first+len, val, aliasCompare);
if (res-first != len && !aliasCompare(val, *res)) {
return res;
} else {
return nullptr;
}
}
Arch::Arch(ArchArgs args) : args(args) Arch::Arch(ArchArgs args) : args(args)
{ {
family = "GW1N-1"; family = "GW1N-1";
@ -336,35 +349,37 @@ Arch::Arch(ArchArgs args) : args(args)
IdString::initialize_add(this, db->id_strs[i].get(), uint32_t(i) + db->num_constids); IdString::initialize_add(this, db->id_strs[i].get(), uint32_t(i) + db->num_constids);
} }
// setup db // setup db
char buf[32];
for (int i = 0; i < db->rows * db->cols; i++) { for (int i = 0; i < db->rows * db->cols; i++) {
int row = i / db->cols; int row = i / db->cols;
int col = i % db->cols; int col = i % db->cols;
const TilePOD *tile = db->grid[i].get(); const TilePOD *tile = db->grid[i].get();
// setup pips // setup wires
for(unsigned int j=0; j < tile->num_pips; j++) { const PairPOD* pips[2] = { tile->pips.get(), tile->clock_pips.get()};
const PairPOD pip = tile->pips[j]; unsigned int num_pips[2] = { tile->num_pips, tile->num_clock_pips};
IdString gdestname = wireToGlobal(row, col, db, pip.dest_id); for(int p = 0; p < 2; p++) {
if(wires.count(gdestname) == 0) addWire(gdestname, pip.dest_id, col, row); for (unsigned int j = 0; j < num_pips[p]; j++) {
IdString gsrcname = wireToGlobal(row, col, db, pip.src_id); const PairPOD pip = pips[p][j];
if(wires.count(gsrcname) == 0) addWire(gsrcname, pip.src_id, col, row); int destrow = row;
int destcol = col;
IdString gdestname = wireToGlobal(destrow, destcol, db, pip.dest_id);
if (wires.count(gdestname) == 0)
addWire(gdestname, pip.dest_id, destcol, destrow);
int srcrow = row;
int srccol = col;
IdString gsrcname = wireToGlobal(srcrow, srccol, db, pip.src_id);
if (wires.count(gsrcname) == 0)
addWire(gsrcname, pip.src_id, srccol, srcrow);
} }
for(unsigned int j=0; j < tile->num_clock_pips; j++) {
const PairPOD pip = tile->clock_pips[j];
IdString gdestname = wireToGlobal(row, col, db, pip.dest_id);
if(wires.count(gdestname) == 0) addWire(gdestname, pip.dest_id, col, row);
IdString gsrcname = wireToGlobal(row, col, db, pip.src_id);
if(wires.count(gsrcname) == 0) addWire(gsrcname, pip.src_id, col, row);
} }
for (unsigned int j = 0; j < tile->num_bels; j++) { for (unsigned int j = 0; j < tile->num_bels; j++) {
const BelsPOD *bel = &tile->bels[j]; const BelsPOD *bel = &tile->bels[j];
char buf[32];
IdString belname; IdString belname;
IdString wirename; IdString wirename;
IdString portname; IdString portname;
int z = 0; int z = 0;
bool dff = true; bool dff = true;
switch (static_cast<ConstIds>(bel->type_id)) switch (static_cast<ConstIds>(bel->type_id)) {
{
// fall through the ++ // fall through the ++
case ID_LUT7: case ID_LUT7:
z++; z++;
@ -439,7 +454,7 @@ Arch::Arch(ArchArgs args) : args(args)
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z); snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
belname = id(buf); belname = id(buf);
addBel(belname, id_IOB, Loc(col, row, z), false); addBel(belname, id_IOB, Loc(col, row, z), false);
portname = pairLookup(bel->ports.get(), bel->num_ports, -1, ID_I).src_id; portname = pairLookup(bel->ports.get(), bel->num_ports, -1, ID_O).src_id;
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
wirename = id(buf); wirename = id(buf);
addBelInput(belname, id_I, wirename); addBelInput(belname, id_I, wirename);
@ -451,12 +466,51 @@ Arch::Arch(ArchArgs args) : args(args)
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
wirename = id(buf); wirename = id(buf);
addBelInput(belname, id_OE, wirename); addBelInput(belname, id_OE, wirename);
break;
default: default:
break; break;
} }
} }
} }
// setup pips
for (int i = 0; i < db->rows * db->cols; i++) {
int row = i / db->cols;
int col = i % db->cols;
const TilePOD *tile = db->grid[i].get();
const PairPOD* pips[2] = { tile->pips.get(), tile->clock_pips.get()};
unsigned int num_pips[2] = { tile->num_pips, tile->num_clock_pips};
for(int p = 0; p < 2; p++) {
for (unsigned int j = 0; j < num_pips[p]; j++) {
const PairPOD pip = pips[p][j];
int destrow = row;
int destcol = col;
IdString gdestname = wireToGlobal(destrow, destcol, db, pip.dest_id);
int srcrow = row;
int srccol = col;
IdString gsrcname = wireToGlobal(srcrow, srccol, db, pip.src_id);
snprintf(buf, 32, "R%dC%d_%s_%s", row + 1, col + 1, IdString(pip.src_id).c_str(this),
IdString(pip.dest_id).c_str(this));
IdString pipname = id(buf);
DelayInfo delay;
delay.delay = 0.1; // TODO
uint16_t srcid = pip.src_id;
GlobalAliasPOD alias;
alias.dest_col = srccol;
alias.dest_row = srcrow;
alias.dest_id = srcid;
auto alias_src = aliasLookup(db->aliases.get(), db->num_aliases, alias);
if(alias_src!=nullptr) {
srccol = alias_src->src_col;
srcrow = alias_src->src_row;
gsrcname = wireToGlobal(srcrow, srccol, db, alias_src->src_id);
std::cout << buf << std::endl;
}
addPip(pipname, pip.dest_id, gsrcname, gdestname, delay, Loc(col, row, j));
}
}
}
// Dummy for empty decals // Dummy for empty decals
decal_graphics[IdString()]; decal_graphics[IdString()];
} }
@ -468,7 +522,6 @@ void IdString::initialize_arch(const BaseCtx *ctx)
#undef X #undef X
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
BelId Arch::getBelByName(IdString name) const BelId Arch::getBelByName(IdString name) const

View File

@ -34,6 +34,8 @@ template <typename T> struct RelPtr
const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); } const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); }
T *get_mut() const { return const_cast<T *>(reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset)); }
const T &operator[](size_t index) const { return get()[index]; } const T &operator[](size_t index) const { return get()[index]; }
const T &operator*() const { return *(get()); } const T &operator*() const { return *(get()); }
@ -240,7 +242,7 @@ struct Arch : BaseCtx
void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold); void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold);
void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq); void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq);
IdString wireToGlobal(int row, int col, const DatabasePOD* db, IdString wire); IdString wireToGlobal(int &row, int &col, const DatabasePOD* db, IdString wire);
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Common Arch API. Every arch must provide the following methods. // Common Arch API. Every arch must provide the following methods.