constraints

This commit is contained in:
Pepijn de Vos 2020-12-14 16:46:28 +01:00
parent e14f5fccbd
commit ea3d579c13
6 changed files with 98 additions and 56 deletions

View File

@ -19,6 +19,7 @@
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include <regex>
#include "embed.h" #include "embed.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "placer1.h" #include "placer1.h"
@ -311,17 +312,14 @@ const PairPOD* pairLookup(const PairPOD *list, const size_t len, const int dest)
return nullptr; return nullptr;
} }
bool aliasCompare (GlobalAliasPOD i, GlobalAliasPOD j) { 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) || 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); (i.dest_row == j.dest_row && i.dest_col == j.dest_col && i.dest_id < j.dest_id);
} }
bool timingCompare (TimingPOD i, TimingPOD j) { bool timingCompare(TimingPOD i, TimingPOD j) { return i.name_id < j.name_id; }
return i.name_id < j.name_id;
}
template <class T, class C> template <class T, class C> const T *genericLookup(const T *first, int len, const T val, C compare)
const T* genericLookup(const T *first, int len, const T val, C compare)
{ {
auto res = std::lower_bound(first, first + len, val, compare); auto res = std::lower_bound(first, first + len, val, compare);
if (res - first != len && !compare(val, *res)) { if (res - first != len && !compare(val, *res)) {
@ -331,7 +329,8 @@ const T* genericLookup(const T *first, int len, const T val, C compare)
} }
} }
DelayInfo delayLookup(const TimingPOD* first, int len, IdString name) { DelayInfo delayLookup(const TimingPOD *first, int len, IdString name)
{
TimingPOD needle; TimingPOD needle;
needle.name_id = name.index; needle.name_id = name.index;
const TimingPOD *timing = genericLookup(first, len, needle, timingCompare); const TimingPOD *timing = genericLookup(first, len, needle, timingCompare);
@ -350,11 +349,11 @@ DelayInfo delayLookup(const TimingPOD* first, int len, IdString name) {
return info; return info;
} }
DelayInfo Arch::getWireTypeDelay(IdString wire) { DelayInfo Arch::getWireTypeDelay(IdString wire)
{
IdString len; IdString len;
IdString glbsrc; IdString glbsrc;
switch (wire.index) switch (wire.index) {
{
case ID_X01: case ID_X01:
case ID_X02: case ID_X02:
case ID_X03: case ID_X03:
@ -479,12 +478,35 @@ DelayInfo Arch::getWireTypeDelay(IdString wire) {
} }
} }
void Arch::read_cst(std::istream &in) {
std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+);");
std::smatch match;
std::string line;
while (!in.eof()) {
std::getline(in, line);
if(!std::regex_match(line, match, iobre)) continue;
std::cout << match[1] << " " << match[2] << std::endl;
IdString net = id(match[1]);
IdString pinname = id(match[2]);
const PairPOD *belname = pairLookup(package->pins.get(), package->num_pins, pinname.index);
if ( belname == nullptr)
log_error("Pin %s not found", pinname.c_str(this));
//BelId bel = getBelByName(belname->src_id);
// for (auto cell : sorted(cells)) {
// std::cout << cell.first.str(this) << std::endl;
// }
auto it = cells.find(net);
if (it == cells.end())
log_error("Cell %s not found", net.c_str(this));
std::string bel = IdString(belname->src_id).str(this);
it->second->attrs[ID_BEL] = bel;
}
}
Arch::Arch(ArchArgs args) : args(args) Arch::Arch(ArchArgs args) : args(args)
{ {
family = args.family; family = args.family;
device = args.device; device = args.device;
package = args.package;
// Load database // Load database
std::string chipdb = stringf("gowin/chipdb-%s.bin", family.c_str()); std::string chipdb = stringf("gowin/chipdb-%s.bin", family.c_str());
@ -512,6 +534,22 @@ Arch::Arch(ArchArgs args) : args(args)
if (speed == nullptr) { if (speed == nullptr) {
log_error("Unsuported speed grade '%s'.\n", args.speed.c_str()); log_error("Unsuported speed grade '%s'.\n", args.speed.c_str());
} }
package = nullptr;
for (unsigned int i = 0; i < db->num_packages; i++) {
auto pkg = &db->packages[i];
// std::cout << IdString(pkg->name_id).str(this) << std::endl;
if (IdString(pkg->name_id) == id(args.package)) {
package = pkg;
break;
}
// for (int j=0; j < pkg->num_pins; j++) {
// auto pin = pkg->pins[j];
// std::cout << IdString(pin.src_id).str(this) << " " << IdString(pin.dest_id).str(this) << std::endl;
// }
}
if (package == nullptr) {
log_error("Unsuported package '%s'.\n", args.package.c_str());
}
// setup db // setup db
char buf[32]; char buf[32];
for (int i = 0; i < db->rows * db->cols; i++) { for (int i = 0; i < db->rows * db->cols; i++) {

View File

@ -118,6 +118,12 @@ NPNR_PACKED_STRUCT(struct TimingClassPOD {
RelPtr<TimingGroupsPOD> groups; RelPtr<TimingGroupsPOD> groups;
}); });
NPNR_PACKED_STRUCT(struct PackagePOD {
uint32_t name_id;
uint32_t num_pins;
RelPtr<PairPOD> pins;
});
NPNR_PACKED_STRUCT(struct DatabasePOD { NPNR_PACKED_STRUCT(struct DatabasePOD {
RelPtr<char> family; RelPtr<char> family;
uint32_t version; uint32_t version;
@ -128,6 +134,8 @@ NPNR_PACKED_STRUCT(struct DatabasePOD {
RelPtr<GlobalAliasPOD> aliases; RelPtr<GlobalAliasPOD> aliases;
uint32_t num_speeds; uint32_t num_speeds;
RelPtr<TimingClassPOD> speeds; RelPtr<TimingClassPOD> speeds;
uint32_t num_packages;
RelPtr<PackagePOD> packages;
uint16_t num_constids; uint16_t num_constids;
uint16_t num_ids; uint16_t num_ids;
RelPtr<RelPtr<char>> id_strs; RelPtr<RelPtr<char>> id_strs;
@ -141,7 +149,7 @@ struct ArchArgs
std::string package; std::string package;
// y = mx + c relationship between distance and delay for interconnect // y = mx + c relationship between distance and delay for interconnect
// delay estimates // delay estimates
double delayScale = 0.1, delayOffset = 0.4; double delayScale = 0.4, delayOffset = 0.4;
}; };
struct WireInfo; struct WireInfo;
@ -229,7 +237,7 @@ struct Arch : BaseCtx
{ {
std::string family; std::string family;
std::string device; std::string device;
std::string package; const PackagePOD *package;
const TimingGroupsPOD *speed; const TimingGroupsPOD *speed;
std::unordered_map<IdString, WireInfo> wires; std::unordered_map<IdString, WireInfo> wires;
@ -287,6 +295,7 @@ struct Arch : BaseCtx
IdString wireToGlobal(int &row, int &col, const DatabasePOD* db, IdString &wire); IdString wireToGlobal(int &row, int &col, const DatabasePOD* db, IdString &wire);
DelayInfo getWireTypeDelay(IdString wire); DelayInfo getWireTypeDelay(IdString wire);
void read_cst(std::istream &in);
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Common Arch API. Every arch must provide the following methods. // Common Arch API. Every arch must provide the following methods.

View File

@ -74,9 +74,6 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff) void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
{ {
for(auto f : lut->ports) {
std::cout << f.first.str(ctx) << std::endl;
}
lc->params[id_INIT] = lut->params[id_INIT]; lc->params[id_INIT] = lut->params[id_INIT];
IdString sim_names[4] = {id_I0, id_I1, id_I2, id_I3}; IdString sim_names[4] = {id_I0, id_I1, id_I2, id_I3};
@ -101,9 +98,6 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
replace_port(dff, id_RESET, lc, id_LSR); replace_port(dff, id_RESET, lc, id_LSR);
replace_port(dff, id_CLEAR, lc, id_LSR); replace_port(dff, id_CLEAR, lc, id_LSR);
replace_port(dff, id_PRESET, lc, id_LSR); replace_port(dff, id_PRESET, lc, id_LSR);
for(auto f : dff->ports) {
std::cout << f.first.str(ctx) << std::endl;
}
if (pass_thru_lut) { if (pass_thru_lut) {
// Fill LUT with alternating 10 // Fill LUT with alternating 10
const int init_size = 1 << 4; const int init_size = 1 << 4;

View File

@ -393,6 +393,7 @@ X(FF_TYPE)
X(INPUT_USED) X(INPUT_USED)
X(OUTPUT_USED) X(OUTPUT_USED)
X(ENABLE_USED) X(ENABLE_USED)
X(BEL)
// ports // ports
X(EN) X(EN)

View File

@ -65,13 +65,13 @@ std::unique_ptr<Context> GowinCommandHandler::createContext(std::unordered_map<s
void GowinCommandHandler::customAfterLoad(Context *ctx) void GowinCommandHandler::customAfterLoad(Context *ctx)
{ {
// if (vm.count("cst")) { if (vm.count("cst")) {
// std::string filename = vm["pdc"].as<std::string>(); std::string filename = vm["cst"].as<std::string>();
// std::ifstream in(filename); std::ifstream in(filename);
// if (!in) if (!in)
// log_error("Failed to open input PDC file %s.\n", filename.c_str()); log_error("Failed to open input CST file %s.\n", filename.c_str());
// ctx->read_pdc(in); ctx->read_cst(in);
// } }
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -250,11 +250,11 @@ static void pack_io(Context *ctx)
create_generic_cell(ctx, id_IOB, ci->name.str(ctx) + "$iob"); create_generic_cell(ctx, id_IOB, ci->name.str(ctx) + "$iob");
gwio_to_iob(ctx, ci, ice_cell.get(), packed_cells); gwio_to_iob(ctx, ci, ice_cell.get(), packed_cells);
new_cells.push_back(std::move(ice_cell)); new_cells.push_back(std::move(ice_cell));
iob = new_cells.back().get(); auto gwiob = new_cells.back().get();
packed_cells.insert(ci->name); packed_cells.insert(ci->name);
if (iob != nullptr) if (iob != nullptr)
std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(iob->attrs, iob->attrs.begin())); std::copy(iob->attrs.begin(), iob->attrs.end(), std::inserter(gwiob->attrs, gwiob->attrs.begin()));
} }
} }
for (auto pcell : packed_cells) { for (auto pcell : packed_cells) {