2018-06-12 21:37:28 +08:00
|
|
|
/*
|
|
|
|
* nextpnr -- Next Generation Place and Route
|
|
|
|
*
|
|
|
|
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nextpnr.h"
|
|
|
|
|
|
|
|
NEXTPNR_NAMESPACE_BEGIN
|
|
|
|
|
2018-06-19 18:08:37 +08:00
|
|
|
BaseCtx *IdString::global_ctx = nullptr;
|
2018-06-12 21:37:28 +08:00
|
|
|
|
2018-06-19 18:08:37 +08:00
|
|
|
void IdString::set(const BaseCtx *ctx, const std::string &s)
|
2018-06-12 21:37:28 +08:00
|
|
|
{
|
2018-06-18 20:53:01 +08:00
|
|
|
auto it = ctx->idstring_str_to_idx->find(s);
|
|
|
|
if (it == ctx->idstring_str_to_idx->end()) {
|
|
|
|
index = ctx->idstring_idx_to_str->size();
|
|
|
|
auto insert_rc = ctx->idstring_str_to_idx->insert({s, index});
|
|
|
|
ctx->idstring_idx_to_str->push_back(&insert_rc.first->first);
|
|
|
|
} else {
|
|
|
|
index = it->second;
|
|
|
|
}
|
2018-06-12 21:50:33 +08:00
|
|
|
}
|
|
|
|
|
2018-06-19 18:08:37 +08:00
|
|
|
const std::string &IdString::str(const BaseCtx *ctx) const
|
2018-06-12 21:50:33 +08:00
|
|
|
{
|
2018-06-18 20:53:01 +08:00
|
|
|
return *ctx->idstring_idx_to_str->at(index);
|
|
|
|
}
|
|
|
|
|
2018-06-19 18:08:37 +08:00
|
|
|
const char *IdString::c_str(const BaseCtx *ctx) const
|
2018-06-18 21:53:18 +08:00
|
|
|
{
|
|
|
|
return str(ctx).c_str();
|
|
|
|
}
|
2018-06-18 20:53:01 +08:00
|
|
|
|
2018-06-19 18:08:37 +08:00
|
|
|
void IdString::initialize_add(const BaseCtx *ctx, const char *s, int idx)
|
2018-06-18 20:53:01 +08:00
|
|
|
{
|
|
|
|
assert(ctx->idstring_str_to_idx->count(s) == 0);
|
|
|
|
assert(int(ctx->idstring_idx_to_str->size()) == idx);
|
|
|
|
auto insert_rc = ctx->idstring_str_to_idx->insert({s, idx});
|
|
|
|
ctx->idstring_idx_to_str->push_back(&insert_rc.first->first);
|
2018-06-12 21:37:28 +08:00
|
|
|
}
|
|
|
|
|
2018-06-21 21:47:41 +08:00
|
|
|
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;
|
2018-06-22 01:36:20 +08:00
|
|
|
for (auto &it : nets) {
|
2018-06-21 21:47:41 +08:00
|
|
|
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;
|
2018-06-22 01:36:20 +08:00
|
|
|
for (auto &it : cells) {
|
2018-06-21 21:47:41 +08:00
|
|
|
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)
|
2018-06-22 01:36:20 +08:00
|
|
|
port_x = xorshift32(port_x +
|
|
|
|
xorshift32(p.second.net->name.index));
|
2018-06-21 21:47:41 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-06-12 21:37:28 +08:00
|
|
|
NEXTPNR_NAMESPACE_END
|