aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ice40/cells.cc24
-rw-r--r--ice40/pack.cc35
2 files changed, 56 insertions, 3 deletions
diff --git a/ice40/cells.cc b/ice40/cells.cc
index a8200d76..b7a02790 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -79,6 +79,30 @@ CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
add_port(new_cell, "D_IN_0", PORT_OUT);
add_port(new_cell, "D_IN_1", PORT_OUT);
+ } else if (type == "ICESTORM_RAM") {
+ new_cell->params["NEG_CLK_W"] = "0";
+ new_cell->params["NEG_CLK_R"] = "0";
+ new_cell->params["WRITE_MODE"] = "0";
+ new_cell->params["READ_MODE"] = "0";
+
+ add_port(new_cell, "RCLK", PORT_IN);
+ add_port(new_cell, "RCLKE", PORT_IN);
+ add_port(new_cell, "RE", PORT_IN);
+
+ add_port(new_cell, "WCLK", PORT_IN);
+ add_port(new_cell, "WCLKE", PORT_IN);
+ add_port(new_cell, "WE", PORT_IN);
+
+ for (int i = 0; i < 16; i++) {
+ add_port(new_cell, "WDATA_" + std::to_string(i), PORT_IN);
+ add_port(new_cell, "MASK_" + std::to_string(i), PORT_IN);
+ add_port(new_cell, "RDATA_" + std::to_string(i), PORT_OUT);
+ }
+
+ for (int i = 0; i < 11; i++) {
+ add_port(new_cell, "RADDR_" + std::to_string(i), PORT_IN);
+ add_port(new_cell, "WADDR_" + std::to_string(i), PORT_IN);
+ }
} else if (type == "SB_GB") {
add_port(new_cell, "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN);
add_port(new_cell, "GLOBAL_BUFFER_OUTPUT", PORT_OUT);
diff --git a/ice40/pack.cc b/ice40/pack.cc
index f3b62c52..f4c024da 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -117,18 +117,47 @@ static void pack_nonlut_ffs(Design *design)
// "Pack" RAMs
static void pack_ram(Design *design)
{
+ log_info("Packing RAMs..\n");
+
+ std::unordered_set<IdString> packed_cells;
+ std::vector<CellInfo *> new_cells;
+
for (auto cell : design->cells) {
CellInfo *ci = cell.second;
if (is_ram(ci)) {
- ci->params["NEG_CLK_W"] =
+ CellInfo *packed = create_ice_cell(design, "ICESTORM_RAM",
+ ci->name.str() + "_RAM");
+ packed_cells.insert(ci->name);
+ new_cells.push_back(packed);
+ packed->params["READ_MODE"] = ci->params.at("READ_MODE");
+ packed->params["WRITE_MODE"] = ci->params.at("WRITE_MODE");
+ packed->params["NEG_CLK_W"] =
std::to_string(ci->type == "SB_RAM40_4KNW" ||
ci->type == "SB_RAM40_4KNRNW");
- ci->params["NEG_CLK_R"] =
+ packed->params["NEG_CLK_R"] =
std::to_string(ci->type == "SB_RAM40_4KNR" ||
ci->type == "SB_RAM40_4KNRNW");
- ci->type = "ICESTORM_RAM";
+ packed->type = "ICESTORM_RAM";
+ for (auto port : ci->ports) {
+ PortInfo &pi = port.second;
+ std::string newname = pi.name;
+ size_t bpos = newname.find('[');
+ if (bpos != std::string::npos) {
+ newname = newname.substr(0, bpos) + "_" +
+ newname.substr(bpos + 1,
+ (newname.size() - bpos) - 2);
+ }
+ replace_port(ci, pi.name, packed, newname);
+ }
}
}
+
+ for (auto pcell : packed_cells) {
+ design->cells.erase(pcell);
+ }
+ for (auto ncell : new_cells) {
+ design->cells[ncell->name] = ncell;
+ }
}
// Merge a net into a constant net