3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-11 13:17:54 +02:00
parent f592f2f3af
commit 8e522b08c0
206 changed files with 3081 additions and 2782 deletions

View file

@ -94,7 +94,7 @@ struct AigMaker
int inport(TwineRef portname, int portbit = 0, bool inverter = false)
{
if (portbit >= GetSize(cell->getPort(portname))) {
if (cell->parameters.count(portname.str() + "_SIGNED") && cell->getParam(portname.str() + "_SIGNED").as_bool())
if (cell->parameters.count(cell->module->design->twines.str(portname) + "_SIGNED") && cell->getParam(cell->module->design->twines.str(portname) + "_SIGNED").as_bool())
return inport(portname, GetSize(cell->getPort(portname))-1, inverter);
return bool_node(inverter);
}
@ -247,7 +247,7 @@ struct AigMaker
void outport(int node, TwineRef portname, int portbit = 0)
{
if (portbit < GetSize(cell->getPort(portname)))
aig->nodes.at(node).outports.push_back(pair<IdString, int>(portname, portbit));
aig->nodes.at(node).outports.push_back(pair<TwineRef, int>(portname, portbit));
}
void outport_bool(int node, TwineRef portname)
@ -305,9 +305,9 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_)))
{
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(ID::A, i);
int A = mk.inport(TW::A, i);
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
mk.outport(Y, ID::Y, i);
mk.outport(Y, TW::Y, i);
}
goto optimize;
}
@ -315,8 +315,8 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
{
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(ID::A, i);
int B = mk.inport(ID::B, i);
int A = mk.inport(TW::A, i);
int B = mk.inport(TW::B, i);
int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) :
cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) :
cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) :
@ -325,30 +325,30 @@ Aig::Aig(Cell *cell)
cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) :
cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) :
cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
mk.outport(Y, ID::Y, i);
mk.outport(Y, TW::Y, i);
}
goto optimize;
}
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_)))
{
int S = mk.inport(ID::S);
int S = mk.inport(TW::S);
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(ID::A, i);
int B = mk.inport(ID::B, i);
int A = mk.inport(TW::A, i);
int B = mk.inport(TW::B, i);
int Y = mk.mux_gate(A, B, S);
if (cell->type == ID($_NMUX_))
Y = mk.not_gate(Y);
mk.outport(Y, ID::Y, i);
mk.outport(Y, TW::Y, i);
}
goto optimize;
}
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)))
{
int Y = mk.inport(ID::A, 0);
int Y = mk.inport(TW::A, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++) {
int A = mk.inport(ID::A, i);
int A = mk.inport(TW::A, i);
if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y);
if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y);
if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y);
@ -357,35 +357,35 @@ Aig::Aig(Cell *cell)
}
if (cell->type == ID($reduce_xnor))
Y = mk.not_gate(Y);
mk.outport(Y, ID::Y, 0);
mk.outport(Y, TW::Y, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
mk.outport(mk.bool_node(false), ID::Y, i);
mk.outport(mk.bool_node(false), TW::Y, i);
goto optimize;
}
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
{
int A = mk.inport(ID::A, 0), Y = -1;
int A = mk.inport(TW::A, 0), Y = -1;
for (int i = 1; i < GetSize(cell->getPort(TW::A)); i++)
A = mk.or_gate(mk.inport(ID::A, i), A);
A = mk.or_gate(mk.inport(TW::A, i), A);
if (cell->type.in(ID($logic_and), ID($logic_or))) {
int B = mk.inport(ID::B, 0);
int B = mk.inport(TW::B, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++)
B = mk.or_gate(mk.inport(ID::B, i), B);
B = mk.or_gate(mk.inport(TW::B, i), B);
if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B);
if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B);
} else {
if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
}
mk.outport_bool(Y, ID::Y);
mk.outport_bool(Y, TW::Y);
goto optimize;
}
if (cell->type.in(ID($add), ID($sub)))
{
int width = GetSize(cell->getPort(TW::Y));
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width);
int carry = mk.bool_node(false);
if (cell->type == ID($sub)) {
for (auto &n : B)
@ -393,7 +393,7 @@ Aig::Aig(Cell *cell)
carry = mk.not_gate(carry);
}
vector<int> Y = mk.adder(A, B, carry);
mk.outport_vec(Y, ID::Y);
mk.outport_vec(Y, TW::Y);
goto optimize;
}
@ -401,8 +401,8 @@ Aig::Aig(Cell *cell)
{
int width = std::max(GetSize(cell->getPort(TW::A)),
GetSize(cell->getPort(TW::B))) + 1;
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width);
if (cell->type.in(ID($gt), ID($ge)))
std::swap(A, B);
@ -411,86 +411,86 @@ Aig::Aig(Cell *cell)
for (auto &n : B)
n = mk.not_gate(n);
vector<int> Y = mk.adder(A, B, carry);
mk.outport(Y.back(), ID::Y);
mk.outport(Y.back(), TW::Y);
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
mk.outport(mk.bool_node(false), ID::Y, i);
mk.outport(mk.bool_node(false), TW::Y, i);
goto optimize;
}
if (cell->type == ID($alu))
{
int width = GetSize(cell->getPort(TW::Y));
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
int carry = mk.inport(ID::CI);
int binv = mk.inport(ID::BI);
vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width);
int carry = mk.inport(TW::CI);
int binv = mk.inport(TW::BI);
for (auto &n : B)
n = mk.xor_gate(n, binv);
vector<int> X(width), CO(width);
vector<int> Y = mk.adder(A, B, carry, &X, &CO);
for (int i = 0; i < width; i++)
X[i] = mk.xor_gate(A[i], B[i]);
mk.outport_vec(Y, ID::Y);
mk.outport_vec(X, ID::X);
mk.outport_vec(CO, ID::CO);
mk.outport_vec(Y, TW::Y);
mk.outport_vec(X, TW::X);
mk.outport_vec(CO, TW::CO);
goto optimize;
}
if (cell->type.in(ID($eq), ID($ne)))
{
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
vector<int> A = mk.inport_vec(TW::A, width);
vector<int> B = mk.inport_vec(TW::B, width);
int Y = mk.bool_node(false);
for (int i = 0; i < width; i++)
Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i]));
if (cell->type == ID($eq))
Y = mk.not_gate(Y);
mk.outport_bool(Y, ID::Y);
mk.outport_bool(Y, TW::Y);
goto optimize;
}
if (cell->type == ID($_AOI3_))
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID::C);
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
int C = mk.inport(TW::C);
int Y = mk.nor_gate(mk.and_gate(A, B), C);
mk.outport(Y, ID::Y);
mk.outport(Y, TW::Y);
goto optimize;
}
if (cell->type == ID($_OAI3_))
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID::C);
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
int C = mk.inport(TW::C);
int Y = mk.nand_gate(mk.or_gate(A, B), C);
mk.outport(Y, ID::Y);
mk.outport(Y, TW::Y);
goto optimize;
}
if (cell->type == ID($_AOI4_))
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID::C);
int D = mk.inport(ID::D);
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
int C = mk.inport(TW::C);
int D = mk.inport(TW::D);
int a_and_b = mk.and_gate(A, B);
int Y = mk.nor_gate(a_and_b, mk.and_gate(C, D));
mk.outport(Y, ID::Y);
mk.outport(Y, TW::Y);
goto optimize;
}
if (cell->type == ID($_OAI4_))
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
int C = mk.inport(ID::C);
int D = mk.inport(ID::D);
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
int C = mk.inport(TW::C);
int D = mk.inport(TW::D);
int a_or_b = mk.or_gate(A, B);
int Y = mk.nand_gate(a_or_b, mk.or_gate(C, D));
mk.outport(Y, ID::Y);
mk.outport(Y, TW::Y);
goto optimize;
}

View file

@ -30,7 +30,7 @@ struct AigNode
int portbit;
bool inverter;
int left_parent, right_parent;
vector<pair<IdString, int>> outports;
vector<pair<TwineRef, int>> outports;
AigNode();
bool operator==(const AigNode &other) const;

View file

@ -31,9 +31,9 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
else if (is_signed && a_width > 0)
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
db->add_edge(cell, TW::A, a_width-1, TW::Y, i, -1);
}
}
@ -54,14 +54,14 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
else if (is_signed && a_width > 0)
db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
db->add_edge(cell, TW::A, a_width-1, TW::Y, i, -1);
if (i < b_width)
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
else if (is_signed && b_width > 0)
db->add_edge(cell, ID::B, b_width-1, ID::Y, i, -1);
db->add_edge(cell, TW::B, b_width-1, TW::Y, i, -1);
}
}
@ -76,7 +76,7 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++)
for (int k = 0; k <= i && k < a_width; k++)
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
}
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -96,10 +96,10 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int k = 0; k <= i; k++)
{
if (k < a_width)
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
if (k < b_width)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
}
}
}
@ -109,7 +109,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int a_width = GetSize(cell->getPort(TW::A));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
}
void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -118,9 +118,9 @@ void logic_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
db->add_edge(cell, TW::B, i, TW::Y, 0, -1);
}
void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -129,9 +129,9 @@ void concat_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, ID::B, i, ID::Y, a_width + i, -1);
db->add_edge(cell, TW::B, i, TW::Y, a_width + i, -1);
}
void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -143,7 +143,7 @@ void slice_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++) {
int a_bit = offset + i;
if (a_bit >= 0 && a_bit < a_width)
db->add_edge(cell, ID::A, a_bit, ID::Y, i, -1);
db->add_edge(cell, TW::A, a_bit, TW::Y, i, -1);
}
}
@ -153,10 +153,10 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B));
for (int i = 0; i < a_width; i++)
db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
db->add_edge(cell, TW::A, i, TW::Y, 0, -1);
for (int i = 0; i < b_width; i++)
db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
db->add_edge(cell, TW::B, i, TW::Y, 0, -1);
}
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -167,13 +167,13 @@ void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < a_width; i++)
{
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
for (int k = i; k < b_width; k += a_width)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
for (int k = 0; k < s_width; k++)
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
}
}
@ -186,10 +186,10 @@ void bmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < width; i++)
{
for (int k = i; k < a_width; k += width)
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
for (int k = 0; k < s_width; k++)
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
}
}
@ -201,9 +201,9 @@ void demux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < width; i++)
{
db->add_edge(cell, ID::A, i % a_width, ID::Y, i, -1);
db->add_edge(cell, TW::A, i % a_width, TW::Y, i, -1);
for (int k = 0; k < s_width; k++)
db->add_edge(cell, ID::S, k, ID::Y, i, -1);
db->add_edge(cell, TW::S, k, TW::Y, i, -1);
}
}
@ -275,11 +275,11 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
if (i < b_range_upper) {
for (int k = a_range_lower; k < a_range_upper; k++)
db->add_edge(cell, ID::A, k, ID::Y, i, -1);
db->add_edge(cell, TW::A, k, TW::Y, i, -1);
} else {
// only influence is through sign extension
if (is_signed)
db->add_edge(cell, ID::A, a_width - 1, ID::Y, i, -1);
db->add_edge(cell, TW::A, a_width - 1, TW::Y, i, -1);
}
for (int k = 0; k < b_width_capped; k++) {
@ -289,13 +289,13 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int skip = 1 << (k + 1);
int base = skip -1;
if (i % skip != base && i - a_width + 2 < 1 << b_width_capped)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else if (is_signed) {
if (i - a_width + 2 < 1 << b_width_capped)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else {
if (i - a_width + 1 < 1 << b_width_capped)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
}
// right shifts
} else if (cell->type.in(ID($shr), ID($sshr)) || (cell->type.in(ID($shift), ID($shiftx)) && !is_b_signed)) {
@ -306,10 +306,10 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
&& (((y_width - i) & ~(1 << k)) < (1 << b_width_capped)));
if (shift_in_bulk || (cell->type.in(ID($shr), ID($shift), ID($shiftx)) && zpad_jump))
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else {
if (i < a_width)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
}
// bidirectional shifts (positive B shifts right, negative left)
} else if (cell->type.in(ID($shift), ID($shiftx)) && is_b_signed) {
@ -326,14 +326,14 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
l = l && (~(i - a_width) & ((1 << (k + 1)) - 1)) != 0;
}
if (r_shift_in_bulk || r_zpad_jump || l)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else {
if (y_width - i <= b_high || a_width - 2 - i >= b_low)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
}
} else {
if (a_width - 1 - i >= b_low)
db->add_edge(cell, ID::B, k, ID::Y, i, -1);
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
}
} else {
log_assert(false && "unreachable");
@ -353,14 +353,14 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < n_rd_ports; i++) {
if (rd_clk_enable[i] != State::S0) {
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::RD_ARST, i, ID::RD_DATA, i * width + k, -1);
db->add_edge(cell, TW::RD_ARST, i, TW::RD_DATA, i * width + k, -1);
continue;
}
for (int j = 0; j < abits; j++)
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::RD_ADDR, i * abits + j,
ID::RD_DATA, i * width + k, -1);
db->add_edge(cell, TW::RD_ADDR, i * abits + j,
TW::RD_DATA, i * width + k, -1);
}
}
@ -373,14 +373,14 @@ void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
if (cell->type == ID($memrd_v2)) {
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::ARST, 0, ID::DATA, k, -1);
db->add_edge(cell, TW::ARST, 0, TW::DATA, k, -1);
}
return;
}
for (int j = 0; j < abits; j++)
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::ADDR, j, ID::DATA, k, -1);
db->add_edge(cell, TW::ADDR, j, TW::DATA, k, -1);
}
void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
@ -401,32 +401,32 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) {
for (int k = 0; k < width; k++) {
db->add_edge(cell, ID::D, k, ID::Q, k, -1);
db->add_edge(cell, ID::EN, 0, ID::Q, k, -1);
db->add_edge(cell, TW::D, k, TW::Q, k, -1);
db->add_edge(cell, TW::EN, 0, TW::Q, k, -1);
}
}
if (cell->hasPort(ID::CLR))
if (cell->hasPort(TW::CLR))
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::CLR, 0, ID::Q, k, -1);
if (cell->hasPort(ID::SET))
db->add_edge(cell, TW::CLR, 0, TW::Q, k, -1);
if (cell->hasPort(TW::SET))
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::SET, 0, ID::Q, k, -1);
if (cell->hasPort(ID::ALOAD))
db->add_edge(cell, TW::SET, 0, TW::Q, k, -1);
if (cell->hasPort(TW::ALOAD))
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::ALOAD, 0, ID::Q, k, -1);
if (cell->hasPort(ID::AD))
db->add_edge(cell, TW::ALOAD, 0, TW::Q, k, -1);
if (cell->hasPort(TW::AD))
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::AD, k, ID::Q, k, -1);
if (cell->hasPort(ID::ARST))
db->add_edge(cell, TW::AD, k, TW::Q, k, -1);
if (cell->hasPort(TW::ARST))
for (int k = 0; k < width; k++)
db->add_edge(cell, ID::ARST, 0, ID::Q, k, -1);
db->add_edge(cell, TW::ARST, 0, TW::Q, k, -1);
}
void full_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
std::vector<RTLIL::IdString> input_ports;
std::vector<RTLIL::IdString> output_ports;
std::vector<TwineRef> input_ports;
std::vector<TwineRef> output_ports;
for (auto &conn : cell->connections())
{
@ -461,8 +461,8 @@ void bweqx_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int max_width = std::min(width, std::min(a_width, b_width));
for (int i = 0; i < max_width; i++) {
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
}
}
@ -475,9 +475,9 @@ void bwmux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int max_width = std::min(width, std::min(a_width, std::min(b_width, s_width)));
for (int i = 0; i < max_width; i++) {
db->add_edge(cell, ID::A, i, ID::Y, i, -1);
db->add_edge(cell, ID::B, i, ID::Y, i, -1);
db->add_edge(cell, ID::S, i, ID::Y, i, -1);
db->add_edge(cell, TW::A, i, TW::Y, i, -1);
db->add_edge(cell, TW::B, i, TW::Y, i, -1);
db->add_edge(cell, TW::S, i, TW::Y, i, -1);
}
}

View file

@ -28,7 +28,7 @@ YOSYS_NAMESPACE_BEGIN
struct AbstractCellEdgesDatabase
{
virtual ~AbstractCellEdgesDatabase() { }
virtual void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int delay) = 0;
virtual void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int delay) = 0;
bool add_edges_from_cell(RTLIL::Cell *cell);
};
@ -38,7 +38,7 @@ struct FwdCellEdgesDatabase : AbstractCellEdgesDatabase
dict<SigBit, pool<SigBit>> db;
FwdCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int) override {
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
db[from_sigbit].insert(to_sigbit);
@ -51,7 +51,7 @@ struct RevCellEdgesDatabase : AbstractCellEdgesDatabase
dict<SigBit, pool<SigBit>> db;
RevCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
void add_edge(RTLIL::Cell *cell, TwineRef from_port, int from_bit, TwineRef to_port, int to_bit, int) override {
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
db[to_sigbit].insert(from_sigbit);

View file

@ -75,7 +75,7 @@ struct CellTypes
if (wire->port_output)
outputs.insert(wire->meta_->name);
}
setup_type(module->name, inputs, outputs);
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
}
void setup_design(RTLIL::Design *design)

View file

@ -132,19 +132,19 @@ struct ConstEval
RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y;
log_assert(cell->hasPort(ID::Y));
log_assert(cell->hasPort(TW::Y));
sig_y = values_map(assign_map(cell->getPort(TW::Y)));
if (sig_y.is_fully_const())
return true;
if (cell->hasPort(ID::S)) {
if (cell->hasPort(TW::S)) {
sig_s = cell->getPort(TW::S);
}
if (cell->hasPort(ID::A))
if (cell->hasPort(TW::A))
sig_a = cell->getPort(TW::A);
if (cell->hasPort(ID::B))
if (cell->hasPort(TW::B))
sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
@ -337,9 +337,9 @@ struct ConstEval
RTLIL::SigSpec sig_c, sig_d;
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
if (cell->hasPort(ID::C))
if (cell->hasPort(TW::C))
sig_c = cell->getPort(TW::C);
if (cell->hasPort(ID::D))
if (cell->hasPort(TW::D))
sig_d = cell->getPort(TW::D);
}

View file

@ -5,8 +5,8 @@ USING_YOSYS_NAMESPACE
unsigned int CellCosts::get(RTLIL::Module *mod)
{
if (mod_cost_cache_.count(mod->name))
return mod_cost_cache_.at(mod->name);
if (mod_cost_cache_.count(mod->meta_->name))
return mod_cost_cache_.at(mod->meta_->name);
unsigned int module_cost = 1;
for (auto c : mod->cells()) {
@ -14,7 +14,7 @@ unsigned int CellCosts::get(RTLIL::Module *mod)
module_cost = new_cost >= module_cost ? new_cost : INT_MAX;
}
mod_cost_cache_[mod->name] = module_cost;
mod_cost_cache_[mod->meta_->name] = module_cost;
return module_cost;
}
@ -124,7 +124,7 @@ unsigned int max_inp_width(RTLIL::Cell *cell)
unsigned int port_width_sum(RTLIL::Cell *cell)
{
unsigned int sum = 0;
TwineRef port_width_params[] = {
IdString port_width_params[] = {
ID::WIDTH, ID::A_WIDTH, ID::B_WIDTH, ID::S_WIDTH, ID::Y_WIDTH,
};
@ -146,7 +146,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
log_debug("%s is a module, recurse\n", cell->name);
return get(design_->module(cell->type));
} else if (cell->is_builtin_ff()) {
log_assert(cell->hasPort(ID::Q) && "Weird flip flop");
log_assert(cell->hasPort(TW::Q) && "Weird flip flop");
log_debug("%s is ff\n", cell->name);
return cell->getParam(ID::WIDTH).as_int();
} else if (cell->type.in(ID($mem), ID($mem_v2))) {

View file

@ -28,7 +28,7 @@ struct CellCosts
{
private:
dict<RTLIL::IdString, int> mod_cost_cache_;
dict<TwineRef, int> mod_cost_cache_;
Design *design_ = nullptr;
public:

View file

@ -746,7 +746,7 @@ void DriverMap::add(SigSpec const &a, SigSpec const &b)
}
}
void DriverMap::add_port(Cell *cell, IdString const &port, SigSpec const &b)
void DriverMap::add_port(Cell *cell, TwineRef port, SigSpec const &b)
{
int offset = 0;
for (auto const &chunk : b.chunks()) {
@ -877,8 +877,8 @@ std::string log_signal(DriveChunkWire const &chunk)
std::string log_signal(DriveChunkPort const &chunk)
{
std::string cell_id = chunk.cell->name.unescape();
std::string port_id = chunk.port.unescape();
std::string cell_id = chunk.cell->module->design->twines.str(cell->meta_->name);
std::string port_id = chunk.cell->module->design->twines.str(chunk.port);
if (chunk.is_whole())
return stringf("%s <%s>", cell_id, port_id);
if (chunk.width == 1)

View file

@ -87,10 +87,10 @@ struct DriveBitWire
struct DriveBitPort
{
Cell *cell;
IdString port;
TwineRef port;
int offset;
DriveBitPort(Cell *cell, IdString port, int offset) : cell(cell), port(port), offset(offset) {}
DriveBitPort(Cell *cell, TwineRef port, int offset) : cell(cell), port(port), offset(offset) {}
bool operator==(const DriveBitPort &other) const
{
@ -485,15 +485,15 @@ struct DriveChunkWire
struct DriveChunkPort
{
Cell *cell;
IdString port;
TwineRef port;
int offset;
int width;
DriveChunkPort(Cell *cell, IdString port, int offset, int width) :
DriveChunkPort(Cell *cell, TwineRef port, int offset, int width) :
cell(cell), port(port), offset(offset), width(width) { }
DriveChunkPort(Cell *cell, IdString port) :
DriveChunkPort(Cell *cell, TwineRef port) :
cell(cell), port(port), offset(0), width(GetSize(cell->connections().at(port))) { }
DriveChunkPort(Cell *cell, std::pair<IdString, SigSpec> const &conn) :
DriveChunkPort(Cell *cell, std::pair<TwineRef, SigSpec> const &conn) :
cell(cell), port(conn.first), offset(0), width(GetSize(conn.second)) { }
DriveChunkPort(DriveBitPort const &bit) :
cell(bit.cell), port(bit.port), offset(bit.offset), width(1) { }
@ -1141,7 +1141,7 @@ private:
// Maps cell ports to a the first DriveBitId of the consecutive range used
// for that cell port.
dict<pair<Cell *, IdString>, DriveBitId> port_offsets;
dict<pair<Cell *, TwineRef>, DriveBitId> port_offsets;
// For the inverse map that maps DriveBitIds back to DriveBits we use a
// sorted map containing only the first DriveBit for each wire and cell
@ -1237,7 +1237,7 @@ public:
void add(SigSpec const &a, SigSpec const &b);
private:
void add_port(Cell *cell, IdString const &port, SigSpec const &b);
void add_port(Cell *cell, TwineRef port, SigSpec const &b);
// Only used a local variables in `orient_undirected`, always cleared, only
// stored to reduce allocations.

View file

@ -498,21 +498,21 @@ void FfData::aload_to_sr() {
pol_clr = false;
pol_set = true;
if (pol_aload) {
sig_clr = patcher.Mux(NEW_ID, Const(State::S1, width), sig_ad, sig_aload);
sig_set = patcher.Mux(NEW_ID, Const(State::S0, width), sig_ad, sig_aload);
sig_clr = patcher.Mux(NEW_TWINE, Const(State::S1, width), sig_ad, sig_aload);
sig_set = patcher.Mux(NEW_TWINE, Const(State::S0, width), sig_ad, sig_aload);
} else {
sig_clr = patcher.Mux(NEW_ID, sig_ad, Const(State::S1, width), sig_aload);
sig_set = patcher.Mux(NEW_ID, sig_ad, Const(State::S0, width), sig_aload);
sig_clr = patcher.Mux(NEW_TWINE, sig_ad, Const(State::S1, width), sig_aload);
sig_set = patcher.Mux(NEW_TWINE, sig_ad, Const(State::S0, width), sig_aload);
}
} else {
pol_clr = pol_aload;
pol_set = pol_aload;
if (pol_aload) {
sig_clr = patcher.AndnotGate(NEW_ID, sig_aload, sig_ad);
sig_set = patcher.AndGate(NEW_ID, sig_aload, sig_ad);
sig_clr = patcher.AndnotGate(NEW_TWINE, sig_aload, sig_ad);
sig_set = patcher.AndGate(NEW_TWINE, sig_aload, sig_ad);
} else {
sig_clr = patcher.OrGate(NEW_ID, sig_aload, sig_ad);
sig_set = patcher.OrnotGate(NEW_ID, sig_aload, sig_ad);
sig_clr = patcher.OrGate(NEW_TWINE, sig_aload, sig_ad);
sig_set = patcher.OrnotGate(NEW_TWINE, sig_aload, sig_ad);
}
}
patcher.commit_inheriting_src(cell);
@ -527,31 +527,31 @@ void FfData::convert_ce_over_srst(bool val) {
if (!is_fine) {
if (pol_ce) {
if (pol_srst) {
sig_ce = patcher.Or(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.Or(NEW_TWINE, sig_ce, sig_srst);
} else {
SigSpec tmp = patcher.Not(NEW_ID, sig_srst);
sig_ce = patcher.Or(NEW_ID, sig_ce, tmp);
SigSpec tmp = patcher.Not(NEW_TWINE, sig_srst);
sig_ce = patcher.Or(NEW_TWINE, sig_ce, tmp);
}
} else {
if (pol_srst) {
SigSpec tmp = patcher.Not(NEW_ID, sig_srst);
sig_ce = patcher.And(NEW_ID, sig_ce, tmp);
SigSpec tmp = patcher.Not(NEW_TWINE, sig_srst);
sig_ce = patcher.And(NEW_TWINE, sig_ce, tmp);
} else {
sig_ce = patcher.And(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.And(NEW_TWINE, sig_ce, sig_srst);
}
}
} else {
if (pol_ce) {
if (pol_srst) {
sig_ce = patcher.OrGate(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.OrGate(NEW_TWINE, sig_ce, sig_srst);
} else {
sig_ce = patcher.OrnotGate(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.OrnotGate(NEW_TWINE, sig_ce, sig_srst);
}
} else {
if (pol_srst) {
sig_ce = patcher.AndnotGate(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.AndnotGate(NEW_TWINE, sig_ce, sig_srst);
} else {
sig_ce = patcher.AndGate(NEW_ID, sig_ce, sig_srst);
sig_ce = patcher.AndGate(NEW_TWINE, sig_ce, sig_srst);
}
}
}
@ -560,31 +560,31 @@ void FfData::convert_ce_over_srst(bool val) {
if (!is_fine) {
if (pol_srst) {
if (pol_ce) {
sig_srst = patcher.And(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.And(NEW_TWINE, sig_srst, sig_ce);
} else {
SigSpec tmp = patcher.Not(NEW_ID, sig_ce);
sig_srst = patcher.And(NEW_ID, sig_srst, tmp);
SigSpec tmp = patcher.Not(NEW_TWINE, sig_ce);
sig_srst = patcher.And(NEW_TWINE, sig_srst, tmp);
}
} else {
if (pol_ce) {
SigSpec tmp = patcher.Not(NEW_ID, sig_ce);
sig_srst = patcher.Or(NEW_ID, sig_srst, tmp);
SigSpec tmp = patcher.Not(NEW_TWINE, sig_ce);
sig_srst = patcher.Or(NEW_TWINE, sig_srst, tmp);
} else {
sig_srst = patcher.Or(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.Or(NEW_TWINE, sig_srst, sig_ce);
}
}
} else {
if (pol_srst) {
if (pol_ce) {
sig_srst = patcher.AndGate(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.AndGate(NEW_TWINE, sig_srst, sig_ce);
} else {
sig_srst = patcher.AndnotGate(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.AndnotGate(NEW_TWINE, sig_srst, sig_ce);
}
} else {
if (pol_ce) {
sig_srst = patcher.OrnotGate(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.OrnotGate(NEW_TWINE, sig_srst, sig_ce);
} else {
sig_srst = patcher.OrGate(NEW_ID, sig_srst, sig_ce);
sig_srst = patcher.OrGate(NEW_TWINE, sig_srst, sig_ce);
}
}
}
@ -603,14 +603,14 @@ void FfData::unmap_ce() {
RTLIL::Patch patcher(module);
if (!is_fine) {
if (pol_ce)
sig_d = patcher.Mux(NEW_ID, sig_q, sig_d, sig_ce);
sig_d = patcher.Mux(NEW_TWINE, sig_q, sig_d, sig_ce);
else
sig_d = patcher.Mux(NEW_ID, sig_d, sig_q, sig_ce);
sig_d = patcher.Mux(NEW_TWINE, sig_d, sig_q, sig_ce);
} else {
if (pol_ce)
sig_d = patcher.MuxGate(NEW_ID, sig_q, sig_d, sig_ce);
sig_d = patcher.MuxGate(NEW_TWINE, sig_q, sig_d, sig_ce);
else
sig_d = patcher.MuxGate(NEW_ID, sig_d, sig_q, sig_ce);
sig_d = patcher.MuxGate(NEW_TWINE, sig_d, sig_q, sig_ce);
}
patcher.commit_inheriting_src(cell);
has_ce = false;
@ -625,14 +625,14 @@ void FfData::unmap_srst() {
RTLIL::Patch patcher(module);
if (!is_fine) {
if (pol_srst)
sig_d = patcher.Mux(NEW_ID, sig_d, val_srst, sig_srst);
sig_d = patcher.Mux(NEW_TWINE, sig_d, val_srst, sig_srst);
else
sig_d = patcher.Mux(NEW_ID, val_srst, sig_d, sig_srst);
sig_d = patcher.Mux(NEW_TWINE, val_srst, sig_d, sig_srst);
} else {
if (pol_srst)
sig_d = patcher.MuxGate(NEW_ID, sig_d, val_srst[0], sig_srst);
sig_d = patcher.MuxGate(NEW_TWINE, sig_d, val_srst[0], sig_srst);
else
sig_d = patcher.MuxGate(NEW_ID, val_srst[0], sig_d, sig_srst);
sig_d = patcher.MuxGate(NEW_TWINE, val_srst[0], sig_d, sig_srst);
}
patcher.commit_inheriting_src(cell);
has_srst = false;
@ -664,48 +664,48 @@ Cell *FfData::emit() {
cell = module->addAnyinit(name, sig_d, sig_q);
log_assert(val_init.is_fully_undef());
} else {
cell = module->addFf(name, sig_d, sig_q);
cell = module->addFf(Twine{name.str()}, sig_d, sig_q);
}
} else if (!has_aload && !has_clk) {
log_assert(has_sr);
cell = module->addSr(name, sig_set, sig_clr, sig_q, pol_set, pol_clr);
cell = module->addSr(Twine{name.str()}, sig_set, sig_clr, sig_q, pol_set, pol_clr);
} else if (!has_clk) {
log_assert(!has_srst);
if (has_sr)
cell = module->addDlatchsr(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
cell = module->addDlatchsr(Twine{name.str()}, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
else if (has_arst)
cell = module->addAdlatch(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst);
cell = module->addAdlatch(Twine{name.str()}, sig_aload, sig_arst, sig_ad, sig_q, val_arst, pol_aload, pol_arst);
else
cell = module->addDlatch(name, sig_aload, sig_ad, sig_q, pol_aload);
cell = module->addDlatch(Twine{name.str()}, sig_aload, sig_ad, sig_q, pol_aload);
} else {
if (has_sr) {
if (has_ce)
cell = module->addDffsre(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
cell = module->addDffsre(Twine{name.str()}, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
else
cell = module->addDffsr(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
cell = module->addDffsr(Twine{name.str()}, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
} else if (has_arst) {
if (has_ce)
cell = module->addAdffe(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst);
cell = module->addAdffe(Twine{name.str()}, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_ce, pol_arst);
else
cell = module->addAdff(name, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst);
cell = module->addAdff(Twine{name.str()}, sig_clk, sig_arst, sig_d, sig_q, val_arst, pol_clk, pol_arst);
} else if (has_aload) {
if (has_ce)
cell = module->addAldffe(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
cell = module->addAldffe(Twine{name.str()}, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
else
cell = module->addAldff(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
cell = module->addAldff(Twine{name.str()}, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
} else if (has_srst) {
if (has_ce)
if (ce_over_srst)
cell = module->addSdffce(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
cell = module->addSdffce(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
else
cell = module->addSdffe(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
cell = module->addSdffe(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_ce, pol_srst);
else
cell = module->addSdff(name, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst);
cell = module->addSdff(Twine{name.str()}, sig_clk, sig_srst, sig_d, sig_q, val_srst, pol_clk, pol_srst);
} else {
if (has_ce)
cell = module->addDffe(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
cell = module->addDffe(Twine{name.str()}, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
else
cell = module->addDff(name, sig_clk, sig_d, sig_q, pol_clk);
cell = module->addDff(Twine{name.str()}, sig_clk, sig_d, sig_q, pol_clk);
}
}
} else {
@ -717,47 +717,47 @@ Cell *FfData::emit() {
log_assert(!has_srst);
log_assert(!has_sr);
log_assert(!is_anyinit);
cell = module->addFfGate(name, sig_d, sig_q);
cell = module->addFfGate(Twine{name.str()}, sig_d, sig_q);
} else if (!has_aload && !has_clk) {
log_assert(has_sr);
cell = module->addSrGate(name, sig_set, sig_clr, sig_q, pol_set, pol_clr);
cell = module->addSrGate(Twine{name.str()}, sig_set, sig_clr, sig_q, pol_set, pol_clr);
} else if (!has_clk) {
log_assert(!has_srst);
if (has_sr)
cell = module->addDlatchsrGate(name, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
cell = module->addDlatchsrGate(Twine{name.str()}, sig_aload, sig_set, sig_clr, sig_ad, sig_q, pol_aload, pol_set, pol_clr);
else if (has_arst)
cell = module->addAdlatchGate(name, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst);
cell = module->addAdlatchGate(Twine{name.str()}, sig_aload, sig_arst, sig_ad, sig_q, val_arst.as_bool(), pol_aload, pol_arst);
else
cell = module->addDlatchGate(name, sig_aload, sig_ad, sig_q, pol_aload);
cell = module->addDlatchGate(Twine{name.str()}, sig_aload, sig_ad, sig_q, pol_aload);
} else {
if (has_sr) {
if (has_ce)
cell = module->addDffsreGate(name, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
cell = module->addDffsreGate(Twine{name.str()}, sig_clk, sig_ce, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_ce, pol_set, pol_clr);
else
cell = module->addDffsrGate(name, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
cell = module->addDffsrGate(Twine{name.str()}, sig_clk, sig_set, sig_clr, sig_d, sig_q, pol_clk, pol_set, pol_clr);
} else if (has_arst) {
if (has_ce)
cell = module->addAdffeGate(name, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst);
cell = module->addAdffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_ce, pol_arst);
else
cell = module->addAdffGate(name, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst);
cell = module->addAdffGate(Twine{name.str()}, sig_clk, sig_arst, sig_d, sig_q, val_arst.as_bool(), pol_clk, pol_arst);
} else if (has_aload) {
if (has_ce)
cell = module->addAldffeGate(name, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
cell = module->addAldffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_ce, pol_aload);
else
cell = module->addAldffGate(name, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
cell = module->addAldffGate(Twine{name.str()}, sig_clk, sig_aload, sig_d, sig_q, sig_ad, pol_clk, pol_aload);
} else if (has_srst) {
if (has_ce)
if (ce_over_srst)
cell = module->addSdffceGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
cell = module->addSdffceGate(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
else
cell = module->addSdffeGate(name, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
cell = module->addSdffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_ce, pol_srst);
else
cell = module->addSdffGate(name, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst);
cell = module->addSdffGate(Twine{name.str()}, sig_clk, sig_srst, sig_d, sig_q, val_srst.as_bool(), pol_clk, pol_srst);
} else {
if (has_ce)
cell = module->addDffeGate(name, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
cell = module->addDffeGate(Twine{name.str()}, sig_clk, sig_ce, sig_d, sig_q, pol_clk, pol_ce);
else
cell = module->addDffGate(name, sig_clk, sig_d, sig_q, pol_clk);
cell = module->addDffGate(Twine{name.str()}, sig_clk, sig_d, sig_q, pol_clk);
}
}
}
@ -766,19 +766,8 @@ Cell *FfData::emit() {
// pool, no flatten. The OwnedTwine still holds its own ref until
// FfData is destroyed; set_src_id retains on the cell's behalf.
cell->attributes = attributes;
if (!src_twine.empty() && cell->module && cell->module->design) {
TwinePool *dst_pool = &cell->module->design->twines;
if (src_twine.pool() == dst_pool) {
cell->set_src_id(src_twine.id());
} else {
// Cross-pool (unusual — FfData migrated between
// designs). Rebuild the twine structure into the
// destination pool, then adopt that fresh id.
TwineRef migrated = dst_pool->copy_from(*src_twine.pool(), src_twine.id());
cell->set_src_id(migrated);
dst_pool->release(migrated);
}
}
if (src_twine != Twine::Null && cell->module && cell->module->design)
cell->set_src_id(src_twine);
if (initvals && !is_anyinit)
initvals->set_init(cell->getPort(TW::Q), val_init);
return cell;
@ -826,7 +815,7 @@ void FfData::flip_bits(const pool<int> &bits) {
Wire *new_q = module->addWire(NEW_TWINE, width);
if (has_sr && cell) {
log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", module->name.unescape(), cell->name.unescape(), cell->type.unescape());
log_warning("Flipping D/Q/init and inserting priority fixup to legalize %s.%s [%s].\n", module->design->twines.str(module->meta_->name).c_str(), cell->module->design->twines.str(cell->meta_->name), cell->type.unescape());
}
if (is_fine) {
@ -835,15 +824,15 @@ void FfData::flip_bits(const pool<int> &bits) {
SigSpec new_sig_clr;
if (pol_set) {
if (pol_clr) {
new_sig_clr = module->AndnotGate(NEW_ID, sig_set, sig_clr);
new_sig_clr = module->AndnotGate(NEW_TWINE, sig_set, sig_clr);
} else {
new_sig_clr = module->AndGate(NEW_ID, sig_set, sig_clr);
new_sig_clr = module->AndGate(NEW_TWINE, sig_set, sig_clr);
}
} else {
if (pol_clr) {
new_sig_clr = module->OrGate(NEW_ID, sig_set, sig_clr);
new_sig_clr = module->OrGate(NEW_TWINE, sig_set, sig_clr);
} else {
new_sig_clr = module->OrnotGate(NEW_ID, sig_set, sig_clr);
new_sig_clr = module->OrnotGate(NEW_TWINE, sig_set, sig_clr);
}
}
pol_set = pol_clr;
@ -852,10 +841,10 @@ void FfData::flip_bits(const pool<int> &bits) {
sig_clr = new_sig_clr;
}
if (has_clk || has_gclk)
sig_d = module->NotGate(NEW_ID, sig_d);
sig_d = module->NotGate(NEW_TWINE, sig_d);
if (has_aload)
sig_ad = module->NotGate(NEW_ID, sig_ad);
module->addNotGate(NEW_ID, new_q, sig_q);
sig_ad = module->NotGate(NEW_TWINE, sig_ad);
module->addNotGate(NEW_TWINE, new_q, sig_q);
}
else
{
@ -863,17 +852,17 @@ void FfData::flip_bits(const pool<int> &bits) {
SigSpec not_clr;
if (!pol_clr) {
not_clr = sig_clr;
sig_clr = module->Not(NEW_ID, sig_clr);
sig_clr = module->Not(NEW_TWINE, sig_clr);
pol_clr = true;
} else {
not_clr = module->Not(NEW_ID, sig_clr);
not_clr = module->Not(NEW_TWINE, sig_clr);
}
if (!pol_set) {
sig_set = module->Not(NEW_ID, sig_set);
sig_set = module->Not(NEW_TWINE, sig_set);
pol_set = true;
}
SigSpec masked_set = module->And(NEW_ID, sig_set, not_clr);
SigSpec masked_set = module->And(NEW_TWINE, sig_set, not_clr);
for (auto bit: bits) {
sig_set[bit] = sig_clr[bit];
sig_clr[bit] = masked_set[bit];
@ -885,10 +874,10 @@ void FfData::flip_bits(const pool<int> &bits) {
mask.set(bit, State::S1);
if (has_clk || has_gclk)
sig_d = module->Xor(NEW_ID, sig_d, mask);
sig_d = module->Xor(NEW_TWINE, sig_d, mask);
if (has_aload)
sig_ad = module->Xor(NEW_ID, sig_ad, mask);
module->addXor(NEW_ID, new_q, mask, sig_q);
sig_ad = module->Xor(NEW_TWINE, sig_ad, mask);
module->addXor(NEW_TWINE, new_q, mask, sig_q);
}
sig_q = new_q;

View file

@ -301,7 +301,7 @@ void FfMergeHelper::remove_output_ff(const pool<std::pair<Cell *, int>> &bits) {
SigSpec q = cell->getPort(TW::Q);
initvals->remove_init(q[idx]);
dff_driver.erase((*sigmap)(q[idx]));
q[idx] = module->addWire(stringf("$ffmerge_disconnected$%d", autoidx++));
q[idx] = module->addWire(Twine{stringf("$ffmerge_disconnected$%d", autoidx++)});
cell->setPort(TW::Q, q);
initvals->set_init(cell->getPort(TW::Q), (*initvals)(q));
}
@ -311,7 +311,7 @@ void FfMergeHelper::mark_input_ff(const pool<std::pair<Cell *, int>> &bits) {
for (auto &it : bits) {
Cell *cell = it.first;
int idx = it.second;
if (cell->hasPort(ID::D)) {
if (cell->hasPort(TW::D)) {
SigSpec d = cell->getPort(TW::D);
// The user count was already at least 1
// (for the D port). Bump it as it is now connected
@ -337,7 +337,7 @@ void FfMergeHelper::set(FfInitVals *initvals_, RTLIL::Module *module_)
for (auto cell : module->cells()) {
if (cell->is_builtin_ff()) {
if (cell->hasPort(ID::D)) {
if (cell->hasPort(TW::D)) {
SigSpec d = (*sigmap)(cell->getPort(TW::D));
for (int i = 0; i < GetSize(d); i++)
dff_sink[d[i]].insert(std::make_pair(cell, i));

View file

@ -31,7 +31,7 @@ void Fmt::append_literal(const std::string &str) {
void Fmt::parse_rtlil(const RTLIL::Cell *cell) {
std::string fmt = cell->getParam(ID(FORMAT)).decode_string();
RTLIL::SigSpec args = cell->getPort(ID(ARGS));
RTLIL::SigSpec args = cell->getPort(TW::ARGS);
parts.clear();
FmtPart part;
@ -261,7 +261,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const {
cell->setParam(ID(FORMAT), fmt);
cell->setParam(ID(ARGS_WIDTH), args.size());
cell->setPort(ID(ARGS), args);
cell->setPort(TW::ARGS, args);
}
static size_t compute_required_decimal_places(size_t size, bool signed_)

View file

@ -218,15 +218,15 @@ private:
y = factory.mux(y, factory.slice(b, a.width() * i, a.width()), factory.slice(s, i, 1));
return y;
}
dict<IdString, Node> handle_fa(Node a, Node b, Node c) {
dict<TwineRef, Node> handle_fa(Node a, Node b, Node c) {
Node t1 = factory.bitwise_xor(a, b);
Node t2 = factory.bitwise_and(a, b);
Node t3 = factory.bitwise_and(c, t1);
Node y = factory.bitwise_xor(c, t1);
Node x = factory.bitwise_or(t2, t3);
return {{ID(X), x}, {ID(Y), y}};
return {{TW::X, x}, {TW::Y, y}};
}
dict<IdString, Node> handle_alu(Node a_in, Node b_in, int y_width, bool is_signed, Node ci, Node bi) {
dict<TwineRef, Node> handle_alu(Node a_in, Node b_in, int y_width, bool is_signed, Node ci, Node bi) {
Node a = factory.extend(a_in, y_width, is_signed);
Node b_uninverted = factory.extend(b_in, y_width, is_signed);
Node b = factory.mux(b_uninverted, factory.bitwise_not(b_uninverted), bi);
@ -240,13 +240,13 @@ private:
Node y = factory.slice(y_extra, 0, y_width);
Node carries = factory.bitwise_xor(y_extra, factory.bitwise_xor(a_extra, b_extra));
Node co = factory.slice(carries, 1, y_width);
return {{ID(X), x}, {ID(Y), y}, {ID(CO), co}};
return {{TW::X, x}, {TW::Y, y}, {TW::CO, co}};
}
Node handle_lcu(Node p, Node g, Node ci) {
return handle_alu(g, factory.bitwise_or(p, g), g.width(), false, ci, factory.constant(Const(State::S0, 1))).at(ID(CO));
return handle_alu(g, factory.bitwise_or(p, g), g.width(), false, ci, factory.constant(Const(State::S0, 1))).at(TW::CO);
}
public:
std::variant<dict<IdString, Node>, Node> handle(IdString cellName, IdString cellType, dict<IdString, Const> parameters, dict<IdString, Node> inputs)
std::variant<dict<TwineRef, Node>, Node> handle(IdString cellName, IdString cellType, dict<IdString, Const> parameters, dict<TwineRef, Node> inputs)
{
int a_width = parameters.at(ID(A_WIDTH), Const(-1)).as_int();
int b_width = parameters.at(ID(B_WIDTH), Const(-1)).as_int();
@ -255,8 +255,8 @@ public:
bool b_signed = parameters.at(ID(B_SIGNED), Const(0)).as_bool();
if(cellType.in(ID($add), ID($sub), ID($and), ID($or), ID($xor), ID($xnor), ID($mul))){
bool is_signed = a_signed && b_signed;
Node a = factory.extend(inputs.at(ID(A)), y_width, is_signed);
Node b = factory.extend(inputs.at(ID(B)), y_width, is_signed);
Node a = factory.extend(inputs.at(TW::A), y_width, is_signed);
Node b = factory.extend(inputs.at(TW::B), y_width, is_signed);
if(cellType == ID($add))
return factory.add(a, b);
else if(cellType == ID($sub))
@ -276,8 +276,8 @@ public:
}else if(cellType.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($le), ID($lt), ID($ge), ID($gt))){
bool is_signed = a_signed && b_signed;
int width = max(a_width, b_width);
Node a = factory.extend(inputs.at(ID(A)), width, is_signed);
Node b = factory.extend(inputs.at(ID(B)), width, is_signed);
Node a = factory.extend(inputs.at(TW::A), width, is_signed);
Node b = factory.extend(inputs.at(TW::B), width, is_signed);
if(cellType.in(ID($eq), ID($eqx)))
return factory.extend(factory.equal(a, b), y_width, false);
else if(cellType.in(ID($ne), ID($nex)))
@ -293,48 +293,48 @@ public:
else
log_abort();
}else if(cellType.in(ID($logic_or), ID($logic_and))){
Node a = factory.reduce_or(inputs.at(ID(A)));
Node b = factory.reduce_or(inputs.at(ID(B)));
Node a = factory.reduce_or(inputs.at(TW::A));
Node b = factory.reduce_or(inputs.at(TW::B));
Node y = cellType == ID($logic_and) ? factory.bitwise_and(a, b) : factory.bitwise_or(a, b);
return factory.extend(y, y_width, false);
}else if(cellType == ID($not)){
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.bitwise_not(a);
}else if(cellType == ID($pos)){
return factory.extend(inputs.at(ID(A)), y_width, a_signed);
return factory.extend(inputs.at(TW::A), y_width, a_signed);
}else if(cellType == ID($neg)){
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.unary_minus(a);
}else if(cellType == ID($logic_not)){
Node a = factory.reduce_or(inputs.at(ID(A)));
Node a = factory.reduce_or(inputs.at(TW::A));
Node y = factory.bitwise_not(a);
return factory.extend(y, y_width, false);
}else if(cellType.in(ID($reduce_or), ID($reduce_bool))){
Node a = factory.reduce_or(inputs.at(ID(A)));
Node a = factory.reduce_or(inputs.at(TW::A));
return factory.extend(a, y_width, false);
}else if(cellType == ID($reduce_and)){
Node a = factory.reduce_and(inputs.at(ID(A)));
Node a = factory.reduce_and(inputs.at(TW::A));
return factory.extend(a, y_width, false);
}else if(cellType.in(ID($reduce_xor), ID($reduce_xnor))){
Node a = factory.reduce_xor(inputs.at(ID(A)));
Node a = factory.reduce_xor(inputs.at(TW::A));
Node y = cellType == ID($reduce_xnor) ? factory.bitwise_not(a) : a;
return factory.extend(y, y_width, false);
}else if(cellType == ID($shl) || cellType == ID($sshl)){
Node a = factory.extend(inputs.at(ID(A)), y_width, a_signed);
Node b = inputs.at(ID(B));
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
Node b = inputs.at(TW::B);
return logical_shift_left(a, b);
}else if(cellType == ID($shr) || cellType == ID($sshr)){
int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(ID(A)), width, a_signed);
Node b = inputs.at(ID(B));
Node a = factory.extend(inputs.at(TW::A), width, a_signed);
Node b = inputs.at(TW::B);
Node y = a_signed && cellType == ID($sshr) ?
arithmetic_shift_right(a, b) :
logical_shift_right(a, b);
return factory.extend(y, y_width, a_signed);
}else if(cellType == ID($shiftx) || cellType == ID($shift)){
int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(ID(A)), width, cellType == ID($shift) && a_signed);
Node b = inputs.at(ID(B));
Node a = factory.extend(inputs.at(TW::A), width, cellType == ID($shift) && a_signed);
Node b = inputs.at(TW::B);
Node shr = logical_shift_right(a, b);
if(b_signed) {
Node shl = logical_shift_left(a, factory.unary_minus(b));
@ -344,22 +344,22 @@ public:
return factory.extend(shr, y_width, false);
}
}else if(cellType == ID($mux)){
return factory.mux(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(S)));
return factory.mux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($pmux)){
return handle_pmux(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(S)));
return handle_pmux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($concat)){
Node a = inputs.at(ID(A));
Node b = inputs.at(ID(B));
Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B);
return factory.concat(a, b);
}else if(cellType == ID($slice)){
int offset = parameters.at(ID(OFFSET)).as_int();
Node a = inputs.at(ID(A));
Node a = inputs.at(TW::A);
return factory.slice(a, offset, y_width);
}else if(cellType.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) {
int width = max(a_width, b_width);
bool is_signed = a_signed && b_signed;
Node a = factory.extend(inputs.at(ID(A)), width, is_signed);
Node b = factory.extend(inputs.at(ID(B)), width, is_signed);
Node a = factory.extend(inputs.at(TW::A), width, is_signed);
Node b = factory.extend(inputs.at(TW::B), width, is_signed);
if(is_signed) {
if(cellType == ID($div)) {
// divide absolute values, then flip the sign if input signs differ
@ -403,44 +403,44 @@ public:
return factory.extend(factory.unsigned_div(a, b), y_width, false);
}
} else if(cellType == ID($pow)) {
return handle_pow(inputs.at(ID(A)), inputs.at(ID(B)), y_width, a_signed && b_signed);
return handle_pow(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed);
} else if (cellType == ID($lut)) {
int width = parameters.at(ID(WIDTH)).as_int();
Const lut_table = parameters.at(ID(LUT));
lut_table.extu(1 << width);
return handle_bmux(factory.constant(lut_table), inputs.at(ID(A)), 0, 1, width);
return handle_bmux(factory.constant(lut_table), inputs.at(TW::A), 0, 1, width);
} else if (cellType == ID($bwmux)) {
Node a = inputs.at(ID(A));
Node b = inputs.at(ID(B));
Node s = inputs.at(ID(S));
Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B);
Node s = inputs.at(TW::S);
return factory.bitwise_or(
factory.bitwise_and(a, factory.bitwise_not(s)),
factory.bitwise_and(b, s));
} else if (cellType == ID($bweqx)) {
Node a = inputs.at(ID(A));
Node b = inputs.at(ID(B));
Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B);
return factory.bitwise_not(factory.bitwise_xor(a, b));
} else if(cellType == ID($bmux)) {
int width = parameters.at(ID(WIDTH)).as_int();
int s_width = parameters.at(ID(S_WIDTH)).as_int();
return handle_bmux(inputs.at(ID(A)), inputs.at(ID(S)), 0, width, s_width);
return handle_bmux(inputs.at(TW::A), inputs.at(TW::S), 0, width, s_width);
} else if(cellType == ID($demux)) {
int width = parameters.at(ID(WIDTH)).as_int();
int s_width = parameters.at(ID(S_WIDTH)).as_int();
int y_width = width << s_width;
int b_width = ceil_log2(y_width);
Node a = factory.extend(inputs.at(ID(A)), y_width, false);
Node s = factory.extend(inputs.at(ID(S)), b_width, false);
Node a = factory.extend(inputs.at(TW::A), y_width, false);
Node s = factory.extend(inputs.at(TW::S), b_width, false);
Node b = factory.mul(s, factory.constant(Const(width, b_width)));
return factory.logical_shift_left(a, b);
} else if(cellType == ID($fa)) {
return handle_fa(inputs.at(ID(A)), inputs.at(ID(B)), inputs.at(ID(C)));
return handle_fa(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::C));
} else if(cellType == ID($lcu)) {
return handle_lcu(inputs.at(ID(P)), inputs.at(ID(G)), inputs.at(ID(CI)));
return handle_lcu(inputs.at(TW::P), inputs.at(TW::G), inputs.at(TW::CI));
} else if(cellType == ID($alu)) {
return handle_alu(inputs.at(ID(A)), inputs.at(ID(B)), y_width, a_signed && b_signed, inputs.at(ID(CI)), inputs.at(ID(BI)));
return handle_alu(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed, inputs.at(TW::CI), inputs.at(TW::BI));
} else if(cellType.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(ID(A)), inputs.at(ID(EN)));
Node a = factory.mux(factory.constant(Const(State::S1, 1)), inputs.at(TW::A), inputs.at(TW::EN));
auto &output = factory.add_output(cellName, cellType, Sort(1));
output.set_value(a);
return {};
@ -468,7 +468,7 @@ public:
class FunctionalIRConstruction {
std::deque<std::variant<DriveSpec, Cell *>> queue;
dict<DriveSpec, Node> graph_nodes;
dict<std::pair<Cell *, IdString>, Node> cell_outputs;
dict<std::pair<Cell *, TwineRef>, Node> cell_outputs;
DriverMap driver_map;
Factory& factory;
CellSimplifier simplifier;
@ -488,7 +488,7 @@ class FunctionalIRConstruction {
}else
return it->second;
}
Node enqueue_cell(Cell *cell, IdString port_name)
Node enqueue_cell(Cell *cell, TwineRef port_name)
{
auto it = cell_outputs.find({cell, port_name});
if(it == cell_outputs.end()) {
@ -497,7 +497,7 @@ class FunctionalIRConstruction {
for(auto const &[name, sigspec] : cell->connections())
if(driver_map.celltypes.cell_output(cell->type, name)) {
auto node = factory.create_pending(sigspec.size());
factory.suggest_name(node, cell->name.str() + "$" + name.str());
factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name));
cell_outputs.emplace({cell, name}, node);
if(name == port_name)
rv = node;
@ -539,7 +539,7 @@ private:
Node concatenate_read_results(Mem *mem, vector<Node> results)
{
// sanity check: all read ports concatenated should equal to the RD_DATA port
const SigSpec &rd_data = mem->cell->connections().at(ID(RD_DATA));
const SigSpec &rd_data = mem->cell->connections().at(TW::RD_DATA);
int current = 0;
for(size_t i = 0; i < mem->rd_ports.size(); i++) {
int width = mem->width << mem->rd_ports[i].wide_log2;
@ -604,7 +604,7 @@ private:
"Call memory_collect to avoid this error.\n", log_const(cell->parameters.at(ID(MEMID))));
}
Node node = handle_memory(mem);
factory.update_pending(cell_outputs.at({cell, ID(RD_DATA)}), node);
factory.update_pending(cell_outputs.at({cell, TW::RD_DATA}), node);
} else if (cell->is_builtin_ff()) {
FfData ff(&ff_initvals, cell);
if (!ff.has_gclk)
@ -613,12 +613,12 @@ private:
auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width));
Node q_value = factory.value(state);
factory.suggest_name(q_value, ff.name);
factory.update_pending(cell_outputs.at({cell, ID(Q)}), q_value);
factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value);
state.set_next_value(enqueue(ff.sig_d));
state.set_initial_value(ff.val_init);
} else {
dict<IdString, Node> connections;
IdString output_name; // for the single output case
dict<TwineRef, Node> connections;
TwineRef output_name; // for the single output case
int n_outputs = 0;
for(auto const &[name, sigspec] : cell->connections()) {
if(driver_map.celltypes.cell_input(cell->type, name) && sigspec.size() > 0)
@ -628,12 +628,12 @@ private:
n_outputs++;
}
}
std::variant<dict<IdString, Node>, Node> outputs = simplifier.handle(cell->name, cell->type, cell->parameters, connections);
std::variant<dict<TwineRef, Node>, Node> outputs = simplifier.handle(cell->name, cell->type, cell->parameters, connections);
if(auto *nodep = std::get_if<Node>(&outputs); nodep != nullptr) {
log_assert(n_outputs == 1);
factory.update_pending(cell_outputs.at({cell, output_name}), *nodep);
} else {
for(auto [name, node] : std::get<dict<IdString, Node>>(outputs))
for(auto [name, node] : std::get<dict<TwineRef, Node>>(outputs))
factory.update_pending(cell_outputs.at({cell, name}), node);
}
}
@ -695,7 +695,8 @@ public:
factory.update_pending(pending, node);
} else {
DriveSpec driver = driver_map(DriveSpec(port_chunk));
check_undriven(driver, port_chunk.cell->name.unescape() + " port " + port_chunk.port.unescape());
auto& twines = port_chunk.cell->module->design->twines;
check_undriven(driver, twines.str(port_chunk.cell->meta_->name) + " port " + twines.str(port_chunk.port));
factory.update_pending(pending, enqueue(driver));
}
} else {

View file

@ -619,6 +619,39 @@ const char *log_id(const RTLIL::IdString &str)
return log_id_cache.back();
}
static const char *log_id_twine(const RTLIL::Design *design, TwineRef name)
{
std::string unescaped = RTLIL::unescape_id(design->twines.str(name));
log_id_cache.push_back(strdup(unescaped.c_str()));
return log_id_cache.back();
}
const char *log_id(const RTLIL::Module *obj, const char *nullstr)
{
if (nullstr && obj == nullptr) return nullstr;
return log_id_twine(obj->design, obj->meta_->name);
}
const char *log_id(const RTLIL::Cell *obj, const char *nullstr)
{
if (nullstr && obj == nullptr) return nullstr;
return log_id_twine(obj->module->design, obj->meta_->name);
}
const char *log_id(const RTLIL::Wire *obj, const char *nullstr)
{
if (nullstr && obj == nullptr) return nullstr;
return log_id_twine(obj->module->design, obj->meta_->name);
}
const char *log_id(const RTLIL::Memory *obj, const char *nullstr)
{
if (nullstr && obj == nullptr) return nullstr;
return log_id_twine(obj->module->design, obj->meta_->name);
}
const char *log_id(const RTLIL::Process *obj, const char *nullstr)
{
if (nullstr && obj == nullptr) return nullstr;
return log_id_twine(obj->module->design, obj->meta_->name);
}
void log_module(RTLIL::Module *module, std::string indent)
{
std::stringstream buf;

View file

@ -259,11 +259,11 @@ std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
std::string log_const(const RTLIL::Const &value, bool autoint = true);
const char *log_id(const RTLIL::IdString &id);
template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {
if (nullstr && obj == nullptr)
return nullstr;
return log_id(obj->name);
}
const char *log_id(const RTLIL::Module *obj, const char *nullstr = nullptr);
const char *log_id(const RTLIL::Cell *obj, const char *nullstr = nullptr);
const char *log_id(const RTLIL::Wire *obj, const char *nullstr = nullptr);
const char *log_id(const RTLIL::Memory *obj, const char *nullstr = nullptr);
const char *log_id(const RTLIL::Process *obj, const char *nullstr = nullptr);
void log_module(RTLIL::Module *module, std::string indent = "");
void log_cell(RTLIL::Cell *cell, std::string indent = "");

View file

@ -28,7 +28,7 @@ void Mem::remove() {
cell = nullptr;
}
if (mem) {
module->memories.erase(mem->name);
module->memories.erase(mem->meta_->name);
delete mem;
mem = nullptr;
}
@ -116,14 +116,14 @@ void Mem::emit() {
if (packed) {
if (mem) {
module->memories.erase(mem->name);
module->memories.erase(mem->meta_->name);
delete mem;
mem = nullptr;
}
if (!cell) {
if (memid.empty())
memid = NEW_ID;
cell = module->addCell(memid, ID($mem_v2));
cell = module->addCell(Twine{memid.str()}, ID($mem_v2));
}
cell->type = ID($mem_v2);
cell->attributes = attributes;
@ -292,10 +292,7 @@ void Mem::emit() {
if (!mem) {
if (memid.empty())
memid = NEW_ID;
mem = new RTLIL::Memory;
mem->name = memid;
mem->module = module;
module->memories[memid] = mem;
mem = module->addMemory(Twine{memid.str()});
}
mem->width = width;
mem->start_offset = start_offset;
@ -562,14 +559,14 @@ namespace {
};
Mem mem_from_memory(Module *module, RTLIL::Memory *mem, const MemIndex &index) {
Mem res(module, mem->name, mem->width, mem->start_offset, mem->size);
Mem res(module, RTLIL::IdString(module->design->twines.str(mem->meta_->name)), mem->width, mem->start_offset, mem->size);
res.packed = false;
res.mem = mem;
res.attributes = mem->attributes;
std::vector<bool> rd_transparent;
std::vector<int> wr_portid;
if (index.rd_ports.count(mem->name)) {
for (auto cell : index.rd_ports.at(mem->name)) {
if (index.rd_ports.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
for (auto cell : index.rd_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
MemRd mrd;
bool is_compat = cell->type == ID($memrd);
mrd.cell = cell;
@ -611,9 +608,9 @@ namespace {
rd_transparent.push_back(transparent);
}
}
if (index.wr_ports.count(mem->name)) {
if (index.wr_ports.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
std::vector<std::pair<int, MemWr>> ports;
for (auto cell : index.wr_ports.at(mem->name)) {
for (auto cell : index.wr_ports.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
MemWr mwr;
bool is_compat = cell->type == ID($memwr);
mwr.cell = cell;
@ -656,9 +653,9 @@ namespace {
}
}
}
if (index.inits.count(mem->name)) {
if (index.inits.count(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
std::vector<std::pair<int, MemInit>> inits;
for (auto cell : index.inits.at(mem->name)) {
for (auto cell : index.inits.at(RTLIL::IdString(module->design->twines.str(mem->meta_->name)))) {
MemInit init;
init.cell = cell;
init.attributes = cell->attributes;
@ -933,7 +930,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
if (width)
{
SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid, idx), width);
SigSpec sig_q = module->addWire(Twine{stringf("$%s$rdreg[%d]$q", memid, idx)}, width);
SigSpec sig_d;
int pos = 0;
@ -943,7 +940,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
port.addr[i] = sig_q[pos++];
}
c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity, mem_src);
c = module->addDff(Twine{stringf("$%s$rdreg[%d]", memid, idx)}, port.clk, sig_d, sig_q, port.clk_polarity, mem_src);
} else {
c = nullptr;
}
@ -952,7 +949,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
{
log_assert(port.arst == State::S0 || port.srst == State::S0);
SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid, idx), GetSize(port.data));
SigSpec async_d = module->addWire(Twine{stringf("$%s$rdreg[%d]$d", memid, idx)}, GetSize(port.data));
SigSpec sig_d = async_d;
for (int i = 0; i < GetSize(wr_ports); i++) {
@ -975,7 +972,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
raddr = port.sub_addr(sub);
SigSpec addr_eq;
if (raddr != waddr)
addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr, false, mem_src);
addr_eq = module->Eq(Twine{stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub)}, raddr, waddr, false, mem_src);
int pos = 0;
int ewidth = width << min_wide_log2;
int wsub = wide_write ? sub : 0;
@ -988,10 +985,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos);
SigSpec cond;
if (raddr != waddr)
cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq, false, mem_src);
cond = module->And(Twine{stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos)}, wport.en[pos + wsub * width], addr_eq, false, mem_src);
else
cond = wport.en[pos + wsub * width];
SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond, mem_src);
SigSpec merged = module->Mux(Twine{stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos)}, cur, other, cond, mem_src);
sig_d.replace(pos + rsub * width, merged);
pos = epos;
}
@ -1140,7 +1137,7 @@ void Mem::emulate_priority(int idx1, int idx2, FfInitVals *initvals)
addr1 = port1.sub_addr(sub);
else
addr2 = port2.sub_addr(sub);
SigSpec addr_eq = module->Eq(NEW_ID, addr1, addr2);
SigSpec addr_eq = module->Eq(NEW_TWINE, addr1, addr2);
int ewidth = width << min_wide_log2;
int sub1 = wide1 ? sub : 0;
int sub2 = wide1 ? 0 : sub;
@ -1152,9 +1149,9 @@ void Mem::emulate_priority(int idx1, int idx2, FfInitVals *initvals)
if (cache.count(key)) {
en1 = cache[key];
} else {
SigBit active2 = module->And(NEW_ID, addr_eq, en2);
SigBit nactive2 = module->Not(NEW_ID, active2);
en1 = cache[key] = module->And(NEW_ID, en1, nactive2);
SigBit active2 = module->And(NEW_TWINE, addr_eq, en2);
SigBit nactive2 = module->Not(NEW_TWINE, active2);
en1 = cache[key] = module->And(NEW_TWINE, en1, nactive2);
}
}
}
@ -1179,7 +1176,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
// the mux whenever this would be relevant. It does, however, need to have the same
// clock enable signal as the read port.
SigSpec wdata_q = module->addWire(NEW_TWINE, GetSize(wport.data));
module->addDffe(NEW_ID, rport.clk, rport.en, wport.data, wdata_q, rport.clk_polarity, true);
module->addDffe(NEW_TWINE, rport.clk, rport.en, wport.data, wdata_q, rport.clk_polarity, true);
for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) {
SigSpec raddr = rport.addr;
SigSpec waddr = wport.addr;
@ -1190,7 +1187,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
raddr = rport.sub_addr(sub);
SigSpec addr_eq;
if (raddr != waddr)
addr_eq = module->Eq(NEW_ID, raddr, waddr);
addr_eq = module->Eq(NEW_TWINE, raddr, waddr);
int pos = 0;
int ewidth = width << min_wide_log2;
int wsub = wide_write ? sub : 0;
@ -1202,7 +1199,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
epos++;
SigSpec cond;
if (raddr != waddr)
cond = module->And(NEW_ID, wport.en[pos + wsub * width], addr_eq);
cond = module->And(NEW_TWINE, wport.en[pos + wsub * width], addr_eq);
else
cond = wport.en[pos + wsub * width];
SigSpec cond_q = module->addWire(NEW_TWINE);
@ -1243,7 +1240,7 @@ void Mem::emulate_transparency(int widx, int ridx, FfInitVals *initvals) {
SigSpec cur = rdata_a.extract(pos, epos-pos);
SigSpec other = wdata_q.extract(pos + wsub * width, epos-pos);
SigSpec dest = rport.data.extract(pos + rsub * width, epos-pos);
module->addMux(NEW_ID, cur, other, cond_q, dest);
module->addMux(NEW_TWINE, cur, other, cond_q, dest);
pos = epos;
}
rport.data.replace(rsub * width, rdata_a);
@ -1389,8 +1386,8 @@ void Mem::widen_wr_port(int idx, int wide_log2) {
} else {
// May or may not write to this subword.
new_data.append(port.data);
SigSpec addr_eq = module->Eq(NEW_ID, addr_lo, cur_addr_lo);
SigSpec en = module->Mux(NEW_ID, Const(State::S0, GetSize(port.data)), port.en, addr_eq);
SigSpec addr_eq = module->Eq(NEW_TWINE, addr_lo, cur_addr_lo);
SigSpec en = module->Mux(NEW_TWINE, Const(State::S0, GetSize(port.data)), port.en, addr_eq);
new_en.append(en);
}
}
@ -1457,7 +1454,7 @@ void Mem::emulate_rden(int idx, FfInitVals *initvals) {
}
ff_sel.emit();
ff_data.emit();
module->addMux(NEW_ID, prev_data, new_data, sel, port.data);
module->addMux(NEW_TWINE, prev_data, new_data, sel, port.data);
port.data = new_data;
port.en = State::S1;
}
@ -1506,7 +1503,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
}
}
ff_sel.emit();
module->addMux(NEW_ID, port.init_value, new_data, sel, port.data);
module->addMux(NEW_TWINE, port.init_value, new_data, sel, port.data);
port.data = new_data;
port.init_value = Const(State::Sx, GetSize(port.data));
}
@ -1546,7 +1543,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
}
}
ff_sel.emit();
module->addMux(NEW_ID, port.arst_value, new_data, sel, port.data);
module->addMux(NEW_TWINE, port.arst_value, new_data, sel, port.data);
port.data = new_data;
port.arst = State::S0;
}
@ -1581,7 +1578,7 @@ void Mem::emulate_reset(int idx, bool emu_init, bool emu_arst, bool emu_srst, Ff
ff_sel.val_arst = State::S1;
}
ff_sel.emit();
module->addMux(NEW_ID, port.srst_value, new_data, sel, port.data);
module->addMux(NEW_TWINE, port.srst_value, new_data, sel, port.data);
port.data = new_data;
port.srst = State::S0;
}
@ -1595,7 +1592,7 @@ void Mem::emulate_rd_ce_over_srst(int idx) {
return;
}
port.ce_over_srst = false;
port.srst = module->And(NEW_ID, port.en, port.srst);
port.srst = module->And(NEW_TWINE, port.en, port.srst);
}
void Mem::emulate_rd_srst_over_ce(int idx) {
@ -1606,7 +1603,7 @@ void Mem::emulate_rd_srst_over_ce(int idx) {
return;
}
port.ce_over_srst = true;
port.en = module->Or(NEW_ID, port.en, port.srst);
port.en = module->Or(NEW_TWINE, port.en, port.srst);
}
bool Mem::emulate_read_first_ok() {

View file

@ -590,7 +590,7 @@ struct NewCellTypes {
if (wire->port_output)
outputs.insert(wire->meta_->name);
}
setup_type(module->name, inputs, outputs);
setup_type(RTLIL::IdString(module->design->twines.str(module->meta_->name)), inputs, outputs);
}
void setup_type(RTLIL::IdString type, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false) {

View file

@ -305,8 +305,8 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
{
std::string backup_selected_active_module = design->selected_active_module;
design->selected_active_module.clear();
TwineRef backup_selected_active_module = design->selected_active_module;
design->selected_active_module = Twine::Null;
design->push_selection(selection);
Pass::call(design, command);
@ -317,8 +317,8 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::vector<std::string> args)
{
std::string backup_selected_active_module = design->selected_active_module;
design->selected_active_module.clear();
TwineRef backup_selected_active_module = design->selected_active_module;
design->selected_active_module = Twine::Null;
design->push_selection(selection);
Pass::call(design, args);
@ -329,8 +329,8 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele
void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
{
std::string backup_selected_active_module = design->selected_active_module;
design->selected_active_module = module->name.str();
TwineRef backup_selected_active_module = design->selected_active_module;
design->selected_active_module = module->meta_->name;
design->push_empty_selection();
design->select(module);
@ -342,8 +342,8 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str
void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector<std::string> args)
{
std::string backup_selected_active_module = design->selected_active_module;
design->selected_active_module = module->name.str();
TwineRef backup_selected_active_module = design->selected_active_module;
design->selected_active_module = module->meta_->name;
design->push_empty_selection();
design->select(module);
@ -1021,10 +1021,10 @@ struct HelpPass : public Pass {
json.name("code"); json.value(ch.code);
vector<string> inputs, outputs;
for (auto &input : ct.inputs)
inputs.push_back(input.str());
inputs.push_back(RTLIL::IdString((RTLIL::StaticId)input).str());
json.name("inputs"); json.value(inputs);
for (auto &output : ct.outputs)
outputs.push_back(output.str());
outputs.push_back(RTLIL::IdString((RTLIL::StaticId)output).str());
json.name("outputs"); json.value(outputs);
vector<string> properties;
// CellType properties

View file

@ -196,9 +196,10 @@ struct IdStringCollector {
trace(selection_var.selected_modules);
trace(selection_var.selected_members);
}
void trace_named(const RTLIL::NamedObject &named) {
void trace_named(const RTLIL::AttrObject &named) {
trace_keys(named.attributes);
trace(named.name);
if (named.meta_)
trace(named.meta_->name);
}
void trace(const RTLIL::Wire &wire) {
trace_named(wire);
@ -1548,6 +1549,7 @@ RTLIL::Module *RTLIL::Design::addModule(TwineRef name)
RTLIL::Module *module = new RTLIL::Module;
modules_[name] = module;
module->design = this;
module->meta_ = alloc_obj_meta();
module->meta_->name = name;
for (auto mon : monitors)
@ -1938,7 +1940,7 @@ void RTLIL::Module::makeblackbox()
void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
{
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", name.unescape());
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", design->twines.str(meta_->name).c_str());
}
bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
@ -1950,7 +1952,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
{
if (mayfail)
return IdString();
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
}
@ -1958,13 +1960,12 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
{
if (mayfail)
return IdString();
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
}
size_t RTLIL::Module::count_id(TwineRef id)
{
IdString sid(design->twines.str(id));
return wires_.count(id) + cells_.count(id) + memories.count(sid) + processes.count(sid);
return wires_.count(id) + cells_.count(id) + memories.count(id) + processes.count(id);
}
#ifndef NDEBUG
@ -1983,9 +1984,11 @@ namespace {
std::stringstream buf;
RTLIL_BACKEND::dump_cell(buf, " ", cell);
std::string mod_name = module ? module->design->twines.str(module->meta_->name) : std::string();
std::string cell_name = cell->module->design->twines.str(cell->meta_->name);
log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
module ? module->name.c_str() : "", module ? "." : "",
cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
mod_name.c_str(), module ? "." : "",
cell_name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
}
int param(IdString name)
@ -2951,8 +2954,8 @@ void RTLIL::Module::sort()
wires_.sort(sort_twine_by_str);
cells_.sort(sort_twine_by_str);
parameter_default_values.sort(sort_by_id_str());
memories.sort(sort_by_id_str());
processes.sort(sort_by_id_str());
memories.sort(sort_twine_by_str);
processes.sort(sort_twine_by_str);
for (auto &it : cells_)
it.second->sort();
for (auto &it : wires_)
@ -2969,13 +2972,13 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool
pool<std::string> memory_strings;
for (auto &it : module->memories) {
log_assert(it.first == it.second->name);
log_assert(!it.first.empty());
log_assert(it.second->meta_ && it.first == it.second->meta_->name);
log_assert(it.first != Twine::Null);
log_assert(it.second->width >= 0);
log_assert(it.second->size >= 0);
for (auto &it2 : it.second->attributes)
log_assert(!it2.first.empty());
memory_strings.insert(it.second->name.str());
memory_strings.insert(module->design->twines.str(it.second->meta_->name));
}
std::vector<MonotonicFlag> ports_declared(GetSize(module->ports));
@ -3047,8 +3050,8 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool
log_assert(memids_pool.insert(memid).second);
for (auto &it : module->processes) {
log_assert(it.first == it.second->name);
log_assert(!it.first.empty());
log_assert(it.second->meta_ && it.first == it.second->meta_->name);
log_assert(it.first != Twine::Null);
log_assert(it.second->root_case.compare.empty());
std::vector<RTLIL::CaseRule*> all_cases = {&it.second->root_case};
for (size_t i = 0; i < all_cases.size(); i++) {
@ -3172,7 +3175,8 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
}
for (auto it = memories.rbegin(); it != memories.rend(); ++it) {
const RTLIL::Memory *o = it->second;
RTLIL::Memory *m = new_mod->addMemory(it->first);
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
RTLIL::Memory *m = new_mod->addMemory(dst_name);
m->width = o->width;
m->start_offset = o->start_offset;
m->size = o->size;
@ -3190,8 +3194,11 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
}
for (auto it = processes.rbegin(); it != processes.rend(); ++it) {
const RTLIL::Process *o = it->second;
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
RTLIL::Process *p = o->clone();
p->name = it->first;
if (!p->meta_)
p->meta_ = new_mod->design->alloc_obj_meta();
p->meta_->name = dst_name;
new_mod->add(p);
copy_meta(o, p);
std::vector<std::pair<const RTLIL::CaseRule*, RTLIL::CaseRule*>> case_stack;
@ -3236,16 +3243,20 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
new_mod->addWire(dst_id, it->second);
}
for (auto it = memories.rbegin(); it != memories.rend(); ++it)
new_mod->addMemory(it->first, it->second);
for (auto it = memories.rbegin(); it != memories.rend(); ++it) {
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
new_mod->addMemory(dst_id, it->second);
}
for (auto it = cells_.rbegin(); it != cells_.rend(); ++it) {
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
new_mod->addCell(dst_id, it->second);
}
for (auto it = processes.rbegin(); it != processes.rend(); ++it)
new_mod->addProcess(it->first, it->second);
for (auto it = processes.rbegin(); it != processes.rend(); ++it) {
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
new_mod->addProcess(dst_id, it->second);
}
}
struct RewriteSigSpecWorker
@ -3272,7 +3283,8 @@ RTLIL::Module *RTLIL::Module::clone() const
{
RTLIL::Module *new_mod = new RTLIL::Module;
new_mod->design = design;
new_mod->name = name;
new_mod->meta_ = design->alloc_obj_meta();
new_mod->meta_->name = meta_->name;
cloneInto(new_mod);
return new_mod;
}
@ -3281,7 +3293,8 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, bool src_id_verbatim) co
{
RTLIL::Module *new_mod = new RTLIL::Module;
new_mod->design = dst;
new_mod->name = name;
new_mod->meta_ = dst->alloc_obj_meta();
new_mod->meta_->name = dst->twines.copy_from(design->twines, meta_->name);
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
return new_mod;
@ -3291,7 +3304,8 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, RTLIL::IdString target_n
{
RTLIL::Module *new_mod = new RTLIL::Module;
new_mod->design = dst;
new_mod->name = target_name;
new_mod->meta_ = dst->alloc_obj_meta();
new_mod->meta_->name = dst->twines.add(Twine{target_name.str()});
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
return new_mod;
@ -3371,9 +3385,9 @@ std::vector<RTLIL::Process*> RTLIL::Module::selected_processes() const
return result;
}
std::vector<RTLIL::NamedObject*> RTLIL::Module::selected_members() const
std::vector<RTLIL::AttrObject*> RTLIL::Module::selected_members() const
{
std::vector<RTLIL::NamedObject*> result;
std::vector<RTLIL::AttrObject*> result;
auto cells = selected_cells();
auto memories = selected_memories();
auto wires = selected_wires();
@ -3407,9 +3421,9 @@ void RTLIL::Module::add(RTLIL::Cell *cell)
void RTLIL::Module::add(RTLIL::Process *process)
{
log_assert(!process->name.empty());
log_assert(count_id(design->twines.lookup(process->name.str())) == 0);
processes[process->name] = process;
log_assert(process->meta_ && process->meta_->name != Twine::Null);
log_assert(count_id(process->meta_->name) == 0);
processes[process->meta_->name] = process;
process->module = this;
// Propagate module back-pointer to every CaseRule/SwitchRule in the
// root case tree and every MemWriteAction in the sync rules — so the
@ -3476,15 +3490,15 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
void RTLIL::Module::remove(RTLIL::Memory *memory)
{
log_assert(memories.count(memory->name) != 0);
memories.erase(memory->name);
log_assert(memory->meta_ && memories.count(memory->meta_->name) != 0);
memories.erase(memory->meta_->name);
delete memory;
}
void RTLIL::Module::remove(RTLIL::Process *process)
{
log_assert(processes.count(process->name) != 0);
processes.erase(process->name);
log_assert(process->meta_ && processes.count(process->meta_->name) != 0);
processes.erase(process->meta_->name);
delete process;
}
@ -3729,20 +3743,30 @@ RTLIL::Cell *RTLIL::Module::addCell(Twine &&name, const RTLIL::Cell *other)
return addCell(design->twines.add(std::move(name)), other);
}
RTLIL::Memory *RTLIL::Module::addMemory(IdString name)
RTLIL::Memory *RTLIL::Module::addMemory(TwineRef name)
{
log_assert(design);
RTLIL::Memory *mem = new RTLIL::Memory;
mem->name = std::move(name);
mem->module = this;
memories[mem->name] = mem;
mem->meta_ = design->alloc_obj_meta();
mem->meta_->name = name;
memories[name] = mem;
return mem;
}
RTLIL::Memory *RTLIL::Module::addMemory(IdString name, const RTLIL::Memory *other)
RTLIL::Memory *RTLIL::Module::addMemory(Twine &&name)
{
log_assert(design);
return addMemory(design->twines.add(std::move(name)));
}
RTLIL::Memory *RTLIL::Module::addMemory(TwineRef name, const RTLIL::Memory *other)
{
log_assert(design);
RTLIL::Memory *mem = new RTLIL::Memory;
mem->name = std::move(name);
mem->module = this;
mem->meta_ = design->alloc_obj_meta();
mem->meta_->name = name;
mem->width = other->width;
mem->start_offset = other->start_offset;
mem->size = other->size;
@ -3753,18 +3777,26 @@ RTLIL::Memory *RTLIL::Module::addMemory(IdString name, const RTLIL::Memory *othe
// common case.
(void)other;
}
memories[mem->name] = mem;
memories[name] = mem;
return mem;
}
RTLIL::Process *RTLIL::Module::addProcess(IdString name)
RTLIL::Process *RTLIL::Module::addProcess(TwineRef name)
{
log_assert(design);
RTLIL::Process *proc = new RTLIL::Process;
proc->name = std::move(name);
proc->meta_ = design->alloc_obj_meta();
proc->meta_->name = name;
add(proc);
return proc;
}
RTLIL::Process *RTLIL::Module::addProcess(Twine &&name)
{
log_assert(design);
return addProcess(design->twines.add(std::move(name)));
}
namespace {
// Walk two process trees in parallel and transfer src across the
// design boundary for every AttrObject (CaseRule, SwitchRule,
@ -3806,10 +3838,13 @@ namespace {
}
}
RTLIL::Process *RTLIL::Module::addProcess(IdString name, const RTLIL::Process *other)
RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *other)
{
log_assert(design);
RTLIL::Process *proc = other->clone();
proc->name = std::move(name);
if (!proc->meta_)
proc->meta_ = design->alloc_obj_meta();
proc->meta_->name = name;
add(proc);
// Migrate src across the design boundary for the inner-process tree.
// Process::clone drops src on CaseRule/SwitchRule/MemWriteAction since
@ -6747,7 +6782,6 @@ RTLIL::Process *RTLIL::Process::clone() const
{
RTLIL::Process *new_proc = new RTLIL::Process;
new_proc->name = name;
new_proc->attributes = attributes;
// clone() drops src across the whole tree; the caller is responsible
// for migrating src via context after the clone has a module.

View file

@ -1951,8 +1951,8 @@ struct RTLIL::Selection
// add member of module to this selection
template<typename T1, typename T2> void select(T1 *module, T2 *member) {
if (!selects_all() && selected_modules.count(module->name) == 0) {
selected_members[module->name].insert(member->name);
if (!selects_all() && selected_modules.count(module->meta_->name) == 0) {
selected_members[module->meta_->name].insert(member->meta_->name);
if (module->get_blackbox_attribute())
selects_boxes = true;
}
@ -2921,13 +2921,13 @@ struct RTLIL::ModuleNameMasq {
bool operator!=(const ModuleNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); }
};
struct RTLIL::Module : public RTLIL::NamedObject, public CellAdderMixin<RTLIL::Module>
struct RTLIL::Module : public RTLIL::AttrObject, public CellAdderMixin<RTLIL::Module>
{
friend struct RTLIL::SigNormIndex;
friend struct RTLIL::Cell;
friend struct RTLIL::Design;
// [[no_unique_address]] RTLIL::ModuleNameMasq name;
[[no_unique_address]] RTLIL::ModuleNameMasq name;
Hasher::hash_t hashidx_;
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
@ -2952,8 +2952,8 @@ public:
idict<RTLIL::IdString> avail_parameters;
dict<RTLIL::IdString, RTLIL::Const> parameter_default_values;
dict<RTLIL::IdString, RTLIL::Memory*> memories;
dict<RTLIL::IdString, RTLIL::Process*> processes;
dict<TwineRef, RTLIL::Memory*> memories;
dict<TwineRef, RTLIL::Process*> processes;
// Context-aware src helpers. Resolve Design via this->design and
// route to the per-Design meta vector; assert the module is attached.
@ -3053,7 +3053,7 @@ public:
std::vector<RTLIL::Cell*> selected_cells() const;
std::vector<RTLIL::Memory*> selected_memories() const;
std::vector<RTLIL::Process*> selected_processes() const;
std::vector<RTLIL::NamedObject*> selected_members() const;
std::vector<RTLIL::AttrObject*> selected_members() const;
template<typename T> bool selected(T *member) const {
return design->selected_member(meta_->name, member->meta_->name);
@ -3122,11 +3122,13 @@ public:
return design->twines.add(Twine{Twine::Suffix{pref, std::to_string(autoidx++)}});
}
RTLIL::Memory *addMemory(RTLIL::IdString name);
RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other);
RTLIL::Memory *addMemory(TwineRef name);
RTLIL::Memory *addMemory(Twine &&name);
RTLIL::Memory *addMemory(TwineRef name, const RTLIL::Memory *other);
RTLIL::Process *addProcess(RTLIL::IdString name);
RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other);
RTLIL::Process *addProcess(TwineRef name);
RTLIL::Process *addProcess(Twine &&name);
RTLIL::Process *addProcess(TwineRef name, const RTLIL::Process *other);
// The add* methods create a cell and return the created cell. All signals must exist in advance.
@ -3298,18 +3300,6 @@ inline RTLIL::CellNameMasq::operator RTLIL::IdString() const {
return RTLIL::IdString(c->module->design->twines.flat_string(id));
}
inline RTLIL::ModuleNameMasq::operator RTLIL::IdString() const {
const RTLIL::Module *m = reinterpret_cast<const RTLIL::Module*>(
reinterpret_cast<const char*>(this) - offsetof(RTLIL::Module, name));
return m->design ? m->design->obj_name(m) : std::string();
}
inline RTLIL::ModuleNameMasq::operator TwineRef() const {
const RTLIL::Module *m = reinterpret_cast<const RTLIL::Module*>(
reinterpret_cast<const char*>(this) - offsetof(RTLIL::Module, name));
return m->design ? m->design->obj_src_id(m) : Twine::Null;
}
// inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) {
// RTLIL::Module *m = reinterpret_cast<RTLIL::Module*>(
// reinterpret_cast<char*>(this) - offsetof(RTLIL::Module, name));

View file

@ -1283,7 +1283,7 @@ void RTLIL::Cell::setPort(TwineRef portname, RTLIL::SigSpec signal)
}
if (yosys_xtrace) {
log("#X# Connect %s.%s.%s = %s (%d)\n", module ? module->name.unescape() : "PATCH", this, module->design->twines.str(portname), log_signal(signal), GetSize(signal));
log("#X# Connect %s.%s.%s = %s (%d)\n", module ? log_id(module) : "PATCH", this, module->design->twines.str(portname).c_str(), log_signal(signal), GetSize(signal));
log_backtrace("-X- ", yosys_xtrace-1);
}

View file

@ -270,11 +270,11 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
obj = mod->memories.at(obj_id, nullptr);
obj = mod->memories.at(obj_twine, nullptr);
if (!obj)
obj = mod->cell(obj_twine);
if (!obj)
obj = mod->processes.at(obj_id, nullptr);
obj = mod->processes.at(obj_twine, nullptr);
}
if (!obj)
@ -335,11 +335,11 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
obj = mod->memories.at(obj_id, nullptr);
obj = mod->memories.at(obj_twine, nullptr);
if (!obj)
obj = mod->cell(obj_twine);
if (!obj)
obj = mod->processes.at(obj_id, nullptr);
obj = mod->processes.at(obj_twine, nullptr);
}
if (!obj)
@ -390,11 +390,11 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
obj = mod->memories.at(obj_id, nullptr);
obj = mod->memories.at(obj_twine, nullptr);
if (!obj)
obj = mod->cell(obj_twine);
if (!obj)
obj = mod->processes.at(obj_id, nullptr);
obj = mod->processes.at(obj_twine, nullptr);
}
if (!obj)

View file

@ -37,9 +37,10 @@ struct TimingInfo
bool operator==(const NameBit& nb) const { return nb.name == name && nb.offset == offset; }
bool operator!=(const NameBit& nb) const { return !operator==(nb); }
std::optional<SigBit> get_connection(RTLIL::Cell *cell) {
if (!cell->hasPort(name))
TwineRef port_name = cell->module->design->twines.lookup(name.str());
if (!cell->hasPort(port_name))
return {};
auto &port = cell->getPort(name);
auto &port = cell->getPort(port_name);
if (offset >= port.size())
return {};
return port[offset];
@ -92,7 +93,7 @@ struct TimingInfo
const ModuleTiming& setup_module(RTLIL::Module *module)
{
auto r = data.insert(module->name);
auto r = data.insert(RTLIL::IdString(module->design->twines.str(module->meta_->name)));
log_assert(r.second);
auto &t = r.first->second;

View file

@ -24,7 +24,7 @@ inline std::pair<SigSpec, SigSpec> emit_fa(Module *module, SigSpec a, SigSpec b,
SigSpec sum = module->addWire(NEW_TWINE, width);
SigSpec cout = module->addWire(NEW_TWINE, width);
module->addFa(NEW_ID, a, b, c, cout, sum);
module->addFa(NEW_TWINE, a, b, c, cout, sum);
SigSpec carry;
carry.append(State::S0);

View file

@ -240,7 +240,7 @@ void yosys_setup()
already_shutdown = false;
IdString::ensure_prepopulated();
Twine::ensure_prepopulated();
twine_prepopulate();
#ifdef YOSYS_ENABLE_PYTHON
// Starting Python 3.12, calling PyImport_AppendInittab on an already
@ -364,13 +364,13 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter)
if (recursion_counter > 1)
str += stringf("(%d) ", recursion_counter);
str += "yosys";
if (!design->selected_active_module.empty())
str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module));
if (design->selected_active_module != Twine::Null)
str += stringf(" [%s]", RTLIL::unescape_id(design->twines.str(design->selected_active_module)).c_str());
if (!design->full_selection()) {
if (design->selected_active_module.empty())
if (design->selected_active_module == Twine::Null)
str += "*";
else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 ||
design->selection().selected_modules.count(design->twines.intern(design->selected_active_module)) == 0)
design->selection().selected_modules.count(design->selected_active_module) == 0)
str += "*";
}
snprintf(buffer, 100, "%s> ", str.c_str());
@ -951,11 +951,13 @@ static char *readline_obj_generator(const char *text, int state)
RTLIL::Design *design = yosys_get_design();
int len = strlen(text);
if (design->selected_active_module.empty())
if (design->selected_active_module == Twine::Null)
{
for (auto mod : design->modules())
if (mod->name.unescape().compare(0, len, text) == 0)
obj_names.push_back(strdup(mod->name.unescape().c_str()));
for (auto mod : design->modules()) {
std::string mod_name = design->twines.str(mod->meta_->name);
if (mod_name.compare(0, len, text) == 0)
obj_names.push_back(strdup(mod_name.c_str()));
}
}
else if (design->module(design->selected_active_module) != nullptr)
{
@ -965,17 +967,21 @@ static char *readline_obj_generator(const char *text, int state)
if (w->name.unescape().compare(0, len, text) == 0)
obj_names.push_back(strdup(w->name.unescape().c_str()));
for (auto &it : module->memories)
if (it.first.unescape().compare(0, len, text) == 0)
obj_names.push_back(strdup(it.first.unescape().c_str()));
for (auto &it : module->memories) {
std::string mem_name = design->twines.str(it.first);
if (mem_name.compare(0, len, text) == 0)
obj_names.push_back(strdup(mem_name.c_str()));
}
for (auto cell : module->cells())
if (cell->name.unescape().compare(0, len, text) == 0)
obj_names.push_back(strdup(cell->name.unescape().c_str()));
if (cell->module->design->twines.str(cell->meta_->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(cell->module->design->twines.str(cell->meta_->name).c_str()));
for (auto &it : module->processes)
if (it.first.unescape().compare(0, len, text) == 0)
obj_names.push_back(strdup(it.first.unescape().c_str()));
for (auto &it : module->processes) {
std::string proc_name = design->twines.str(it.first);
if (proc_name.compare(0, len, text) == 0)
obj_names.push_back(strdup(proc_name.c_str()));
}
}
std::sort(obj_names.begin(), obj_names.end());