wip
This commit is contained in:
parent
d19702d1a8
commit
dddfcec4b9
@ -97,6 +97,11 @@ CellInfo *NgUltraPacker::create_cell_ptr(IdString type, IdString name)
|
|||||||
} else if (type == id_WFB) {
|
} else if (type == id_WFB) {
|
||||||
add_port("ZI", PORT_IN);
|
add_port("ZI", PORT_IN);
|
||||||
add_port("ZO", PORT_OUT);
|
add_port("ZO", PORT_OUT);
|
||||||
|
} else if (type == id_GCK) {
|
||||||
|
add_port("SI1", PORT_IN);
|
||||||
|
add_port("SI2", PORT_IN);
|
||||||
|
add_port("CMD", PORT_IN);
|
||||||
|
add_port("SO", PORT_OUT);
|
||||||
} else {
|
} else {
|
||||||
log_error("Trying to create unknown cell type %s\n", type.c_str(ctx));
|
log_error("Trying to create unknown cell type %s\n", type.c_str(ctx));
|
||||||
}
|
}
|
||||||
|
@ -387,13 +387,13 @@ def create_tile_types(ch: Chip, bels, bel_pins, crossbars, interconnects, muxes,
|
|||||||
#elif (tile_type.startswith("CKG") and bel=="WFG"):
|
#elif (tile_type.startswith("CKG") and bel=="WFG"):
|
||||||
# by = tt.create_pip(f"{name}.ZI",f"{name}.ZO","BYPASS")
|
# by = tt.create_pip(f"{name}.ZI",f"{name}.ZO","BYPASS")
|
||||||
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||||
elif (tile_type.startswith("TUBE") and bel=="GCK"):
|
#elif (tile_type.startswith("TUBE") and bel=="GCK"):
|
||||||
# 20 clock signals comming to 20 GCK, SI1 is bypass
|
# # 20 clock signals comming to 20 GCK, SI1 is bypass
|
||||||
by = tt.create_pip(f"{name}.SI1",f"{name}.SO","BYPASS")
|
# by = tt.create_pip(f"{name}.SI1",f"{name}.SO","BYPASS")
|
||||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||||
# there are CMD signals that can be bypassed as well
|
# # there are CMD signals that can be bypassed as well
|
||||||
by = tt.create_pip(f"{name}.CMD",f"{name}.SO","BYPASS")
|
# by = tt.create_pip(f"{name}.CMD",f"{name}.SO","BYPASS")
|
||||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,1,0)
|
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,1,0)
|
||||||
|
|
||||||
|
|
||||||
# Add LUT permutation
|
# Add LUT permutation
|
||||||
|
@ -78,6 +78,9 @@ void NgUltraImpl::init(Context *ctx)
|
|||||||
} else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) {
|
} else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) {
|
||||||
global_capable_bels.emplace(bel,id_P19RI);
|
global_capable_bels.emplace(bel,id_P19RI);
|
||||||
}
|
}
|
||||||
|
} else if (ctx->getBelType(bel) == id_GCK) {
|
||||||
|
int lobe = ctx->getBelName(bel)[1].c_str(ctx)[1] - '0';
|
||||||
|
gck_per_lobe[lobe].emplace(bel);
|
||||||
}
|
}
|
||||||
locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel);
|
locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ struct NgUltraImpl : HimbaechelAPI
|
|||||||
|
|
||||||
bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip)==0; }
|
bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip)==0; }
|
||||||
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
||||||
|
int tile_lobe(int tile) const;
|
||||||
public:
|
public:
|
||||||
IdString tile_name_id(int tile) const;
|
IdString tile_name_id(int tile) const;
|
||||||
std::string tile_name(int tile) const;
|
std::string tile_name(int tile) const;
|
||||||
@ -70,6 +71,7 @@ public:
|
|||||||
dict<std::string, std::string> bank_voltage;
|
dict<std::string, std::string> bank_voltage;
|
||||||
dict<BelId,IdString> global_capable_bels;
|
dict<BelId,IdString> global_capable_bels;
|
||||||
dict<std::string,BelId> locations;
|
dict<std::string,BelId> locations;
|
||||||
|
dict<int,pool<BelId>> gck_per_lobe;
|
||||||
|
|
||||||
pool<PipId> blocked_pips;
|
pool<PipId> blocked_pips;
|
||||||
dict<IdString, std::deque<BelId>> wfg_c_per_bank;
|
dict<IdString, std::deque<BelId>> wfg_c_per_bank;
|
||||||
@ -86,7 +88,6 @@ private:
|
|||||||
bool get_mux_data(WireId wire, uint8_t *value);
|
bool get_mux_data(WireId wire, uint8_t *value);
|
||||||
|
|
||||||
const NGUltraTileInstExtraDataPOD *tile_extra_data(int tile) const;
|
const NGUltraTileInstExtraDataPOD *tile_extra_data(int tile) const;
|
||||||
int tile_lobe(int tile) const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1456,8 +1456,93 @@ void NgUltraImpl::postPlace()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
remove_constants();
|
remove_constants();
|
||||||
|
|
||||||
|
|
||||||
|
NgUltraPacker packer(ctx, this);
|
||||||
|
log_break();
|
||||||
|
log_info("Running post-placement ...\n");
|
||||||
|
packer.duplicate_gck();
|
||||||
|
packer.insert_bypass_gck();
|
||||||
|
//log_info("Running post-placement legalisation...\n");
|
||||||
|
log_break();
|
||||||
|
ctx->assignArchInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NgUltraPacker::duplicate_gck()
|
||||||
|
{
|
||||||
|
//log_info("Duplicating existing GCKs...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NgUltraPacker::insert_bypass_gck()
|
||||||
|
{
|
||||||
|
dict<IdString,pool<IdString>> glb_sources;
|
||||||
|
glb_sources[id_IOM].insert(id_CKO1);
|
||||||
|
glb_sources[id_IOM].insert(id_CKO2);
|
||||||
|
glb_sources[id_WFB].insert(id_ZO);
|
||||||
|
glb_sources[id_WFG].insert(id_ZO);
|
||||||
|
|
||||||
|
dict<IdString,pool<IdString>> clock_sinks;
|
||||||
|
clock_sinks[id_BEYOND_FE].insert(id_CK);
|
||||||
|
//clock_sinks[id_DFF].insert(id_CK); // This is part of BEYOND_FE
|
||||||
|
clock_sinks[id_RF].insert(id_WCK);
|
||||||
|
clock_sinks[id_RFSP].insert(id_WCK);
|
||||||
|
clock_sinks[id_XHRF].insert(id_WCK1);
|
||||||
|
clock_sinks[id_XHRF].insert(id_WCK2);
|
||||||
|
clock_sinks[id_XWRF].insert(id_WCK1);
|
||||||
|
clock_sinks[id_XWRF].insert(id_WCK2);
|
||||||
|
clock_sinks[id_XPRF].insert(id_WCK1);
|
||||||
|
clock_sinks[id_XPRF].insert(id_WCK2);
|
||||||
|
clock_sinks[id_RAM].insert(id_ACK);
|
||||||
|
clock_sinks[id_RAM].insert(id_BCK);
|
||||||
|
//glb_sources[id_BFR].insert(id_O);
|
||||||
|
//glb_sources[id_GCK].insert(id_SO);
|
||||||
|
|
||||||
|
log_info("Inserting bypass GCKs...\n");
|
||||||
|
for (auto &net : ctx->nets) {
|
||||||
|
NetInfo *glb_net = net.second.get();
|
||||||
|
if (!glb_net->driver.cell)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// check if we have a global clock net, skip otherwise
|
||||||
|
if (!(glb_sources.count(glb_net->driver.cell->type) && glb_sources[glb_net->driver.cell->type].count(glb_net->driver.port)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
log_info(" Global signal '%s'\n", glb_net->name.c_str(ctx));
|
||||||
|
dict<int, std::vector<PortRef>> connections;
|
||||||
|
for (const auto &usr : glb_net->users) {
|
||||||
|
if (clock_sinks.count(usr.cell->type) && clock_sinks[usr.cell->type].count(usr.port)) {
|
||||||
|
if (usr.cell->bel==BelId()) {
|
||||||
|
log_error("Cell '%s' not placed\n",usr.cell->name.c_str(ctx));
|
||||||
|
}
|
||||||
|
int lobe = uarch->tile_lobe(usr.cell->bel.tile);
|
||||||
|
if (lobe > 0) {
|
||||||
|
connections[lobe].push_back(usr);
|
||||||
|
usr.cell->disconnectPort(usr.port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &conn : connections) {
|
||||||
|
pool<BelId>& gck = uarch->gck_per_lobe[conn.first];
|
||||||
|
if (gck.size()==0)
|
||||||
|
log_error("No GCK left to promote global signal.\n");
|
||||||
|
|
||||||
|
BelId bel = gck.pop();
|
||||||
|
|
||||||
|
log_info(" Create GCK for lobe %d\n",conn.first);
|
||||||
|
CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->id(glb_net->name.str(ctx) + "$gck_"+ std::to_string(conn.first)));
|
||||||
|
gck_cell->params[id_std_mode] = Property("BYPASS");
|
||||||
|
gck_cell->connectPort(id_SI1, glb_net);
|
||||||
|
NetInfo *new_clk = ctx->createNet(ctx->id(gck_cell->name.str(ctx)));
|
||||||
|
gck_cell->connectPort(id_SO, new_clk);
|
||||||
|
for (const auto &usr : conn.second) {
|
||||||
|
CellInfo *cell = usr.cell;
|
||||||
|
IdString port = usr.port;
|
||||||
|
cell->connectPort(port, new_clk);
|
||||||
|
}
|
||||||
|
ctx->bindBel(bel, gck_cell, PlaceStrength::STRENGTH_LOCKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void NgUltraImpl::route_clocks()
|
void NgUltraImpl::route_clocks()
|
||||||
{
|
{
|
||||||
dict<IdString,pool<IdString>> glb_sources;
|
dict<IdString,pool<IdString>> glb_sources;
|
||||||
|
@ -65,6 +65,10 @@ struct NgUltraPacker
|
|||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
|
// Post placement
|
||||||
|
void duplicate_gck();
|
||||||
|
void insert_bypass_gck();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_lut_input_if_constant(CellInfo *cell, IdString input);
|
void set_lut_input_if_constant(CellInfo *cell, IdString input);
|
||||||
void lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table);
|
void lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table);
|
||||||
|
Loading…
Reference in New Issue
Block a user