aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-08-08 19:35:13 +0200
committerClifford Wolf <clifford@clifford.at>2018-08-08 19:35:13 +0200
commitf6189e4677c7bdaeaa5b9b796a67d750e6c7d49d (patch)
treea13673a636ddbea3b5fd5585e3bb109b56b69435 /ice40/arch.cc
parenta3ae3f97913c291dbe36a49b1a20388156943abc (diff)
parentcd4e761bb799ca99f02d3aa177961af28a93f2d8 (diff)
downloadnextpnr-f6189e4677c7bdaeaa5b9b796a67d750e6c7d49d.tar.gz
nextpnr-f6189e4677c7bdaeaa5b9b796a67d750e6c7d49d.tar.bz2
nextpnr-f6189e4677c7bdaeaa5b9b796a67d750e6c7d49d.zip
Merge branch 'master' of github.com:YosysHQ/nextpnr into constids
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r--ice40/arch.cc99
1 files changed, 77 insertions, 22 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 0c078f0e..7e2dd7f7 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
// -----------------------------------------------------------------------
@@ -181,7 +182,8 @@ BelId Arch::getBelByLocation(Loc loc) const
BelRange Arch::getBelsByTile(int x, int y) const
{
- // In iCE40 chipdb bels at the same tile are consecutive and dense z ordinates are used
+ // In iCE40 chipdb bels at the same tile are consecutive and dense z ordinates
+ // are used
BelRange br;
br.b.cursor = Arch::getBelByLocation(Loc(x, y, 0)).index;
@@ -535,23 +537,27 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
auto sink_loc = getBelLocation(sink.cell->bel);
if (driver_loc.y == sink_loc.y)
budget = 0;
- else switch (args.type) {
+ else
+ switch (args.type) {
#ifndef ICE40_HX1K_ONLY
case ArchArgs::HX8K:
#endif
case ArchArgs::HX1K:
- budget = 190; break;
+ budget = 190;
+ break;
#ifndef ICE40_HX1K_ONLY
case ArchArgs::LP384:
case ArchArgs::LP1K:
case ArchArgs::LP8K:
- budget = 290; break;
+ budget = 290;
+ break;
case ArchArgs::UP5K:
- budget = 560; break;
+ budget = 560;
+ break;
#endif
default:
log_error("Unsupported iCE40 chip type.\n");
- }
+ }
return true;
}
return false;
@@ -770,27 +776,76 @@ 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;
+ 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) {
+
+ if (port == id_RCLK || port == id_WCLK)
+ return TMG_CLOCK_INPUT;
+
if (port.str(this)[0] == 'R')
- return id_RCLK;
+ clockPort = id_RCLK;
else
- return id_WCLK;
- }
- return IdString();
-}
+ clockPort = id_WCLK;
-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;
+ if (cell->ports.at(port).type == PORT_OUT)
+ return TMG_REGISTER_OUTPUT;
+ else
+ return TMG_REGISTER_INPUT;
+ } else if (cell->type == id_ICESTORM_DSP || cell->type == id_ICESTORM_SPRAM) {
+ clockPort = id_CLK;
+ if (port == id_CLK)
+ return TMG_CLOCK_INPUT;
+ else if (cell->ports.at(port).type == PORT_OUT)
+ return TMG_REGISTER_OUTPUT;
+ else
+ 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 || port == id_OUTPUT_ENABLE)
+ return TMG_ENDPOINT;
+ 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;
+ } else if (cell->type == id_SB_GB) {
+ if (port == id_GLOBAL_BUFFER_OUTPUT)
+ return TMG_COMB_OUTPUT;
+ return TMG_COMB_INPUT;
+ } else if (cell->type == id_SB_WARMBOOT) {
+ return TMG_ENDPOINT;
+ }
+ log_error("no timing info for port '%s' of cell type '%s'\n", port.c_str(this), cell->type.c_str(this));
}
bool Arch::isGlobalNet(const NetInfo *net) const