ice40: Debugging the packer

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-12 12:46:30 +02:00
parent 2f61a9b98a
commit f72807f790
5 changed files with 37 additions and 4 deletions

3
ice40/blinky_nopack.ys Normal file
View File

@ -0,0 +1,3 @@
read_verilog blinky.v
synth_ice40 -nocarry -top blinky
write_json blinky.json

View File

@ -36,6 +36,7 @@ CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
} else { } else {
new_cell->name = name; new_cell->name = name;
} }
new_cell->type = type;
if (type == "ICESTORM_LC") { if (type == "ICESTORM_LC") {
new_cell->params["LUT_INIT"] = "0"; new_cell->params["LUT_INIT"] = "0";
new_cell->params["NEG_CLK"] = "0"; new_cell->params["NEG_CLK"] = "0";
@ -60,7 +61,6 @@ CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
} else { } else {
log_error("unable to create iCE40 cell of type %s", type.c_str()); log_error("unable to create iCE40 cell of type %s", type.c_str());
} }
design->cells[new_cell->name] = new_cell;
return new_cell; return new_cell;
} }
@ -120,4 +120,6 @@ void dff_to_lc(CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
lc->params["LUT_INIT"] = "2"; lc->params["LUT_INIT"] = "2";
replace_port(dff, "D", lc, "I0"); replace_port(dff, "D", lc, "I0");
} }
replace_port(dff, "Q", lc, "O");
} }

View File

@ -29,6 +29,7 @@
#include "log.h" #include "log.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "pack.h"
#include "place.h" #include "place.h"
#include "pybindings.h" #include "pybindings.h"
#include "route.h" #include "route.h"
@ -67,6 +68,10 @@ int main(int argc, char *argv[])
options.add_options()("test", "just a check"); options.add_options()("test", "just a check");
options.add_options()("gui", "start gui"); options.add_options()("gui", "start gui");
options.add_options()("svg", "dump SVG file"); options.add_options()("svg", "dump SVG file");
options.add_options()("pack", "pack design prior to place and route");
options.add_options()("pack-only",
"pack design only without placement or routing");
options.add_options()("run", po::value<std::vector<std::string>>(), options.add_options()("run", po::value<std::vector<std::string>>(),
"python file to execute"); "python file to execute");
options.add_options()("json", po::value<std::string>(), options.add_options()("json", po::value<std::string>(),
@ -251,8 +256,13 @@ int main(int argc, char *argv[])
std::istream *f = new std::ifstream(filename); std::istream *f = new std::ifstream(filename);
parse_json_file(f, filename, &design); parse_json_file(f, filename, &design);
place_design(&design); if (vm.count("pack") || vm.count("pack-only")) {
route_design(&design); pack_design(&design);
}
if (!vm.count("pack-only")) {
place_design(&design);
route_design(&design);
}
} }
if (vm.count("asc")) { if (vm.count("asc")) {

View File

@ -29,12 +29,18 @@
static void pack_lut_lutffs(Design *design) static void pack_lut_lutffs(Design *design)
{ {
std::unordered_set<IdString> packed_cells; std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
for (auto cell : design->cells) { for (auto cell : design->cells) {
CellInfo *ci = cell.second; CellInfo *ci = cell.second;
log_info("cell '%s' is of type '%s'\n", ci->name.c_str(),
ci->type.c_str());
if (is_lut(ci)) { if (is_lut(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC", CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
std::string(ci->name) + "_LC"); std::string(ci->name) + "_LC");
packed_cells.insert(ci->name); packed_cells.insert(ci->name);
new_cells.push_back(packed);
log_info("packed cell %s into %s\n", ci->name.c_str(),
packed->name.c_str());
// See if we can pack into a DFF // See if we can pack into a DFF
// TODO: LUT cascade // TODO: LUT cascade
NetInfo *o = ci->ports.at("O").net; NetInfo *o = ci->ports.at("O").net;
@ -42,7 +48,10 @@ static void pack_lut_lutffs(Design *design)
if (dff) { if (dff) {
lut_to_lc(ci, packed, false); lut_to_lc(ci, packed, false);
dff_to_lc(dff, packed, false); dff_to_lc(dff, packed, false);
design->nets.erase(o->name);
packed_cells.insert(dff->name); packed_cells.insert(dff->name);
log_info("packed cell %s into %s\n", dff->name.c_str(),
packed->name.c_str());
} else { } else {
lut_to_lc(ci, packed, true); lut_to_lc(ci, packed, true);
} }
@ -51,24 +60,33 @@ static void pack_lut_lutffs(Design *design)
for (auto pcell : packed_cells) { for (auto pcell : packed_cells) {
design->cells.erase(pcell); design->cells.erase(pcell);
} }
for (auto ncell : new_cells) {
design->cells[ncell->name] = ncell;
}
} }
// Pack FFs not packed as LUTFFs // Pack FFs not packed as LUTFFs
static void pack_nonlut_ffs(Design *design) static void pack_nonlut_ffs(Design *design)
{ {
std::unordered_set<IdString> packed_cells; std::unordered_set<IdString> packed_cells;
std::vector<CellInfo *> new_cells;
for (auto cell : design->cells) { for (auto cell : design->cells) {
CellInfo *ci = cell.second; CellInfo *ci = cell.second;
if (is_ff(ci)) { if (is_ff(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC", CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
std::string(ci->name) + "_LC"); std::string(ci->name) + "_LC");
packed_cells.insert(ci->name); packed_cells.insert(ci->name);
new_cells.push_back(packed);
dff_to_lc(ci, packed, true); dff_to_lc(ci, packed, true);
} }
} }
for (auto pcell : packed_cells) { for (auto pcell : packed_cells) {
design->cells.erase(pcell); design->cells.erase(pcell);
} }
for (auto ncell : new_cells) {
design->cells[ncell->name] = ncell;
}
} }
// Main pack function // Main pack function

View File

@ -20,6 +20,6 @@ for cell, cinfo in sorted(design.cells, key=lambda x: x.first):
val = "{}'b{}".format(len(val), val) val = "{}'b{}".format(len(val), val)
print("\t\t{}: {}".format(param, val)) print("\t\t{}: {}".format(param, val))
if cinfo.bel != -1: if cinfo.bel.index != -1:
print("\tBel: {}".format(chip.getBelName(cinfo.bel))) print("\tBel: {}".format(chip.getBelName(cinfo.bel)))
print() print()