ice40: Add support for LC placement constraints in packer

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-12 15:13:33 +02:00
parent a139654980
commit 6707b985b4
4 changed files with 82 additions and 11 deletions

View File

@ -75,7 +75,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdString>
return std::hash<std::string>()(obj.data);
}
};
}
} // namespace std
NEXTPNR_NAMESPACE_BEGIN

View File

@ -19,12 +19,12 @@
*/
#include "pack.h"
#include <algorithm>
#include <unordered_set>
#include "cells.h"
#include "design_utils.h"
#include "log.h"
#include <unordered_set>
NEXTPNR_NAMESPACE_BEGIN
// Pack LUTs and LUT-FF pairs
@ -39,6 +39,8 @@ static void pack_lut_lutffs(Design *design)
if (is_lut(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
ci->name.str() + "_LC");
std::copy(ci->attrs.begin(), ci->attrs.end(),
std::inserter(packed->attrs, packed->attrs.begin()));
packed_cells.insert(ci->name);
new_cells.push_back(packed);
log_info("packed cell %s into %s\n", ci->name.c_str(),
@ -47,14 +49,26 @@ static void pack_lut_lutffs(Design *design)
// TODO: LUT cascade
NetInfo *o = ci->ports.at("O").net;
CellInfo *dff = net_only_drives(o, is_ff, "D", true);
auto lut_bel = ci->attrs.find("BEL");
bool packed_dff = false;
if (dff) {
lut_to_lc(ci, packed, false);
dff_to_lc(dff, packed, false);
design->nets.erase(o->name);
packed_cells.insert(dff->name);
log_info("packed cell %s into %s\n", dff->name.c_str(),
packed->name.c_str());
} else {
auto dff_bel = dff->attrs.find("BEL");
if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() &&
lut_bel->second != dff_bel->second) {
// Locations don't match, can't pack
} else {
lut_to_lc(ci, packed, false);
dff_to_lc(dff, packed, false);
design->nets.erase(o->name);
if (dff_bel != dff->attrs.end())
packed->attrs["BEL"] = dff_bel->second;
packed_cells.insert(dff->name);
log_info("packed cell %s into %s\n", dff->name.c_str(),
packed->name.c_str());
packed_dff = true;
}
}
if (!packed_dff) {
lut_to_lc(ci, packed, true);
}
}
@ -78,6 +92,8 @@ static void pack_nonlut_ffs(Design *design)
if (is_ff(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
ci->name.str() + "_LC");
std::copy(ci->attrs.begin(), ci->attrs.end(),
std::inserter(packed->attrs, packed->attrs.begin()));
packed_cells.insert(ci->name);
new_cells.push_back(packed);
dff_to_lc(ci, packed, true);

View File

@ -0,0 +1,54 @@
module top(input clk, cen, rst, ina, inb, output outa, outb, outc, outd);
wire temp0, temp1;
(* BEL="1_1_lc0" *)
SB_LUT4 #(
.LUT_INIT(2'b01)
) lut0 (
.I3(),
.I2(),
.I1(),
.I0(ina),
.O(temp0)
);
(* BEL="1_3_lc0" *)
SB_LUT4 #(
.LUT_INIT(2'b01)
) lut1 (
.I3(),
.I2(),
.I1(),
.I0(inb),
.O(temp1)
);
(* BEL="1_1_lc0" *)
SB_DFF ff0 (
.C(clk),
.D(temp1),
.Q(outa)
);
(* BEL="1_1_lc7" *)
SB_DFF ff1 (
.C(clk),
.D(inb),
.Q(outb)
);
(* BEL="1_6_lc7" *)
SB_DFF ff2 (
.C(clk),
.D(temp1),
.Q(outc)
);
assign outd = 1'b0;
endmodule

View File

@ -5,7 +5,8 @@ yosys -p "synth_ice40 -nocarry -top io_wrapper; write_json ${NAME}.json" $1 io_w
../../nextpnr-ice40 --json ${NAME}.json --pack --asc ${NAME}.asc
icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
yosys -p "rename chip gate;\
yosys -p "read_verilog +/ice40/cells_sim.v;\
rename chip gate;\
read_verilog $1;\
rename top gold;\
hierarchy;\