aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5/arch.cc
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-10-17 11:14:27 +0100
committerGitHub <noreply@github.com>2018-10-17 11:14:27 +0100
commitb53a4862db99e41f16c06425f314a1a398a21985 (patch)
treedbe277f6d9487eab64715e4c14ce9be230820c38 /ecp5/arch.cc
parent529a595157a2eef24f8529b0de0c504a40ed503b (diff)
parent1cde2080902c25d2a59e8ebb5b0b23a90f693e8e (diff)
downloadnextpnr-b53a4862db99e41f16c06425f314a1a398a21985.tar.gz
nextpnr-b53a4862db99e41f16c06425f314a1a398a21985.tar.bz2
nextpnr-b53a4862db99e41f16c06425f314a1a398a21985.zip
Merge pull request #89 from YosysHQ/ecp5_bram
ECP5 BRAM support
Diffstat (limited to 'ecp5/arch.cc')
-rw-r--r--ecp5/arch.cc62
1 files changed, 59 insertions, 3 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 9c059005..1be76c07 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -19,6 +19,7 @@
*/
#include <algorithm>
+#include <boost/range/adaptor/reversed.hpp>
#include <cmath>
#include <cstring>
#include "gfx.h"
@@ -76,11 +77,13 @@ Arch::Arch(ArchArgs args) : args(args)
log_error("Unsupported ECP5 chip type.\n");
}
#else
- if (args.type == ArchArgs::LFE5U_25F) {
+ if (args.type == ArchArgs::LFE5U_25F || args.type == ArchArgs::LFE5UM_25F || args.type == ArchArgs::LFE5UM5G_25F) {
chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_25k));
- } else if (args.type == ArchArgs::LFE5U_45F) {
+ } else if (args.type == ArchArgs::LFE5U_45F || args.type == ArchArgs::LFE5UM_45F ||
+ args.type == ArchArgs::LFE5UM5G_45F) {
chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_45k));
- } else if (args.type == ArchArgs::LFE5U_85F) {
+ } else if (args.type == ArchArgs::LFE5U_85F || args.type == ArchArgs::LFE5UM_85F ||
+ args.type == ArchArgs::LFE5UM5G_85F) {
chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_85k));
} else {
log_error("Unsupported ECP5 chip type.\n");
@@ -110,6 +113,18 @@ std::string Arch::getChipName() const
return "LFE5U-45F";
} else if (args.type == ArchArgs::LFE5U_85F) {
return "LFE5U-85F";
+ } else if (args.type == ArchArgs::LFE5UM_25F) {
+ return "LFE5UM-25F";
+ } else if (args.type == ArchArgs::LFE5UM_45F) {
+ return "LFE5UM-45F";
+ } else if (args.type == ArchArgs::LFE5UM_85F) {
+ return "LFE5UM-85F";
+ } else if (args.type == ArchArgs::LFE5UM5G_25F) {
+ return "LFE5UM5G-25F";
+ } else if (args.type == ArchArgs::LFE5UM5G_45F) {
+ return "LFE5UM5G-45F";
+ } else if (args.type == ArchArgs::LFE5UM5G_85F) {
+ return "LFE5UM5G-85F";
} else {
log_error("Unknown chip\n");
}
@@ -125,6 +140,18 @@ IdString Arch::archArgsToId(ArchArgs args) const
return id("lfe5u_45f");
if (args.type == ArchArgs::LFE5U_85F)
return id("lfe5u_85f");
+ if (args.type == ArchArgs::LFE5UM_25F)
+ return id("lfe5um_25f");
+ if (args.type == ArchArgs::LFE5UM_45F)
+ return id("lfe5um_45f");
+ if (args.type == ArchArgs::LFE5UM_85F)
+ return id("lfe5um_85f");
+ if (args.type == ArchArgs::LFE5UM5G_25F)
+ return id("lfe5um5g_25f");
+ if (args.type == ArchArgs::LFE5UM5G_45F)
+ return id("lfe5um5g_45f");
+ if (args.type == ArchArgs::LFE5UM5G_85F)
+ return id("lfe5um5g_85f");
return IdString();
}
@@ -531,6 +558,19 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
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;
}
@@ -582,6 +622,22 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
if (port == id_CLKO)
return TMG_COMB_OUTPUT;
return TMG_IGNORE;
+ } else if (cell->type == id_DP16KD) {
+ if (port == id_CLKA || port == id_CLKB)
+ return TMG_CLOCK_INPUT;
+ std::string port_name = port.str(this);
+ for (auto c : boost::adaptors::reverse(port_name)) {
+ if (std::isdigit(c))
+ continue;
+ if (c == 'A')
+ clockPort = id_CLKA;
+ else if (c == 'B')
+ clockPort = id_CLKB;
+ else
+ NPNR_ASSERT_FALSE_STR("bad ram port");
+ return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
+ }
+ NPNR_ASSERT_FALSE_STR("no timing type for RAM port '" + port.str(this) + "'");
} else {
NPNR_ASSERT_FALSE_STR("no timing data for cell type '" + cell->type.str(this) + "'");
}