diff options
Diffstat (limited to 'ecp5')
| -rw-r--r-- | ecp5/arch.cc | 136 | ||||
| -rw-r--r-- | ecp5/arch.h | 32 | ||||
| -rw-r--r-- | ecp5/main.cc | 6 | ||||
| -rw-r--r-- | ecp5/project.cc | 2 | 
4 files changed, 82 insertions, 94 deletions
| diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 7a4aadf1..db78b5e5 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -96,7 +96,7 @@ Arch::Arch(ArchArgs args) : args(args)              break;          }      } -    speed_grade = &(chip_info->speed_grades[args.speedGrade]); +    speed_grade = &(chip_info->speed_grades[args.speed]);      if (!package_info)          log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); @@ -482,94 +482,74 @@ DecalXY Arch::getGroupDecal(GroupId pip) const { return {}; };  // ----------------------------------------------------------------------- -bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const +bool Arch::getDelayFromTimingDatabase(IdString tctype, IdString from, IdString to, DelayInfo &delay) const  { -    // 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; +    for (int i = 0; i < speed_grade->num_cell_timings; i++) { +        const auto &tc = speed_grade->cell_timings[i]; +        if (tc.cell_type == tctype.index) { +            for (int j = 0; j < tc.num_prop_delays; j++) { +                const auto &dly = tc.prop_delays[j]; +                if (dly.from_port == from.index && dly.to_port == to.index) { +                    delay.max_delay = dly.max_delay; +                    delay.min_delay = dly.min_delay; +                    return true; +                }              } +            return false;          } +    } +    NPNR_ASSERT_FALSE("failed to find timing cell in db"); +} -        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; +void Arch::getSetupHoldFromTimingDatabase(IdString tctype, IdString clock, IdString port, DelayInfo &setup, +                                          DelayInfo &hold) const +{ +    for (int i = 0; i < speed_grade->num_cell_timings; i++) { +        const auto &tc = speed_grade->cell_timings[i]; +        if (tc.cell_type == tctype.index) { +            for (int j = 0; j < tc.num_setup_holds; j++) { +                const auto &sh = tc.setup_holds[j]; +                if (sh.clock_port == clock.index && sh.sig_port == port.index) { +                    setup.max_delay = sh.max_setup; +                    setup.min_delay = sh.min_setup; +                    hold.max_delay = sh.max_hold; +                    hold.min_delay = sh.min_hold; +                    return; +                }              }          } +    } +    NPNR_ASSERT_FALSE("failed to find timing cell in db"); +} -        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; -            } -        } +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const +{ -        if (fromPort == id_CLK && (toPort == id_Q0 || toPort == id_Q1)) { -            delay.delay = 395; -            return true; +    // 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 || fromPort == id_A1 || +            fromPort == id_B1 || fromPort == id_C1 || fromPort == id_D1 || fromPort == id_M0 || fromPort == id_FCI) { +            return getDelayFromTimingDatabase(has_carry ? id_SCCU2C : id_SLOGICB, fromPort, toPort, delay);          } -        if (fromPort == id_M0 && toPort == id_OFX0) { -            delay.delay = 193; -            return true; -        } -#if 0 // FIXME -            if (fromPort == id_WCK && (toPort == id_F0 || toPort == id_F1)) { -                delay.delay = 717; -                return true; -            } -#endif          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; +            delay.min_delay = 0; +            delay.max_delay = 0;              return true;          }          return false;      } else if (cell->type == id_DCCA) {          if (fromPort == id_CLKI && toPort == id_CLKO) { -            delay.delay = 0; +            delay.min_delay = 0; +            delay.max_delay = 0;              return true;          }          return false;      } else if (cell->type == id_DP16KD) { -        if (fromPort == id_CLKA) { -            if (toPort.str(this).substr(0, 3) == "DOA") { -                delay.delay = 4260; -                return true; -            } -        } else if (fromPort == id_CLKB) { -            if (toPort.str(this).substr(0, 3) == "DOB") { -                delay.delay = 4280; -                return true; -            } -        }          return false;      } else {          return false; @@ -669,9 +649,9 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in  TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const  {      TimingClockingInfo info; -    info.setup.delay = 0; -    info.hold.delay = 0; -    info.clockToQ.delay = 0; +    info.setup = getDelayFromNS(0); +    info.hold = getDelayFromNS(0); +    info.clockToQ = getDelayFromNS(0);      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); @@ -679,18 +659,18 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port              port == id_WAD3 || port == id_WRE) {              info.edge = RISING_EDGE;              info.clock_port = id_WCK; -            info.setup.delay = 100; -            info.hold.delay = 0; +            getSetupHoldFromTimingDatabase(id_SDPRAME, id_WCK, port, info.setup, info.hold);          } else if (port == id_DI0 || port == id_DI1 || port == id_CE || port == id_LSR || (sd0 == 1 && port == id_M0) ||                     (sd1 == 1 && port == id_M1)) {              info.edge = cell->sliceInfo.clkmux == id("INV") ? FALLING_EDGE : RISING_EDGE;              info.clock_port = id_CLK; -            info.setup.delay = 100; -            info.hold.delay = 0; +            getSetupHoldFromTimingDatabase(id_SLOGICB, id_CLK, port, info.setup, info.hold); +          } else {              info.edge = cell->sliceInfo.clkmux == id("INV") ? FALLING_EDGE : RISING_EDGE;              info.clock_port = id_CLK; -            info.clockToQ.delay = 395; +            bool is_path = getDelayFromTimingDatabase(id_SLOGICB, id_CLK, port, info.clockToQ); +            NPNR_ASSERT(is_path);          }      } else if (cell->type == id_DP16KD) {          std::string port_name = port.str(this); @@ -711,10 +691,12 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port                              ? FALLING_EDGE                              : RISING_EDGE;          if (cell->ports.at(port).type == PORT_OUT) { -            info.clockToQ.delay = 4280; +            bool is_path = getDelayFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, info.clock_port, port, +                                                      info.clockToQ); +            NPNR_ASSERT(is_path);          } else { -            info.setup.delay = 100; -            info.hold.delay = 0; +            getSetupHoldFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, info.clock_port, port, info.setup, +                                           info.hold);          }      } else if (cell->type == id_DCUA) {          std::string prefix = port.str(this).substr(0, 9); diff --git a/ecp5/arch.h b/ecp5/arch.h index 9fb33c9b..938ca354 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -158,23 +158,21 @@ NPNR_PACKED_STRUCT(struct CellPropDelayPOD {      int32_t max_delay;  }); -  NPNR_PACKED_STRUCT(struct CellSetupHoldPOD { -   int32_t sig_port; -   int32_t clock_port; -   int32_t min_setup; -   int32_t max_setup; -   int32_t min_hold; -   int32_t max_hold; +    int32_t sig_port; +    int32_t clock_port; +    int32_t min_setup; +    int32_t max_setup; +    int32_t min_hold; +    int32_t max_hold;  }); -  NPNR_PACKED_STRUCT(struct CellTimingPOD { -   int32_t cell_type; -   int32_t num_prop_delays; -   int32_t num_setup_holds; -   RelPtr<CellPropDelayPOD> prop_delays; -   RelPtr<CellSetupHoldPOD> setup_holds; +    int32_t cell_type; +    int32_t num_prop_delays; +    int32_t num_setup_holds; +    RelPtr<CellPropDelayPOD> prop_delays; +    RelPtr<CellSetupHoldPOD> setup_holds;  });  NPNR_PACKED_STRUCT(struct PipDelayPOD { @@ -443,11 +441,11 @@ struct ArchArgs      std::string package;      enum SpeedGrade      { -        SPEED_6, +        SPEED_6 = 0,          SPEED_7,          SPEED_8,          SPEED_8_5G, -    } speedGrade = SPEED_6; +    } speed = SPEED_6;  };  struct Arch : BaseCtx @@ -946,6 +944,10 @@ struct Arch : BaseCtx      // Return true if a port is a net      bool isGlobalNet(const NetInfo *net) const; +    bool getDelayFromTimingDatabase(IdString tctype, IdString from, IdString to, DelayInfo &delay) const; +    void getSetupHoldFromTimingDatabase(IdString tctype, IdString clock, IdString port, DelayInfo &setup, +                                        DelayInfo &hold) const; +      // -------------------------------------------------      // Placement validity checks      bool isValidBelForCell(CellInfo *cell, BelId bel) const; diff --git a/ecp5/main.cc b/ecp5/main.cc index cc004df3..0b187942 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -111,7 +111,11 @@ std::unique_ptr<Context> ECP5CommandHandler::createContext()          chipArgs.package = vm["package"].as<std::string>();      else          chipArgs.package = "CABGA381"; -    chipArgs.speed = 6; +    if (chipArgs.type == ArchArgs::LFE5UM5G_25F || chipArgs.type == ArchArgs::LFE5UM5G_45F || +        chipArgs.type == ArchArgs::LFE5UM5G_85F) +        chipArgs.speed = ArchArgs::SPEED_8_5G; +    else +        chipArgs.speed = ArchArgs::SPEED_6;      return std::unique_ptr<Context>(new Context(chipArgs));  } diff --git a/ecp5/project.cc b/ecp5/project.cc index bca21643..43318b1c 100644 --- a/ecp5/project.cc +++ b/ecp5/project.cc @@ -45,7 +45,7 @@ std::unique_ptr<Context> ProjectHandler::createContext(pt::ptree &root)          chipArgs.type = ArchArgs::LFE5U_85F;      }      chipArgs.package = root.get<std::string>("project.arch.package"); -    chipArgs.speed = root.get<int>("project.arch.speed"); +    chipArgs.speed = ArchArgs::SpeedGrade(root.get<int>("project.arch.speed"));      return std::unique_ptr<Context>(new Context(chipArgs));  } | 
