Better RF/XRF handling

This commit is contained in:
Miodrag Milanovic 2024-05-16 11:35:28 +02:00
parent 1437f1c209
commit ba805f67be
3 changed files with 78 additions and 19 deletions

View File

@ -188,6 +188,13 @@ struct BitstreamJsonBackend
}
};
template <typename KeyType> std::string extract_bits_or_default(const dict<KeyType, Property> &ct, const KeyType &key, int bits, int def = 0)
{
Property extr = get_or_default(ct, key, Property()).extract(0, bits);
std::string str = extr.str;
std::reverse(str.begin(), str.end());
return str;
};
std::vector<std::string> config;
@ -308,10 +315,7 @@ struct BitstreamJsonBackend
void write_fe(CellInfo *cell) {
if (bool_or_default(cell->params, id_lut_used)) {
open_instance_fe(cell, "LUT", ".LUT");
Property init = get_or_default(cell->params, id_lut_table, Property()).extract(0, 16);
std::string lut = init.str;
std::reverse(lut.begin(), lut.end());
add_config("lut_table", lut);
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
close_instance();
}
if (bool_or_default(cell->params, id_dff_used)) {
@ -350,11 +354,28 @@ struct BitstreamJsonBackend
}
void write_rf(CellInfo *cell) {
open_instance(cell, "RF");
int mode = int_or_default(cell->params, ctx->id("mode"), 0);
switch(mode) {
case 0 : open_instance(cell, "RF"); break;
case 1 : open_instance(cell, "RFSP"); break;
case 2 : open_instance(cell, "XHRF"); break;
case 3 : open_instance(cell, "XWRF"); break;
case 4 : open_instance(cell, "XPRF"); break;
default:
log_error("Unknown mode %d for cell '%s'.\n", mode, cell->name.c_str(ctx));
}
add_config("mode", mode);
add_config("wck_edge", bool_or_default(cell->params, ctx->id("wck_edge"), false));
close_instance();
}
void write_ram(CellInfo *cell) {
open_instance(cell, "RAM");
add_config("raw_config0", extract_bits_or_default(cell->params, ctx->id("raw_config0"), 4));
add_config("raw_config1", extract_bits_or_default(cell->params, ctx->id("raw_config1"), 16));
close_instance();
}
void write_interconnections()
{
for (auto &net : ctx->nets) {
@ -404,10 +425,10 @@ struct BitstreamJsonBackend
case id_DDFR.index: write_dfr(cell.second.get()); break;
case id_DFR.index: write_dfr(cell.second.get()); break;
//case id_XLUT.index:
//case id_RAM.index:
case id_RAM.index: write_ram(cell.second.get()); break;
//case id_RF.index:
case id_RF.index: write_rf(cell.second.get()); break;
//case id_XRF.index: write_xrf(cell.second.get()); break;
case id_XRF.index: write_rf(cell.second.get()); break;
//case id_FIFO.index:
//case id_XFIFO.index:
//case id_CDC.index:

View File

@ -195,6 +195,16 @@ void NgUltraPacker::set_lut_input_if_constant(CellInfo *cell, IdString input)
cell->disconnectPort(input);
}
void NgUltraPacker::disconnect_if_gnd(CellInfo *cell, IdString input)
{
NetInfo *net = cell->getPort(input);
if (!net)
return;
if (net->name.in(ctx->id("$PACKER_GND"))) {
cell->disconnectPort(input);
}
}
void NgUltraPacker::lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table)
{
fe->params[id_lut_table] = lut_table;
@ -782,10 +792,16 @@ ClusterPlacement getPortPlacement(Context *ctx, IdString port)
void NgUltraPacker::pack_xrf_input_and_output(CellInfo *xrf, IdString cluster, IdString in_port, IdString out_port, int &lut_only, int &lut_and_ff, int &dff_only)
{
disconnect_if_gnd(xrf, in_port);
NetInfo *net = xrf->getPort(in_port);
NetInfo *net_out = nullptr;
if (out_port != IdString())
if (out_port != IdString()) {
net_out = xrf->getPort(out_port);
if (net_out->users.entries()==0) {
xrf->disconnectPort(out_port);
net_out = nullptr;
}
}
if (!net && !net_out) return;
CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->id(xrf->name.str(ctx) + "$" + in_port.c_str(ctx)));
@ -843,19 +859,24 @@ void NgUltraPacker::pack_rfs(void)
CellInfo &ci = *cell.second;
if (!ci.type.in(id_NX_RFB_U))
continue;
int mode = int_or_default(ci.params, ctx->id("mode"), 0);
ci.type = id_RF;
//ci.ports[id_WCK1].name = id_WCK1;
//ci.ports[id_WCK1].type = PORT_IN;
//ci.ports[id_WCK2].name = id_WCK2;
//ci.ports[id_WCK2].type = PORT_IN;
if (mode > 1) {
// XRF
ci.type = id_XRF;
ci.ports[id_WCK1].name = id_WCK1;
ci.ports[id_WCK1].type = PORT_IN;
ci.ports[id_WCK2].name = id_WCK2;
ci.ports[id_WCK2].type = PORT_IN;
//NetInfo *net = ci.getPort(id_WCK);
//if (net) {
// ci.disconnectPort(id_WCK);
//
//ci.connectPort(id_WCK1, net);
//ci.connectPort(id_WCK2, net);
//}
NetInfo *net = ci.getPort(id_WCK);
if (net) {
ci.disconnectPort(id_WCK);
ci.connectPort(id_WCK1, net);
ci.connectPort(id_WCK2, net);
}
}
ci.cluster = ci.name;
pack_xrf_input_and_output(&ci, ci.name, id_I1, id_O1, lut_only, lut_and_ff, dff_only);
@ -1008,6 +1029,18 @@ void NgUltraPacker::promote_globals()
if (ddfr_removed)
log_info(" Removed %d unused DDFRs\n", ddfr_removed);
}
void NgUltraPacker::pack_rams(void)
{
log_info("Packing RAMs..\n");
for (auto &cell : ctx->cells) {
CellInfo &ci = *cell.second;
if (!ci.type.in(id_NX_RAM))
continue;
ci.type = id_RAM;
}
}
void NgUltraImpl::pack()
{
const ArchArgs &args = ctx->args;
@ -1020,6 +1053,7 @@ void NgUltraImpl::pack()
packer.update_dffs();
packer.pack_iobs();
packer.pack_ioms();
packer.pack_rams();
packer.pack_rfs();
packer.pack_cys();
packer.pack_lut_dffs();

View File

@ -50,6 +50,8 @@ struct NgUltraPacker
void pack_cys();
void pack_rfs();
void pack_rams();
// IO
void pack_iobs();
void pack_ioms();
@ -66,6 +68,8 @@ private:
void pack_xrf_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int &lut_only, int &lut_and_ff, int &dff_only);
void disconnect_if_gnd(CellInfo *cell, IdString input);
// General helper functions
void flush_cells();