diff options
| -rw-r--r-- | common/nextpnr.h | 2 | ||||
| -rw-r--r-- | ecp5/arch.cc | 7 | ||||
| -rw-r--r-- | ecp5/arch.h | 6 | ||||
| -rw-r--r-- | generic/arch.cc | 8 | ||||
| -rw-r--r-- | generic/arch.h | 4 | ||||
| -rw-r--r-- | ice40/arch.cc | 68 | ||||
| -rw-r--r-- | ice40/arch.h | 6 | 
7 files changed, 66 insertions, 35 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index d4925a16..938f4f95 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -301,7 +301,7 @@ enum TimingPortClass      TMG_COMB_OUTPUT,     // Combinational output, no paths start here      TMG_STARTPOINT,      // Unclocked primary startpoint, such as an IO cell output      TMG_ENDPOINT,        // Unclocked primary endpoint, such as an IO cell input -    TMG_ASYNC,           // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis +    TMG_IGNORE,          // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis  };  struct DeterministicRNG diff --git a/ecp5/arch.cc b/ecp5/arch.cc index de3abd44..12707a03 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -495,9 +495,10 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort      return false;  } -IdString Arch::getPortClock(const CellInfo *cell, IdString port) const { return IdString(); } - -bool Arch::isClockPort(const CellInfo *cell, IdString port) const { return false; } +TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const +{ +    return TMG_IGNORE; +}  bool Arch::isIOCell(const CellInfo *cell) const { return cell->type == id("TRELLIS_IO"); } diff --git a/ecp5/arch.h b/ecp5/arch.h index fd8d0a13..7bbb9da5 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -827,10 +827,8 @@ struct Arch : BaseCtx      // Get the delay through a cell from one port to another, returning false      // if no path exists      bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; -    // Get the associated clock to a port, or empty if the port is combinational -    IdString getPortClock(const CellInfo *cell, IdString port) const; -    // Return true if a port is a clock -    bool isClockPort(const CellInfo *cell, IdString port) const; +    // Get the port class, also setting clockPort if applicable +    TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const;      // Return true if a port is a net      bool isGlobalNet(const NetInfo *net) const;      // Return true if a cell is an IO diff --git a/generic/arch.cc b/generic/arch.cc index 0fa93da8..25e4d08c 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -435,9 +435,11 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort      return false;  } -IdString Arch::getPortClock(const CellInfo *cell, IdString port) const { return IdString(); } - -bool Arch::isClockPort(const CellInfo *cell, IdString port) const { return false; } +// Get the port class, also setting clockPort if applicable +TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const +{ +    return TMG_IGNORE; +}  bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; }  bool Arch::isBelLocationValid(BelId bel) const { return true; } diff --git a/generic/arch.h b/generic/arch.h index e7010885..fb4f3660 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -213,8 +213,8 @@ struct Arch : BaseCtx      DecalXY getGroupDecal(GroupId group) const;      bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; -    IdString getPortClock(const CellInfo *cell, IdString port) const; -    bool isClockPort(const CellInfo *cell, IdString port) const; +    // Get the port class, also setting clockPort if applicable +    TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const;      // Return true if a cell is an IO      bool isIOCell(const CellInfo *cell) const; diff --git a/ice40/arch.cc b/ice40/arch.cc index 16104033..0f81bfea 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -27,6 +27,7 @@  #include "placer1.h"  #include "router1.h"  #include "util.h" +  NEXTPNR_NAMESPACE_BEGIN  // ----------------------------------------------------------------------- @@ -106,7 +107,9 @@ BelType Arch::belTypeFromId(IdString type) const  void IdString::initialize_arch(const BaseCtx *ctx)  {  #define X(t) initialize_add(ctx, #t, PIN_##t); +  #include "portpins.inc" +  #undef X  } @@ -888,27 +891,56 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort      return false;  } -IdString Arch::getPortClock(const CellInfo *cell, IdString port) const +// Get the port class, also setting clockPort to associated clock if applicable +TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const  { -    if (cell->type == id_icestorm_lc && cell->lcInfo.dffEnable) { -        if (port != id_lo && port != id_cin && port != id_cout) -            return id_clk; -    } else if (cell->type == id_icestorm_ram) { -        if (port.str(this)[0] == 'R') -            return id_rclk; +    if (cell->type == id_icestorm_lc) { +        if (port == id_clk) +            return TMG_CLOCK_INPUT; +        if (port == id_cin) +            return TMG_COMB_INPUT; +        if (port == id_cout || port == id_lo) +            return TMG_COMB_OUTPUT; +        if (cell->lcInfo.dffEnable) { +            clockPort = id_clk; +            if (port == id_o) +                return TMG_REGISTER_OUTPUT; +            else +                return TMG_REGISTER_INPUT; +        } else { +            if (port == id_o) +                return TMG_COMB_OUTPUT; +            else +                return TMG_COMB_INPUT; +        } +    } else if (cell->type == id_icestorm_ram || cell->type == id("ICESTORM_DSP") || +               cell->type == id("ICESTORM_SPRAM")) { +        if (port == id_clk) +            return TMG_CLOCK_INPUT; +        else if (cell->ports.at(port).type == PORT_OUT) +            return TMG_REGISTER_OUTPUT;          else -            return id_wclk; +            return TMG_REGISTER_INPUT; +    } else if (cell->type == id_sb_io) { +        if (port == id("D_IN_0") || port == id("D_IN_1")) +            return TMG_STARTPOINT; +        if (port == id("D_OUT_0") || port == id("D_OUT_1")) +            return TMG_STARTPOINT; +        return TMG_IGNORE; +    } else if (cell->type == id("ICESTORM_PLL")) { +        if (port == id("PLLOUT_A") || port == id("PLLOUT_B")) +            return TMG_GEN_CLOCK; +        return TMG_IGNORE; +    } else if (cell->type == id("ICESTORM_LFOSC")) { +        if (port == id("CLKLF")) +            return TMG_GEN_CLOCK; +        return TMG_IGNORE; +    } else if (cell->type == id("ICESTORM_HFOSC")) { +        if (port == id("CLKHF")) +            return TMG_GEN_CLOCK; +        return TMG_IGNORE;      } -    return IdString(); -} - -bool Arch::isClockPort(const CellInfo *cell, IdString port) const -{ -    if (cell->type == id("ICESTORM_LC") && port == id("CLK")) -        return true; -    if (cell->type == id("ICESTORM_RAM") && (port == id("RCLK") || (port == id("WCLK")))) -        return true; -    return false; +    return TMG_IGNORE;  }  bool Arch::isGlobalNet(const NetInfo *net) const diff --git a/ice40/arch.h b/ice40/arch.h index a5be7e33..7cc8495d 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -788,10 +788,8 @@ struct Arch : BaseCtx      // Get the delay through a cell from one port to another, returning false      // if no path exists      bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; -    // Get the associated clock to a port, or empty if the port is combinational -    IdString getPortClock(const CellInfo *cell, IdString port) const; -    // Return true if a port is a clock -    bool isClockPort(const CellInfo *cell, IdString port) const; +    // Get the port class, also setting clockDomain if applicable +    TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockDomain) const;      // Return true if a port is a net      bool isGlobalNet(const NetInfo *net) const;      // Return true if a cell is an IO  | 
