ice40: Debugging the packer
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
2f61a9b98a
commit
f72807f790
3
ice40/blinky_nopack.ys
Normal file
3
ice40/blinky_nopack.ys
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
read_verilog blinky.v
|
||||||
|
synth_ice40 -nocarry -top blinky
|
||||||
|
write_json blinky.json
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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")) {
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user