ecp5: Add cell delays
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
cdc9dc545e
commit
ec94848774
142
ecp5/arch.cc
142
ecp5/arch.cc
@ -46,13 +46,16 @@ static std::tuple<int, int, std::string> split_identifier_name(const std::string
|
||||
void IdString::initialize_arch(const BaseCtx *ctx)
|
||||
{
|
||||
#define X(t) initialize_add(ctx, #t, ID_##t);
|
||||
|
||||
#include "constids.inc"
|
||||
|
||||
#undef X
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
|
||||
static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr)
|
||||
{ return ptr->get(); }
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
void load_chipdb();
|
||||
@ -381,13 +384,16 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
|
||||
return 50 * (abs(driver_loc.x - sink_loc.x) + abs(driver_loc.y - sink_loc.y));
|
||||
}
|
||||
|
||||
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
|
||||
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
|
||||
{ return false; }
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||
bool Arch::place()
|
||||
{ return placer1(getCtx(), Placer1Cfg(getCtx())); }
|
||||
|
||||
bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||
bool Arch::route()
|
||||
{ return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@ -408,8 +414,8 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
|
||||
el.x1 = bel.location.x + logic_cell_x1;
|
||||
el.x2 = bel.location.x + logic_cell_x2;
|
||||
el.y1 = bel.location.y + logic_cell_y1 + (z)*logic_cell_pitch;
|
||||
el.y2 = bel.location.y + logic_cell_y2 + (z)*logic_cell_pitch;
|
||||
el.y1 = bel.location.y + logic_cell_y1 + (z) * logic_cell_pitch;
|
||||
el.y2 = bel.location.y + logic_cell_y2 + (z) * logic_cell_pitch;
|
||||
ret.push_back(el);
|
||||
}
|
||||
|
||||
@ -438,22 +444,136 @@ DecalXY Arch::getBelDecal(BelId bel) const
|
||||
return decalxy;
|
||||
}
|
||||
|
||||
DecalXY Arch::getWireDecal(WireId wire) const { return {}; }
|
||||
DecalXY Arch::getWireDecal(WireId wire) const
|
||||
{ return {}; }
|
||||
|
||||
DecalXY Arch::getPipDecal(PipId pip) const { return {}; };
|
||||
DecalXY Arch::getPipDecal(PipId pip) const
|
||||
{ return {}; };
|
||||
|
||||
DecalXY Arch::getGroupDecal(GroupId pip) const { return {}; };
|
||||
DecalXY Arch::getGroupDecal(GroupId pip) const
|
||||
{ return {}; };
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
return false;
|
||||
// Data for -8 grade
|
||||
if (cell->type == id_TRELLIS_SLICE) {
|
||||
bool has_carry = str_or_default(cell->params, id("MODE"), "LOGIC") == "CCU2";
|
||||
if (fromPort == id_A0 || fromPort == id_B0 || fromPort == id_C0 || fromPort == id_D0) {
|
||||
if (toPort == id_F0) {
|
||||
delay.delay = 180;
|
||||
return true;
|
||||
} else if (has_carry && toPort == id_F1) {
|
||||
delay.delay = 500;
|
||||
return true;
|
||||
} else if (has_carry && toPort == id_FCO) {
|
||||
delay.delay = 355;
|
||||
return true;
|
||||
} else if (toPort == id_OFX0) {
|
||||
delay.delay = 306;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fromPort == id_A1 || fromPort == id_B1 || fromPort == id_C1 || fromPort == id_D1) {
|
||||
if (toPort == id_F1) {
|
||||
delay.delay = 180;
|
||||
return true;
|
||||
} else if (has_carry && toPort == id_FCO) {
|
||||
delay.delay = 355;
|
||||
return true;
|
||||
} else if (toPort == id_OFX0) {
|
||||
delay.delay = 306;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_carry && fromPort == id_FCI) {
|
||||
if (toPort == id_F0) {
|
||||
delay.delay = 328;
|
||||
return true;
|
||||
} else if (toPort == id_F1) {
|
||||
delay.delay = 349;
|
||||
return true;
|
||||
} else if (toPort == id_FCO) {
|
||||
delay.delay = 56;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fromPort == id_CLK && (toPort == id_Q0 || toPort == id_Q1)) {
|
||||
delay.delay = 395;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fromPort == id_M0 && toPort == id_OFX0) {
|
||||
delay.delay = 193;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fromPort == id_WCK && (toPort == id_F0 || toPort == id_F1)) {
|
||||
delay.delay = 717;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((fromPort == id_A0 && toPort == id_WADO3) ||
|
||||
(fromPort == id_A1 && toPort == id_WDO1) ||
|
||||
(fromPort == id_B0 && toPort == id_WADO1) ||
|
||||
(fromPort == id_B1 && toPort == id_WDO3) ||
|
||||
(fromPort == id_C0 && toPort == id_WADO2) ||
|
||||
(fromPort == id_C1 && toPort == id_WDO0) ||
|
||||
(fromPort == id_D0 && toPort == id_WADO0) ||
|
||||
(fromPort == id_D1 && toPort == id_WDO2)) {
|
||||
delay.delay = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const
|
||||
{
|
||||
return TMG_IGNORE;
|
||||
if (cell->type == id_TRELLIS_SLICE) {
|
||||
int sd0 = int_or_default(cell->params, id("REG0_SD"), 0), sd1 = int_or_default(cell->params, id("REG1_SD"), 0);
|
||||
if (port == id_CLK || port == id_WCK)
|
||||
return TMG_CLOCK_INPUT;
|
||||
if (port == id_A0 || port == id_A1 || port == id_B0 || port == id_B1 || port == id_C0 || port == id_C1 ||
|
||||
port == id_D0 || port == id_D1 || port == id_FCI || port == id_FXA || port == id_FXB)
|
||||
return TMG_COMB_INPUT;
|
||||
if (port == id_F0 || port == id_F1 || port == id_FCO || port == id_OFX0 || port == id_OFX1)
|
||||
return TMG_COMB_OUTPUT;
|
||||
if (port == id_DI0 || port == id_DI1 || port == id_CE || port == id_LSR || (sd0 == 1 && port == id_M0) || (sd1 == 1 && port == id_M1)) {
|
||||
clockPort = id_CLK;
|
||||
return TMG_REGISTER_INPUT;
|
||||
}
|
||||
if (port == id_M0 || port == id_M1)
|
||||
return TMG_COMB_INPUT;
|
||||
if (port == id_Q0 || port == id_Q1) {
|
||||
clockPort = id_CLK;
|
||||
return TMG_REGISTER_OUTPUT;
|
||||
}
|
||||
|
||||
if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3 || port == id_WADO0 || port == id_WADO1 || port == id_WADO2 || port == id_WADO3)
|
||||
return TMG_COMB_OUTPUT;
|
||||
|
||||
if (port == id_WD0 || port == id_WD1 || port == id_WAD0 || port == id_WAD1 || port == id_WAD2 || port == id_WAD3 || port == id_WRE) {
|
||||
clockPort = id_WCK;
|
||||
return TMG_REGISTER_INPUT;
|
||||
}
|
||||
|
||||
NPNR_ASSERT_FALSE_STR("no timing type for slice port '" + port.str(this) + "'");
|
||||
} else if (cell->type == id_TRELLIS_IO) {
|
||||
if (port == id_T || port == id_I)
|
||||
return TMG_ENDPOINT;
|
||||
if (port == id_O)
|
||||
return TMG_STARTPOINT;
|
||||
return TMG_IGNORE;
|
||||
} else {
|
||||
NPNR_ASSERT_FALSE_STR("no timing data for cell type '" + cell->type.str(this) + "'");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> Arch::getTilesAtLocation(int row, int col)
|
||||
|
Loading…
Reference in New Issue
Block a user