Add CSC per TILE when needed
This commit is contained in:
parent
62a357f029
commit
87f10ce901
@ -93,6 +93,8 @@ void NgUltraImpl::init(Context *ctx)
|
||||
gck_per_lobe[lobe][num-1] = GckConfig(bel);
|
||||
}
|
||||
locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel);
|
||||
Loc loc = ctx->getBelLocation(bel);
|
||||
tile_locations.emplace(tile_name(bel.tile).c_str(),Loc(loc.x & 0xfffe, loc.y & 0xfffe, 0));
|
||||
}
|
||||
for (auto bel : ctx->getBels()) {
|
||||
if (ctx->getBelType(bel) == id_DSP) {
|
||||
@ -486,6 +488,8 @@ struct SectionFEWorker
|
||||
std::string type = str_or_default(cell->params, ctx->id("type"), "");
|
||||
if (type=="CSC" && (extra_data.flags & BEL_EXTRA_FE_CSC) == 0) return false; // No CSC capability on FE
|
||||
if (type=="SCC" && (extra_data.flags & BEL_EXTRA_FE_SCC) == 0) return false; // No SCC capability on FE
|
||||
if (extra_data.flags & BEL_EXTRA_FE_CSC)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
dict<std::string, std::string> bank_voltage;
|
||||
dict<BelId,IdString> global_capable_bels;
|
||||
dict<std::string,BelId> locations;
|
||||
dict<std::string,Loc> tile_locations;
|
||||
dict<int,std::vector<GckConfig>> gck_per_lobe;
|
||||
|
||||
pool<PipId> blocked_pips;
|
||||
@ -94,7 +95,6 @@ public:
|
||||
dict<BelId, IdString> unused_wfg;
|
||||
dict<BelId, IdString> unused_pll;
|
||||
dict<BelId, BelId> dsp_cascade;
|
||||
dict<IdString,int> lowskew_signals;
|
||||
|
||||
TESTABLE_PRIVATE:
|
||||
void write_bitstream_json(const std::string &filename);
|
||||
|
@ -2137,6 +2137,96 @@ IdString NgUltraPacker::assign_wfg(IdString ckg, IdString ckg2, CellInfo *cell)
|
||||
log_error(" No more available WFGs for cell '%s'.\n", cell->name.c_str(ctx));
|
||||
}
|
||||
|
||||
void NgUltraPacker::extract_lowskew_signals(CellInfo *cell, dict<IdString,dict<IdString,std::vector<PortRef>>> &lowskew_signals)
|
||||
{
|
||||
IdString loc;
|
||||
if (cell->bel != BelId())
|
||||
loc = uarch->tile_name_id(cell->bel.tile);
|
||||
|
||||
PortRef ref;
|
||||
ref.cell = cell;
|
||||
if (cell->type == id_BEYOND_FE) {
|
||||
NetInfo *clock = cell->getPort(id_CK);
|
||||
NetInfo *load = cell->getPort(id_L);
|
||||
NetInfo *reset = cell->getPort(id_R);
|
||||
if (clock && !global_lowskew.count(clock->name)) {
|
||||
ref.port = id_CK;
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
}
|
||||
if (load && !global_lowskew.count(load->name)) {
|
||||
ref.port = id_L;
|
||||
lowskew_signals[loc][load->name].push_back(ref);
|
||||
}
|
||||
if (reset && !global_lowskew.count(reset->name)) {
|
||||
ref.port = id_R;
|
||||
lowskew_signals[loc][reset->name].push_back(ref);
|
||||
}
|
||||
} else if (cell->type.in(id_RF,id_RFSP)) {
|
||||
NetInfo *clock = cell->getPort(id_WCK);
|
||||
ref.port = id_WCK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_XHRF,id_XWRF,id_XPRF)) {
|
||||
NetInfo *clock = cell->getPort(id_WCK1);
|
||||
ref.port = id_WCK1;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_WCK2);
|
||||
ref.port = id_WCK2;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_RAM)) {
|
||||
NetInfo *clock = cell->getPort(id_ACK);
|
||||
ref.port = id_ACK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_BCK);
|
||||
ref.port = id_BCK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_CDC,id_DDE,id_TDE,id_XCDC)) {
|
||||
NetInfo *clock = cell->getPort(id_CK1);
|
||||
ref.port = id_CK1;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_CK2);
|
||||
ref.port = id_CK2;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_FIFO)) {
|
||||
NetInfo *clock = cell->getPort(id_RCK);
|
||||
ref.port = id_RCK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_WCK);
|
||||
ref.port = id_WCK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_XHFIFO,id_XWFIFO)) {
|
||||
NetInfo *clock = cell->getPort(id_RCK1);
|
||||
ref.port = id_RCK1;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_RCK2);
|
||||
ref.port = id_RCK2;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_WCK1);
|
||||
ref.port = id_WCK1;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
clock = cell->getPort(id_WCK2);
|
||||
ref.port = id_WCK2;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
} else if (cell->type.in(id_DSP)) {
|
||||
NetInfo *clock = cell->getPort(id_CK);
|
||||
ref.port = id_CK;
|
||||
if (clock && !global_lowskew.count(clock->name))
|
||||
lowskew_signals[loc][clock->name].push_back(ref);
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraPacker::pre_place(void)
|
||||
{
|
||||
log_info("Pre-placing PLLs..\n");
|
||||
@ -2255,23 +2345,13 @@ void NgUltraPacker::pre_place(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &cell : ctx->cells) {
|
||||
auto ci = cell.second.get();
|
||||
if (ci->type == id_BEYOND_FE) {
|
||||
NetInfo *clock = ci->getPort(id_CK);
|
||||
NetInfo *load = ci->getPort(id_L);
|
||||
NetInfo *reset = ci->getPort(id_R);
|
||||
if (clock)
|
||||
uarch->lowskew_signals[clock->name]++;
|
||||
if (load)
|
||||
uarch->lowskew_signals[load->name]++;
|
||||
if (reset)
|
||||
uarch->lowskew_signals[reset->name]++;
|
||||
}
|
||||
}
|
||||
dict<IdString,dict<IdString,std::vector<PortRef>>> lowskew_signals;
|
||||
for (auto &cell : ctx->cells)
|
||||
extract_lowskew_signals(cell.second.get(), lowskew_signals);
|
||||
|
||||
log_info("Adding GCK for lowskew signals..\n");
|
||||
for(auto &n : uarch->lowskew_signals) {
|
||||
for(auto &n : lowskew_signals[IdString()]) {
|
||||
//printf("\t%ld --- %s\n", n.second.size(),n.first.c_str(ctx));
|
||||
NetInfo *net = ctx->nets.at(n.first).get();
|
||||
if (net->driver.cell->type.in(id_BFR,id_DFR,id_DDFR)) {
|
||||
CellInfo *bfr = net->driver.cell;
|
||||
@ -2373,10 +2453,92 @@ void NgUltraImpl::postPlace()
|
||||
log_info("Running post-placement ...\n");
|
||||
packer.duplicate_gck();
|
||||
packer.insert_bypass_gck();
|
||||
packer.insert_csc();
|
||||
log_break();
|
||||
ctx->assignArchInfo();
|
||||
}
|
||||
|
||||
BelId getCSC(Context *ctx, Loc l) {
|
||||
BelId bel = ctx->getBelByLocation(Loc(l.x+1,l.y+2,0));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+1,l.y+2,15));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+1,l.y+2,16));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+1,l.y+2,31));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
|
||||
bel = ctx->getBelByLocation(Loc(l.x+2,l.y+3,0));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+2,l.y+3,15));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+2,l.y+3,16));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+2,l.y+3,31));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
|
||||
bel = ctx->getBelByLocation(Loc(l.x+3,l.y+2,0));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+3,l.y+2,15));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+3,l.y+2,16));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
bel = ctx->getBelByLocation(Loc(l.x+3,l.y+2,31));
|
||||
if (!ctx->getBoundBelCell(bel)) return bel;
|
||||
return BelId();
|
||||
}
|
||||
|
||||
void NgUltraPacker::insert_csc()
|
||||
{
|
||||
dict<IdString,dict<IdString,std::vector<PortRef>>> local_system_matrix;
|
||||
//log_info("================== Local system matrix detection ===================\n");
|
||||
for (auto &cell : ctx->cells) {
|
||||
auto ci = cell.second.get();
|
||||
if (ci->bel != BelId()) {
|
||||
if (uarch->tile_type(ci->bel.tile)==TILE_EXTRA_FABRIC) {
|
||||
extract_lowskew_signals(ci, local_system_matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(auto &lsm : local_system_matrix) {
|
||||
//printf("name:%s\n",lsm.first.c_str(ctx));
|
||||
std::string name = lsm.first.c_str(ctx);
|
||||
Loc loc = uarch->tile_locations[name];
|
||||
std::vector<std::pair<int, IdString>> fanout;
|
||||
for(auto &n : lsm.second) {
|
||||
fanout.push_back(std::make_pair(n.second.size(),n.first));
|
||||
}
|
||||
std::sort(fanout.begin(), fanout.end(), std::greater<std::pair<int, IdString>>());
|
||||
int available_csc = 12;
|
||||
for (std::size_t i = 0; i < std::min<std::size_t>(fanout.size(),available_csc ); i++) {
|
||||
auto &n = fanout.at(i);
|
||||
if (lsm.second[n.second].size() < 4) break;
|
||||
BelId newbel = getCSC(ctx,loc);
|
||||
if (newbel==BelId()) break;
|
||||
|
||||
NetInfo *net = ctx->nets.at(n.second).get();
|
||||
|
||||
CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->id(net->name.str(ctx) + "$" + lsm.first.c_str(ctx) + "$csc"));
|
||||
NetInfo *new_out = ctx->createNet(ctx->id(fe->name.str(ctx) + "$o"));
|
||||
fe->params[id_lut_table] = Property(0xaaaa, 16);
|
||||
fe->params[id_lut_used] = Property(1,1);
|
||||
fe->params[ctx->id("CSC")] = Property(Property::State::S1);
|
||||
fe->params[ctx->id("type")] = Property("CSC");
|
||||
fe->params[id_dff_used] = Property(1,1);
|
||||
fe->connectPort(id_I1, net);
|
||||
fe->connectPort(id_DO,new_out);
|
||||
|
||||
|
||||
for(auto &conn : lsm.second[n.second])
|
||||
conn.cell->disconnectPort(conn.port);
|
||||
for(auto &conn : lsm.second[n.second])
|
||||
conn.cell->connectPort(conn.port,new_out);
|
||||
|
||||
ctx->bindBel(newbel, fe, PlaceStrength::STRENGTH_LOCKED);
|
||||
//printf("\t%d --- %s %d %d\n", n.first,n.second.c_str(ctx),loc.x,loc.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
BelId NgUltraPacker::get_available_gck(int lobe, NetInfo *si1, NetInfo *si2)
|
||||
{
|
||||
auto &gcks = uarch->gck_per_lobe[lobe];
|
||||
@ -2460,7 +2622,7 @@ void NgUltraPacker::duplicate_gck()
|
||||
IdString port = usr.port;
|
||||
cell->connectPort(port, new_clk);
|
||||
}
|
||||
|
||||
global_lowskew.emplace(new_clk->name);
|
||||
ctx->bindBel(bel, gck_cell, PlaceStrength::STRENGTH_LOCKED);
|
||||
cnt++;
|
||||
}
|
||||
@ -2507,6 +2669,7 @@ void NgUltraPacker::insert_bypass_gck()
|
||||
IdString port = usr.port;
|
||||
cell->connectPort(port, new_clk);
|
||||
}
|
||||
global_lowskew.emplace(new_clk->name);
|
||||
ctx->bindBel(bel, gck_cell, PlaceStrength::STRENGTH_LOCKED);
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ struct NgUltraPacker
|
||||
// Post placement
|
||||
void duplicate_gck();
|
||||
void insert_bypass_gck();
|
||||
void insert_csc();
|
||||
|
||||
TESTABLE_PRIVATE:
|
||||
void set_lut_input_if_constant(CellInfo *cell, IdString input);
|
||||
@ -109,6 +110,7 @@ TESTABLE_PRIVATE:
|
||||
int memory_addr_bits(int config,bool ecc);
|
||||
|
||||
void constrain_location(CellInfo *cell);
|
||||
void extract_lowskew_signals(CellInfo *cell, dict<IdString,dict<IdString,std::vector<PortRef>>> &lowskew_signals);
|
||||
// Cell creating
|
||||
std::unique_ptr<CellInfo> create_cell(IdString type, IdString name);
|
||||
CellInfo *create_cell_ptr(IdString type, IdString name);
|
||||
@ -118,6 +120,7 @@ TESTABLE_PRIVATE:
|
||||
|
||||
pool<IdString> packed_cells;
|
||||
std::vector<std::unique_ptr<CellInfo>> new_cells;
|
||||
pool<IdString> global_lowskew;
|
||||
|
||||
HimbaechelHelpers h;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user