aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-13 16:26:21 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-13 16:26:21 +0200
commit5af707a0b6eb5455b40fac572a7bfeb5c3940eb4 (patch)
treebd62726eed83634fbd577644937fe2da7b0fd46e
parent4a85cd57c0fabfba5b3851361c000ae801cb43f7 (diff)
downloadnextpnr-5af707a0b6eb5455b40fac572a7bfeb5c3940eb4.tar.gz
nextpnr-5af707a0b6eb5455b40fac572a7bfeb5c3940eb4.tar.bz2
nextpnr-5af707a0b6eb5455b40fac572a7bfeb5c3940eb4.zip
ice40: Pack RAMs
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r--ice40/cells.cc3
-rw-r--r--ice40/cells.h9
-rw-r--r--ice40/pack.cc42
3 files changed, 46 insertions, 8 deletions
diff --git a/ice40/cells.cc b/ice40/cells.cc
index 604baccb..a8200d76 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -166,7 +166,8 @@ void nxio_to_sb(CellInfo *nxio, CellInfo *sbio)
}
}
-bool is_global_net(NetInfo *net) {
+bool is_global_net(NetInfo *net)
+{
return bool(net_driven_by(net, is_gbuf, "GLOBAL_BUFFER_OUTPUT"));
}
diff --git a/ice40/cells.h b/ice40/cells.h
index 660c7265..e5b4fa9c 100644
--- a/ice40/cells.h
+++ b/ice40/cells.h
@@ -51,7 +51,14 @@ inline bool is_ff(const CellInfo *cell)
inline bool is_sb_io(const CellInfo *cell) { return cell->type == "SB_IO"; }
// Return true if a cell is a global buffer
-inline bool is_gbuf(const CellInfo *cell) {return cell->type == "SB_GB"; }
+inline bool is_gbuf(const CellInfo *cell) { return cell->type == "SB_GB"; }
+
+// Return true if a cell is a RAM
+inline bool is_ram(const CellInfo *cell)
+{
+ return cell->type == "SB_RAM40_4K" || cell->type == "SB_RAM40_4KNR" ||
+ cell->type == "SB_RAM40_4KNW" || cell->type == "SB_RAM40_4KNRNW";
+}
// Convert a SB_LUT primitive to (part of) an ICESTORM_LC, swapping ports
// as needed. Set no_dff if a DFF is not being used, so that the output
diff --git a/ice40/pack.cc b/ice40/pack.cc
index e8876283..be8d1db1 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -110,6 +110,23 @@ static void pack_nonlut_ffs(Design *design)
}
}
+// "Pack" RAMs
+static void pack_ram(Design *design)
+{
+ for (auto cell : design->cells) {
+ CellInfo *ci = cell.second;
+ if (is_ram(ci)) {
+ ci->params["NEG_CLK_W"] =
+ std::to_string(ci->type == "SB_RAM40_4KNW" ||
+ ci->type == "SB_RAM40_4KNRNW");
+ ci->params["NEG_CLK_R"] =
+ std::to_string(ci->type == "SB_RAM40_4KNR" ||
+ ci->type == "SB_RAM40_4KNRNW");
+ ci->type = "ICESTORM_RAM";
+ }
+ }
+}
+
// Merge a net into a constant net
static void set_net_constant(NetInfo *orig, NetInfo *constnet, bool constval)
{
@@ -222,6 +239,17 @@ static void pack_io(Design *design)
}
}
+static bool is_clock_port(const PortRef &port)
+{
+ if (port.cell == nullptr)
+ return false;
+ if (is_ff(port.cell))
+ return port.port == "C";
+ if (is_ram(port.cell))
+ return port.port == "RCLK" || port.port == "WCLK";
+ return false;
+}
+
// Simple global promoter (clock only)
static void promote_globals(Design *design)
{
@@ -231,15 +259,16 @@ static void promote_globals(Design *design)
if (ni->driver.cell != nullptr && !is_global_net(ni)) {
clock_count[net.first] = 0;
for (auto user : ni->users) {
- if (user.cell != nullptr && is_ff(user.cell) && user.port == "C")
+ if (is_clock_port(user))
clock_count[net.first]++;
}
}
}
- auto global_clock = std::max_element(clock_count.begin(), clock_count.end(), [](
- const std::pair<IdString, int> &a, const std::pair<IdString, int> &b) {
- return a.second < b.second;
- });
+ auto global_clock = std::max_element(clock_count.begin(), clock_count.end(),
+ [](const std::pair<IdString, int> &a,
+ const std::pair<IdString, int> &b) {
+ return a.second < b.second;
+ });
if (global_clock->second > 0) {
NetInfo *clknet = design->nets[global_clock->first];
CellInfo *gb = create_ice_cell(design, "SB_GB");
@@ -257,7 +286,7 @@ static void promote_globals(Design *design)
design->nets[glbnet->name] = glbnet;
std::vector<PortRef> keep_users;
for (auto user : clknet->users) {
- if (user.cell != nullptr && is_ff(user.cell) && user.port == "C") {
+ if (is_clock_port(user)) {
user.cell->ports[user.port].net = glbnet;
glbnet->users.push_back(user);
} else {
@@ -277,6 +306,7 @@ void pack_design(Design *design)
pack_io(design);
pack_lut_lutffs(design);
pack_nonlut_ffs(design);
+ pack_ram(design);
}
NEXTPNR_NAMESPACE_END