Addressed review comments

This commit is contained in:
Miodrag Milanovic 2024-07-08 20:09:14 +02:00
parent 6ff846dbe6
commit 9ba4e1381d
5 changed files with 89 additions and 112 deletions

View File

@ -21,7 +21,9 @@
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
static const Loc ng_ultra_place_cy_map[24] = { namespace {
const Loc ng_ultra_place_cy_map[24] = {
{ 0, 1, 0 }, // S1 0 -> S2 0 CY24->CY1 { 0, 1, 0 }, // S1 0 -> S2 0 CY24->CY1
{ 0, 0, -1 }, // S1 1 -> S1 0 CY23->CY24 { 0, 0, -1 }, // S1 1 -> S1 0 CY23->CY24
{ 0, 0, -1 }, // S1 2 -> S1 1 CY22->CY23 { 0, 0, -1 }, // S1 2 -> S1 1 CY22->CY23
@ -53,7 +55,7 @@ static const Loc ng_ultra_place_cy_map[24] = {
{0,-1, 0}, // S10 3 -> S9 3 CY12->CY13 {0,-1, 0}, // S10 3 -> S9 3 CY12->CY13
}; };
static const Loc ng_ultra_place_xrf[] = const Loc ng_ultra_place_xrf[] =
{ {
{-1, 0, 1},// I/O1 {-1, 0, 1},// I/O1
{-1, 0, 2},// I/O2 {-1, 0, 2},// I/O2
@ -118,7 +120,7 @@ static const Loc ng_ultra_place_xrf[] =
}; };
static const Loc ng_ultra_place_cdc1[] = const Loc ng_ultra_place_cdc1[] =
{ {
{+1, 0, 1}, // AI1 {+1, 0, 1}, // AI1
{+1, 0, 2}, // AI2 {+1, 0, 2}, // AI2
@ -140,7 +142,7 @@ static const Loc ng_ultra_place_cdc1[] =
{+1, 0, 8}, // BDRSTI {+1, 0, 8}, // BDRSTI
}; };
static const Loc ng_ultra_place_cdc2[] = const Loc ng_ultra_place_cdc2[] =
{ {
{-1, 0, 4}, // AI1 {-1, 0, 4}, // AI1
{-1, 0, 5}, // AI2 {-1, 0, 5}, // AI2
@ -162,7 +164,7 @@ static const Loc ng_ultra_place_cdc2[] =
{-1, 0, 7}, // BDRSTI {-1, 0, 7}, // BDRSTI
}; };
static const Loc ng_ultra_place_xcdc[] = const Loc ng_ultra_place_xcdc[] =
{ {
{ 0, 0, 1}, // AI1 { 0, 0, 1}, // AI1
{ 0, 0, 2}, // AI2 { 0, 0, 2}, // AI2
@ -203,7 +205,7 @@ static const Loc ng_ultra_place_xcdc[] =
{ 0, 0, 7}, // DDRSTI { 0, 0, 7}, // DDRSTI
}; };
static const Loc ng_ultra_place_fifo1[] = const Loc ng_ultra_place_fifo1[] =
{ {
{-1, 0, 1}, // I/O1 {-1, 0, 1}, // I/O1
{-1, 0, 2}, // I/O2 {-1, 0, 2}, // I/O2
@ -283,7 +285,7 @@ static const Loc ng_ultra_place_fifo1[] =
{ 0, 0, 0}, // REQ2 { 0, 0, 0}, // REQ2
}; };
static const Loc ng_ultra_place_fifo2[] = const Loc ng_ultra_place_fifo2[] =
{ {
{+1, 0, 1}, // I/O1 {+1, 0, 1}, // I/O1
{+1, 0, 2}, // I/O2 {+1, 0, 2}, // I/O2
@ -363,7 +365,7 @@ static const Loc ng_ultra_place_fifo2[] =
{ 0, 0, 0}, // REQ2 { 0, 0, 0}, // REQ2
}; };
static const Loc ng_ultra_place_xfifo[] = const Loc ng_ultra_place_xfifo[] =
{ {
{-1, 0, 1}, // I/O1 {-1, 0, 1}, // I/O1
{-1, 0, 2}, // I/O2 {-1, 0, 2}, // I/O2
@ -448,6 +450,10 @@ static const Loc ng_ultra_place_xfifo[] =
// {+1, 0, 28}, REQ2 // {+1, 0, 28}, REQ2
}; };
};
namespace ng_ultra {
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc) Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc)
{ {
BelId bel = impl->ctx->getBelByLocation(loc); BelId bel = impl->ctx->getBelByLocation(loc);
@ -533,4 +539,5 @@ Loc getFIFOFE(Loc root, int pos)
return result; return result;
} }
};
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -25,6 +25,8 @@
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
namespace ng_ultra {
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc); Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc);
Loc getNextLocInCYChain(Loc loc); Loc getNextLocInCYChain(Loc loc);
Loc getCYFE(Loc root, int pos); Loc getCYFE(Loc root, int pos);
@ -33,5 +35,7 @@ Loc getXRFFE(Loc root, int pos);
Loc getCDCFE(Loc root, int pos); Loc getCDCFE(Loc root, int pos);
Loc getFIFOFE(Loc root, int pos); Loc getFIFOFE(Loc root, int pos);
};
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END
#endif #endif

View File

@ -37,6 +37,7 @@
#define GEN_INIT_CONSTIDS #define GEN_INIT_CONSTIDS
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc" #define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
#include "himbaechel_constids.h" #include "himbaechel_constids.h"
using namespace NEXTPNR_NAMESPACE_PREFIX ng_ultra;
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -75,7 +76,7 @@ void NgUltraImpl::init(Context *ctx)
} }
std::pair<IdString,IdString> p; std::pair<IdString,IdString> p;
p.first = *ckg.begin(); p.first = *ckg.begin();
if (ckg.size()==2) p.second = *ckg.end(); if (ckg.size()==2) p.second = *(ckg.begin()++);
bank_to_ckg[bank] = p; bank_to_ckg[bank] = p;
} else if (ctx->getBelType(bel) == id_IOTP) { } else if (ctx->getBelType(bel) == id_IOTP) {
if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) { if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) {
@ -85,8 +86,8 @@ void NgUltraImpl::init(Context *ctx)
} }
} else if (ctx->getBelType(bel) == id_GCK) { } else if (ctx->getBelType(bel) == id_GCK) {
std::string name = ctx->getBelName(bel)[1].c_str(ctx); std::string name = ctx->getBelName(bel)[1].c_str(ctx);
int lobe = name[1] - '0'; int lobe = std::stoi(name.substr(1,1));
int num = atoi(name.substr(4,2).c_str()); int num = std::stoi(name.substr(4,2).c_str());
gck_per_lobe[lobe].insert(gck_per_lobe[lobe].begin()+num-1, GckConfig(bel)); gck_per_lobe[lobe].insert(gck_per_lobe[lobe].begin()+num-1, GckConfig(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);
@ -106,136 +107,109 @@ void NgUltraImpl::init(Context *ctx)
} }
} }
} }
}
// Note: These are per Cell type not Bel type namespace {
// Sinks // Note: These are per Cell type not Bel type
// Sinks
const dict<IdString,pool<IdString>> fabric_clock_sinks = {
// TILE - DFF // TILE - DFF
fabric_clock_sinks[id_BEYOND_FE].insert(id_CK); { id_BEYOND_FE, { id_CK }},
//fabric_clock_sinks[id_DFF].insert(id_CK); // This is part of BEYOND_FE // { id_DFF, { id_CK }}, // This is part of BEYOND_FE
// TILE - Register file // TILE - Register file
fabric_clock_sinks[id_RF].insert(id_WCK); { id_RF, { id_WCK }},
fabric_clock_sinks[id_RFSP].insert(id_WCK); { id_RFSP, { id_WCK }},
fabric_clock_sinks[id_XHRF].insert(id_WCK1); { id_XHRF, { id_WCK1, id_WCK2 }},
fabric_clock_sinks[id_XHRF].insert(id_WCK2); { id_XWRF, { id_WCK1, id_WCK2 }},
fabric_clock_sinks[id_XWRF].insert(id_WCK1); { id_XPRF, { id_WCK1, id_WCK2 }},
fabric_clock_sinks[id_XWRF].insert(id_WCK2);
fabric_clock_sinks[id_XPRF].insert(id_WCK1);
fabric_clock_sinks[id_XPRF].insert(id_WCK2);
// TILE - CDC // TILE - CDC
fabric_clock_sinks[id_CDC].insert(id_CK1); { id_CDC, { id_CK1, id_CK2 }},
fabric_clock_sinks[id_CDC].insert(id_CK2); { id_DDE, { id_CK1, id_CK2 }},
fabric_clock_sinks[id_DDE].insert(id_CK1); { id_TDE, { id_CK1, id_CK2 }},
fabric_clock_sinks[id_DDE].insert(id_CK2); { id_XCDC, { id_CK1, id_CK2 }},
fabric_clock_sinks[id_TDE].insert(id_CK1);
fabric_clock_sinks[id_TDE].insert(id_CK2);
fabric_clock_sinks[id_XCDC].insert(id_CK1);
fabric_clock_sinks[id_XCDC].insert(id_CK2);
// TILE - FIFO // TILE - FIFO
fabric_clock_sinks[id_FIFO].insert(id_RCK); { id_FIFO, { id_RCK, id_WCK }},
fabric_clock_sinks[id_FIFO].insert(id_WCK); { id_XHFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }},
fabric_clock_sinks[id_XHFIFO].insert(id_RCK1); { id_XWFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }},
fabric_clock_sinks[id_XHFIFO].insert(id_RCK2);
fabric_clock_sinks[id_XHFIFO].insert(id_WCK1);
fabric_clock_sinks[id_XHFIFO].insert(id_WCK2);
fabric_clock_sinks[id_XWFIFO].insert(id_RCK1);
fabric_clock_sinks[id_XWFIFO].insert(id_RCK2);
fabric_clock_sinks[id_XWFIFO].insert(id_WCK1);
fabric_clock_sinks[id_XWFIFO].insert(id_WCK2);
// CGB - RAM // CGB - RAM
fabric_clock_sinks[id_RAM].insert(id_ACK); { id_RAM, { id_ACK, id_BCK }},
fabric_clock_sinks[id_RAM].insert(id_BCK);
// CGB - DSP // CGB - DSP
fabric_clock_sinks[id_DSP].insert(id_CK); { id_DSP, {id_CK }},
};
const dict<IdString,pool<IdString>> ring_clock_sinks = {
// CKG // CKG
ring_clock_sinks[id_PLL].insert(id_CLK_CAL); { id_PLL, { id_CLK_CAL, id_FBK, id_REF }},
ring_clock_sinks[id_PLL].insert(id_FBK); { id_WFB, { id_ZI }},
ring_clock_sinks[id_PLL].insert(id_REF); { id_WFG, { id_ZI }}
ring_clock_sinks[id_WFB].insert(id_ZI); };
ring_clock_sinks[id_WFG].insert(id_ZI);
const dict<IdString,pool<IdString>> ring_over_tile_clock_sinks = {
// IOB // IOB
ring_over_tile_clock_sinks[id_DFR].insert(id_CK); { id_DFR, { id_CK }},
ring_over_tile_clock_sinks[id_DDFR].insert(id_CK); { id_DDFR, { id_CK }},
ring_over_tile_clock_sinks[id_DDFR].insert(id_CKF); { id_DDFR, { id_CKF }},
// ring_clock_sinks[id_IOM].insert(id_ALCK1); };
// ring_clock_sinks[id_IOM].insert(id_ALCK2); // IOB
// ring_clock_sinks[id_IOM].insert(id_ALCK3); // { id_IOM, { id_ALCK1, id_ALCK2, id_ALCK3, id_CCK, id_FCK1, id_FCK2, id_FDCK,
// ring_clock_sinks[id_IOM].insert(id_CCK); // id_LDSCK1, id_LDSCK2, id_LDSCK3, id_SWRX1CK, id_SWRX2CK }},
// ring_clock_sinks[id_IOM].insert(id_FCK1);
// ring_clock_sinks[id_IOM].insert(id_FCK2);
// ring_clock_sinks[id_IOM].insert(id_FDCK);
// ring_clock_sinks[id_IOM].insert(id_LDSCK1);
// ring_clock_sinks[id_IOM].insert(id_LDSCK2);
// ring_clock_sinks[id_IOM].insert(id_LDSCK3);
// ring_clock_sinks[id_IOM].insert(id_SWRX1CK);
// ring_clock_sinks[id_IOM].insert(id_SWRX2CK);
// HSSL // HSSL
// ring_clock_sinks[id_CRX].insert(id_LINK); // { id_CRX, { id_LINK }},
// ring_clock_sinks[id_CTX].insert(id_LINK); // { id_CTX, { id_LINK }},
// ring_clock_sinks[id_PMA].insert(id_hssl_clock_i1); // { id_PMA, { id_hssl_clock_i1, id_hssl_clock_i2, id_hssl_clock_i3, id_hssl_clock_i4 },
// ring_clock_sinks[id_PMA].insert(id_hssl_clock_i2);
// ring_clock_sinks[id_PMA].insert(id_hssl_clock_i3);
// ring_clock_sinks[id_PMA].insert(id_hssl_clock_i4);
const dict<IdString,pool<IdString>> tube_clock_sinks = {
// TUBE // TUBE
tube_clock_sinks[id_GCK].insert(id_SI1); { id_GCK, { id_SI1, id_SI2 }},
tube_clock_sinks[id_GCK].insert(id_SI2); };
// Sources // Sources
// CKG // CKG
ring_clock_source[id_IOM].insert(id_CKO1); const dict<IdString,pool<IdString>> ring_clock_source = {
ring_clock_source[id_IOM].insert(id_CKO2); { id_IOM, { id_CKO1, id_CKO2 }},
ring_clock_source[id_WFB].insert(id_ZO); { id_WFB, { id_ZO }},
ring_clock_source[id_WFG].insert(id_ZO); { id_WFG, { id_ZO }},
ring_clock_source[id_PLL].insert(id_OSC); { id_PLL, { id_OSC, id_VCO, id_REFO, id_LDFO,
ring_clock_source[id_PLL].insert(id_VCO); id_CLK_DIV1, id_CLK_DIV2, id_CLK_DIV3, id_CLK_DIV4,
ring_clock_source[id_PLL].insert(id_REFO); id_CLK_DIVD1, id_CLK_DIVD2, id_CLK_DIVD3, id_CLK_DIVD4, id_CLK_DIVD5,
ring_clock_source[id_PLL].insert(id_LDFO); id_CLK_CAL_DIV }}
ring_clock_source[id_PLL].insert(id_CLK_DIV1); };
ring_clock_source[id_PLL].insert(id_CLK_DIV2);
ring_clock_source[id_PLL].insert(id_CLK_DIV3);
ring_clock_source[id_PLL].insert(id_CLK_DIV4);
ring_clock_source[id_PLL].insert(id_CLK_DIVD1);
ring_clock_source[id_PLL].insert(id_CLK_DIVD2);
ring_clock_source[id_PLL].insert(id_CLK_DIVD3);
ring_clock_source[id_PLL].insert(id_CLK_DIVD4);
ring_clock_source[id_PLL].insert(id_CLK_DIVD5);
ring_clock_source[id_PLL].insert(id_CLK_CAL_DIV);
// TUBE // TUBE
tube_clock_source[id_GCK].insert(id_SO); const dict<IdString,pool<IdString>> tube_clock_source = {
} { id_GCK, { id_SO }},
};
};
bool NgUltraImpl::is_fabric_clock_sink(const PortRef &ref) bool NgUltraImpl::is_fabric_clock_sink(const PortRef &ref)
{ {
return fabric_clock_sinks.count(ref.cell->type) && fabric_clock_sinks[ref.cell->type].count(ref.port); return fabric_clock_sinks.count(ref.cell->type) && fabric_clock_sinks.at(ref.cell->type).count(ref.port);
} }
bool NgUltraImpl::is_ring_clock_sink(const PortRef &ref) bool NgUltraImpl::is_ring_clock_sink(const PortRef &ref)
{ {
return ring_clock_sinks.count(ref.cell->type) && ring_clock_sinks[ref.cell->type].count(ref.port); return ring_clock_sinks.count(ref.cell->type) && ring_clock_sinks.at(ref.cell->type).count(ref.port);
} }
bool NgUltraImpl::is_ring_over_tile_clock_sink(const PortRef &ref) bool NgUltraImpl::is_ring_over_tile_clock_sink(const PortRef &ref)
{ {
return ring_over_tile_clock_sinks.count(ref.cell->type) && ring_over_tile_clock_sinks[ref.cell->type].count(ref.port); return ring_over_tile_clock_sinks.count(ref.cell->type) && ring_over_tile_clock_sinks.at(ref.cell->type).count(ref.port);
} }
bool NgUltraImpl::is_tube_clock_sink(const PortRef &ref) bool NgUltraImpl::is_tube_clock_sink(const PortRef &ref)
{ {
return tube_clock_sinks.count(ref.cell->type) && tube_clock_sinks[ref.cell->type].count(ref.port); return tube_clock_sinks.count(ref.cell->type) && tube_clock_sinks.at(ref.cell->type).count(ref.port);
} }
bool NgUltraImpl::is_ring_clock_source(const PortRef &ref) bool NgUltraImpl::is_ring_clock_source(const PortRef &ref)
{ {
return ring_clock_source.count(ref.cell->type) && ring_clock_source[ref.cell->type].count(ref.port); return ring_clock_source.count(ref.cell->type) && ring_clock_source.at(ref.cell->type).count(ref.port);
} }
bool NgUltraImpl::is_tube_clock_source(const PortRef &ref) bool NgUltraImpl::is_tube_clock_source(const PortRef &ref)
{ {
return tube_clock_source.count(ref.cell->type) && tube_clock_source[ref.cell->type].count(ref.port); return tube_clock_source.count(ref.cell->type) && tube_clock_source.at(ref.cell->type).count(ref.port);
} }
const NGUltraTileInstExtraDataPOD *NgUltraImpl::tile_extra_data(int tile) const const NGUltraTileInstExtraDataPOD *NgUltraImpl::tile_extra_data(int tile) const

View File

@ -105,14 +105,6 @@ TESTABLE_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;
dict<IdString,pool<IdString>> fabric_clock_sinks;
dict<IdString,pool<IdString>> ring_clock_sinks;
dict<IdString,pool<IdString>> ring_over_tile_clock_sinks;
dict<IdString,pool<IdString>> tube_clock_sinks;
dict<IdString,pool<IdString>> ring_clock_source;
dict<IdString,pool<IdString>> tube_clock_source;
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -1505,7 +1505,7 @@ void NgUltraPacker::insert_wfb(CellInfo *cell, IdString port)
// If all in ring and none in fabric no need for WFB // If all in ring and none in fabric no need for WFB
if (in_ring && !in_fabric) return; if (in_ring && !in_fabric) return;
log_info(" Inserting WFB for cell '%s' port '%s'\n", cell->name.c_str(ctx), port.c_str(ctx)); log_info(" Inserting WFB for cell '%s' port '%s'\n", cell->name.c_str(ctx), port.c_str(ctx));
CellInfo *wfb = create_cell_ptr(id_WFB, ctx->id(std::string(cell->name.c_str(ctx)) + "$" + port.c_str(ctx))); CellInfo *wfb = create_cell_ptr(id_WFB, ctx->idf("%s$%s", cell->name.c_str(ctx), port.c_str(ctx)));
if (in_ring && in_fabric) { if (in_ring && in_fabric) {
// If both in ring and in fabric create new signal // If both in ring and in fabric create new signal
wfb->connectPort(id_ZI, net); wfb->connectPort(id_ZI, net);
@ -1521,7 +1521,7 @@ void NgUltraPacker::insert_wfb(CellInfo *cell, IdString port)
// Only in fabric, reconnect wire directly to WFB // Only in fabric, reconnect wire directly to WFB
cell->disconnectPort(port); cell->disconnectPort(port);
wfb->connectPort(id_ZO, net); wfb->connectPort(id_ZO, net);
NetInfo *new_out = ctx->createNet(ctx->id(net->name.str(ctx) + "$" + port.c_str(ctx))); NetInfo *new_out = ctx->createNet(ctx->idf("%s$%s", net->name.c_str(ctx), port.c_str(ctx)));
cell->connectPort(port, new_out); cell->connectPort(port, new_out);
wfb->connectPort(id_ZI, new_out); wfb->connectPort(id_ZI, new_out);
} }
@ -2095,7 +2095,7 @@ void NgUltraPacker::duplicate_gck()
gck_cell = driver; gck_cell = driver;
log_info(" Assign GCK '%s' to lobe %d\n",gck_cell->name.c_str(ctx), conn.first); log_info(" Assign GCK '%s' to lobe %d\n",gck_cell->name.c_str(ctx), conn.first);
} else { } else {
gck_cell = create_cell_ptr(id_GCK, ctx->id(driver->name.str(ctx) + "$gck_"+ std::to_string(conn.first))); gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$gck_%d", driver->name.c_str(ctx), conn.first));
log_info(" Create GCK '%s' for lobe %d\n",gck_cell->name.c_str(ctx), conn.first); log_info(" Create GCK '%s' for lobe %d\n",gck_cell->name.c_str(ctx), conn.first);
for (auto &params : driver->params) for (auto &params : driver->params)
gck_cell->params[params.first] = params.second; gck_cell->params[params.first] = params.second;
@ -2148,7 +2148,7 @@ void NgUltraPacker::insert_bypass_gck()
BelId bel = get_available_gck(conn.first, glb_net, nullptr); BelId bel = get_available_gck(conn.first, glb_net, nullptr);
log_info(" Create GCK for lobe %d\n",conn.first); 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))); CellInfo *gck_cell = create_cell_ptr(id_GCK, ctx->idf("%s$gck_%d", glb_net->name.c_str(ctx), conn.first));
gck_cell->params[id_std_mode] = Property("BYPASS"); gck_cell->params[id_std_mode] = Property("BYPASS");
gck_cell->connectPort(id_SI1, glb_net); gck_cell->connectPort(id_SI1, glb_net);
NetInfo *new_clk = ctx->createNet(ctx->id(gck_cell->name.str(ctx))); NetInfo *new_clk = ctx->createNet(ctx->id(gck_cell->name.str(ctx)));