Simple IO buffer insertion, enable packer by default
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
a76f5c5678
commit
94eea289ae
@ -60,6 +60,26 @@ CellInfo *create_ice_cell(Design *design, IdString type, IdString name)
|
||||
add_port(new_cell, "LO", PORT_OUT);
|
||||
add_port(new_cell, "O", PORT_OUT);
|
||||
add_port(new_cell, "OUT", PORT_OUT);
|
||||
} else if (type == "SB_IO") {
|
||||
new_cell->params["PIN_TYPE"] = "0";
|
||||
new_cell->params["PULLUP"] = "0";
|
||||
new_cell->params["NEG_TRIGGER"] = "0";
|
||||
new_cell->params["IOSTANDARD"] = "SB_LVCMOS";
|
||||
|
||||
add_port(new_cell, "PACKAGE_PIN", PORT_INOUT);
|
||||
|
||||
add_port(new_cell, "LATCH_INPUT_VALUE", PORT_IN);
|
||||
add_port(new_cell, "CLOCK_ENABLE", PORT_IN);
|
||||
add_port(new_cell, "INPUT_CLK", PORT_IN);
|
||||
add_port(new_cell, "OUTPUT_CLK", PORT_IN);
|
||||
|
||||
add_port(new_cell, "OUTPUT_ENABLE", PORT_IN);
|
||||
add_port(new_cell, "D_OUT_0", PORT_IN);
|
||||
add_port(new_cell, "D_OUT_1", PORT_IN);
|
||||
|
||||
add_port(new_cell, "D_IN_0", PORT_OUT);
|
||||
add_port(new_cell, "D_IN_1", PORT_OUT);
|
||||
|
||||
} else {
|
||||
log_error("unable to create iCE40 cell of type %s", type.c_str());
|
||||
}
|
||||
@ -128,4 +148,20 @@ void dff_to_lc(CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
|
||||
replace_port(dff, "Q", lc, "O");
|
||||
}
|
||||
|
||||
void nxio_to_sb(CellInfo *nxio, CellInfo *sbio)
|
||||
{
|
||||
if (nxio->type == "$nextpnr_ibuf") {
|
||||
sbio->params["PIN_TYPE"] = "1";
|
||||
auto pu_attr = nxio->attrs.find("PULLUP");
|
||||
if (pu_attr != nxio->attrs.end())
|
||||
sbio->params["PULLUP"] = pu_attr->second;
|
||||
replace_port(nxio, "O", sbio, "D_IN_0");
|
||||
} else if (nxio->type == "$nextpnr_obuf") {
|
||||
sbio->params["PIN_TYPE"] = "25";
|
||||
replace_port(nxio, "I", sbio, "D_OUT_0");
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -61,6 +61,9 @@ void lut_to_lc(CellInfo *lut, CellInfo *lc, bool no_dff = true);
|
||||
// ignored
|
||||
void dff_to_lc(CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false);
|
||||
|
||||
// Convert a nextpnr IO buffer to a SB_IO
|
||||
void nxio_to_sb(CellInfo *nxio, CellInfo *sbio);
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
@ -67,7 +67,6 @@ int main(int argc, char *argv[])
|
||||
options.add_options()("help,h", "show help");
|
||||
options.add_options()("gui", "start gui");
|
||||
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");
|
||||
|
||||
@ -195,9 +194,7 @@ int main(int argc, char *argv[])
|
||||
std::istream *f = new std::ifstream(filename);
|
||||
|
||||
parse_json_file(f, filename, &design);
|
||||
if (vm.count("pack") || vm.count("pack-only")) {
|
||||
pack_design(&design);
|
||||
}
|
||||
pack_design(&design);
|
||||
if (!vm.count("pack-only")) {
|
||||
place_design(&design);
|
||||
route_design(&design);
|
||||
|
@ -149,39 +149,35 @@ static void pack_io(Design *design)
|
||||
for (auto cell : design->cells) {
|
||||
CellInfo *ci = cell.second;
|
||||
if (is_nextpnr_iob(ci)) {
|
||||
CellInfo *sb = nullptr;
|
||||
if (ci->type == "$nextpnr_ibuf" || ci->type == "$nextpnr_iobuf") {
|
||||
CellInfo *sb = net_only_drives(ci->ports.at("O").net, is_sb_io,
|
||||
"PACKAGE_PIN", true, ci);
|
||||
if (sb != nullptr) {
|
||||
// Trivial case, SB_IO used. Just destroy the net and the
|
||||
// iobuf
|
||||
packed_cells.insert(ci->name);
|
||||
log_info("%s feeds SB_IO %s, removing %s %s.\n",
|
||||
ci->name.c_str(), sb->name.c_str(),
|
||||
ci->type.c_str(), ci->name.c_str());
|
||||
NetInfo *net = sb->ports.at("PACKAGE_PIN").net;
|
||||
if (net != nullptr) {
|
||||
design->nets.erase(net->name);
|
||||
sb->ports.at("PACKAGE_PIN").net = nullptr;
|
||||
}
|
||||
}
|
||||
sb = net_only_drives(ci->ports.at("O").net, is_sb_io,
|
||||
"PACKAGE_PIN", true, ci);
|
||||
|
||||
} else if (ci->type == "$nextpnr_obuf") {
|
||||
CellInfo *sb = net_only_drives(ci->ports.at("I").net, is_sb_io,
|
||||
"PACKAGE_PIN", true, ci);
|
||||
if (sb != nullptr) {
|
||||
// Trivial case, SB_IO used. Just destroy the net and the
|
||||
// iobuf
|
||||
packed_cells.insert(ci->name);
|
||||
log_info("%s feeds SB_IO %s, removing %s %s.\n",
|
||||
ci->name.c_str(), sb->name.c_str(),
|
||||
ci->type.c_str(), ci->name.c_str());
|
||||
NetInfo *net = sb->ports.at("PACKAGE_PIN").net;
|
||||
if (net != nullptr) {
|
||||
design->nets.erase(net->name);
|
||||
sb->ports.at("PACKAGE_PIN").net = nullptr;
|
||||
}
|
||||
}
|
||||
sb = net_only_drives(ci->ports.at("I").net, is_sb_io,
|
||||
"PACKAGE_PIN", true, ci);
|
||||
}
|
||||
if (sb != nullptr) {
|
||||
// Trivial case, SB_IO used. Just destroy the net and the
|
||||
// iobuf
|
||||
log_info("%s feeds SB_IO %s, removing %s %s.\n",
|
||||
ci->name.c_str(), sb->name.c_str(), ci->type.c_str(),
|
||||
ci->name.c_str());
|
||||
NetInfo *net = sb->ports.at("PACKAGE_PIN").net;
|
||||
if (net != nullptr) {
|
||||
design->nets.erase(net->name);
|
||||
sb->ports.at("PACKAGE_PIN").net = nullptr;
|
||||
}
|
||||
} else {
|
||||
// Create a SB_IO buffer
|
||||
sb = create_ice_cell(design, "SB_IO");
|
||||
nxio_to_sb(ci, sb);
|
||||
new_cells.push_back(sb);
|
||||
}
|
||||
packed_cells.insert(ci->name);
|
||||
std::copy(ci->attrs.begin(), ci->attrs.end(),
|
||||
std::inserter(sb->attrs, sb->attrs.begin()));
|
||||
}
|
||||
}
|
||||
for (auto pcell : packed_cells) {
|
||||
|
Loading…
Reference in New Issue
Block a user