Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr
This commit is contained in:
commit
136ce3d18f
@ -110,7 +110,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdString>
|
|||||||
return obj.index;
|
return obj.index;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace std
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -123,6 +123,11 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
|||||||
def("parse_json", parse_json_shim);
|
def("parse_json", parse_json_shim);
|
||||||
def("load_design", load_design_shim);
|
def("load_design", load_design_shim);
|
||||||
|
|
||||||
|
class_<IdString>("IdString")
|
||||||
|
.def("__str__", &IdString::str,
|
||||||
|
return_value_policy<copy_const_reference>())
|
||||||
|
.def(self < self)
|
||||||
|
.def(self == self);
|
||||||
arch_wrap_python();
|
arch_wrap_python();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,18 @@ MainWindow::MainWindow(Design *_design, QWidget *parent)
|
|||||||
: QMainWindow(parent), ui(new Ui::MainWindow), design(_design)
|
: QMainWindow(parent), ui(new Ui::MainWindow), design(_design)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->treeWidget->setColumnCount(1);
|
||||||
|
ui->treeWidget->setHeaderLabel(QString("Items"));
|
||||||
|
QTreeWidgetItem *belroot = new QTreeWidgetItem(ui->treeWidget);
|
||||||
|
belroot->setText(0, QString("Bels"));
|
||||||
|
ui->treeWidget->insertTopLevelItem(0, belroot);
|
||||||
|
QList<QTreeWidgetItem *> items;
|
||||||
|
for (auto bel : design->chip.getBels()) {
|
||||||
|
auto name = design->chip.getBelName(bel);
|
||||||
|
items.append(new QTreeWidgetItem((QTreeWidget *)nullptr,
|
||||||
|
QStringList(QString(name.c_str()))));
|
||||||
|
}
|
||||||
|
belroot->addChildren(items);
|
||||||
PyImport_ImportModule("emb");
|
PyImport_ImportModule("emb");
|
||||||
|
|
||||||
write = [this](std::string s) {
|
write = [this](std::string s) {
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTreeView" name="treeView">
|
<widget class="QTreeWidget" name="treeWidget">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>300</width>
|
<width>300</width>
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <unordered_set>
|
||||||
#include "cells.h"
|
#include "cells.h"
|
||||||
#include "design_utils.h"
|
#include "design_utils.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// Pack LUTs and LUT-FF pairs
|
// Pack LUTs and LUT-FF pairs
|
||||||
@ -39,6 +39,8 @@ static void pack_lut_lutffs(Design *design)
|
|||||||
if (is_lut(ci)) {
|
if (is_lut(ci)) {
|
||||||
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
|
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
|
||||||
ci->name.str() + "_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);
|
packed_cells.insert(ci->name);
|
||||||
new_cells.push_back(packed);
|
new_cells.push_back(packed);
|
||||||
log_info("packed cell %s into %s\n", ci->name.c_str(),
|
log_info("packed cell %s into %s\n", ci->name.c_str(),
|
||||||
@ -47,14 +49,27 @@ static void pack_lut_lutffs(Design *design)
|
|||||||
// TODO: LUT cascade
|
// TODO: LUT cascade
|
||||||
NetInfo *o = ci->ports.at("O").net;
|
NetInfo *o = ci->ports.at("O").net;
|
||||||
CellInfo *dff = net_only_drives(o, is_ff, "D", true);
|
CellInfo *dff = net_only_drives(o, is_ff, "D", true);
|
||||||
|
auto lut_bel = ci->attrs.find("BEL");
|
||||||
|
bool packed_dff = false;
|
||||||
if (dff) {
|
if (dff) {
|
||||||
lut_to_lc(ci, packed, false);
|
log_info("found attached dff %s\n", dff->name.c_str());
|
||||||
dff_to_lc(dff, packed, false);
|
auto dff_bel = dff->attrs.find("BEL");
|
||||||
design->nets.erase(o->name);
|
if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() &&
|
||||||
packed_cells.insert(dff->name);
|
lut_bel->second != dff_bel->second) {
|
||||||
log_info("packed cell %s into %s\n", dff->name.c_str(),
|
// Locations don't match, can't pack
|
||||||
packed->name.c_str());
|
} else {
|
||||||
} 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);
|
lut_to_lc(ci, packed, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +92,11 @@ static void pack_nonlut_ffs(Design *design)
|
|||||||
CellInfo *ci = cell.second;
|
CellInfo *ci = cell.second;
|
||||||
if (is_ff(ci)) {
|
if (is_ff(ci)) {
|
||||||
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
|
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
|
||||||
ci->name.str() + "_LC");
|
ci->name.str() + "_DFFLC");
|
||||||
|
std::copy(ci->attrs.begin(), ci->attrs.end(),
|
||||||
|
std::inserter(packed->attrs, packed->attrs.begin()));
|
||||||
|
log_info("packed cell %s into %s\n", ci->name.c_str(),
|
||||||
|
packed->name.c_str());
|
||||||
packed_cells.insert(ci->name);
|
packed_cells.insert(ci->name);
|
||||||
new_cells.push_back(packed);
|
new_cells.push_back(packed);
|
||||||
dff_to_lc(ci, packed, true);
|
dff_to_lc(ci, packed, true);
|
||||||
|
54
ice40/pack_tests/place_constr.v
Normal file
54
ice40/pack_tests/place_constr.v
Normal 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
|
@ -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
|
../../nextpnr-ice40 --json ${NAME}.json --pack --asc ${NAME}.asc
|
||||||
icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
|
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;\
|
read_verilog $1;\
|
||||||
rename top gold;\
|
rename top gold;\
|
||||||
hierarchy;\
|
hierarchy;\
|
||||||
|
Loading…
Reference in New Issue
Block a user