constraints
This commit is contained in:
parent
e14f5fccbd
commit
ea3d579c13
114
gowin/arch.cc
114
gowin/arch.cc
@ -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"
|
||||||
@ -300,7 +301,7 @@ IdString Arch::wireToGlobal(int &row, int &col, const DatabasePOD *db, IdString
|
|||||||
return id(buf);
|
return id(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PairPOD* pairLookup(const PairPOD *list, const size_t len, const int dest)
|
const PairPOD *pairLookup(const PairPOD *list, const size_t len, const int dest)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
const PairPOD *pair = &list[i];
|
const PairPOD *pair = &list[i];
|
||||||
@ -311,36 +312,34 @@ 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) ||
|
|
||||||
(i.dest_row==j.dest_row && i.dest_col==j.dest_col && i.dest_id<j.dest_id);
|
|
||||||
}
|
|
||||||
bool timingCompare (TimingPOD i, TimingPOD j) {
|
|
||||||
return i.name_id < j.name_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class C>
|
|
||||||
const T* genericLookup(const T *first, int len, const T val, C compare)
|
|
||||||
{
|
{
|
||||||
auto res = std::lower_bound(first, first+len, val, compare);
|
return (i.dest_row < j.dest_row) || (i.dest_row == j.dest_row && i.dest_col < j.dest_col) ||
|
||||||
if (res-first != len && !compare(val, *res)) {
|
(i.dest_row == j.dest_row && i.dest_col == j.dest_col && i.dest_id < j.dest_id);
|
||||||
|
}
|
||||||
|
bool timingCompare(TimingPOD i, TimingPOD j) { return i.name_id < j.name_id; }
|
||||||
|
|
||||||
|
template <class T, class C> const T *genericLookup(const T *first, int len, const T val, C compare)
|
||||||
|
{
|
||||||
|
auto res = std::lower_bound(first, first + len, val, compare);
|
||||||
|
if (res - first != len && !compare(val, *res)) {
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
DelayInfo info;
|
DelayInfo info;
|
||||||
if (timing != nullptr) {
|
if (timing != nullptr) {
|
||||||
info.maxFall = std::max(timing->ff, timing->rf)/1000;
|
info.maxFall = std::max(timing->ff, timing->rf) / 1000;
|
||||||
info.minFall = std::min(timing->ff, timing->rf)/1000;
|
info.minFall = std::min(timing->ff, timing->rf) / 1000;
|
||||||
info.maxRaise = std::max(timing->rr, timing->fr)/1000;
|
info.maxRaise = std::max(timing->rr, timing->fr) / 1000;
|
||||||
info.minRaise = std::min(timing->rr, timing->fr)/1000;
|
info.minRaise = std::min(timing->rr, timing->fr) / 1000;
|
||||||
} else {
|
} else {
|
||||||
info.maxFall = 0;
|
info.maxFall = 0;
|
||||||
info.minFall = 0;
|
info.minFall = 0;
|
||||||
@ -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:
|
||||||
@ -458,7 +457,7 @@ DelayInfo Arch::getWireTypeDelay(IdString wire) {
|
|||||||
glbsrc = id_BRANCH_PCLK;
|
glbsrc = id_BRANCH_PCLK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (wire.str(this).rfind("SPINE", 0) == 0){
|
if (wire.str(this).rfind("SPINE", 0) == 0) {
|
||||||
glbsrc = ID_CENT_SPINE_PCLK;
|
glbsrc = ID_CENT_SPINE_PCLK;
|
||||||
} else if (wire.str(this).rfind("UNK", 0) == 0) {
|
} else if (wire.str(this).rfind("UNK", 0) == 0) {
|
||||||
glbsrc = ID_PIO_CENT_PCLK;
|
glbsrc = ID_PIO_CENT_PCLK;
|
||||||
@ -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());
|
||||||
@ -501,9 +523,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
}
|
}
|
||||||
// setup timing info
|
// setup timing info
|
||||||
speed = nullptr;
|
speed = nullptr;
|
||||||
for (unsigned int i=0; i<db->num_speeds; i++) {
|
for (unsigned int i = 0; i < db->num_speeds; i++) {
|
||||||
const TimingClassPOD *tc = &db->speeds[i];
|
const TimingClassPOD *tc = &db->speeds[i];
|
||||||
//std::cout << IdString(tc->name_id).str(this) << std::endl;
|
// std::cout << IdString(tc->name_id).str(this) << std::endl;
|
||||||
if (IdString(tc->name_id) == id(args.speed)) {
|
if (IdString(tc->name_id) == id(args.speed)) {
|
||||||
speed = tc->groups.get();
|
speed = tc->groups.get();
|
||||||
break;
|
break;
|
||||||
@ -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++) {
|
||||||
@ -519,9 +557,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
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 wires
|
// setup wires
|
||||||
const PairPOD* pips[2] = { tile->pips.get(), tile->clock_pips.get()};
|
const PairPOD *pips[2] = {tile->pips.get(), tile->clock_pips.get()};
|
||||||
unsigned int num_pips[2] = { tile->num_pips, tile->num_clock_pips};
|
unsigned int num_pips[2] = {tile->num_pips, tile->num_clock_pips};
|
||||||
for(int p = 0; p < 2; p++) {
|
for (int p = 0; p < 2; p++) {
|
||||||
for (unsigned int j = 0; j < num_pips[p]; j++) {
|
for (unsigned int j = 0; j < num_pips[p]; j++) {
|
||||||
const PairPOD pip = pips[p][j];
|
const PairPOD pip = pips[p][j];
|
||||||
int destrow = row;
|
int destrow = row;
|
||||||
@ -644,9 +682,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
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();
|
||||||
const PairPOD* pips[2] = { tile->pips.get(), tile->clock_pips.get()};
|
const PairPOD *pips[2] = {tile->pips.get(), tile->clock_pips.get()};
|
||||||
unsigned int num_pips[2] = { tile->num_pips, tile->num_clock_pips};
|
unsigned int num_pips[2] = {tile->num_pips, tile->num_clock_pips};
|
||||||
for(int p = 0; p < 2; p++) {
|
for (int p = 0; p < 2; p++) {
|
||||||
for (unsigned int j = 0; j < num_pips[p]; j++) {
|
for (unsigned int j = 0; j < num_pips[p]; j++) {
|
||||||
const PairPOD pip = pips[p][j];
|
const PairPOD pip = pips[p][j];
|
||||||
int destrow = row;
|
int destrow = row;
|
||||||
@ -665,7 +703,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
// local alias
|
// local alias
|
||||||
auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, srcid.index);
|
auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, srcid.index);
|
||||||
// std::cout << "srcid " << srcid.str(this) << std::endl;
|
// std::cout << "srcid " << srcid.str(this) << std::endl;
|
||||||
if(local_alias!=nullptr) {
|
if (local_alias != nullptr) {
|
||||||
srcid = local_alias->src_id;
|
srcid = local_alias->src_id;
|
||||||
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
}
|
}
|
||||||
@ -676,12 +714,12 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
alias.dest_row = srcrow;
|
alias.dest_row = srcrow;
|
||||||
alias.dest_id = srcid.index;
|
alias.dest_id = srcid.index;
|
||||||
auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare);
|
auto alias_src = genericLookup(db->aliases.get(), db->num_aliases, alias, aliasCompare);
|
||||||
if(alias_src!=nullptr) {
|
if (alias_src != nullptr) {
|
||||||
srccol = alias_src->src_col;
|
srccol = alias_src->src_col;
|
||||||
srcrow = alias_src->src_row;
|
srcrow = alias_src->src_row;
|
||||||
srcid = alias_src->src_id;
|
srcid = alias_src->src_id;
|
||||||
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
//std::cout << buf << std::endl;
|
// std::cout << buf << std::endl;
|
||||||
}
|
}
|
||||||
addPip(pipname, pip.dest_id, gsrcname, gdestname, delay, Loc(col, row, j));
|
addPip(pipname, pip.dest_id, gsrcname, gdestname, delay, Loc(col, row, j));
|
||||||
}
|
}
|
||||||
@ -1133,7 +1171,7 @@ void Arch::assignArchInfo()
|
|||||||
// add timing paths
|
// add timing paths
|
||||||
addCellTimingClock(cname, id_CLK);
|
addCellTimingClock(cname, id_CLK);
|
||||||
IdString ports[4] = {id_A, id_B, id_C, id_D};
|
IdString ports[4] = {id_A, id_B, id_C, id_D};
|
||||||
for (int i=0; i<4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
DelayInfo setup = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clksetpos);
|
DelayInfo setup = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clksetpos);
|
||||||
DelayInfo hold = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clkholdpos);
|
DelayInfo hold = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clkholdpos);
|
||||||
// DelayInfo setup = getDelayFromNS(0.1);
|
// DelayInfo setup = getDelayFromNS(0.1);
|
||||||
@ -1144,7 +1182,7 @@ void Arch::assignArchInfo()
|
|||||||
// DelayInfo clkout = getDelayFromNS(0.1);
|
// DelayInfo clkout = getDelayFromNS(0.1);
|
||||||
addCellTimingClockToOut(cname, id_Q, id_CLK, clkout);
|
addCellTimingClockToOut(cname, id_Q, id_CLK, clkout);
|
||||||
IdString port_delay[4] = {id_a_f, id_b_f, id_c_f, id_d_f};
|
IdString port_delay[4] = {id_a_f, id_b_f, id_c_f, id_d_f};
|
||||||
for (int i=0; i<4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
DelayInfo delay = delayLookup(speed->lut.timings.get(), speed->lut.num_timings, port_delay[i]);
|
DelayInfo delay = delayLookup(speed->lut.timings.get(), speed->lut.num_timings, port_delay[i]);
|
||||||
// DelayInfo delay = getDelayFromNS(0.1);
|
// DelayInfo delay = getDelayFromNS(0.1);
|
||||||
addCellTimingDelay(cname, ports[i], id_F, delay);
|
addCellTimingDelay(cname, ports[i], id_F, delay);
|
||||||
@ -1167,7 +1205,7 @@ bool Arch::cellsCompatible(const CellInfo **cells, int count) const
|
|||||||
const CellInfo *ci = cells[i];
|
const CellInfo *ci = cells[i];
|
||||||
if (ci->is_slice && ci->slice_clk != nullptr) {
|
if (ci->is_slice && ci->slice_clk != nullptr) {
|
||||||
Loc loc = getBelLocation(ci->bel);
|
Loc loc = getBelLocation(ci->bel);
|
||||||
int cls = loc.z/2;
|
int cls = loc.z / 2;
|
||||||
bool ff_used = ci->params.at(id_FF_USED).as_bool();
|
bool ff_used = ci->params.at(id_FF_USED).as_bool();
|
||||||
if (loc.z >= 6 && ff_used) // top slice have no ff
|
if (loc.z >= 6 && ff_used) // top slice have no ff
|
||||||
return false;
|
return false;
|
||||||
|
13
gowin/arch.h
13
gowin/arch.h
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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[])
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user