aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5/arch.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-10-01 10:36:22 +0100
committerDavid Shah <dave@ds0.me>2019-10-01 12:01:33 +0100
commitd04e5954a6d6c5a249655d4d57fd99c1f87e5ef0 (patch)
tree4ab37a8362b9074f69a85b800538a5bb0634a710 /ecp5/arch.cc
parentcb8d90bcbf6524ef8706c0a262b8f1488b5746a8 (diff)
downloadnextpnr-d04e5954a6d6c5a249655d4d57fd99c1f87e5ef0.tar.gz
nextpnr-d04e5954a6d6c5a249655d4d57fd99c1f87e5ef0.tar.bz2
nextpnr-d04e5954a6d6c5a249655d4d57fd99c1f87e5ef0.zip
ecp5: Adding support for 36-bit wide PDP RAMs
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5/arch.cc')
-rw-r--r--ecp5/arch.cc21
1 files changed, 17 insertions, 4 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 8ba1af4d..348f2192 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -922,28 +922,41 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
}
} else if (cell->type == id_DP16KD) {
std::string port_name = port.str(this);
+ IdString half_clock;
for (auto c : boost::adaptors::reverse(port_name)) {
if (std::isdigit(c))
continue;
if (c == 'A') {
- info.clock_port = id_CLKA;
+ half_clock = id_CLKA;
break;
} else if (c == 'B') {
- info.clock_port = id_CLKB;
+ half_clock = id_CLKB;
break;
} else
NPNR_ASSERT_FALSE_STR("bad ram port " + port.str(this));
}
+ if (cell->ramInfo.is_pdp) {
+ bool is_output = cell->ports.at(port).type == PORT_OUT;
+ // In PDP mode, all read signals are in CLKB domain and write signals in CLKA domain
+ if (is_output || port == id_OCEB || port == id_CEB || port == id_ADB5 || port == id_ADB6 ||
+ port == id_ADB7 || port == id_ADB8 || port == id_ADB9 || port == id_ADB10 || port == id_ADB11 ||
+ port == id_ADB12 || port == id_ADB13)
+ info.clock_port = id_CLKB;
+ else
+ info.clock_port = id_CLKA;
+ } else {
+ info.clock_port = half_clock;
+ }
info.edge = (str_or_default(cell->params, info.clock_port == id_CLKB ? id("CLKBMUX") : id("CLKAMUX"), "CLK") ==
"INV")
? FALLING_EDGE
: RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
- bool is_path = getDelayFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, info.clock_port, port,
+ bool is_path = getDelayFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, half_clock, port,
info.clockToQ);
NPNR_ASSERT(is_path);
} else {
- getSetupHoldFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, info.clock_port, port, info.setup,
+ getSetupHoldFromTimingDatabase(id_DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG, half_clock, port, info.setup,
info.hold);
}
} else if (cell->type == id_DCUA) {