aboutsummaryrefslogtreecommitdiffstats
path: root/mistral
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2022-02-18 10:52:37 +0000
committergatecat <gatecat@ds0.me>2022-02-18 11:13:18 +0000
commit6a32aca4ac8705b637943c236cedd2f36422fb21 (patch)
tree28483964fb3c92bc104ab6162d1c9196651ced26 /mistral
parent61d1db16be2c68cf6ae8b4d2ff3266b5c7086ad2 (diff)
downloadnextpnr-6a32aca4ac8705b637943c236cedd2f36422fb21.tar.gz
nextpnr-6a32aca4ac8705b637943c236cedd2f36422fb21.tar.bz2
nextpnr-6a32aca4ac8705b637943c236cedd2f36422fb21.zip
refactor: New member functions to replace design_utils
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'mistral')
-rw-r--r--mistral/bitstream.cc9
-rw-r--r--mistral/lab.cc46
-rw-r--r--mistral/pack.cc42
3 files changed, 48 insertions, 49 deletions
diff --git a/mistral/bitstream.cc b/mistral/bitstream.cc
index e18d1413..35c1303a 100644
--- a/mistral/bitstream.cc
+++ b/mistral/bitstream.cc
@@ -86,8 +86,7 @@ struct MistralBitgen
void write_io_cell(CellInfo *ci, int x, int y, int bi)
{
- bool is_output =
- (ci->type == id_MISTRAL_OB || (ci->type == id_MISTRAL_IO && get_net_or_empty(ci, id_OE) != nullptr));
+ bool is_output = (ci->type == id_MISTRAL_OB || (ci->type == id_MISTRAL_IO && ci->getPort(id_OE) != nullptr));
auto pos = CycloneV::xy2pos(x, y);
// TODO: configurable pull, IO standard, etc
cv->bmux_b_set(CycloneV::GPIO, pos, CycloneV::USE_WEAK_PULLUP, bi, false);
@@ -229,8 +228,8 @@ struct MistralBitgen
cv->bmux_m_set(block_type, pos, clk_sel[i / 2], alm, clk_choice[ce_idx]);
if (ff->ffInfo.ctrlset.clk.inverted)
cv->bmux_b_set(block_type, pos, clk_inv[ce_idx], 0, true);
- if (get_net_or_empty(ff, id_ENA) != nullptr) { // not using ffInfo.ctrlset, this has a fake net always to
- // ensure different constants don't collide
+ if (ff->getPort(id_ENA) != nullptr) { // not using ffInfo.ctrlset, this has a fake net always to
+ // ensure different constants don't collide
cv->bmux_b_set(block_type, pos, en_en[ce_idx], 0, true);
cv->bmux_b_set(block_type, pos, en_ninv[ce_idx], 0, ff->ffInfo.ctrlset.ena.inverted);
} else {
@@ -262,7 +261,7 @@ struct MistralBitgen
cv->bmux_m_set(block_type, pos, clk_sel[1], alm, clk_choice[ce_idx]);
if (lut->combInfo.wclk.inverted)
cv->bmux_b_set(block_type, pos, clk_inv[ce_idx], 0, true);
- if (get_net_or_empty(lut, id_A1EN) != nullptr) {
+ if (lut->getPort(id_A1EN) != nullptr) {
cv->bmux_b_set(block_type, pos, en_en[ce_idx], 0, true);
cv->bmux_b_set(block_type, pos, en_ninv[ce_idx], 0, lut->combInfo.we.inverted);
} else {
diff --git a/mistral/lab.cc b/mistral/lab.cc
index 4f6b9b00..4b66ed0c 100644
--- a/mistral/lab.cc
+++ b/mistral/lab.cc
@@ -212,7 +212,7 @@ namespace {
ControlSig get_ctrlsig(const Context *ctx, const CellInfo *cell, IdString port, bool explicit_const = false)
{
ControlSig result;
- result.net = get_net_or_empty(cell, port);
+ result.net = cell->getPort(port);
if (result.net == nullptr && explicit_const) {
// For ENA, 1 (and 0) are explicit control set choices even though they aren't routed, as "no ENA" still
// consumes a clock+ENA pair
@@ -278,10 +278,10 @@ void Arch::assign_comb_info(CellInfo *cell) const
cell->combInfo.lut_input_count = 5;
cell->combInfo.lut_bits_count = 32;
for (int i = 0; i < 5; i++)
- cell->combInfo.lut_in[i] = get_net_or_empty(cell, id(stringf("B1ADDR[%d]", i)));
+ cell->combInfo.lut_in[i] = cell->getPort(id(stringf("B1ADDR[%d]", i)));
auto key = get_mlab_key(cell);
cell->combInfo.mlab_group = mlab_groups(key);
- cell->combInfo.comb_out = get_net_or_empty(cell, id_B1DATA);
+ cell->combInfo.comb_out = cell->getPort(id_B1DATA);
} else if (cell->type == id_MISTRAL_ALUT_ARITH) {
cell->combInfo.is_carry = true;
cell->combInfo.lut_input_count = 5;
@@ -292,14 +292,14 @@ void Arch::assign_comb_info(CellInfo *cell) const
{
int i = 0;
for (auto pin : arith_pins) {
- cell->combInfo.lut_in[i++] = get_net_or_empty(cell, pin);
+ cell->combInfo.lut_in[i++] = cell->getPort(pin);
}
}
- const NetInfo *ci = get_net_or_empty(cell, id_CI);
- const NetInfo *co = get_net_or_empty(cell, id_CO);
+ const NetInfo *ci = cell->getPort(id_CI);
+ const NetInfo *co = cell->getPort(id_CO);
- cell->combInfo.comb_out = get_net_or_empty(cell, id_SO);
+ cell->combInfo.comb_out = cell->getPort(id_SO);
cell->combInfo.carry_start = (ci == nullptr) || (ci->driver.cell == nullptr);
cell->combInfo.carry_end = (co == nullptr) || (co->users.empty());
@@ -308,10 +308,10 @@ void Arch::assign_comb_info(CellInfo *cell) const
const CellInfo *prev = ci->driver.cell;
if (prev != nullptr) {
for (int i = 0; i < 5; i++) {
- const NetInfo *a = get_net_or_empty(cell, arith_pins[i]);
+ const NetInfo *a = cell->getPort(arith_pins[i]);
if (a == nullptr)
continue;
- const NetInfo *b = get_net_or_empty(prev, arith_pins[i]);
+ const NetInfo *b = prev->getPort(arith_pins[i]);
if (a == b)
++cell->combInfo.chain_shared_input_count;
}
@@ -323,28 +323,28 @@ void Arch::assign_comb_info(CellInfo *cell) const
switch (cell->type.index) {
case ID_MISTRAL_ALUT6:
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[5] = get_net_or_empty(cell, id_F);
+ cell->combInfo.lut_in[5] = cell->getPort(id_F);
[[fallthrough]];
case ID_MISTRAL_ALUT5:
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[4] = get_net_or_empty(cell, id_E);
+ cell->combInfo.lut_in[4] = cell->getPort(id_E);
[[fallthrough]];
case ID_MISTRAL_ALUT4:
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[3] = get_net_or_empty(cell, id_D);
+ cell->combInfo.lut_in[3] = cell->getPort(id_D);
[[fallthrough]];
case ID_MISTRAL_ALUT3:
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[2] = get_net_or_empty(cell, id_C);
+ cell->combInfo.lut_in[2] = cell->getPort(id_C);
[[fallthrough]];
case ID_MISTRAL_ALUT2:
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[1] = get_net_or_empty(cell, id_B);
+ cell->combInfo.lut_in[1] = cell->getPort(id_B);
[[fallthrough]];
case ID_MISTRAL_BUF: // used to route through to FFs etc
case ID_MISTRAL_NOT: // used for inverters that map to LUTs
++cell->combInfo.lut_input_count;
- cell->combInfo.lut_in[0] = get_net_or_empty(cell, id_A);
+ cell->combInfo.lut_in[0] = cell->getPort(id_A);
[[fallthrough]];
case ID_MISTRAL_CONST:
// MISTRAL_CONST is a nextpnr-inserted cell type for 0-input, constant-generating LUTs
@@ -375,8 +375,8 @@ void Arch::assign_ff_info(CellInfo *cell) const
cell->ffInfo.ctrlset.sload.inverted = false;
}
- cell->ffInfo.sdata = get_net_or_empty(cell, id_SDATA);
- cell->ffInfo.datain = get_net_or_empty(cell, id_DATAIN);
+ cell->ffInfo.sdata = cell->getPort(id_SDATA);
+ cell->ffInfo.datain = cell->getPort(id_DATAIN);
}
// Validity checking functions
@@ -883,7 +883,7 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm)
auto &bel_pins = luts[i]->pin_data[log].bel_pins;
bel_pins.clear();
- NetInfo *net = get_net_or_empty(luts[i], log);
+ NetInfo *net = luts[i]->getPort(log);
if (net == nullptr) {
// Disconnected inputs don't need to be allocated a pin, because the router won't be routing these
continue;
@@ -922,10 +922,10 @@ void Arch::reassign_alm_inputs(uint32_t lab, uint8_t alm)
rt_lut->addInput(id_A);
rt_lut->addOutput(id_Q);
// Disconnect the original data input to the FF, and connect it to the route-thru LUT instead
- NetInfo *datain = get_net_or_empty(ff, id_DATAIN);
- disconnect_port(getCtx(), ff, id_DATAIN);
- connect_port(getCtx(), datain, rt_lut, id_A);
- connect_ports(getCtx(), rt_lut, id_Q, ff, id_DATAIN);
+ NetInfo *datain = ff->getPort(id_DATAIN);
+ ff->disconnectPort(id_DATAIN);
+ rt_lut->connectPort(id_A, datain);
+ rt_lut->connectPorts(id_Q, ff, id_DATAIN);
// Assign route-thru LUT physical ports, input goes to the first half-specific input
rt_lut->pin_data[id_A].bel_pins.push_back(i ? id_D : id_C);
rt_lut->pin_data[id_Q].bel_pins.push_back(id_COMBOUT);
@@ -1050,7 +1050,7 @@ uint64_t Arch::compute_lut_mask(uint32_t lab, uint8_t alm)
else if (state == PIN_1)
index |= (1 << init_idx);
// Ignore if no associated physical pin
- if (get_net_or_empty(lut, log_pin) == nullptr || lut->pin_data.at(log_pin).bel_pins.empty())
+ if (lut->getPort(log_pin) == nullptr || lut->pin_data.at(log_pin).bel_pins.empty())
continue;
// ALM inputs appear to be inverted by default (TODO: check!)
// so only invert if an inverter has _not_ been folded into the pin
diff --git a/mistral/pack.cc b/mistral/pack.cc
index 4b434015..c4b3afe3 100644
--- a/mistral/pack.cc
+++ b/mistral/pack.cc
@@ -41,13 +41,13 @@ struct MistralPacker
vcc_drv->addOutput(id_Q);
gnd_net = ctx->createNet(ctx->id("$PACKER_GND_NET"));
vcc_net = ctx->createNet(ctx->id("$PACKER_VCC_NET"));
- connect_port(ctx, gnd_net, gnd_drv, id_Q);
- connect_port(ctx, vcc_net, vcc_drv, id_Q);
+ gnd_drv->connectPort(id_Q, gnd_net);
+ vcc_drv->connectPort(id_Q, vcc_net);
}
CellPinState get_pin_needed_muxval(CellInfo *cell, IdString port)
{
- NetInfo *net = get_net_or_empty(cell, port);
+ NetInfo *net = cell->getPort(port);
if (net == nullptr || net->driver.cell == nullptr) {
// Pin is disconnected
// If a mux value exists already, honour it
@@ -78,14 +78,14 @@ struct MistralPacker
void uninvert_port(CellInfo *cell, IdString port)
{
// Rewire a port so it is driven by the input to an inverter
- NetInfo *net = get_net_or_empty(cell, port);
+ NetInfo *net = cell->getPort(port);
NPNR_ASSERT(net != nullptr && net->driver.cell != nullptr && net->driver.cell->type == id_MISTRAL_NOT);
CellInfo *inv = net->driver.cell;
- disconnect_port(ctx, cell, port);
+ cell->disconnectPort(port);
- NetInfo *inv_a = get_net_or_empty(inv, id_A);
+ NetInfo *inv_a = inv->getPort(id_A);
if (inv_a != nullptr) {
- connect_port(ctx, inv_a, cell, port);
+ cell->connectPort(port, inv_a);
}
}
@@ -117,12 +117,12 @@ struct MistralPacker
// Pin is tied to a constant
// If there is a hard constant option; use it
if ((pin_style & int(req_mux)) == req_mux) {
- disconnect_port(ctx, cell, port_name);
+ cell->disconnectPort(port_name);
cell->pin_data[port_name].state = req_mux;
} else {
- disconnect_port(ctx, cell, port_name);
+ cell->disconnectPort(port_name);
// There is no hard constant, we need to connect it to the relevant soft-constant net
- connect_port(ctx, (req_mux == PIN_1) ? vcc_net : gnd_net, cell, port_name);
+ cell->connectPort(port_name, (req_mux == PIN_1) ? vcc_net : gnd_net);
}
}
}
@@ -138,7 +138,7 @@ struct MistralPacker
if (ci->type != id_MISTRAL_NOT && ci->type != id_GND && ci->type != id_VCC)
continue;
IdString port = (ci->type == id_MISTRAL_NOT) ? id_Q : id_Y;
- NetInfo *out = get_net_or_empty(ci, port);
+ NetInfo *out = ci->getPort(port);
if (out == nullptr) {
trim_cells.push_back(ci->name);
continue;
@@ -146,7 +146,7 @@ struct MistralPacker
if (!out->users.empty())
continue;
- disconnect_port(ctx, ci, id_A);
+ ci->disconnectPort(id_A);
trim_cells.push_back(ci->name);
trim_nets.push_back(out->name);
@@ -174,7 +174,7 @@ struct MistralPacker
continue;
if (ci->get_pin_state(id_SLOAD) != PIN_0)
continue;
- disconnect_port(ctx, ci, id_SDATA);
+ ci->disconnectPort(id_SDATA);
}
// Remove superfluous inverters and constant drivers
trim_design();
@@ -197,7 +197,7 @@ struct MistralPacker
if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) {
// Might have an input buffer (IB etc) connected to it
is_npnr_iob = true;
- NetInfo *o = get_net_or_empty(ci, id_O);
+ NetInfo *o = ci->getPort(id_O);
if (o == nullptr)
;
else if (o->users.size() > 1)
@@ -208,7 +208,7 @@ struct MistralPacker
if (ci->type == ctx->id("$nextpnr_obuf") || ci->type == ctx->id("$nextpnr_iobuf")) {
// Might have an output buffer (OB etc) connected to it
is_npnr_iob = true;
- NetInfo *i = get_net_or_empty(ci, id_I);
+ NetInfo *i = ci->getPort(id_I);
if (i != nullptr && i->driver.cell != nullptr) {
if (top_port.cell != nullptr)
log_error("Top level pin '%s' has multiple input/output buffers\n", ctx->nameOf(port.first));
@@ -245,8 +245,8 @@ struct MistralPacker
port.second.net = top_port.cell->ports.at(top_port.port).net;
}
// Now remove the nextpnr-inserted buffer
- disconnect_port(ctx, ci, id_I);
- disconnect_port(ctx, ci, id_O);
+ ci->disconnectPort(id_I);
+ ci->disconnectPort(id_O);
ctx->cells.erase(port.first);
}
}
@@ -290,14 +290,14 @@ struct MistralPacker
CellInfo *ci = cell.second.get();
if (ci->type != id_MISTRAL_ALUT_ARITH)
continue;
- const NetInfo *cin = get_net_or_empty(ci, id_CI);
+ const NetInfo *cin = ci->getPort(id_CI);
if (cin != nullptr && cin->driver.cell != nullptr)
continue; // not the start of a chain
std::vector<CellInfo *> chain;
CellInfo *cursor = ci;
while (true) {
chain.push_back(cursor);
- const NetInfo *co = get_net_or_empty(cursor, id_CO);
+ const NetInfo *co = cursor->getPort(id_CO);
if (co == nullptr || co->users.empty())
break;
if (co->users.size() > 1)
@@ -327,7 +327,7 @@ struct MistralPacker
for (int i = 0; i < int(chain.size()); i++) {
auto &c = chain.at(i);
log_info(" i=%d cell=%s dy=%d z=%d ci=%s co=%s\n", i, ctx->nameOf(c), c->constr_y, c->constr_z,
- ctx->nameOf(get_net_or_empty(c, id_CI)), ctx->nameOf(get_net_or_empty(c, id_CO)));
+ ctx->nameOf(c->getPort(id_CI)), ctx->nameOf(c->getPort(id_CO)));
}
}
}
@@ -338,7 +338,7 @@ struct MistralPacker
continue;
if (ci->cluster == ClusterId())
log_error("Failed to include arith cell '%s' in any chain (CI=%s)\n", ctx->nameOf(ci),
- ctx->nameOf(get_net_or_empty(ci, id_CI)));
+ ctx->nameOf(ci->getPort(id_CI)));
}
}