aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-26 16:23:10 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-26 16:23:10 +0200
commit67d4720989f3609ee2fc2335d906e08f7f50843a (patch)
tree0bef5771ef7642089bcbb637e8a2131679087920 /ice40
parent841d126672112e65450322c5f905bbf22b7dfa54 (diff)
downloadnextpnr-67d4720989f3609ee2fc2335d906e08f7f50843a.tar.gz
nextpnr-67d4720989f3609ee2fc2335d906e08f7f50843a.tar.bz2
nextpnr-67d4720989f3609ee2fc2335d906e08f7f50843a.zip
ice40: Fixing carry chain legaliser
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ice40')
-rwxr-xr-xice40/carry_tests/test.sh2
-rw-r--r--ice40/place_legaliser.cc30
2 files changed, 28 insertions, 4 deletions
diff --git a/ice40/carry_tests/test.sh b/ice40/carry_tests/test.sh
index 01aa4209..0ba63365 100755
--- a/ice40/carry_tests/test.sh
+++ b/ice40/carry_tests/test.sh
@@ -3,7 +3,7 @@ set -ex
NAME=${1%.v}
yosys -p "synth_ice40 -top top; write_json ${NAME}.json" $1
../../nextpnr-ice40 --json ${NAME}.json --pcf test.pcf --asc ${NAME}.asc --verbose
-icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
+icebox_vlog -p test.pcf -L ${NAME}.asc > ${NAME}_out.v
iverilog -o ${NAME}_sim.out ${NAME}_tb.v ${NAME}_out.v
vvp ${NAME}_sim.out
diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc
index c783dd0f..4b8a204e 100644
--- a/ice40/place_legaliser.cc
+++ b/ice40/place_legaliser.cc
@@ -303,7 +303,7 @@ class PlacementLegaliser
lc->params[ctx->id("LUT_INIT")] = "65280"; // 0xff00: O = I3
lc->params[ctx->id("CARRY_ENABLE")] = "1";
lc->ports.at(ctx->id("O")).net = cout_port.net;
- NetInfo *co_i3_net = new NetInfo();
+ std::unique_ptr<NetInfo> co_i3_net(new NetInfo());
co_i3_net->name = ctx->id(lc->name.str(ctx) + "$I3");
co_i3_net->driver = cout_port.net->driver;
PortRef i3_r;
@@ -314,13 +314,16 @@ class PlacementLegaliser
o_r.port = ctx->id("O");
o_r.cell = lc.get();
cout_port.net->driver = o_r;
- lc->ports.at(ctx->id("I3")).net = co_i3_net;
+ lc->ports.at(ctx->id("I3")).net = co_i3_net.get();
+ cout_port.net = co_i3_net.get();
// I1=1 feeds carry up the chain, so no need to actually break the chain
lc->ports.at(ctx->id("I1")).net = ctx->nets.at(ctx->id("$PACKER_VCC_NET")).get();
PortRef i1_r;
i1_r.port = ctx->id("I1");
i1_r.cell = lc.get();
ctx->nets.at(ctx->id("$PACKER_VCC_NET"))->users.push_back(i1_r);
+ IdString co_i3_name = co_i3_net->name;
+ ctx->nets[co_i3_name] = std::move(co_i3_net);
IdString name = lc->name;
ctx->cells[lc->name] = std::move(lc);
createdCells.insert(name);
@@ -340,9 +343,30 @@ class PlacementLegaliser
[cin_cell, cin_port](const PortRef &usr) {
return usr.cell == cin_cell && usr.port == cin_port.name;
}));
- NetInfo *out_net = new NetInfo();
+
+ PortRef i1_ref;
+ i1_ref.cell = lc.get();
+ i1_ref.port = ctx->id("I1");
+ lc->ports.at(ctx->id("I1")).net->users.push_back(i1_ref);
+
+ std::unique_ptr<NetInfo> out_net(new NetInfo());
out_net->name = ctx->id(lc->name.str(ctx) + "$O");
+ PortRef drv_ref;
+ drv_ref.port = ctx->id("COUT");
+ drv_ref.cell = lc.get();
+ out_net->driver = drv_ref;
+ lc->ports.at(ctx->id("COUT")).net = out_net.get();
+
+ PortRef usr_ref;
+ usr_ref.port = cin_port.name;
+ usr_ref.cell = cin_cell;
+ out_net->users.push_back(usr_ref);
+ cin_cell->ports.at(cin_port.name).net = out_net.get();
+
+ IdString out_net_name = out_net->name;
+ ctx->nets[out_net_name] = std::move(out_net);
+
IdString name = lc->name;
ctx->cells[lc->name] = std::move(lc);
createdCells.insert(name);