aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-06-17 16:14:58 +0200
committerClifford Wolf <clifford@clifford.at>2018-06-17 16:14:58 +0200
commit4fe8ba5e9ae9e3676ff1276473854dd667794b5c (patch)
tree4e3368abd94bb4f9bf4c7e91bb06d47d13122fe5 /ice40
parent105cde328bb228cbba37cbd730dc60a206d5a219 (diff)
parentf66999a8830c5829872b93ce15491de1673cb4e3 (diff)
downloadnextpnr-4fe8ba5e9ae9e3676ff1276473854dd667794b5c.tar.gz
nextpnr-4fe8ba5e9ae9e3676ff1276473854dd667794b5c.tar.bz2
nextpnr-4fe8ba5e9ae9e3676ff1276473854dd667794b5c.zip
Merge branch 'master' of gitlab.com:SymbioticEDA/nextpnr into chipdbng
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch_place.cc49
-rw-r--r--ice40/bitstream.cc9
-rw-r--r--ice40/main.cc12
-rw-r--r--ice40/pack.cc14
4 files changed, 56 insertions, 28 deletions
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index 1c6361a1..3205fb6e 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -24,8 +24,8 @@
NEXTPNR_NAMESPACE_BEGIN
-static const NetInfo *get_net_or_nullptr(const CellInfo *cell,
- const IdString port)
+static const NetInfo *get_net_or_empty(const CellInfo *cell,
+ const IdString port)
{
auto found = cell->ports.find(port);
if (found != cell->ports.end())
@@ -38,46 +38,53 @@ static bool logicCellsCompatible(const std::vector<const CellInfo *> &cells)
{
bool dffs_exist = false, dffs_neg = false;
const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr;
- std::unordered_set<const NetInfo *> locals;
+ static std::unordered_set<IdString> locals;
+ locals.clear();
for (auto cell : cells) {
if (bool_or_default(cell->params, "DFF_ENABLE")) {
if (!dffs_exist) {
dffs_exist = true;
- cen = get_net_or_nullptr(cell, "CEN");
- clk = get_net_or_nullptr(cell, "CLK");
- sr = get_net_or_nullptr(cell, "SR");
+ cen = get_net_or_empty(cell, "CEN");
+ clk = get_net_or_empty(cell, "CLK");
+ sr = get_net_or_empty(cell, "SR");
- if (!is_global_net(cen))
- locals.insert(cen);
- if (!is_global_net(clk))
- locals.insert(clk);
- if (!is_global_net(sr))
- locals.insert(sr);
+ if (!is_global_net(cen) && cen != nullptr)
+ locals.insert(cen->name);
+ if (!is_global_net(clk) && clk != nullptr)
+ locals.insert(clk->name);
+ if (!is_global_net(sr) && sr != nullptr)
+ locals.insert(sr->name);
if (bool_or_default(cell->params, "NEG_CLK")) {
dffs_neg = true;
}
} else {
- if (cen != get_net_or_nullptr(cell, "CEN"))
+ if (cen != get_net_or_empty(cell, "CEN"))
return false;
- if (clk != get_net_or_nullptr(cell, "CLK"))
+ if (clk != get_net_or_empty(cell, "CLK"))
return false;
- if (sr != get_net_or_nullptr(cell, "SR"))
+ if (sr != get_net_or_empty(cell, "SR"))
return false;
if (dffs_neg != bool_or_default(cell->params, "NEG_CLK"))
return false;
}
}
- locals.insert(get_net_or_nullptr(cell, "I0"));
- locals.insert(get_net_or_nullptr(cell, "I1"));
- locals.insert(get_net_or_nullptr(cell, "I2"));
- locals.insert(get_net_or_nullptr(cell, "I3"));
+ const NetInfo *i0 = get_net_or_empty(cell, "I0"),
+ *i1 = get_net_or_empty(cell, "I1"),
+ *i2 = get_net_or_empty(cell, "I2"),
+ *i3 = get_net_or_empty(cell, "I3");
+ if (i0 != nullptr)
+ locals.insert(i0->name);
+ if (i1 != nullptr)
+ locals.insert(i1->name);
+ if (i2 != nullptr)
+ locals.insert(i2->name);
+ if (i3 != nullptr)
+ locals.insert(i3->name);
}
- locals.erase(nullptr); // disconnected signals don't use local tracks
-
return locals.size() <= 32;
}
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index c207f08c..4991df5e 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -19,6 +19,7 @@
*/
#include "bitstream.h"
#include <vector>
+#include "log.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -59,11 +60,16 @@ void set_config(const TileInfoPOD &ti,
if (index == -1) {
for (int i = 0; i < cfg.num_bits; i++) {
int8_t &cbit = tile_cfg.at(cfg.bits[i].row).at(cfg.bits[i].col);
+ if (cbit && !value)
+ log_error("clearing already set config bit %s", name.c_str());
cbit = value;
}
} else {
int8_t &cbit = tile_cfg.at(cfg.bits[index].row).at(cfg.bits[index].col);
cbit = value;
+ if (cbit && !value)
+ log_error("clearing already set config bit %s[%d]", name.c_str(),
+ index);
}
}
@@ -179,7 +185,8 @@ void write_asc(const Design &design, std::ostream &out)
for (int i = 0; i < 20; i++)
set_config(ti, config.at(y).at(x), "LC_" + std::to_string(z),
lc.at(i), i);
- set_config(ti, config.at(y).at(x), "NegClk", neg_clk);
+ if (dff_enable)
+ set_config(ti, config.at(y).at(x), "NegClk", neg_clk);
} else if (cell.second->type == "SB_IO") {
const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO];
unsigned pin_type = get_param_or_def(cell.second, "PIN_TYPE");
diff --git a/ice40/main.cc b/ice40/main.cc
index eb92d92f..c43bffa7 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -82,6 +82,8 @@ int main(int argc, char *argv[])
"PCF constraints file to ingest");
options.add_options()("asc", po::value<std::string>(),
"asc bitstream file to write");
+ options.add_options()("seed", po::value<int>(),
+ "seed value for random number generator");
options.add_options()("version,V", "show version");
options.add_options()("lp384", "set device type to iCE40LP384");
options.add_options()("lp1k", "set device type to iCE40LP1K");
@@ -223,8 +225,16 @@ int main(int argc, char *argv[])
pack_design(&design);
print_utilisation(&design);
+
+ int seed = 1;
+ if (vm.count("seed")) {
+ seed = vm["seed"].as<int>();
+ if (seed == 0)
+ log_error("seed must be non-zero value");
+ }
+
if (!vm.count("pack-only")) {
- place_design_sa(&design);
+ place_design_sa(&design, seed);
route_design(&design, verbose);
}
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 0b76f3f3..3e852a91 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -279,7 +279,9 @@ static void pack_io(Design *design)
static void insert_global(Design *design, NetInfo *net, bool is_reset,
bool is_cen)
{
- CellInfo *gb = create_ice_cell(design, "SB_GB");
+ std::string glb_name = net->name.str() + std::string("_$glb_") +
+ (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
+ CellInfo *gb = create_ice_cell(design, "SB_GB", "$gbuf_" + glb_name);
gb->ports["USER_SIGNAL_TO_GLOBAL_BUFFER"].net = net;
PortRef pr;
pr.cell = gb;
@@ -289,8 +291,7 @@ static void insert_global(Design *design, NetInfo *net, bool is_reset,
pr.cell = gb;
pr.port = "GLOBAL_BUFFER_OUTPUT";
NetInfo *glbnet = new NetInfo();
- glbnet->name = net->name.str() + std::string("_glb_") +
- (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
+ glbnet->name = glb_name;
glbnet->driver = pr;
design->nets[glbnet->name] = glbnet;
gb->ports["GLOBAL_BUFFER_OUTPUT"].net = glbnet;
@@ -363,19 +364,22 @@ static void promote_globals(Design *design)
++prom_resets;
clock_count.erase(rstnet->name);
reset_count.erase(rstnet->name);
-
+ cen_count.erase(rstnet->name);
} else if (global_cen->second > global_clock->second && prom_cens < 4) {
NetInfo *cennet = design->nets[global_cen->first];
insert_global(design, cennet, false, true);
++prom_globals;
++prom_cens;
- cen_count.erase(cennet->name);
clock_count.erase(cennet->name);
+ reset_count.erase(cennet->name);
+ cen_count.erase(cennet->name);
} else if (global_clock->second != 0) {
NetInfo *clknet = design->nets[global_clock->first];
insert_global(design, clknet, false, false);
++prom_globals;
clock_count.erase(clknet->name);
+ reset_count.erase(clknet->name);
+ cen_count.erase(clknet->name);
} else {
break;
}