diff options
-rw-r--r-- | common/design_utils.cc | 6 | ||||
-rw-r--r-- | common/nextpnr.cc | 123 | ||||
-rw-r--r-- | common/nextpnr.h | 8 | ||||
-rw-r--r-- | common/place_sa.cc | 1 | ||||
-rw-r--r-- | common/route.cc | 2 | ||||
-rw-r--r-- | common/timing.cc | 3 | ||||
-rw-r--r-- | dummy/arch.cc | 6 | ||||
-rw-r--r-- | dummy/arch.h | 4 | ||||
-rw-r--r-- | frontend/json/jsonparse.cc | 3 | ||||
-rw-r--r-- | ice40/arch.h | 16 | ||||
-rw-r--r-- | ice40/pack.cc | 2 |
11 files changed, 171 insertions, 3 deletions
diff --git a/common/design_utils.cc b/common/design_utils.cc index 535b6fda..fa914ee2 100644 --- a/common/design_utils.cc +++ b/common/design_utils.cc @@ -67,8 +67,10 @@ void print_utilisation(const Context *ctx) log_break(); log_info("Device utilisation:\n"); for (auto type : available_types) { - log_info("\t%20s: %5d/%5d\n", ctx->belTypeToId(type.first).c_str(ctx), - get_or_default(used_types, type.first, 0), type.second); + IdString type_id = ctx->belTypeToId(type.first); + int used_bels = get_or_default(used_types, type.first, 0); + log_info("\t%20s: %5d/%5d %5d%%\n", type_id.c_str(ctx), + used_bels, type.second, 100*used_bels/type.second); } log_break(); } diff --git a/common/nextpnr.cc b/common/nextpnr.cc index b093d855..144da7c8 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -53,4 +53,127 @@ void IdString::initialize_add(const BaseCtx *ctx, const char *s, int idx) ctx->idstring_idx_to_str->push_back(&insert_rc.first->first); } +static uint32_t xorshift32(uint32_t x) +{ + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return x; +} + +uint32_t Context::checksum() const +{ + uint32_t cksum = xorshift32(123456789); + + uint32_t cksum_nets_sum = 0; + for (auto &it : nets) + { + auto &ni = *it.second; + uint32_t x = 123456789; + x = xorshift32(x + xorshift32(it.first.index)); + x = xorshift32(x + xorshift32(ni.name.index)); + if (ni.driver.cell) + x = xorshift32(x + xorshift32(ni.driver.cell->name.index)); + x = xorshift32(x + xorshift32(ni.driver.port.index)); + x = xorshift32(x + xorshift32(getDelayChecksum(ni.driver.budget))); + + for (auto &u : ni.users) { + if (u.cell) + x = xorshift32(x + xorshift32(u.cell->name.index)); + x = xorshift32(x + xorshift32(u.port.index)); + x = xorshift32(x + xorshift32(getDelayChecksum(u.budget))); + } + + uint32_t attr_x_sum = 0; + for (auto &a : ni.attrs) { + uint32_t attr_x = 123456789; + attr_x = xorshift32(attr_x + xorshift32(a.first.index)); + for (uint8_t ch : a.second) + attr_x = xorshift32(attr_x + xorshift32(ch)); + attr_x_sum += attr_x; + } + x = xorshift32(x + xorshift32(attr_x_sum)); + + uint32_t wire_x_sum = 0; + for (auto &w : ni.wires) { + uint32_t wire_x = 123456789; + wire_x = xorshift32(wire_x + xorshift32(getWireChecksum(w.first))); + wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second))); + wire_x_sum += wire_x; + } + x = xorshift32(x + xorshift32(wire_x_sum)); + + uint32_t pip_x_sum = 0; + for (auto &p : ni.pips) { + uint32_t pip_x = 123456789; + pip_x = xorshift32(pip_x + xorshift32(getPipChecksum(p.first))); + pip_x = xorshift32(pip_x + xorshift32(p.second)); + pip_x_sum += pip_x; + } + x = xorshift32(x + xorshift32(pip_x_sum)); + + cksum_nets_sum += x; + } + cksum = xorshift32(cksum + xorshift32(cksum_nets_sum)); + + uint32_t cksum_cells_sum = 0; + for (auto &it : cells) + { + auto &ci = *it.second; + uint32_t x = 123456789; + x = xorshift32(x + xorshift32(it.first.index)); + x = xorshift32(x + xorshift32(ci.name.index)); + x = xorshift32(x + xorshift32(ci.type.index)); + + uint32_t port_x_sum = 0; + for (auto &p : ci.ports) { + uint32_t port_x = 123456789; + port_x = xorshift32(port_x + xorshift32(p.first.index)); + port_x = xorshift32(port_x + xorshift32(p.second.name.index)); + if (p.second.net) + port_x = xorshift32(port_x + xorshift32(p.second.net->name.index)); + port_x = xorshift32(port_x + xorshift32(p.second.type)); + port_x_sum += port_x; + } + x = xorshift32(x + xorshift32(port_x_sum)); + + uint32_t attr_x_sum = 0; + for (auto &a : ci.attrs) { + uint32_t attr_x = 123456789; + attr_x = xorshift32(attr_x + xorshift32(a.first.index)); + for (uint8_t ch : a.second) + attr_x = xorshift32(attr_x + xorshift32(ch)); + attr_x_sum += attr_x; + } + x = xorshift32(x + xorshift32(attr_x_sum)); + + uint32_t param_x_sum = 0; + for (auto &p : ci.params) { + uint32_t param_x = 123456789; + param_x = xorshift32(param_x + xorshift32(p.first.index)); + for (uint8_t ch : p.second) + param_x = xorshift32(param_x + xorshift32(ch)); + param_x_sum += param_x; + } + x = xorshift32(x + xorshift32(param_x_sum)); + + x = xorshift32(x + xorshift32(getBelChecksum(ci.bel))); + x = xorshift32(x + xorshift32(ci.belStrength)); + + uint32_t pin_x_sum = 0; + for (auto &a : ci.pins) { + uint32_t pin_x = 123456789; + pin_x = xorshift32(pin_x + xorshift32(a.first.index)); + pin_x = xorshift32(pin_x + xorshift32(a.second.index)); + pin_x_sum += pin_x; + } + x = xorshift32(x + xorshift32(pin_x_sum)); + + cksum_cells_sum += x; + } + cksum = xorshift32(cksum + xorshift32(cksum_cells_sum)); + + return cksum; +} + NEXTPNR_NAMESPACE_END diff --git a/common/nextpnr.h b/common/nextpnr.h index db6901fe..e52f72c2 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -302,10 +302,14 @@ struct Context : Arch { // xorshift64star // https://arxiv.org/abs/1402.6246 + + uint64_t retval = rngstate * 0x2545F4914F6CDD1D; + rngstate ^= rngstate >> 12; rngstate ^= rngstate << 25; rngstate ^= rngstate >> 27; - return rngstate * 0x2545F4914F6CDD1D; + + return retval; } int rng() { return rng64() & 0x3fffffff; } @@ -351,6 +355,8 @@ struct Context : Arch std::sort(a.begin(), a.end()); shuffle(a); } + + uint32_t checksum() const; }; NEXTPNR_NAMESPACE_END diff --git a/common/place_sa.cc b/common/place_sa.cc index 591766aa..4d0d5d08 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -480,6 +480,7 @@ bool place_design_sa(Context *ctx) { SAPlacer placer(ctx); placer.place(); + log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; } diff --git a/common/route.cc b/common/route.cc index bf11b7d2..69a314d7 100644 --- a/common/route.cc +++ b/common/route.cc @@ -480,6 +480,7 @@ bool route_design(Context *ctx) while (!netsQueue.empty()) { if (iterCnt == 200) { log_warning("giving up after %d iterations.\n", iterCnt); + log_info("Checksum: 0x%08x\n", ctx->checksum()); return false; } @@ -616,6 +617,7 @@ bool route_design(Context *ctx) } log_info("routing complete after %d iterations.\n", iterCnt); + log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; } diff --git a/common/timing.cc b/common/timing.cc index a7b37f9d..ac116711 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -78,6 +78,7 @@ static delay_t follow_net(Context *ctx, NetInfo *net, int path_length, void assign_budget(Context *ctx, float default_clock) { + log_break(); log_info("Annotating ports with timing budgets\n"); // Clear delays to a very high value first delay_t default_slack = delay_t(1.0e12 / default_clock); @@ -117,6 +118,8 @@ void assign_budget(Context *ctx, float default_clock) net.first.c_str(ctx), ctx->getDelayNS(user.budget)); } } + + log_info("Checksum: 0x%08x\n", ctx->checksum()); } NEXTPNR_NAMESPACE_END diff --git a/dummy/arch.cc b/dummy/arch.cc index 103eee4d..fa9ca473 100644 --- a/dummy/arch.cc +++ b/dummy/arch.cc @@ -34,6 +34,8 @@ BelId Arch::getBelByName(IdString name) const { return BelId(); } IdString Arch::getBelName(BelId bel) const { return IdString(); } +uint32_t Arch::getBelChecksum(BelId bel) const { return 0; } + void Arch::bindBel(BelId bel, IdString cell) {} void Arch::unbindBel(BelId bel) {} @@ -75,6 +77,8 @@ WireId Arch::getWireByName(IdString name) const { return WireId(); } IdString Arch::getWireName(WireId wire) const { return IdString(); } +uint32_t Arch::getWireChecksum(WireId wire) const { return 0; } + void Arch::bindWire(WireId wire, IdString net) {} void Arch::unbindWire(WireId wire) {} @@ -98,6 +102,8 @@ PipId Arch::getPipByName(IdString name) const { return PipId(); } IdString Arch::getPipName(PipId pip) const { return IdString(); } +uint32_t Arch::getWireChecksum(WireId wire) const { return 0; } + void Arch::bindPip(PipId pip, IdString net) {} void Arch::unbindPip(PipId pip) {} diff --git a/dummy/arch.h b/dummy/arch.h index 929c172a..d8068b22 100644 --- a/dummy/arch.h +++ b/dummy/arch.h @@ -87,6 +87,7 @@ struct Arch : BaseCtx BelId getBelByName(IdString name) const; IdString getBelName(BelId bel) const; + uint32_t getBelChecksum(BelId bel) const; void bindBel(BelId bel, IdString cell); void unbindBel(BelId bel); bool checkBelAvail(BelId bel) const; @@ -100,6 +101,7 @@ struct Arch : BaseCtx WireId getWireByName(IdString name) const; IdString getWireName(WireId wire) const; + uint32_t getWireChecksum(WireId wire) const; void bindWire(WireId wire, IdString net); void unbindWire(WireId wire); bool checkWireAvail(WireId wire) const; @@ -108,6 +110,7 @@ struct Arch : BaseCtx PipId getPipByName(IdString name) const; IdString getPipName(PipId pip) const; + uint32_t getPipChecksum(PipId pip) const; void bindPip(PipId pip, IdString net); void unbindPip(PipId pip); bool checkPipAvail(PipId pip) const; @@ -125,6 +128,7 @@ struct Arch : BaseCtx delay_t getDelayEpsilon() const { return 0.01; } delay_t getRipupDelayPenalty() const { return 1.0; } float getDelayNS(delay_t v) const { return v; } + uint32_t getDelayChecksum(delay_t v) const { return 0; } std::vector<GraphicElement> getFrameGraphics() const; std::vector<GraphicElement> getBelGraphics(BelId bel) const; diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index 32ae0953..277e602a 100644 --- a/frontend/json/jsonparse.cc +++ b/frontend/json/jsonparse.cc @@ -828,6 +828,9 @@ void parse_json_file(std::istream *&f, std::string &filename, Context *ctx) { auto *parser = new JsonParser::JsonFrontend(); parser->execute(f, filename, ctx); + + log_info("Checksum: 0x%08x\n", ctx->checksum()); + log_break(); } NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 4896736b..7778e1c5 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -515,6 +515,11 @@ struct Arch : BaseCtx return id(chip_info->bel_data[bel.index].name.get()); } + uint32_t getBelChecksum(BelId bel) const + { + return bel.index; + } + void bindBel(BelId bel, IdString cell) { assert(bel != BelId()); @@ -607,6 +612,11 @@ struct Arch : BaseCtx return id(chip_info->wire_data[wire.index].name.get()); } + uint32_t getWireChecksum(WireId wire) const + { + return wire.index; + } + void bindWire(WireId wire, IdString net) { assert(wire != WireId()); @@ -646,6 +656,11 @@ struct Arch : BaseCtx PipId getPipByName(IdString name) const; IdString getPipName(PipId pip) const; + uint32_t getPipChecksum(PipId pip) const + { + return pip.index; + } + void bindPip(PipId pip, IdString net) { assert(pip != PipId()); @@ -758,6 +773,7 @@ struct Arch : BaseCtx delay_t getDelayEpsilon() const { return 20; } delay_t getRipupDelayPenalty() const { return 200; } float getDelayNS(delay_t v) const { return v * 0.001; } + uint32_t getDelayChecksum(delay_t v) const { return v; } // ------------------------------------------------- diff --git a/ice40/pack.cc b/ice40/pack.cc index 8a6f1c45..7fcf2750 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -487,12 +487,14 @@ static void promote_globals(Context *ctx) // Main pack function bool pack_design(Context *ctx) { + log_break(); pack_constants(ctx); promote_globals(ctx); pack_io(ctx); pack_lut_lutffs(ctx); pack_nonlut_ffs(ctx); pack_ram(ctx); + log_info("Checksum: 0x%08x\n", ctx->checksum()); return true; } |