ecp5: Working on arch implementation

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-07-05 20:59:11 +02:00
parent eaae6b7dca
commit c4af52dd5b
6 changed files with 153 additions and 104 deletions

View File

@ -7,7 +7,7 @@ option(BUILD_PYTHON "Build Python Integration" ON)
option(BUILD_TESTS "Build GUI" OFF) option(BUILD_TESTS "Build GUI" OFF)
# List of families to build # List of families to build
set(FAMILIES generic ice40) set(FAMILIES generic ice40 ecp5)
set(ARCH "" CACHE STRING "Architecture family for nextpnr build") set(ARCH "" CACHE STRING "Architecture family for nextpnr build")
set_property(CACHE ARCH PROPERTY STRINGS ${FAMILIES}) set_property(CACHE ARCH PROPERTY STRINGS ${FAMILIES})

View File

@ -119,11 +119,17 @@ extern const char chipdb_blob_8k[];
struct BelIterator struct BelIterator
{ {
int cursor; const ChipInfoPOD *chip;
int cursor_index;
int cursor_tile;
BelIterator operator++() BelIterator operator++()
{ {
cursor++; cursor_index++;
while (cursor_index >= ci->locations[ci->location_type[cursor_tile]]->num_bels) {
cursor_index = 0;
cursor_tile++;
}
return *this; return *this;
} }
BelIterator operator++(int) BelIterator operator++(int)
@ -133,14 +139,22 @@ struct BelIterator
return prior; return prior;
} }
bool operator!=(const BelIterator &other) const { return cursor != other.cursor; } bool operator!=(const BelIterator &other) const
{
return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile;
}
bool operator==(const BelIterator &other) const { return cursor == other.cursor; } bool operator==(const BelIterator &other) const
{
return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile;
}
BelId operator*() const BelId operator*() const
{ {
BelId ret; BelId ret;
ret.index = cursor; ret.location.x = cursor_tile % chip->width;
ret.location.y = cursor_tile / chip->width;
ret.index = cursor_index;
return ret; return ret;
} }
}; };
@ -157,7 +171,7 @@ struct BelRange
struct BelPinIterator struct BelPinIterator
{ {
const BelPortPOD *ptr = nullptr; const BelPortPOD *ptr = nullptr;
const Location wire_loc;
void operator++() { ptr++; } void operator++() { ptr++; }
bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; } bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; }
@ -165,6 +179,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.pin = ptr->port; ret.pin = ptr->port;
return ret; return ret;
} }
@ -181,15 +196,42 @@ struct BelPinRange
struct WireIterator struct WireIterator
{ {
int cursor = -1; const ChipInfoPOD *chip;
int cursor_index;
int cursor_tile;
void operator++() { cursor++; } WireIterator operator++()
bool operator!=(const WireIterator &other) const { return cursor != other.cursor; } {
cursor_index++;
while (cursor_index >= ci->locations[ci->location_type[cursor_tile]]->num_wires) {
cursor_index = 0;
cursor_tile++;
}
return *this;
}
WireIterator operator++(int)
{
WireIterator prior(*this);
cursor++;
return prior;
}
bool operator!=(const WireIterator &other) const
{
return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile;
}
bool operator==(const WireIterator &other) const
{
return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile;
}
WireId operator*() const WireId operator*() const
{ {
WireId ret; WireId ret;
ret.index = cursor; ret.location.x = cursor_tile % chip->width;
ret.location.y = cursor_tile / chip->width;
ret.index = cursor_index;
return ret; return ret;
} }
}; };
@ -205,15 +247,42 @@ struct WireRange
struct AllPipIterator struct AllPipIterator
{ {
int cursor = -1; const ChipInfoPOD *chip;
int cursor_index;
int cursor_tile;
void operator++() { cursor++; } AllPipIterator operator++()
bool operator!=(const AllPipIterator &other) const { return cursor != other.cursor; } {
cursor_index++;
while (cursor_index >= ci->locations[ci->location_type[cursor_tile]]->num_pips) {
cursor_index = 0;
cursor_tile++;
}
return *this;
}
AllPipIterator operator++(int)
{
WireIterator prior(*this);
cursor++;
return prior;
}
bool operator!=(const AllPipIterator &other) const
{
return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile;
}
bool operator==(const AllPipIterator &other) const
{
return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile;
}
PipId operator*() const PipId operator*() const
{ {
PipId ret; PipId ret;
ret.index = cursor; ret.location.x = cursor_tile % chip->width;
ret.location.y = cursor_tile / chip->width;
ret.index = cursor_index;
return ret; return ret;
} }
}; };
@ -229,7 +298,9 @@ struct AllPipRange
struct PipIterator struct PipIterator
{ {
const int *cursor = nullptr;
const PipLocatorPOD *cursor = nullptr;
Location wire_loc;
void operator++() { cursor++; } void operator++() { cursor++; }
bool operator!=(const PipIterator &other) const { return cursor != other.cursor; } bool operator!=(const PipIterator &other) const { return cursor != other.cursor; }
@ -237,7 +308,8 @@ struct PipIterator
PipId operator*() const PipId operator*() const
{ {
PipId ret; PipId ret;
ret.index = *cursor; ret.index = cursor->index;
ret.location = wire_loc + cursor->location;
return ret; return ret;
} }
}; };
@ -254,14 +326,12 @@ struct ArchArgs
enum enum
{ {
NONE, NONE,
LP384, LFE5U_25F,
LP1K, LFE5U_45F,
LP8K, LFE5U_85F,
HX1K,
HX8K,
UP5K
} type = NONE; } type = NONE;
std::string package; std::string package;
int speed = 6;
}; };
struct Arch : BaseCtx struct Arch : BaseCtx
@ -273,17 +343,17 @@ struct Arch : BaseCtx
mutable std::unordered_map<IdString, int> wire_by_name; mutable std::unordered_map<IdString, int> wire_by_name;
mutable std::unordered_map<IdString, int> pip_by_name; mutable std::unordered_map<IdString, int> pip_by_name;
std::vector<IdString> bel_to_cell; std::unordered_map<BelId, IdString> bel_to_cell;
std::vector<IdString> wire_to_net; std::unordered_map<WireId, IdString> wire_to_net;
std::vector<IdString> pip_to_net; std::unordered_map<PipId, IdString> pip_to_net;
std::vector<IdString> switches_locked; std::unordered_map<PipId, IdString> switches_locked;
ArchArgs args; ArchArgs args;
Arch(ArchArgs args); Arch(ArchArgs args);
std::string getChipName(); std::string getChipName();
IdString archId() const { return id("ice40"); } IdString archId() const { return id("ecp5"); }
IdString archArgsToId(ArchArgs args) const; IdString archArgsToId(ArchArgs args) const;
IdString belTypeToId(BelType type) const; IdString belTypeToId(BelType type) const;
@ -307,8 +377,8 @@ struct Arch : BaseCtx
void bindBel(BelId bel, IdString cell, PlaceStrength strength) void bindBel(BelId bel, IdString cell, PlaceStrength strength)
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); NPNR_ASSERT(bel_to_cell[bel] == IdString());
bel_to_cell[bel.index] = cell; bel_to_cell[bel] = cell;
cells[cell]->bel = bel; cells[cell]->bel = bel;
cells[cell]->belStrength = strength; cells[cell]->belStrength = strength;
} }
@ -331,13 +401,13 @@ struct Arch : BaseCtx
IdString getBoundBelCell(BelId bel) const IdString getBoundBelCell(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
return bel_to_cell[bel.index]; return bel_to_cell.at(bel);
} }
IdString getConflictingBelCell(BelId bel) const IdString getConflictingBelCell(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
return bel_to_cell[bel.index]; return bel_to_cell.at(bel);
} }
BelRange getBels() const BelRange getBels() const
@ -613,27 +683,6 @@ struct Arch : BaseCtx
bool isClockPort(const CellInfo *cell, IdString port) const; bool isClockPort(const CellInfo *cell, IdString port) const;
// Return true if a port is a net // Return true if a port is a net
bool isGlobalNet(const NetInfo *net) const; bool isGlobalNet(const NetInfo *net) const;
// -------------------------------------------------
// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc)
// Whether or not a given cell can be placed at a given Bel
// This is not intended for Bel type checks, but finer-grained constraints
// such as conflicting set/reset signals, etc
bool isValidBelForCell(CellInfo *cell, BelId bel) const;
// Return true whether all Bels at a given location are valid
bool isBelLocationValid(BelId bel) const;
// Helper function for above
bool logicCellsCompatible(const std::vector<const CellInfo *> &cells) const;
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_neg_clk;
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -60,13 +60,13 @@ enum PortPin : int32_t
PIN_MAXIDX PIN_MAXIDX
}; };
NPNR_PACKED_STRUCT( NPNR_PACKED_STRUCT(struct Location {
struct Location {
int16_t x = -1, y = -1; int16_t x = -1, y = -1;
bool operator==(const Location &other) const { return x == other.x && y == other.y; } bool operator==(const Location &other) const { return x == other.x && y == other.y; }
bool operator!=(const Location &other) const { return x != other.x || y == other.y; } bool operator!=(const Location &other) const { return x != other.x || y == other.y; }
} });
);
Location operator+(const Location &a, const Location &b) { return Location{a.x + b.x, a.y + b.y};}
struct BelId struct BelId
{ {

0
ecp5/family.cmake Normal file
View File