aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-06-09 18:19:20 +0200
committerClifford Wolf <clifford@clifford.at>2018-06-09 18:19:20 +0200
commitdfbfbf87db6e0fc68d541593b2221db4d5c349f9 (patch)
tree665a111ab708ef482c5a2e66da089edafa9ef4ae /ice40
parent208d3783225e1de6d95650c37f0b0ee69f793f42 (diff)
downloadnextpnr-dfbfbf87db6e0fc68d541593b2221db4d5c349f9.tar.gz
nextpnr-dfbfbf87db6e0fc68d541593b2221db4d5c349f9.tar.bz2
nextpnr-dfbfbf87db6e0fc68d541593b2221db4d5c349f9.zip
Add very basic router
Signed-off-by: Clifford Wolf <clifford@clifford.at>
Diffstat (limited to 'ice40')
-rw-r--r--ice40/chip.cc35
-rw-r--r--ice40/chip.h106
-rw-r--r--ice40/chipdb.py34
-rw-r--r--ice40/main.cc2
-rw-r--r--ice40/portpins.inc8
5 files changed, 150 insertions, 35 deletions
diff --git a/ice40/chip.cc b/ice40/chip.cc
index ed79be0b..9c6d7a1a 100644
--- a/ice40/chip.cc
+++ b/ice40/chip.cc
@@ -18,6 +18,7 @@
*/
#include "chip.h"
+#include "log.h"
// -----------------------------------------------------------------------
@@ -45,7 +46,7 @@ BelType belTypeFromId(IdString id)
// -----------------------------------------------------------------------
-IdString PortPinToId(PortPin type)
+IdString portPinToId(PortPin type)
{
#define X(t) \
if (type == PIN_##t) \
@@ -57,7 +58,7 @@ IdString PortPinToId(PortPin type)
return IdString();
}
-PortPin PortPinFromId(IdString id)
+PortPin portPinFromId(IdString id)
{
#define X(t) \
if (id == #t) \
@@ -76,28 +77,26 @@ Chip::Chip(ChipArgs args)
#ifdef ICE40_HX1K_ONLY
if (args.type == ChipArgs::HX1K) {
chip_info = chip_info_1k;
- return;
+ } else {
+ log_error("Unsupported iCE40 chip type.\n");
}
#else
if (args.type == ChipArgs::LP384) {
chip_info = chip_info_384;
- return;
} else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
chip_info = chip_info_1k;
- return;
} else if (args.type == ChipArgs::UP5K) {
chip_info = chip_info_5k;
- return;
} else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
chip_info = chip_info_8k;
- return;
} else {
- fprintf(stderr, "Unsupported chip type\n");
- exit(EXIT_FAILURE);
+ log_error("Unsupported iCE40 chip type.\n");
}
#endif
- abort();
+ bel_to_cell.resize(chip_info.num_bels);
+ wire_to_net.resize(chip_info.num_wires);
+ pip_to_net.resize(chip_info.num_pips);
}
// -----------------------------------------------------------------------
@@ -120,8 +119,20 @@ BelId Chip::getBelByName(IdString name) const
WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
{
- // FIXME
- return WireId();
+ WireId ret;
+
+ assert(!bel.nil());
+
+ int num_bel_wires = chip_info.bel_data[bel.index].num_bel_wires;
+ BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires;
+
+ for (int i = 0; i < num_bel_wires; i++)
+ if (bel_wires[i].port == pin) {
+ ret.index = bel_wires[i].wire_index;
+ break;
+ }
+
+ return ret;
}
// -----------------------------------------------------------------------
diff --git a/ice40/chip.h b/ice40/chip.h
index 3125b17f..87a65b2d 100644
--- a/ice40/chip.h
+++ b/ice40/chip.h
@@ -26,8 +26,16 @@ struct DelayInfo
{
float delay = 0;
- float raiseDelay() { return delay; }
- float fallDelay() { return delay; }
+ float raiseDelay() const { return delay; }
+ float fallDelay() const { return delay; }
+ float avgDelay() const { return delay; }
+
+ DelayInfo operator+(const DelayInfo &other) const
+ {
+ DelayInfo ret;
+ ret.delay = this->delay + other.delay;
+ return ret;
+ }
};
// -----------------------------------------------------------------------
@@ -51,15 +59,23 @@ enum PortPin
#undef X
};
-IdString PortPinToId(PortPin type);
-PortPin PortPinFromId(IdString id);
+IdString portPinToId(PortPin type);
+PortPin portPinFromId(IdString id);
// -----------------------------------------------------------------------
+struct BelWirePOD
+{
+ int32_t wire_index;
+ PortPin port;
+};
+
struct BelInfoPOD
{
const char *name;
BelType type;
+ int num_bel_wires;
+ BelWirePOD *bel_wires;
int8_t x, y, z;
};
@@ -343,6 +359,10 @@ struct Chip
mutable dict<IdString, int> wire_by_name;
mutable dict<IdString, int> pip_by_name;
+ vector<IdString> bel_to_cell;
+ vector<IdString> wire_to_net;
+ vector<IdString> pip_to_net;
+
Chip(ChipArgs args);
// -------------------------------------------------
@@ -355,11 +375,31 @@ struct Chip
return chip_info.bel_data[bel.index].name;
}
- void bindBel(BelId bel, IdString cell) {}
+ void bindBel(BelId bel, IdString cell)
+ {
+ assert(!bel.nil());
+ assert(bel_to_cell[bel.index] == IdString());
+ bel_to_cell[bel.index] = cell;
+ }
+
+ void unbindBel(BelId bel)
+ {
+ assert(!bel.nil());
+ assert(bel_to_cell[bel.index] != IdString());
+ bel_to_cell[bel.index] = IdString();
+ }
- void unbindBel(BelId bel) {}
+ bool checkBelAvail(BelId bel) const
+ {
+ assert(!bel.nil());
+ return bel_to_cell[bel.index] == IdString();
+ }
- bool checkBelAvail(BelId bel) const {}
+ IdString getBelCell(BelId bel) const
+ {
+ assert(!bel.nil());
+ return bel_to_cell[bel.index];
+ }
BelRange getBels() const
{
@@ -425,11 +465,31 @@ struct Chip
return chip_info.wire_data[wire.index].name;
}
- void bindWire(WireId bel, IdString net) {}
+ void bindWire(WireId wire, IdString net)
+ {
+ assert(!wire.nil());
+ assert(wire_to_net[wire.index] == IdString());
+ wire_to_net[wire.index] = net;
+ }
+
+ void unbindWire(WireId wire)
+ {
+ assert(!wire.nil());
+ assert(wire_to_net[wire.index] != IdString());
+ wire_to_net[wire.index] = IdString();
+ }
- void unbindWire(WireId bel) {}
+ bool checkWireAvail(WireId wire) const
+ {
+ assert(!wire.nil());
+ return wire_to_net[wire.index] == IdString();
+ }
- bool checkWireAvail(WireId bel) const {}
+ IdString getWireNet(WireId wire) const
+ {
+ assert(!wire.nil());
+ return wire_to_net[wire.index];
+ }
WireRange getWires() const
{
@@ -453,11 +513,31 @@ struct Chip
return src_name + "->" + dst_name;
}
- void bindPip(PipId bel, IdString net) {}
+ void bindPip(PipId pip, IdString net)
+ {
+ assert(!pip.nil());
+ assert(pip_to_net[pip.index] == IdString());
+ pip_to_net[pip.index] = net;
+ }
+
+ void unbindPip(PipId pip)
+ {
+ assert(!pip.nil());
+ assert(pip_to_net[pip.index] != IdString());
+ pip_to_net[pip.index] = IdString();
+ }
- void unbindPip(PipId bel) {}
+ bool checkPipAvail(PipId pip) const
+ {
+ assert(!pip.nil());
+ return pip_to_net[pip.index] == IdString();
+ }
- bool checkPipAvail(PipId bel) const {}
+ IdString getPipNet(PipId pip) const
+ {
+ assert(!pip.nil());
+ return pip_to_net[pip.index];
+ }
AllPipRange getPips() const
{
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index 58dd0dd2..7b1ba93a 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys
+import re
dev_name = None
dev_width = None
@@ -16,6 +17,7 @@ pip_xy = dict()
bel_name = list()
bel_type = list()
bel_pos = list()
+bel_wires = list()
wire_uphill_belport = dict()
wire_downhill_belports = dict()
@@ -24,7 +26,16 @@ wire_names = dict()
wire_names_r = dict()
wire_xy = dict()
+def maj_wire_name(name):
+ if re.match(r"lutff_\d/(in|out)", name[2]):
+ return True
+ return False
+
def cmp_wire_names(newname, oldname):
+ if maj_wire_name(newname):
+ return True
+ if maj_wire_name(oldname):
+ return False
return newname < oldname
with open(sys.argv[1], "r") as f:
@@ -126,16 +137,19 @@ def add_bel_input(bel, wire, port):
if wire not in wire_downhill_belports:
wire_downhill_belports[wire] = set()
wire_downhill_belports[wire].add((bel, port))
+ bel_wires[bel].append((wire, port))
def add_bel_output(bel, wire, port):
assert wire not in wire_uphill_belport
wire_uphill_belport[wire] = (bel, port)
+ bel_wires[bel].append((wire, port))
def add_bel_lc(x, y, z):
bel = len(bel_name)
bel_name.append("%d_%d_lc%d" % (x, y, z))
bel_type.append("ICESTORM_LC")
bel_pos.append((x, y, z))
+ bel_wires.append(list())
wire_cen = wire_names[(x, y, "lutff_global/cen")]
wire_clk = wire_names[(x, y, "lutff_global/clk")]
@@ -159,10 +173,10 @@ def add_bel_lc(x, y, z):
add_bel_input(bel, wire_s_r, "SR")
add_bel_input(bel, wire_cin, "CIN")
- add_bel_input(bel, wire_in_0, "IN_0")
- add_bel_input(bel, wire_in_1, "IN_1")
- add_bel_input(bel, wire_in_2, "IN_2")
- add_bel_input(bel, wire_in_3, "IN_3")
+ add_bel_input(bel, wire_in_0, "I0")
+ add_bel_input(bel, wire_in_1, "I1")
+ add_bel_input(bel, wire_in_2, "I2")
+ add_bel_input(bel, wire_in_3, "I3")
add_bel_output(bel, wire_out, "O")
add_bel_output(bel, wire_cout, "COUT")
@@ -175,6 +189,7 @@ def add_bel_io(x, y, z):
bel_name.append("%d_%d_lc%d" % (x, y, z))
bel_type.append("SB_IO")
bel_pos.append((x, y, z))
+ bel_wires.append(list())
wire_cen = wire_names[(x, y, "io_global/cen")]
wire_iclk = wire_names[(x, y, "io_global/inclk")]
@@ -204,6 +219,7 @@ def add_bel_ram(x, y):
bel_name.append("%d_%d_ram" % (x, y))
bel_type.append("ICESTORM_RAM")
bel_pos.append((x, y, 0))
+ bel_wires.append(list())
if (x, y, "ram/WE") in wire_names:
# iCE40 1K-style memories
@@ -241,10 +257,16 @@ for tile_xy, tile_type in sorted(tiles.items()):
print('#include "chip.h"')
+for bel in range(len(bel_name)):
+ print("BelWirePOD bel_wires_%d[%d] = {" % (bel, len(bel_wires[bel])))
+ for i in range(len(bel_wires[bel])):
+ print(" {%d, PIN_%s}%s" % (bel_wires[bel][i] + ("," if i+1 < len(bel_wires[bel]) else "",)))
+ print("};")
+
print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, len(bel_name)))
for bel in range(len(bel_name)):
- print(" {\"%s\", TYPE_%s, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel],
- bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2],
+ print(" {\"%s\", TYPE_%s, %d, bel_wires_%d, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel],
+ len(bel_wires[bel]), bel, bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2],
"," if bel+1 < len(bel_name) else ""))
print("};")
diff --git a/ice40/main.cc b/ice40/main.cc
index 073bbae2..9f909bba 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -29,6 +29,7 @@
#include "mainwindow.h"
#include "place.h"
#include "pybindings.h"
+#include "route.h"
#include "version.h"
void svg_dump_el(const GraphicElement &el)
@@ -247,6 +248,7 @@ int main(int argc, char *argv[])
parse_json_file(f, filename, &design);
place_design(&design);
+ route_design(&design);
}
if (vm.count("run")) {
diff --git a/ice40/portpins.inc b/ice40/portpins.inc
index 9eda4bbd..13a22bcc 100644
--- a/ice40/portpins.inc
+++ b/ice40/portpins.inc
@@ -1,7 +1,7 @@
-X(IN_0)
-X(IN_1)
-X(IN_2)
-X(IN_3)
+X(I0)
+X(I1)
+X(I2)
+X(I3)
X(O)
X(LO)
X(CIN)