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;
|
||||
|
||||
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user