Better RF/XRF handling
This commit is contained in:
parent
1437f1c209
commit
ba805f67be
@ -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;
|
std::vector<std::string> config;
|
||||||
|
|
||||||
@ -308,10 +315,7 @@ struct BitstreamJsonBackend
|
|||||||
void write_fe(CellInfo *cell) {
|
void write_fe(CellInfo *cell) {
|
||||||
if (bool_or_default(cell->params, id_lut_used)) {
|
if (bool_or_default(cell->params, id_lut_used)) {
|
||||||
open_instance_fe(cell, "LUT", ".LUT");
|
open_instance_fe(cell, "LUT", ".LUT");
|
||||||
Property init = get_or_default(cell->params, id_lut_table, Property()).extract(0, 16);
|
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
|
||||||
std::string lut = init.str;
|
|
||||||
std::reverse(lut.begin(), lut.end());
|
|
||||||
add_config("lut_table", lut);
|
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
if (bool_or_default(cell->params, id_dff_used)) {
|
if (bool_or_default(cell->params, id_dff_used)) {
|
||||||
@ -350,11 +354,28 @@ struct BitstreamJsonBackend
|
|||||||
}
|
}
|
||||||
|
|
||||||
void write_rf(CellInfo *cell) {
|
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));
|
add_config("wck_edge", bool_or_default(cell->params, ctx->id("wck_edge"), false));
|
||||||
close_instance();
|
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()
|
void write_interconnections()
|
||||||
{
|
{
|
||||||
for (auto &net : ctx->nets) {
|
for (auto &net : ctx->nets) {
|
||||||
@ -404,10 +425,10 @@ struct BitstreamJsonBackend
|
|||||||
case id_DDFR.index: write_dfr(cell.second.get()); break;
|
case id_DDFR.index: write_dfr(cell.second.get()); break;
|
||||||
case id_DFR.index: write_dfr(cell.second.get()); break;
|
case id_DFR.index: write_dfr(cell.second.get()); break;
|
||||||
//case id_XLUT.index:
|
//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:
|
||||||
case id_RF.index: write_rf(cell.second.get()); break;
|
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_FIFO.index:
|
||||||
//case id_XFIFO.index:
|
//case id_XFIFO.index:
|
||||||
//case id_CDC.index:
|
//case id_CDC.index:
|
||||||
|
@ -195,6 +195,16 @@ void NgUltraPacker::set_lut_input_if_constant(CellInfo *cell, IdString input)
|
|||||||
cell->disconnectPort(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)
|
void NgUltraPacker::lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table)
|
||||||
{
|
{
|
||||||
fe->params[id_lut_table] = 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)
|
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 = xrf->getPort(in_port);
|
||||||
NetInfo *net_out = nullptr;
|
NetInfo *net_out = nullptr;
|
||||||
if (out_port != IdString())
|
if (out_port != IdString()) {
|
||||||
net_out = xrf->getPort(out_port);
|
net_out = xrf->getPort(out_port);
|
||||||
|
if (net_out->users.entries()==0) {
|
||||||
|
xrf->disconnectPort(out_port);
|
||||||
|
net_out = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!net && !net_out) return;
|
if (!net && !net_out) return;
|
||||||
CellInfo *fe = create_cell_ptr(id_BEYOND_FE, ctx->id(xrf->name.str(ctx) + "$" + in_port.c_str(ctx)));
|
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;
|
CellInfo &ci = *cell.second;
|
||||||
if (!ci.type.in(id_NX_RFB_U))
|
if (!ci.type.in(id_NX_RFB_U))
|
||||||
continue;
|
continue;
|
||||||
|
int mode = int_or_default(ci.params, ctx->id("mode"), 0);
|
||||||
ci.type = id_RF;
|
ci.type = id_RF;
|
||||||
//ci.ports[id_WCK1].name = id_WCK1;
|
if (mode > 1) {
|
||||||
//ci.ports[id_WCK1].type = PORT_IN;
|
// XRF
|
||||||
//ci.ports[id_WCK2].name = id_WCK2;
|
ci.type = id_XRF;
|
||||||
//ci.ports[id_WCK2].type = PORT_IN;
|
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);
|
NetInfo *net = ci.getPort(id_WCK);
|
||||||
//if (net) {
|
if (net) {
|
||||||
// ci.disconnectPort(id_WCK);
|
ci.disconnectPort(id_WCK);
|
||||||
//
|
|
||||||
//ci.connectPort(id_WCK1, net);
|
ci.connectPort(id_WCK1, net);
|
||||||
//ci.connectPort(id_WCK2, net);
|
ci.connectPort(id_WCK2, net);
|
||||||
//}
|
}
|
||||||
|
}
|
||||||
ci.cluster = ci.name;
|
ci.cluster = ci.name;
|
||||||
|
|
||||||
pack_xrf_input_and_output(&ci, ci.name, id_I1, id_O1, lut_only, lut_and_ff, dff_only);
|
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)
|
if (ddfr_removed)
|
||||||
log_info(" Removed %d unused DDFRs\n", 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()
|
void NgUltraImpl::pack()
|
||||||
{
|
{
|
||||||
const ArchArgs &args = ctx->args;
|
const ArchArgs &args = ctx->args;
|
||||||
@ -1020,6 +1053,7 @@ void NgUltraImpl::pack()
|
|||||||
packer.update_dffs();
|
packer.update_dffs();
|
||||||
packer.pack_iobs();
|
packer.pack_iobs();
|
||||||
packer.pack_ioms();
|
packer.pack_ioms();
|
||||||
|
packer.pack_rams();
|
||||||
packer.pack_rfs();
|
packer.pack_rfs();
|
||||||
packer.pack_cys();
|
packer.pack_cys();
|
||||||
packer.pack_lut_dffs();
|
packer.pack_lut_dffs();
|
||||||
|
@ -50,6 +50,8 @@ struct NgUltraPacker
|
|||||||
void pack_cys();
|
void pack_cys();
|
||||||
void pack_rfs();
|
void pack_rfs();
|
||||||
|
|
||||||
|
void pack_rams();
|
||||||
|
|
||||||
// IO
|
// IO
|
||||||
void pack_iobs();
|
void pack_iobs();
|
||||||
void pack_ioms();
|
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 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
|
// General helper functions
|
||||||
void flush_cells();
|
void flush_cells();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user