diff options
| -rw-r--r-- | common/nextpnr.h | 2 | ||||
| -rw-r--r-- | common/pybindings.cc | 5 | ||||
| -rw-r--r-- | gui/mainwindow.cc | 12 | ||||
| -rw-r--r-- | gui/mainwindow.ui | 2 | ||||
| -rw-r--r-- | ice40/pack.cc | 39 | ||||
| -rw-r--r-- | ice40/pack_tests/place_constr.v | 54 | ||||
| -rwxr-xr-x | ice40/pack_tests/test.sh | 3 | 
7 files changed, 104 insertions, 13 deletions
| diff --git a/common/nextpnr.h b/common/nextpnr.h index fc14299d..4288f7fc 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -110,7 +110,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX IdString>          return obj.index;      }  }; -} +} // namespace std  NEXTPNR_NAMESPACE_BEGIN diff --git a/common/pybindings.cc b/common/pybindings.cc index 8aa831ca..7c43c84f 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -123,6 +123,11 @@ BOOST_PYTHON_MODULE(MODULE_NAME)      def("parse_json", parse_json_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();  } diff --git a/gui/mainwindow.cc b/gui/mainwindow.cc index 31ce8fae..c436fd6c 100644 --- a/gui/mainwindow.cc +++ b/gui/mainwindow.cc @@ -16,6 +16,18 @@ MainWindow::MainWindow(Design *_design, QWidget *parent)          : QMainWindow(parent), ui(new Ui::MainWindow), design(_design)  {      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");      write = [this](std::string s) { diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 3fe0f400..7352af1f 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -64,7 +64,7 @@         <property name="orientation">          <enum>Qt::Vertical</enum>         </property>        -       <widget class="QTreeView" name="treeView"> +       <widget class="QTreeWidget" name="treeWidget">          <property name="minimumSize">           <size>            <width>300</width> diff --git a/ice40/pack.cc b/ice40/pack.cc index a971dcc3..8f770a07 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -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,27 @@ 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 { +                log_info("found attached dff %s\n", dff->name.c_str()); +                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);              }          } @@ -77,7 +92,11 @@ static void pack_nonlut_ffs(Design *design)          CellInfo *ci = cell.second;          if (is_ff(ci)) {              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);              new_cells.push_back(packed);              dff_to_lc(ci, packed, true); diff --git a/ice40/pack_tests/place_constr.v b/ice40/pack_tests/place_constr.v new file mode 100644 index 00000000..f915a203 --- /dev/null +++ b/ice40/pack_tests/place_constr.v @@ -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 diff --git a/ice40/pack_tests/test.sh b/ice40/pack_tests/test.sh index 88ff5b1d..dd1f345c 100755 --- a/ice40/pack_tests/test.sh +++ b/ice40/pack_tests/test.sh @@ -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;\ | 
