diff options
Diffstat (limited to 'ecp5/arch.cc')
-rw-r--r-- | ecp5/arch.cc | 124 |
1 files changed, 119 insertions, 5 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index acf1b42e..82ebfba1 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -46,7 +46,9 @@ 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 } @@ -92,6 +94,8 @@ Arch::Arch(ArchArgs args) : args(args) if (!package_info) log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); + + bel_to_cell.resize(chip_info->height * chip_info->width * max_loc_bels, nullptr); } // ----------------------------------------------------------------------- @@ -367,7 +371,7 @@ BelId Arch::getBelByLocation(Loc loc) const delay_t Arch::estimateDelay(WireId src, WireId dst) const { - return 50 * (abs(src.location.x - dst.location.x) + abs(src.location.y - dst.location.y)); + return 100 * (abs(src.location.x - dst.location.x) + abs(src.location.y - dst.location.y)); } delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const @@ -376,7 +380,7 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const auto driver_loc = getBelLocation(driver.cell->bel); auto sink_loc = getBelLocation(sink.cell->bel); - return 50 * (abs(driver_loc.x - sink_loc.x) + abs(driver_loc.y - sink_loc.y)); + return 100 * (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; } @@ -432,7 +436,7 @@ DecalXY Arch::getBelDecal(BelId bel) const decalxy.decal.type = DecalId::TYPE_BEL; decalxy.decal.location = bel.location; decalxy.decal.z = bel.index; - decalxy.decal.active = bel_to_cell.count(bel) && (bel_to_cell.at(bel) != nullptr); + decalxy.decal.active = (bel_to_cell.at(getBelFlatIndex(bel)) != nullptr); return decalxy; } @@ -446,12 +450,122 @@ 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) |