aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-26 16:22:19 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-26 16:22:19 +0100
commit4a21436dfa98caa458a8e6e130cf1f6305968650 (patch)
tree4e1dd3f04e5b671acf958eba6f7dc930ae4d1547 /ice40
parentc897c0ca9afab1d758f5c1b77312e77057a4c814 (diff)
parent03f92948d1504c32049da065c0e73e01f96d8033 (diff)
downloadnextpnr-4a21436dfa98caa458a8e6e130cf1f6305968650.tar.gz
nextpnr-4a21436dfa98caa458a8e6e130cf1f6305968650.tar.bz2
nextpnr-4a21436dfa98caa458a8e6e130cf1f6305968650.zip
Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc292
-rw-r--r--ice40/arch.h7
-rw-r--r--ice40/benchmark/.gitignore6
-rw-r--r--ice40/benchmark/Makefile10
-rw-r--r--ice40/benchmark/report.ipynb69
-rw-r--r--ice40/bitstream.cc5
-rw-r--r--ice40/chipdb.py3
-rw-r--r--ice40/gfx.cc11
-rw-r--r--ice40/main.cc10
-rw-r--r--ice40/pack.cc12
-rwxr-xr-xice40/picorv32_benchmark.py3
-rw-r--r--ice40/place_legaliser.cc17
12 files changed, 307 insertions, 138 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 1d7e9546..d08463d2 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -188,6 +188,13 @@ Arch::Arch(ArchArgs args) : args(args)
id_i3 = id("I3");
id_dff_en = id("DFF_ENABLE");
id_neg_clk = id("NEG_CLK");
+ id_cin = id("CIN");
+ id_cout = id("COUT");
+ id_o = id("O");
+ id_lo = id("LO");
+ id_icestorm_ram = id("ICESTORM_RAM");
+ id_rclk = id("RCLK");
+ id_wclk = id("WCLK");
}
// -----------------------------------------------------------------------
@@ -433,11 +440,103 @@ GroupId Arch::getGroupByName(IdString name) const
return GroupId();
}
-IdString Arch::getGroupName(GroupId group) const { return IdString(); }
+IdString Arch::getGroupName(GroupId group) const
+{
+ std::string suffix;
+
+ switch (group.type) {
+ case GroupId::TYPE_FRAME:
+ suffix = "tile";
+ break;
+ case GroupId::TYPE_MAIN_SW:
+ suffix = "main_sw";
+ break;
+ case GroupId::TYPE_LOCAL_SW:
+ suffix = "local_sw";
+ break;
+ case GroupId::TYPE_LC0_SW:
+ suffix = "lc0_sw";
+ break;
+ case GroupId::TYPE_LC1_SW:
+ suffix = "lc1_sw";
+ break;
+ case GroupId::TYPE_LC2_SW:
+ suffix = "lc2_sw";
+ break;
+ case GroupId::TYPE_LC3_SW:
+ suffix = "lc3_sw";
+ break;
+ case GroupId::TYPE_LC4_SW:
+ suffix = "lc4_sw";
+ break;
+ case GroupId::TYPE_LC5_SW:
+ suffix = "lc5_sw";
+ break;
+ case GroupId::TYPE_LC6_SW:
+ suffix = "lc6_sw";
+ break;
+ case GroupId::TYPE_LC7_SW:
+ suffix = "lc7_sw";
+ break;
+ default:
+ return IdString();
+ }
+
+ return id("X" + std::to_string(group.x) + "/Y" + std::to_string(group.y) + "/" + suffix);
+}
std::vector<GroupId> Arch::getGroups() const
{
std::vector<GroupId> ret;
+
+ for (int y = 0; y < chip_info->height; y++) {
+ for (int x = 0; x < chip_info->width; x++) {
+ TileType type = chip_info->tile_grid[y * chip_info->width + x];
+ if (type == TILE_NONE)
+ continue;
+
+ GroupId group;
+ group.type = GroupId::TYPE_FRAME;
+ group.x = x;
+ group.y = y;
+ // ret.push_back(group);
+
+ group.type = GroupId::TYPE_MAIN_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LOCAL_SW;
+ ret.push_back(group);
+
+#if 0
+ if (type == TILE_LOGIC)
+ {
+ group.type = GroupId::TYPE_LC0_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC1_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC2_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC3_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC4_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC5_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC6_SW;
+ ret.push_back(group);
+
+ group.type = GroupId::TYPE_LC7_SW;
+ ret.push_back(group);
+ }
+#endif
+ }
+ }
return ret;
}
@@ -545,15 +644,63 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
std::vector<GraphicElement> ret;
if (decal.type == DecalId::TYPE_FRAME) {
- for (int x = 0; x <= chip_info->width; x++)
- for (int y = 0; y <= chip_info->height; y++) {
- GraphicElement el;
- el.type = GraphicElement::G_LINE;
- el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0;
- ret.push_back(el);
- el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0;
- ret.push_back(el);
- }
+ /* nothing */
+ }
+
+ if (decal.type == DecalId::TYPE_GROUP) {
+ int type = (decal.index >> 16) & 255;
+ int x = (decal.index >> 8) & 255;
+ int y = decal.index & 255;
+
+ if (type == GroupId::TYPE_FRAME) {
+ GraphicElement el;
+ el.type = GraphicElement::G_LINE;
+ el.style = GraphicElement::G_FRAME;
+
+ el.x1 = x + 0.01, el.x2 = x + 0.02, el.y1 = y + 0.01, el.y2 = y + 0.01;
+ ret.push_back(el);
+ el.x1 = x + 0.01, el.x2 = x + 0.01, el.y1 = y + 0.01, el.y2 = y + 0.02;
+ ret.push_back(el);
+
+ el.x1 = x + 0.99, el.x2 = x + 0.98, el.y1 = y + 0.01, el.y2 = y + 0.01;
+ ret.push_back(el);
+ el.x1 = x + 0.99, el.x2 = x + 0.99, el.y1 = y + 0.01, el.y2 = y + 0.02;
+ ret.push_back(el);
+
+ el.x1 = x + 0.99, el.x2 = x + 0.98, el.y1 = y + 0.99, el.y2 = y + 0.99;
+ ret.push_back(el);
+ el.x1 = x + 0.99, el.x2 = x + 0.99, el.y1 = y + 0.99, el.y2 = y + 0.98;
+ ret.push_back(el);
+
+ el.x1 = x + 0.01, el.x2 = x + 0.02, el.y1 = y + 0.99, el.y2 = y + 0.99;
+ ret.push_back(el);
+ el.x1 = x + 0.01, el.x2 = x + 0.01, el.y1 = y + 0.99, el.y2 = y + 0.98;
+ ret.push_back(el);
+ }
+
+ if (type == GroupId::TYPE_MAIN_SW) {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.style = GraphicElement::G_FRAME;
+
+ el.x1 = x + main_swbox_x1;
+ el.x2 = x + main_swbox_x2;
+ el.y1 = y + main_swbox_y1;
+ el.y2 = y + main_swbox_y2;
+ ret.push_back(el);
+ }
+
+ if (type == GroupId::TYPE_LOCAL_SW) {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.style = GraphicElement::G_FRAME;
+
+ el.x1 = x + local_swbox_x1;
+ el.x2 = x + local_swbox_x2;
+ el.y1 = y + local_swbox_y1;
+ el.y2 = y + local_swbox_y2;
+ ret.push_back(el);
+ }
}
if (decal.type == DecalId::TYPE_WIRE) {
@@ -588,103 +735,32 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
(chip_info->bel_data[bel.index].z) * logic_cell_pitch;
el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 +
(chip_info->bel_data[bel.index].z) * logic_cell_pitch;
- el.z = 0;
ret.push_back(el);
-
- if (chip_info->bel_data[bel.index].z == 0) {
- int tx = chip_info->bel_data[bel.index].x;
- int ty = chip_info->bel_data[bel.index].y;
-
- // Main switchbox
- GraphicElement main_sw;
- main_sw.type = GraphicElement::G_BOX;
- main_sw.style = GraphicElement::G_FRAME;
- main_sw.x1 = tx + main_swbox_x1;
- main_sw.x2 = tx + main_swbox_x2;
- main_sw.y1 = ty + main_swbox_y1;
- main_sw.y2 = ty + main_swbox_y2;
- ret.push_back(main_sw);
-
- // Local tracks to LUT input switchbox
- GraphicElement local_sw;
- local_sw.type = GraphicElement::G_BOX;
- local_sw.style = GraphicElement::G_FRAME;
- local_sw.x1 = tx + local_swbox_x1;
- local_sw.x2 = tx + local_swbox_x2;
- local_sw.y1 = ty + local_swbox_y1;
- local_sw.y2 = ty + local_swbox_y2;
- local_sw.z = 0;
- ret.push_back(local_sw);
- }
}
if (bel_type == TYPE_SB_IO) {
- if (chip_info->bel_data[bel.index].x == 0 || chip_info->bel_data[bel.index].x == chip_info->width - 1) {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- el.x1 = chip_info->bel_data[bel.index].x + 0.1;
- el.x2 = chip_info->bel_data[bel.index].x + 0.9;
- if (chip_info->bel_data[bel.index].z == 0) {
- el.y1 = chip_info->bel_data[bel.index].y + 0.10;
- el.y2 = chip_info->bel_data[bel.index].y + 0.45;
- } else {
- el.y1 = chip_info->bel_data[bel.index].y + 0.55;
- el.y2 = chip_info->bel_data[bel.index].y + 0.90;
- }
- el.z = 0;
- ret.push_back(el);
- } else {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- if (chip_info->bel_data[bel.index].z == 0) {
- el.x1 = chip_info->bel_data[bel.index].x + 0.10;
- el.x2 = chip_info->bel_data[bel.index].x + 0.45;
- } else {
- el.x1 = chip_info->bel_data[bel.index].x + 0.55;
- el.x2 = chip_info->bel_data[bel.index].x + 0.90;
- }
- el.y1 = chip_info->bel_data[bel.index].y + 0.1;
- el.y2 = chip_info->bel_data[bel.index].y + 0.9;
- el.z = 0;
- ret.push_back(el);
- }
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE;
+ el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1;
+ el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2;
+ el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 +
+ (4 * chip_info->bel_data[bel.index].z) * logic_cell_pitch;
+ el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 +
+ (4 * chip_info->bel_data[bel.index].z + 3) * logic_cell_pitch;
+ ret.push_back(el);
}
if (bel_type == TYPE_ICESTORM_RAM) {
for (int i = 0; i < 2; i++) {
- int tx = chip_info->bel_data[bel.index].x;
- int ty = chip_info->bel_data[bel.index].y + i;
-
GraphicElement el;
el.type = GraphicElement::G_BOX;
el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE;
el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1;
el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2;
- el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1;
- el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7 * logic_cell_pitch;
- el.z = 0;
+ el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + i;
+ el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + i + 7 * logic_cell_pitch;
ret.push_back(el);
-
- // Main switchbox
- GraphicElement main_sw;
- main_sw.type = GraphicElement::G_BOX;
- main_sw.style = GraphicElement::G_FRAME;
- main_sw.x1 = tx + main_swbox_x1;
- main_sw.x2 = tx + main_swbox_x2;
- main_sw.y1 = ty + main_swbox_y1;
- main_sw.y2 = ty + main_swbox_y2;
- ret.push_back(main_sw);
-
- // Local tracks to LUT input switchbox
- GraphicElement local_sw;
- local_sw.type = GraphicElement::G_BOX;
- local_sw.style = GraphicElement::G_FRAME;
- local_sw.x1 = tx + local_swbox_x1;
- local_sw.x2 = tx + local_swbox_x2;
- local_sw.y1 = ty + local_swbox_y1;
- local_sw.y2 = ty + local_swbox_y2;
- local_sw.z = 0;
- ret.push_back(local_sw);
}
}
}
@@ -696,26 +772,26 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const
{
- if (cell->type == id("ICESTORM_LC")) {
- if ((fromPort == id("I0") || fromPort == id("I1") || fromPort == id("I2") || fromPort == id("I3")) &&
- (toPort == id("O") || toPort == id("LO"))) {
+ if (cell->type == id_icestorm_lc) {
+ if ((fromPort == id_i0 || fromPort == id_i1 || fromPort == id_i2 || fromPort == id_i3) &&
+ (toPort == id_o || toPort == id_lo)) {
delay = 450;
return true;
- } else if (fromPort == id("CIN") && toPort == id("COUT")) {
+ } else if (fromPort == id_cin && toPort == id_cout) {
delay = 120;
return true;
- } else if (fromPort == id("I1") && toPort == id("COUT")) {
+ } else if (fromPort == id_i1 && toPort == id_cout) {
delay = 260;
return true;
- } else if (fromPort == id("I2") && toPort == id("COUT")) {
+ } else if (fromPort == id_i2 && toPort == id_cout) {
delay = 230;
return true;
- } else if (fromPort == id("CLK") && toPort == id("O")) {
+ } else if (fromPort == id_clk && toPort == id_o) {
delay = 540;
return true;
}
- } else if (cell->type == id("ICESTORM_RAM")) {
- if (fromPort == id("RCLK")) {
+ } else if (cell->type == id_icestorm_ram) {
+ if (fromPort == id_rclk) {
delay = 2140;
return true;
}
@@ -725,14 +801,14 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
IdString Arch::getPortClock(const CellInfo *cell, IdString port) const
{
- if (cell->type == id("ICESTORM_LC") && bool_or_default(cell->params, id("DFF_ENABLE"))) {
- if (port != id("LO") && port != id("CIN") && port != id("COUT"))
- return id("CLK");
- } else if (cell->type == id("ICESTORM_RAM")) {
+ if (cell->type == id_icestorm_lc && cell->lcInfo.dffEnable) {
+ if (port != id_lo && port != id_cin && port != id_cout)
+ return id_clk;
+ } else if (cell->type == id_icestorm_ram) {
if (port.str(this)[0] == 'R')
- return id("RCLK");
+ return id_rclk;
else
- return id("WCLK");
+ return id_wclk;
}
return IdString();
}
diff --git a/ice40/arch.h b/ice40/arch.h
index bd937371..51cbe725 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -469,6 +469,8 @@ struct Arch : BaseCtx
return id(chip_info->wire_data[wire.index].name.get());
}
+ IdString getWireType(WireId wire) const { return IdString(); }
+
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
void bindWire(WireId wire, IdString net, PlaceStrength strength)
@@ -611,6 +613,8 @@ struct Arch : BaseCtx
IdString getPipName(PipId pip) const;
+ IdString getPipType(PipId pip) const { return IdString(); }
+
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
WireId getPipSrcWire(PipId pip) const
@@ -739,6 +743,9 @@ struct Arch : BaseCtx
IdString id_cen, id_clk, id_sr;
IdString id_i0, id_i1, id_i2, id_i3;
IdString id_dff_en, id_neg_clk;
+ IdString id_cin, id_cout;
+ IdString id_o, id_lo;
+ IdString id_icestorm_ram, id_rclk, id_wclk;
// -------------------------------------------------
BelPin getIOBSharingPLLPin(BelId pll, PortPin pll_pin) const
diff --git a/ice40/benchmark/.gitignore b/ice40/benchmark/.gitignore
new file mode 100644
index 00000000..306b5c6e
--- /dev/null
+++ b/ice40/benchmark/.gitignore
@@ -0,0 +1,6 @@
+hx8kdemo.log
+hx8kdemo.blif
+hx8kdemo.json
+hx8kdemo_[an][0-9].asc
+hx8kdemo_[an][0-9].log
+report_[an][0-9].txt
diff --git a/ice40/benchmark/Makefile b/ice40/benchmark/Makefile
index 38cc2b0d..5e16d9b0 100644
--- a/ice40/benchmark/Makefile
+++ b/ice40/benchmark/Makefile
@@ -10,14 +10,18 @@ report_n$1.txt: hx8kdemo_n$1.asc
icetime -m -r report_n$1.txt -d hx8k hx8kdemo_n$1.asc
hx8kdemo_a$1.asc: hx8kdemo.blif
- arachne-pnr -d 8k -p hx8kdemo.pcf -o hx8kdemo_a$1.asc -s $1 hx8kdemo.blif
+ arachne-pnr -d 8k -p hx8kdemo.pcf -o hx8kdemo_a$1.asc -s 1$1 hx8kdemo.blif > hx8kdemo_a$1.log 2>&1
hx8kdemo_n$1.asc: hx8kdemo.json
- nextpnr-ice40 --asc hx8kdemo_n$1.asc --json hx8kdemo.json --pcf hx8kdemo.pcf --hx8k --seed $1
+ ../../nextpnr-ice40 --asc hx8kdemo_n$1.asc --json hx8kdemo.json --pcf hx8kdemo.pcf --hx8k --seed 1$1 > hx8kdemo_n$1.log 2>&1
endef
-$(foreach i,1 2 3 4 5 6 7 8,$(eval $(call mkreport,$(i))))
+$(foreach i,0 1 2 3 4 5 6 7 8 9,$(eval $(call mkreport,$(i))))
hx8kdemo.blif: hx8kdemo.json
hx8kdemo.json: hx8kdemo.v spimemio.v simpleuart.v picosoc.v picorv32.v
yosys -ql hx8kdemo.log -p 'synth_ice40 -top hx8kdemo -blif hx8kdemo.blif -json hx8kdemo.json' $^
+
+clean:
+ rm -f hx8kdemo.log hx8kdemo.blif hx8kdemo.json
+ rm -f hx8kdemo_[an][0-9].asc hx8kdemo_[an][0-9].log report_[an][0-9].txt
diff --git a/ice40/benchmark/report.ipynb b/ice40/benchmark/report.ipynb
new file mode 100644
index 00000000..3232f38c
--- /dev/null
+++ b/ice40/benchmark/report.ipynb
@@ -0,0 +1,69 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "%matplotlib inline\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import subprocess\n",
+ "\n",
+ "gitrev = subprocess.getoutput(\"git rev-parse --short HEAD\")\n",
+ "\n",
+ "data_a = 1 + np.zeros(10)\n",
+ "data_n = 1 + np.zeros(10)\n",
+ "\n",
+ "for i in range(10):\n",
+ " try:\n",
+ " with open(\"report_a%d.txt\" % i, \"r\") as f:\n",
+ " for line in f:\n",
+ " if line.startswith(\"Total path delay:\"):\n",
+ " data_a[i] = float(line.split()[3])\n",
+ " except:\n",
+ " pass\n",
+ " try:\n",
+ " with open(\"report_n%d.txt\" % i, \"r\") as f:\n",
+ " for line in f:\n",
+ " if line.startswith(\"Total path delay:\"):\n",
+ " data_n[i] = float(line.split()[3])\n",
+ " except:\n",
+ " pass\n",
+ "\n",
+ "plt.figure(figsize=(9,3))\n",
+ "plt.title(\"nextpnr -- ice40/benchmark/ -- %s\" % gitrev)\n",
+ "plt.bar(np.arange(10), data_a, color='blue')\n",
+ "plt.bar(15+np.arange(10), data_n, color='red')\n",
+ "plt.ylabel('Longest path (ns)')\n",
+ "plt.xticks([5, 20], [\"arachne-pnr\", \"nextpnr\"])\n",
+ "plt.xlim(-2, 27)\n",
+ "plt.show()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index e9851a83..af5febce 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -566,9 +566,8 @@ void write_asc(const Context *ctx, std::ostream &out)
set_config(ti, config.at(y).at(x),
"Cascade.IPCON_LC0" + std::to_string(lc_idx) + "_inmux02_5", true);
else
- set_config(ti, config.at(y).at(x),
- "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) + "_LC0" +
- std::to_string(lc_idx) + "_inmux02_5",
+ set_config(ti, config.at(y).at(x), "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) +
+ "_LC0" + std::to_string(lc_idx) + "_inmux02_5",
true);
}
}
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index b5fee359..b6af8fcf 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -675,7 +675,8 @@ class BinaryBlobAssembler:
print("ref %s %s" % (name, comment))
def s(self, s, comment):
- print("str %s" % s)
+ assert "|" not in s
+ print("str |%s| %s" % (s, comment))
def u8(self, v, comment):
if comment is None:
diff --git a/ice40/gfx.cc b/ice40/gfx.cc
index 1b01cbd8..0a583e8e 100644
--- a/ice40/gfx.cc
+++ b/ice40/gfx.cc
@@ -701,6 +701,17 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src,
if (getWireXY_local(src, x1, y1) && getWireXY_local(dst, x2, y2))
pipGfx(g, x, y, x1, y1, x2, y2, local_swbox_x1, local_swbox_y1, local_swbox_x2, local_swbox_y2, style);
+
+ if (src == TILE_WIRE_CARRY_IN && dst == TILE_WIRE_CARRY_IN_MUX) {
+ GraphicElement el;
+ el.type = GraphicElement::G_ARROW;
+ el.style = style;
+ el.x1 = x + logic_cell_x1 + 0.005 * 3;
+ el.x2 = el.x1;
+ el.y1 = y + 0.01;
+ el.y2 = y + 0.02;
+ g.push_back(el);
+ }
}
NEXTPNR_NAMESPACE_END
diff --git a/ice40/main.cc b/ice40/main.cc
index 4de05d00..6201831a 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -144,18 +144,16 @@ int main(int argc, char *argv[])
#endif
if (vm.count("help") || argc == 1) {
help:
- std::cout << boost::filesystem::basename(argv[0])
- << " -- Next Generation Place and Route (git "
- "sha1 " GIT_COMMIT_HASH_STR ")\n";
+ std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
+ "sha1 " GIT_COMMIT_HASH_STR ")\n";
std::cout << "\n";
std::cout << options << "\n";
return argc != 1;
}
if (vm.count("version")) {
- std::cout << boost::filesystem::basename(argv[0])
- << " -- Next Generation Place and Route (git "
- "sha1 " GIT_COMMIT_HASH_STR ")\n";
+ std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
+ "sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1;
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 91dcf846..8182eb70 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -662,12 +662,12 @@ static void pack_special(Context *ctx)
auto feedback_path = packed->params[ctx->id("FEEDBACK_PATH")];
packed->params[ctx->id("FEEDBACK_PATH")] =
- feedback_path == "DELAY"
- ? "0"
- : feedback_path == "SIMPLE" ? "1"
- : feedback_path == "PHASE_AND_DELAY"
- ? "2"
- : feedback_path == "EXTERNAL" ? "6" : feedback_path;
+ feedback_path == "DELAY" ? "0" : feedback_path == "SIMPLE"
+ ? "1"
+ : feedback_path == "PHASE_AND_DELAY"
+ ? "2"
+ : feedback_path == "EXTERNAL" ? "6"
+ : feedback_path;
packed->params[ctx->id("PLLTYPE")] = std::to_string(sb_pll40_type(ctx, ci));
NetInfo *pad_packagepin_net = nullptr;
diff --git a/ice40/picorv32_benchmark.py b/ice40/picorv32_benchmark.py
index 9544db50..a4ec581e 100755
--- a/ice40/picorv32_benchmark.py
+++ b/ice40/picorv32_benchmark.py
@@ -7,7 +7,6 @@ import re
num_runs = 8
if not path.exists("picorv32.json"):
- os.remove("picorv32.json")
subprocess.run(["wget", "https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v"], check=True)
subprocess.run(["yosys", "-q", "-p", "synth_ice40 -json picorv32.json -top top", "picorv32.v", "picorv32_top.v"], check=True)
@@ -23,7 +22,7 @@ for i in range(num_runs):
ascfile = "picorv32_work/picorv32_s{}.asc".format(run)
if path.exists(ascfile):
os.remove(ascfile)
- result = subprocess.run(["../nextpnr-ice40", "--hx8k", "--seed", str(run), "--json", "picorv32.json", "--asc", ascfile], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
+ result = subprocess.run(["../nextpnr-ice40", "--hx8k", "--seed", str(run), "--json", "picorv32.json", "--asc", ascfile, "--freq", "70"], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
if result.returncode != 0:
print("Run {} failed!".format(run))
else:
diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc
index ebc2b865..9fde179d 100644
--- a/ice40/place_legaliser.cc
+++ b/ice40/place_legaliser.cc
@@ -90,21 +90,20 @@ static int get_cell_evilness(const Context *ctx, const CellInfo *cell)
// This returns how "evil" a logic cell is, and thus how likely it is to be ripped up
// during logic tile legalisation
int score = 0;
- if (get_net_or_empty(cell, ctx->id("I0")))
+ if (get_net_or_empty(cell, ctx->id_i0))
++score;
- if (get_net_or_empty(cell, ctx->id("I1")))
+ if (get_net_or_empty(cell, ctx->id_i1))
++score;
- if (get_net_or_empty(cell, ctx->id("I2")))
+ if (get_net_or_empty(cell, ctx->id_i2))
++score;
- if (get_net_or_empty(cell, ctx->id("I3")))
+ if (get_net_or_empty(cell, ctx->id_i3))
++score;
- if (bool_or_default(cell->params, ctx->id("DFF_ENABLE"))) {
- const NetInfo *cen = get_net_or_empty(cell, ctx->id("CEN")), *sr = get_net_or_empty(cell, ctx->id("SR"));
- if (cen)
+ if (cell->lcInfo.dffEnable) {
+ if (cell->lcInfo.cen)
score += 10;
- if (sr)
+ if (cell->lcInfo.sr)
score += 10;
- if (bool_or_default(cell->params, ctx->id("NEG_CLK")))
+ if (cell->lcInfo.negClk)
score += 5;
}
return score;