From 681c9654d7c49d407a999b2b03c980d66bcefd8f Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 17 Jun 2018 14:36:19 +0200 Subject: place_sa: Add a rip-up feature when initial placement fails Signed-off-by: David Shah --- ice40/arch_place.cc | 3 ++- ice40/pack.cc | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'ice40') diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 1c6361a1..276a9378 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -38,7 +38,8 @@ static bool logicCellsCompatible(const std::vector &cells) { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; - std::unordered_set locals; + static std::unordered_set locals; + locals.clear(); for (auto cell : cells) { if (bool_or_default(cell->params, "DFF_ENABLE")) { diff --git a/ice40/pack.cc b/ice40/pack.cc index 0b76f3f3..6840d8d1 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; } -- cgit v1.2.3 From 748171dae29c65182e6360a12a9e2bdbbfc35163 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 17 Jun 2018 15:04:53 +0200 Subject: place_sa: Adding seed option Signed-off-by: David Shah --- ice40/main.cc | 12 +++++++++++- ice40/pack.cc | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'ice40') 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(), "asc bitstream file to write"); + options.add_options()("seed", po::value(), + "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(); + 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 6840d8d1..3e852a91 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -280,7 +280,7 @@ static void insert_global(Design *design, NetInfo *net, bool is_reset, bool is_cen) { std::string glb_name = net->name.str() + std::string("_$glb_") + - (is_reset ? "sr" : (is_cen ? "ce" : "clk")); + (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; -- cgit v1.2.3 From f723aaa373e188a4c926eff07c4c63b0d8467e0e Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 17 Jun 2018 15:21:35 +0200 Subject: ice40: Fixing negative clock bitstream generation Signed-off-by: David Shah --- ice40/bitstream.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'ice40') diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 9309a7da..23cd6af1 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -19,6 +19,7 @@ */ #include "bitstream.h" #include +#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") { TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; unsigned pin_type = get_param_or_def(cell.second, "PIN_TYPE"); -- cgit v1.2.3 From f66999a8830c5829872b93ce15491de1673cb4e3 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 17 Jun 2018 16:03:16 +0200 Subject: Minor performance tweaks and fixes Signed-off-by: David Shah --- ice40/arch_place.cc | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'ice40') diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 276a9378..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,47 +38,53 @@ static bool logicCellsCompatible(const std::vector &cells) { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; - static std::unordered_set locals; + static std::unordered_set 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; } -- cgit v1.2.3