diff options
author | David Shah <davey1576@gmail.com> | 2018-06-13 11:08:20 +0200 |
---|---|---|
committer | David Shah <davey1576@gmail.com> | 2018-06-13 11:08:20 +0200 |
commit | 94eea289ae0fb4d262276d17c474ade3ef21634b (patch) | |
tree | 923e903f87f2d39cb4aa90867da150a0d1a64114 /ice40 | |
parent | a76f5c5678980c8b2e958252a68ba03676d63229 (diff) | |
download | nextpnr-94eea289ae0fb4d262276d17c474ade3ef21634b.tar.gz nextpnr-94eea289ae0fb4d262276d17c474ade3ef21634b.tar.bz2 nextpnr-94eea289ae0fb4d262276d17c474ade3ef21634b.zip |
Simple IO buffer insertion, enable packer by default
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ice40')
-rw-r--r-- | ice40/cells.cc | 36 | ||||
-rw-r--r-- | ice40/cells.h | 3 | ||||
-rw-r--r-- | ice40/main.cc | 5 | ||||
-rw-r--r-- | ice40/pack.cc | 54 |
4 files changed, 65 insertions, 33 deletions
diff --git a/ice40/cells.cc b/ice40/cells.cc index ad728d2c..b038db68 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -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 diff --git a/ice40/cells.h b/ice40/cells.h index da4e2bd8..3cf0b718 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -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 diff --git a/ice40/main.cc b/ice40/main.cc index 6bda4d78..8c418cae 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -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); diff --git a/ice40/pack.cc b/ice40/pack.cc index 73ba0e3d..72dcadea 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -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) { |