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 packed_cells; + std::vector 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