aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-13 11:08:20 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-13 11:08:20 +0200
commit94eea289ae0fb4d262276d17c474ade3ef21634b (patch)
tree923e903f87f2d39cb4aa90867da150a0d1a64114 /ice40
parenta76f5c5678980c8b2e958252a68ba03676d63229 (diff)
downloadnextpnr-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.cc36
-rw-r--r--ice40/cells.h3
-rw-r--r--ice40/main.cc5
-rw-r--r--ice40/pack.cc54
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) {