aboutsummaryrefslogtreecommitdiffstats
path: root/nexus/arch.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-11-11 11:31:14 +0000
committerDavid Shah <dave@ds0.me>2020-11-30 08:45:28 +0000
commit9b89a82573500118269515154265f811cef6191c (patch)
tree0f847e6600b16998094b3de217a03f4db84480c1 /nexus/arch.cc
parent8c1f25cf31644c95e4ba0a1c2a2b212abd622167 (diff)
downloadnextpnr-9b89a82573500118269515154265f811cef6191c.tar.gz
nextpnr-9b89a82573500118269515154265f811cef6191c.tar.bz2
nextpnr-9b89a82573500118269515154265f811cef6191c.zip
nexus: Add LUTRAM and WIDEFN9 timing support
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'nexus/arch.cc')
-rw-r--r--nexus/arch.cc25
1 files changed, 22 insertions, 3 deletions
diff --git a/nexus/arch.cc b/nexus/arch.cc
index b6181011..5cd8ab9b 100644
--- a/nexus/arch.cc
+++ b/nexus/arch.cc
@@ -449,7 +449,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
}
return result;
} else {
- if (toPort == id_F)
+ if (toPort == id_F || toPort == id_OFX)
return lookup_cell_delay(cell->tmg_index, fromPort, toPort, delay);
}
}
@@ -460,11 +460,12 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
{
auto disconnected = [cell](IdString p) { return !cell->ports.count(p) || cell->ports.at(p).net == nullptr; };
if (cell->type == id_OXIDE_COMB) {
- if (port == id_A || port == id_B || port == id_C || port == id_D || port == id_FCI)
+ if (port == id_A || port == id_B || port == id_C || port == id_D || port == id_SEL || port == id_F1 ||
+ port == id_FCI || port == id_WDI)
return TMG_COMB_INPUT;
if (port == id_F || port == id_OFX || port == id_FCO) {
if (disconnected(id_A) && disconnected(id_B) && disconnected(id_C) && disconnected(id_D) &&
- disconnected(id_FCI) && disconnected(id_SEL))
+ disconnected(id_FCI) && disconnected(id_SEL) && disconnected(id_WDI))
return TMG_IGNORE;
else
return TMG_COMB_OUTPUT;
@@ -479,6 +480,17 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
+ } else if (cell->type == id_RAMW) {
+ if (port == id_CLK)
+ return TMG_CLOCK_INPUT;
+ else if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3) {
+ clockInfoCount = 1;
+ return TMG_REGISTER_OUTPUT;
+ } else 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) {
+ clockInfoCount = 1;
+ return TMG_REGISTER_INPUT;
+ }
}
return TMG_IGNORE;
}
@@ -493,6 +505,13 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
NPNR_ASSERT(lookup_cell_delay(cell->tmg_index, id_CLK, port, info.clockToQ));
else
lookup_cell_setuphold(cell->tmg_index, port, id_CLK, info.setup, info.hold);
+ } else if (cell->type == id_RAMW) {
+ info.edge = (cell->ffInfo.ctrlset.clkmux == ID_INV) ? FALLING_EDGE : RISING_EDGE;
+ info.clock_port = id_CLK;
+ if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3)
+ NPNR_ASSERT(lookup_cell_delay(cell->tmg_index, id_CLK, port, info.clockToQ));
+ else
+ lookup_cell_setuphold(cell->tmg_index, port, id_CLK, info.setup, info.hold);
} else {
NPNR_ASSERT_FALSE("missing clocking info");
}