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-12 00:18:53 +02:00
parent afdae7b87e
commit c3ffbf6fae
229 changed files with 3902 additions and 3835 deletions

View file

@ -302,60 +302,60 @@ Aig::Aig(Cell *cell)
}
}
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_)))
if (cell->type.in(TW($not), TW($_NOT_), TW($pos), TW($buf), TW($_BUF_)))
{
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); i++) {
int A = mk.inport(TW::A, i);
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
int Y = cell->type.in(TW($not), TW($_NOT_)) ? mk.not_gate(A) : A;
mk.outport(Y, TW::Y, i);
}
goto optimize;
}
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_)))
if (cell->type.in(TW($and), TW($_AND_), TW($_NAND_), TW($or), TW($_OR_), TW($_NOR_), TW($xor), TW($xnor), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_)))
{
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); 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) :
cell->type.in(ID($_NOR_)) ? mk.nor_gate(A, B) :
cell->type.in(ID($xor), ID($_XOR_)) ? mk.xor_gate(A, B) :
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;
int Y = cell->type.in(TW($and), TW($_AND_)) ? mk.and_gate(A, B) :
cell->type.in(TW($_NAND_)) ? mk.nand_gate(A, B) :
cell->type.in(TW($or), TW($_OR_)) ? mk.or_gate(A, B) :
cell->type.in(TW($_NOR_)) ? mk.nor_gate(A, B) :
cell->type.in(TW($xor), TW($_XOR_)) ? mk.xor_gate(A, B) :
cell->type.in(TW($xnor), TW($_XNOR_)) ? mk.xnor_gate(A, B) :
cell->type.in(TW($_ANDNOT_)) ? mk.andnot_gate(A, B) :
cell->type.in(TW($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
mk.outport(Y, TW::Y, i);
}
goto optimize;
}
if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_)))
if (cell->type.in(TW($mux), TW($_MUX_), TW($_NMUX_)))
{
int S = mk.inport(TW::S);
for (int i = 0; i < GetSize(cell->getPort(TW::Y)); 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_))
if (cell->type == TW($_NMUX_))
Y = mk.not_gate(Y);
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)))
if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool)))
{
int Y = mk.inport(TW::A, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::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);
if (cell->type == ID($reduce_xor)) Y = mk.xor_gate(A, Y);
if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y);
if (cell->type == TW($reduce_and)) Y = mk.and_gate(A, Y);
if (cell->type == TW($reduce_or)) Y = mk.or_gate(A, Y);
if (cell->type == TW($reduce_bool)) Y = mk.or_gate(A, Y);
if (cell->type == TW($reduce_xor)) Y = mk.xor_gate(A, Y);
if (cell->type == TW($reduce_xnor)) Y = mk.xor_gate(A, Y);
}
if (cell->type == ID($reduce_xnor))
if (cell->type == TW($reduce_xnor))
Y = mk.not_gate(Y);
mk.outport(Y, TW::Y, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::Y)); i++)
@ -363,31 +363,31 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
if (cell->type.in(TW($logic_not), TW($logic_and), TW($logic_or)))
{
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(TW::A, i), A);
if (cell->type.in(ID($logic_and), ID($logic_or))) {
if (cell->type.in(TW($logic_and), TW($logic_or))) {
int B = mk.inport(TW::B, 0);
for (int i = 1; i < GetSize(cell->getPort(TW::B)); i++)
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);
if (cell->type == TW($logic_and)) Y = mk.and_gate(A, B);
if (cell->type == TW($logic_or)) Y = mk.or_gate(A, B);
} else {
if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
if (cell->type == TW($logic_not)) Y = mk.not_gate(A);
}
mk.outport_bool(Y, TW::Y);
goto optimize;
}
if (cell->type.in(ID($add), ID($sub)))
if (cell->type.in(TW($add), TW($sub)))
{
int width = GetSize(cell->getPort(TW::Y));
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)) {
if (cell->type == TW($sub)) {
for (auto &n : B)
n = mk.not_gate(n);
carry = mk.not_gate(carry);
@ -397,17 +397,17 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge)))
if (cell->type.in(TW($lt), TW($gt), TW($le), TW($ge)))
{
int width = std::max(GetSize(cell->getPort(TW::A)),
GetSize(cell->getPort(TW::B))) + 1;
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)))
if (cell->type.in(TW($gt), TW($ge)))
std::swap(A, B);
int carry = mk.bool_node(!cell->type.in(ID($le), ID($ge)));
int carry = mk.bool_node(!cell->type.in(TW($le), TW($ge)));
for (auto &n : B)
n = mk.not_gate(n);
vector<int> Y = mk.adder(A, B, carry);
@ -417,7 +417,7 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type == ID($alu))
if (cell->type == TW($alu))
{
int width = GetSize(cell->getPort(TW::Y));
vector<int> A = mk.inport_vec(TW::A, width);
@ -436,7 +436,7 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type.in(ID($eq), ID($ne)))
if (cell->type.in(TW($eq), TW($ne)))
{
int width = max(GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::B)));
vector<int> A = mk.inport_vec(TW::A, width);
@ -444,13 +444,13 @@ Aig::Aig(Cell *cell)
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))
if (cell->type == TW($eq))
Y = mk.not_gate(Y);
mk.outport_bool(Y, TW::Y);
goto optimize;
}
if (cell->type == ID($_AOI3_))
if (cell->type == TW($_AOI3_))
{
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
@ -460,7 +460,7 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type == ID($_OAI3_))
if (cell->type == TW($_OAI3_))
{
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
@ -470,7 +470,7 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type == ID($_AOI4_))
if (cell->type == TW($_AOI4_))
{
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);
@ -482,7 +482,7 @@ Aig::Aig(Cell *cell)
goto optimize;
}
if (cell->type == ID($_OAI4_))
if (cell->type == TW($_OAI4_))
{
int A = mk.inport(TW::A);
int B = mk.inport(TW::B);

View file

@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
bool is_signed = (cell->type != ID($buf)) && cell->getParam(ID::A_SIGNED).as_bool();
bool is_signed = (cell->type != TW($buf)) && cell->getParam(ID::A_SIGNED).as_bool();
int a_width = GetSize(cell->getPort(TW::A));
int y_width = GetSize(cell->getPort(TW::Y));
@ -44,7 +44,7 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B));
int y_width = GetSize(cell->getPort(TW::Y));
if (cell->type == ID($and) && !is_signed) {
if (cell->type == TW($and) && !is_signed) {
if (a_width > b_width)
a_width = b_width;
else
@ -86,7 +86,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
int b_width = GetSize(cell->getPort(TW::B));
int y_width = GetSize(cell->getPort(TW::Y));
if (!is_signed && cell->type != ID($sub)) {
if (!is_signed && cell->type != TW($sub)) {
int ab_width = std::max(a_width, b_width);
y_width = std::min(y_width, ab_width+1);
}
@ -252,16 +252,16 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
// lowest position of A that can be moved to Y[i]
int a_range_lower;
if (cell->type.in(ID($shl), ID($sshl))) {
if (cell->type.in(TW($shl), TW($sshl))) {
b_range_upper = a_width + b_high;
if (is_signed) b_range_upper -= 1;
a_range_lower = max(0, i - b_high);
a_range_upper = min(i+1, a_width);
} else if (cell->type.in(ID($shr), ID($sshr)) || (cell->type.in(ID($shift), ID($shiftx)) && !is_b_signed)) {
} else if (cell->type.in(TW($shr), TW($sshr)) || (cell->type.in(TW($shift), TW($shiftx)) && !is_b_signed)) {
b_range_upper = a_width;
a_range_lower = min(i, a_width - 1);
a_range_upper = min(i+1 + b_high, a_width);
} else if (cell->type.in(ID($shift), ID($shiftx)) && is_b_signed) {
} else if (cell->type.in(TW($shift), TW($shiftx)) && is_b_signed) {
// can go both ways depending on sign of B
// 2's complement range is different depending on direction
b_range_upper = a_width - b_low;
@ -284,7 +284,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int k = 0; k < b_width_capped; k++) {
// left shifts
if (cell->type.in(ID($shl), ID($sshl))) {
if (cell->type.in(TW($shl), TW($sshl))) {
if (a_width == 1 && is_signed) {
int skip = 1 << (k + 1);
int base = skip -1;
@ -298,21 +298,21 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
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)) {
} else if (cell->type.in(TW($shr), TW($sshr)) || (cell->type.in(TW($shift), TW($shiftx)) && !is_b_signed)) {
if (is_signed) {
bool shift_in_bulk = i < a_width - 1;
// can we jump into the zero-padding by toggling B[k]?
bool zpad_jump = (((y_width - i) & ((1 << (k + 1)) - 1)) != 0 \
&& (((y_width - i) & ~(1 << k)) < (1 << b_width_capped)));
if (shift_in_bulk || (cell->type.in(ID($shr), ID($shift), ID($shiftx)) && zpad_jump))
if (shift_in_bulk || (cell->type.in(TW($shr), TW($shift), TW($shiftx)) && zpad_jump))
db->add_edge(cell, TW::B, k, TW::Y, i, -1);
} else {
if (i < a_width)
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) {
} else if (cell->type.in(TW($shift), TW($shiftx)) && is_b_signed) {
if (is_signed) {
if (k != b_width_capped - 1) {
bool r_shift_in_bulk = i < a_width - 1;
@ -344,7 +344,7 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
log_assert(cell->type == ID($mem_v2));
log_assert(cell->type == TW($mem_v2));
Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
int n_rd_ports = cell->getParam(ID::RD_PORTS).as_int();
int abits = cell->getParam(ID::ABITS).as_int();
@ -366,12 +366,12 @@ void packed_mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
log_assert(cell->type.in(ID($memrd), ID($memrd_v2)));
log_assert(cell->type.in(TW($memrd), TW($memrd_v2)));
int abits = cell->getParam(ID::ABITS).as_int();
int width = cell->getParam(ID::WIDTH).as_int();
if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
if (cell->type == ID($memrd_v2)) {
if (cell->type == TW($memrd_v2)) {
for (int k = 0; k < width; k++)
db->add_edge(cell, TW::ARST, 0, TW::DATA, k, -1);
}
@ -385,11 +385,11 @@ void memrd_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void mem_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
if (cell->type == ID($mem_v2))
if (cell->type == TW($mem_v2))
packed_mem_op(db, cell);
else if (cell->type.in(ID($memrd), ID($memrd_v2)))
else if (cell->type.in(TW($memrd), TW($memrd_v2)))
memrd_op(db, cell);
else if (cell->type.in(ID($memwr), ID($memwr_v2), ID($meminit)))
else if (cell->type.in(TW($memwr), TW($memwr_v2), TW($meminit)))
return; /* no edges here */
else
log_abort();
@ -399,7 +399,7 @@ void ff_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
int width = cell->getPort(TW::Q).size();
if (cell->type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) {
if (cell->type.in(TW($dlatch), TW($adlatch), TW($dlatchsr))) {
for (int k = 0; k < width; k++) {
db->add_edge(cell, TW::D, k, TW::Q, k, -1);
db->add_edge(cell, TW::EN, 0, TW::Q, k, -1);
@ -485,82 +485,82 @@ PRIVATE_NAMESPACE_END
bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)
{
if (cell->type.in(ID($not), ID($pos), ID($buf))) {
if (cell->type.in(TW($not), TW($pos), TW($buf))) {
bitwise_unary_op(this, cell);
return true;
}
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
if (cell->type.in(TW($and), TW($or), TW($xor), TW($xnor))) {
bitwise_binary_op(this, cell);
return true;
}
if (cell->type == ID($neg)) {
if (cell->type == TW($neg)) {
arith_neg_op(this, cell);
return true;
}
if (cell->type.in(ID($add), ID($sub))) {
if (cell->type.in(TW($add), TW($sub))) {
arith_binary_op(this, cell);
return true;
}
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) {
if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($logic_not))) {
reduce_op(this, cell);
return true;
}
if (cell->type.in(ID($logic_and), ID($logic_or))) {
if (cell->type.in(TW($logic_and), TW($logic_or))) {
logic_op(this, cell);
return true;
}
if (cell->type == ID($slice)) {
if (cell->type == TW($slice)) {
slice_op(this, cell);
return true;
}
if (cell->type == ID($concat)) {
if (cell->type == TW($concat)) {
concat_op(this, cell);
return true;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx))) {
shift_op(this, cell);
return true;
}
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
if (cell->type.in(TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt))) {
compare_op(this, cell);
return true;
}
if (cell->type.in(ID($mux), ID($pmux))) {
if (cell->type.in(TW($mux), TW($pmux))) {
mux_op(this, cell);
return true;
}
if (cell->type == ID($bmux)) {
if (cell->type == TW($bmux)) {
bmux_op(this, cell);
return true;
}
if (cell->type == ID($demux)) {
if (cell->type == TW($demux)) {
demux_op(this, cell);
return true;
}
if (cell->type == ID($bweqx)) {
if (cell->type == TW($bweqx)) {
bweqx_op(this, cell);
return true;
}
if (cell->type == ID($bwmux)) {
if (cell->type == TW($bwmux)) {
bwmux_op(this, cell);
return true;
}
if (cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit))) {
if (cell->type.in(TW($mem_v2), TW($memrd), TW($memrd_v2), TW($memwr), TW($memwr_v2), TW($meminit))) {
mem_op(this, cell);
return true;
}
@ -570,21 +570,21 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true;
}
if (cell->type.in(ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow))) {
if (cell->type.in(TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow))) {
full_op(this, cell);
return true;
}
if (cell->type.in(ID($lut), ID($sop), ID($alu), ID($lcu), ID($macc), ID($macc_v2))) {
if (cell->type.in(TW($lut), TW($sop), TW($alu), TW($lcu), TW($macc), TW($macc_v2))) {
full_op(this, cell);
return true;
}
if (cell->type.in(
ID($_BUF_), ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_),
ID($_MUX4_), ID($_MUX8_), ID($_MUX16_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_),
ID($_OAI4_), ID($_TBUF_))) {
TW($_BUF_), TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_), TW($_MUX_), TW($_NMUX_),
TW($_MUX4_), TW($_MUX8_), TW($_MUX16_), TW($_AOI3_), TW($_OAI3_), TW($_AOI4_),
TW($_OAI4_), TW($_TBUF_))) {
full_op(this, cell);
return true;
}
@ -592,7 +592,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
// FIXME: $specify2 $specify3 $specrule ???
// FIXME: $equiv $set_tag $get_tag $overwrite_tag $original_tag
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($initstate), ID($anyconst), ID($anyseq), ID($allconst), ID($allseq)))
if (cell->type.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover), TW($initstate), TW($anyconst), TW($anyseq), TW($allconst), TW($allseq)))
return true; // no-op: these have either no inputs or no outputs
return false;

View file

@ -65,6 +65,11 @@ struct CellTypes
cell_types[ct.type] = ct;
}
void setup_type(const std::string &type_str, const pool<TwineRef> &inputs, const pool<TwineRef> &outputs, bool is_evaluable = false, bool is_combinatorial = false, bool is_synthesizable = false)
{
setup_type(TW::lookup(type_str), inputs, outputs, is_evaluable, is_combinatorial, is_synthesizable);
}
void setup_module(RTLIL::Module *module)
{
pool<TwineRef> inputs, outputs;
@ -230,77 +235,77 @@ struct CellTypes
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(TW($1), {TW::S, TW::R}, {TW::Q});
setup_type(stringf("$_SR_%c%c_", c1, c2), {TW::S, TW::R}, {TW::Q});
setup_type(TW($_FF_), {TW::D}, {TW::Q});
for (auto c1 : list_np)
setup_type(TW($1), {TW::C, TW::D}, {TW::Q});
setup_type(stringf("$_DFF_%c_", c1), {TW::C, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(TW($1), {TW::C, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_DFFE_%c%c_", c1, c2), {TW::C, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q});
setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q});
setup_type(stringf("$_ALDFF_%c%c_", c1, c2), {TW::C, TW::L, TW::AD, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(TW($1), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_ALDFFE_%c%c%c_", c1, c2, c3), {TW::C, TW::L, TW::AD, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D}, {TW::Q});
setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {TW::C, TW::S, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::S, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(TW($1), {TW::C, TW::R, TW::D}, {TW::Q});
setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {TW::C, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_SDFFE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(TW($1), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
setup_type(stringf("$_SDFFCE_%c%c%c%c_", c1, c2, c3, c4), {TW::C, TW::R, TW::D, TW::E}, {TW::Q});
for (auto c1 : list_np)
setup_type(TW($1), {TW::E, TW::D}, {TW::Q});
setup_type(stringf("$_DLATCH_%c_", c1), {TW::E, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(TW($1), {TW::E, TW::R, TW::D}, {TW::Q});
setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {TW::E, TW::R, TW::D}, {TW::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
setup_type(TW($1), {TW::E, TW::S, TW::R, TW::D}, {TW::Q});
setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {TW::E, TW::S, TW::R, TW::D}, {TW::Q});
}
void clear()

View file

@ -49,10 +49,10 @@ struct ConstEval
ct.static_cell_types = StaticCellTypes::Compat::nomem_noff;
for (auto &it : module->cells_) {
if (!ct.cell_known(it.second->type))
if (!ct.cell_known(it.second->type_impl))
continue;
for (auto &it2 : it.second->connections())
if (ct.cell_output(it.second->type, it2.first))
if (ct.cell_output(it.second->type_impl, it2.first))
sig2driver.insert(assign_map(it2.second), it.second);
}
}
@ -93,7 +93,7 @@ struct ConstEval
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
{
if (cell->type == ID($lcu))
if (cell->type == TW($lcu))
{
RTLIL::SigSpec sig_p = cell->getPort(TW::P);
RTLIL::SigSpec sig_g = cell->getPort(TW::G);
@ -147,7 +147,7 @@ struct ConstEval
if (cell->hasPort(TW::B))
sig_b = cell->getPort(TW::B);
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
if (cell->type.in(TW($mux), TW($pmux), TW($_MUX_), TW($_NMUX_)))
{
std::vector<RTLIL::SigSpec> y_candidates;
int count_set_s_bits = 0;
@ -176,7 +176,7 @@ struct ConstEval
for (auto &yc : y_candidates) {
if (!eval(yc, undef, cell))
return false;
if (cell->type == ID($_NMUX_))
if (cell->type == TW($_NMUX_))
y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc)));
else
y_values.push_back(yc.as_const());
@ -199,7 +199,7 @@ struct ConstEval
else
set(sig_y, y_values.front());
}
else if (cell->type == ID($bmux))
else if (cell->type == TW($bmux))
{
if (!eval(sig_s, undef, cell))
return false;
@ -217,7 +217,7 @@ struct ConstEval
set(sig_y, const_bmux(sig_a.as_const(), sig_s.as_const()));
}
}
else if (cell->type == ID($demux))
else if (cell->type == TW($demux))
{
if (!eval(sig_a, undef, cell))
return false;
@ -229,7 +229,7 @@ struct ConstEval
set(sig_y, const_demux(sig_a.as_const(), sig_s.as_const()));
}
}
else if (cell->type == ID($fa))
else if (cell->type == TW($fa))
{
RTLIL::SigSpec sig_c = cell->getPort(TW::C);
RTLIL::SigSpec sig_x = cell->getPort(TW::X);
@ -258,7 +258,7 @@ struct ConstEval
set(sig_y, val_y);
set(sig_x, val_x);
}
else if (cell->type == ID($alu))
else if (cell->type == TW($alu))
{
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
@ -314,7 +314,7 @@ struct ConstEval
}
}
}
else if (cell->type.in(ID($macc), ID($macc_v2)))
else if (cell->type.in(TW($macc), TW($macc_v2)))
{
Macc macc;
macc.from_cell(cell);
@ -336,7 +336,7 @@ struct ConstEval
{
RTLIL::SigSpec sig_c, sig_d;
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
if (cell->type.in(TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_))) {
if (cell->hasPort(TW::C))
sig_c = cell->getPort(TW::C);
if (cell->hasPort(TW::D))

View file

@ -22,24 +22,24 @@ static unsigned int y_coef(TwineRef type)
{
if (
// equality
type.in(ID($bweqx), ID($nex), ID($eqx)) ||
type.in(TW($bweqx), TW($nex), TW($eqx)) ||
// basic logic
type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($not)) ||
type.in(TW($and), TW($or), TW($xor), TW($xnor), TW($not)) ||
// mux
type.in(ID($bwmux), ID($mux)) ||
type.in(TW($bwmux), TW($mux)) ||
// others
type == ID($tribuf)) {
type == TW($tribuf)) {
return 1;
} else if (type == ID($neg)) {
} else if (type == TW($neg)) {
return 4;
} else if (type == ID($demux)) {
} else if (type == TW($demux)) {
return 2;
} else if (type == ID($fa)) {
} else if (type == TW($fa)) {
return 5;
} else if (type.in(ID($add), ID($sub), ID($alu))) {
} else if (type.in(TW($add), TW($sub), TW($alu))) {
// multi-bit adders
return 8;
} else if (type.in(ID($shl), ID($sshl))) {
} else if (type.in(TW($shl), TW($sshl))) {
// left shift
return 10;
}
@ -50,19 +50,19 @@ static unsigned int max_inp_coef(TwineRef type)
{
if (
// binop reduce
type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)) ||
type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool)) ||
// others
type.in(ID($logic_not), ID($pmux), ID($bmux))) {
type.in(TW($logic_not), TW($pmux), TW($bmux))) {
return 1;
} else if (
// equality
type.in(ID($eq), ID($ne)) ||
type.in(TW($eq), TW($ne)) ||
// logic
type.in(ID($logic_and), ID($logic_or))) {
type.in(TW($logic_and), TW($logic_or))) {
return 2;
} else if (type == ID($lcu)) {
} else if (type == TW($lcu)) {
return 5;
} else if (type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
} else if (type.in(TW($lt), TW($le), TW($ge), TW($gt))) {
// comparison
return 7;
}
@ -71,10 +71,10 @@ static unsigned int max_inp_coef(TwineRef type)
static unsigned int sum_coef(TwineRef type)
{
if (type.in(ID($shr), ID($sshr))) {
if (type.in(TW($shr), TW($sshr))) {
// right shift
return 4;
} else if (type.in(ID($shift), ID($shiftx))) {
} else if (type.in(TW($shift), TW($shiftx))) {
// shift
return 8;
}
@ -83,23 +83,23 @@ static unsigned int sum_coef(TwineRef type)
static unsigned int is_div_mod(TwineRef type)
{
return (type == ID($div) || type == ID($divfloor) || type == ID($mod) || type == ID($modfloor));
return (type == TW($div) || type == TW($divfloor) || type == TW($mod) || type == TW($modfloor));
}
static bool is_free(TwineRef type)
{
return (
// tags
type.in(ID($overwrite_tag), ID($set_tag), ID($original_tag), ID($get_tag)) ||
type.in(TW($overwrite_tag), TW($set_tag), TW($original_tag), TW($get_tag)) ||
// formal
type.in(ID($check), ID($equiv), ID($initstate), ID($assert), ID($assume), ID($live), ID($cover), ID($fair)) ||
type.in(ID($allseq), ID($allconst), ID($anyseq), ID($anyconst), ID($anyinit)) ||
type.in(TW($check), TW($equiv), TW($initstate), TW($assert), TW($assume), TW($live), TW($cover), TW($fair)) ||
type.in(TW($allseq), TW($allconst), TW($anyseq), TW($anyconst), TW($anyinit)) ||
// utilities
type.in(ID($scopeinfo), ID($print)) ||
type.in(TW($scopeinfo), TW($print)) ||
// real but free
type.in(ID($concat), ID($slice), ID($pos)) ||
type.in(TW($concat), TW($slice), TW($pos)) ||
// specify
type.in(ID($specrule), ID($specify2), ID($specify3)));
type.in(TW($specrule), TW($specify2), TW($specify3)));
}
unsigned int max_inp_width(RTLIL::Cell *cell)
@ -112,7 +112,7 @@ unsigned int max_inp_width(RTLIL::Cell *cell)
ID::S_WIDTH,
};
if (cell->type == ID($bmux))
if (cell->type == TW($bmux))
return cell->getParam(ID::WIDTH).as_int() << cell->getParam(ID::S_WIDTH).as_int();
for (RTLIL::IdString param : input_width_params)
@ -139,7 +139,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
{
// simple 1-bit cells
if (cmos_gate_cost().count(cell->type))
if (cmos_gate_cost().count(cell->type_impl))
return 1;
if (design_ && design_->module(cell->type) && cell->parameters.empty()) {
@ -149,35 +149,35 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
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))) {
} else if (cell->type.in(TW($mem), TW($mem_v2))) {
log_debug("%s is mem\n", cell->name);
return cell->getParam(ID::WIDTH).as_int() * cell->getParam(ID::SIZE).as_int();
} else if (y_coef(cell->type)) {
} else if (y_coef(cell->type.ref())) {
// linear with Y_WIDTH or WIDTH
log_assert((cell->hasParam(ID::Y_WIDTH) || cell->hasParam(ID::WIDTH)) && "Unknown width");
auto param = cell->hasParam(ID::Y_WIDTH) ? ID::Y_WIDTH : ID::WIDTH;
int width = cell->getParam(param).as_int();
if (cell->type == ID($demux))
if (cell->type == TW($demux))
width <<= cell->getParam(ID::S_WIDTH).as_int();
log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type));
return width * y_coef(cell->type);
} else if (sum_coef(cell->type)) {
log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type.ref()));
return width * y_coef(cell->type.ref());
} else if (sum_coef(cell->type.ref())) {
// linear with sum of port widths
unsigned int sum = port_width_sum(cell);
log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type));
return sum * sum_coef(cell->type);
} else if (max_inp_coef(cell->type)) {
log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type.ref()));
return sum * sum_coef(cell->type.ref());
} else if (max_inp_coef(cell->type.ref())) {
// linear with largest input width
unsigned int max = max_inp_width(cell);
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type));
return max * max_inp_coef(cell->type);
} else if (is_div_mod(cell->type) || cell->type == ID($mul)) {
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type.ref()));
return max * max_inp_coef(cell->type.ref());
} else if (is_div_mod(cell->type.ref()) || cell->type == TW($mul)) {
// quadratic with sum of port widths
unsigned int sum = port_width_sum(cell);
unsigned int coef = cell->type == ID($mul) ? 3 : 5;
unsigned int coef = cell->type == TW($mul) ? 3 : 5;
log_debug("%s coef*(sum**2) %d * %d\n", cell->name, coef, sum * sum);
return coef * sum * sum;
} else if (cell->type.in(ID($macc), ID($macc_v2))) {
} else if (cell->type.in(TW($macc), TW($macc_v2))) {
// quadratic per term
unsigned int cost_sum = 0;
Macc macc;
@ -193,17 +193,17 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
cost_sum += 3 * sum * sum;
}
return cost_sum;
} else if (cell->type == ID($lut)) {
} else if (cell->type == TW($lut)) {
int width = cell->getParam(ID::WIDTH).as_int();
unsigned int cost = 1U << (unsigned int)width;
log_debug("%s is 2**%d\n", cell->name, width);
return cost;
} else if (cell->type == ID($sop)) {
} else if (cell->type == TW($sop)) {
int width = cell->getParam(ID::WIDTH).as_int();
int depth = cell->getParam(ID::DEPTH).as_int();
log_debug("%s is (2*%d + 1)*%d\n", cell->name, width, depth);
return (2 * width + 1) * depth;
} else if (is_free(cell->type)) {
} else if (is_free(cell->type.ref())) {
log_debug("%s is free\n", cell->name);
return 0;
}

View file

@ -34,52 +34,52 @@ struct CellCosts
public:
CellCosts(RTLIL::Design *design) : design_(design) { }
static const dict<RTLIL::IdString, int>& default_gate_cost() {
static const dict<TwineRef, int>& default_gate_cost() {
// Default size heuristics for several common PDK standard cells
// used by abc and stat
static const dict<RTLIL::IdString, int> db = {
{ ID($_BUF_), 1 },
{ ID($_NOT_), 2 },
{ ID($_AND_), 4 },
{ ID($_NAND_), 4 },
{ ID($_OR_), 4 },
{ ID($_NOR_), 4 },
{ ID($_ANDNOT_), 4 },
{ ID($_ORNOT_), 4 },
{ ID($_XOR_), 5 },
{ ID($_XNOR_), 5 },
{ ID($_AOI3_), 6 },
{ ID($_OAI3_), 6 },
{ ID($_AOI4_), 7 },
{ ID($_OAI4_), 7 },
{ ID($_MUX_), 4 },
{ ID($_NMUX_), 4 },
static const dict<TwineRef, int> db = {
{ TW($_BUF_), 1 },
{ TW($_NOT_), 2 },
{ TW($_AND_), 4 },
{ TW($_NAND_), 4 },
{ TW($_OR_), 4 },
{ TW($_NOR_), 4 },
{ TW($_ANDNOT_), 4 },
{ TW($_ORNOT_), 4 },
{ TW($_XOR_), 5 },
{ TW($_XNOR_), 5 },
{ TW($_AOI3_), 6 },
{ TW($_OAI3_), 6 },
{ TW($_AOI4_), 7 },
{ TW($_OAI4_), 7 },
{ TW($_MUX_), 4 },
{ TW($_NMUX_), 4 },
};
return db;
}
static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
static const dict<TwineRef, int>& cmos_gate_cost() {
// Estimated CMOS transistor counts for several common PDK standard cells
// used by stat and optionally by abc
static const dict<RTLIL::IdString, int> db = {
{ ID($_BUF_), 1 },
{ ID($_NOT_), 2 },
{ ID($_AND_), 6 },
{ ID($_NAND_), 4 },
{ ID($_OR_), 6 },
{ ID($_NOR_), 4 },
{ ID($_ANDNOT_), 6 },
{ ID($_ORNOT_), 6 },
{ ID($_XOR_), 12 },
{ ID($_XNOR_), 12 },
{ ID($_AOI3_), 6 },
{ ID($_OAI3_), 6 },
{ ID($_AOI4_), 8 },
{ ID($_OAI4_), 8 },
{ ID($_MUX_), 12 },
{ ID($_NMUX_), 10 },
{ ID($_DFF_P_), 16 },
{ ID($_DFF_N_), 16 },
static const dict<TwineRef, int> db = {
{ TW($_BUF_), 1 },
{ TW($_NOT_), 2 },
{ TW($_AND_), 6 },
{ TW($_NAND_), 4 },
{ TW($_OR_), 6 },
{ TW($_NOR_), 4 },
{ TW($_ANDNOT_), 6 },
{ TW($_ORNOT_), 6 },
{ TW($_XOR_), 12 },
{ TW($_XNOR_), 12 },
{ TW($_AOI3_), 6 },
{ TW($_OAI3_), 6 },
{ TW($_AOI4_), 8 },
{ TW($_OAI4_), 8 },
{ TW($_MUX_), 12 },
{ TW($_NMUX_), 10 },
{ TW($_DFF_P_), 16 },
{ TW($_DFF_N_), 16 },
};
return db;
}

View file

@ -537,8 +537,8 @@ DriverMap::BitMode DriverMap::bit_mode(DriveBit const &bit)
}
case DriveType::PORT: {
auto const &port = bit.port();
bool driver = celltypes.cell_output(port.cell->type, port.port);
bool driven = celltypes.cell_input(port.cell->type, port.port);
bool driver = celltypes.cell_output(port.cell->type.ref(), port.port);
bool driven = celltypes.cell_input(port.cell->type.ref(), port.port);
if (driver && !driven)
return BitMode::DRIVER;
else if (driven && !driver)
@ -866,7 +866,7 @@ DriveSpec DriverMap::operator()(DriveSpec spec)
std::string log_signal(DriveChunkWire const &chunk)
{
std::string id = chunk.wire->name.unescape();
std::string id = design->twines.unescaped_str(chunk.wire->name);
if (chunk.is_whole())
return id;
if (chunk.width == 1)

View file

@ -54,19 +54,19 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
std::string type_str = type.str();
if (type.in(ID($anyinit), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($dlatch), ID($adlatch), ID($dlatchsr), ID($sr))) {
if (type.in(ID($anyinit), ID($ff))) {
if (type.in(TW($anyinit), TW($ff), TW($dff), TW($dffe), TW($dffsr), TW($dffsre), TW($adff), TW($adffe), TW($aldff), TW($aldffe), TW($sdff), TW($sdffe), TW($sdffce), TW($dlatch), TW($adlatch), TW($dlatchsr), TW($sr))) {
if (type.in(TW($anyinit), TW($ff))) {
info.has_gclk = true;
if constexpr (have_cell)
info.sig_d = cell->getPort(TW::D);
if (type == ID($anyinit)) {
if (type == TW($anyinit)) {
info.is_anyinit = true;
if constexpr (have_cell)
log_assert(info.val_init.is_fully_undef());
}
} else if (type == ID($sr)) {
} else if (type == TW($sr)) {
// No data input at all.
} else if (type.in(ID($dlatch), ID($adlatch), ID($dlatchsr))) {
} else if (type.in(TW($dlatch), TW($adlatch), TW($dlatchsr))) {
info.has_aload = true;
if constexpr (have_cell) {
info.sig_aload = cell->getPort(TW::EN);
@ -81,14 +81,14 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.sig_d = cell->getPort(TW::D);
}
}
if (type.in(ID($dffe), ID($dffsre), ID($adffe), ID($aldffe), ID($sdffe), ID($sdffce))) {
if (type.in(TW($dffe), TW($dffsre), TW($adffe), TW($aldffe), TW($sdffe), TW($sdffce))) {
info.has_ce = true;
if constexpr (have_cell) {
info.sig_ce = cell->getPort(TW::EN);
info.pol_ce = cell->getParam(ID::EN_POLARITY).as_bool();
}
}
if (type.in(ID($dffsr), ID($dffsre), ID($dlatchsr), ID($sr))) {
if (type.in(TW($dffsr), TW($dffsre), TW($dlatchsr), TW($sr))) {
info.has_sr = true;
if constexpr (have_cell) {
info.sig_clr = cell->getPort(TW::CLR);
@ -97,7 +97,7 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.pol_set = cell->getParam(ID::SET_POLARITY).as_bool();
}
}
if (type.in(ID($aldff), ID($aldffe))) {
if (type.in(TW($aldff), TW($aldffe))) {
info.has_aload = true;
if constexpr (have_cell) {
info.sig_aload = cell->getPort(TW::ALOAD);
@ -105,7 +105,7 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.sig_ad = cell->getPort(TW::AD);
}
}
if (type.in(ID($adff), ID($adffe), ID($adlatch))) {
if (type.in(TW($adff), TW($adffe), TW($adlatch))) {
info.has_arst = true;
if constexpr (have_cell) {
info.sig_arst = cell->getPort(TW::ARST);
@ -113,16 +113,16 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) {
info.val_arst = cell->getParam(ID::ARST_VALUE);
}
}
if (type.in(ID($sdff), ID($sdffe), ID($sdffce))) {
if (type.in(TW($sdff), TW($sdffe), TW($sdffce))) {
info.has_srst = true;
if constexpr (have_cell) {
info.sig_srst = cell->getPort(TW::SRST);
info.pol_srst = cell->getParam(ID::SRST_POLARITY).as_bool();
info.val_srst = cell->getParam(ID::SRST_VALUE);
}
info.ce_over_srst = type == ID($sdffce);
info.ce_over_srst = type == TW($sdffce);
}
} else if (type == ID($_FF_)) {
} else if (type == TW($_FF_)) {
info.is_fine = true;
info.has_gclk = true;
if constexpr (have_cell)
@ -815,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->design->twines.str(module->meta_->name).c_str(), cell->module->design->twines.str(cell->meta_->name), 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->name, cell->type.unescape());
}
if (is_fine) {

View file

@ -67,7 +67,7 @@ const char *fn_to_string(Fn fn) {
log_error("fn_to_string: unknown Functional::Fn value %d", (int)fn);
}
vector<IRInput const*> IR::inputs(IdString kind) const {
vector<IRInput const*> IR::inputs(TwineRef kind) const {
vector<IRInput const*> ret;
for (const auto &[name, input] : _inputs)
if(input.kind == kind)
@ -75,7 +75,7 @@ vector<IRInput const*> IR::inputs(IdString kind) const {
return ret;
}
vector<IROutput const*> IR::outputs(IdString kind) const {
vector<IROutput const*> IR::outputs(TwineRef kind) const {
vector<IROutput const*> ret;
for (const auto &[name, output] : _outputs)
if(output.kind == kind)
@ -83,7 +83,7 @@ vector<IROutput const*> IR::outputs(IdString kind) const {
return ret;
}
vector<IRState const*> IR::states(IdString kind) const {
vector<IRState const*> IR::states(TwineRef kind) const {
vector<IRState const*> ret;
for (const auto &[name, state] : _states)
if(state.kind == kind)
@ -136,7 +136,7 @@ struct PrintVisitor : DefaultVisitor<std::string> {
std::string Node::to_string()
{
return to_string([](Node n) { return n.name().unescape(); });
return to_string([](Node n) { return design->twines.unescaped_str(n.name()); });
}
std::string Node::to_string(std::function<std::string(Node)> np)
@ -253,87 +253,87 @@ public:
int y_width = parameters.at(ID(Y_WIDTH), Const(-1)).as_int();
bool a_signed = parameters.at(ID(A_SIGNED), Const(0)).as_bool();
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))){
if(cellType.in(TW($add), TW($sub), TW($and), TW($or), TW($xor), TW($xnor), TW($mul))){
bool is_signed = a_signed && b_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))
if(cellType == TW($add))
return factory.add(a, b);
else if(cellType == ID($sub))
else if(cellType == TW($sub))
return factory.sub(a, b);
else if(cellType == ID($mul))
else if(cellType == TW($mul))
return factory.mul(a, b);
else if(cellType == ID($and))
else if(cellType == TW($and))
return factory.bitwise_and(a, b);
else if(cellType == ID($or))
else if(cellType == TW($or))
return factory.bitwise_or(a, b);
else if(cellType == ID($xor))
else if(cellType == TW($xor))
return factory.bitwise_xor(a, b);
else if(cellType == ID($xnor))
else if(cellType == TW($xnor))
return factory.bitwise_not(factory.bitwise_xor(a, b));
else
log_abort();
}else if(cellType.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($le), ID($lt), ID($ge), ID($gt))){
}else if(cellType.in(TW($eq), TW($ne), TW($eqx), TW($nex), TW($le), TW($lt), TW($ge), TW($gt))){
bool is_signed = a_signed && b_signed;
int width = max(a_width, b_width);
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)))
if(cellType.in(TW($eq), TW($eqx)))
return factory.extend(factory.equal(a, b), y_width, false);
else if(cellType.in(ID($ne), ID($nex)))
else if(cellType.in(TW($ne), TW($nex)))
return factory.extend(factory.not_equal(a, b), y_width, false);
else if(cellType == ID($lt))
else if(cellType == TW($lt))
return factory.extend(is_signed ? factory.signed_greater_than(b, a) : factory.unsigned_greater_than(b, a), y_width, false);
else if(cellType == ID($le))
else if(cellType == TW($le))
return factory.extend(is_signed ? factory.signed_greater_equal(b, a) : factory.unsigned_greater_equal(b, a), y_width, false);
else if(cellType == ID($gt))
else if(cellType == TW($gt))
return factory.extend(is_signed ? factory.signed_greater_than(a, b) : factory.unsigned_greater_than(a, b), y_width, false);
else if(cellType == ID($ge))
else if(cellType == TW($ge))
return factory.extend(is_signed ? factory.signed_greater_equal(a, b) : factory.unsigned_greater_equal(a, b), y_width, false);
else
log_abort();
}else if(cellType.in(ID($logic_or), ID($logic_and))){
}else if(cellType.in(TW($logic_or), TW($logic_and))){
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);
Node y = cellType == TW($logic_and) ? factory.bitwise_and(a, b) : factory.bitwise_or(a, b);
return factory.extend(y, y_width, false);
}else if(cellType == ID($not)){
}else if(cellType == TW($not)){
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.bitwise_not(a);
}else if(cellType == ID($pos)){
}else if(cellType == TW($pos)){
return factory.extend(inputs.at(TW::A), y_width, a_signed);
}else if(cellType == ID($neg)){
}else if(cellType == TW($neg)){
Node a = factory.extend(inputs.at(TW::A), y_width, a_signed);
return factory.unary_minus(a);
}else if(cellType == ID($logic_not)){
}else if(cellType == TW($logic_not)){
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))){
}else if(cellType.in(TW($reduce_or), TW($reduce_bool))){
Node a = factory.reduce_or(inputs.at(TW::A));
return factory.extend(a, y_width, false);
}else if(cellType == ID($reduce_and)){
}else if(cellType == TW($reduce_and)){
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))){
}else if(cellType.in(TW($reduce_xor), TW($reduce_xnor))){
Node a = factory.reduce_xor(inputs.at(TW::A));
Node y = cellType == ID($reduce_xnor) ? factory.bitwise_not(a) : a;
Node y = cellType == TW($reduce_xnor) ? factory.bitwise_not(a) : a;
return factory.extend(y, y_width, false);
}else if(cellType == ID($shl) || cellType == ID($sshl)){
}else if(cellType == TW($shl) || cellType == TW($sshl)){
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)){
}else if(cellType == TW($shr) || cellType == TW($sshr)){
int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(TW::A), width, a_signed);
Node b = inputs.at(TW::B);
Node y = a_signed && cellType == ID($sshr) ?
Node y = a_signed && cellType == TW($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)){
}else if(cellType == TW($shiftx) || cellType == TW($shift)){
int width = max(a_width, y_width);
Node a = factory.extend(inputs.at(TW::A), width, cellType == ID($shift) && a_signed);
Node a = factory.extend(inputs.at(TW::A), width, cellType == TW($shift) && a_signed);
Node b = inputs.at(TW::B);
Node shr = logical_shift_right(a, b);
if(b_signed) {
@ -343,35 +343,35 @@ public:
} else {
return factory.extend(shr, y_width, false);
}
}else if(cellType == ID($mux)){
}else if(cellType == TW($mux)){
return factory.mux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($pmux)){
}else if(cellType == TW($pmux)){
return handle_pmux(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::S));
}else if(cellType == ID($concat)){
}else if(cellType == TW($concat)){
Node a = inputs.at(TW::A);
Node b = inputs.at(TW::B);
return factory.concat(a, b);
}else if(cellType == ID($slice)){
}else if(cellType == TW($slice)){
int offset = parameters.at(ID(OFFSET)).as_int();
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))) {
}else if(cellType.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
int width = max(a_width, b_width);
bool is_signed = a_signed && b_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)) {
if(cellType == TW($div)) {
// divide absolute values, then flip the sign if input signs differ
// but extend the width first, to handle the case (most negative value) / (-1)
Node abs_y = factory.unsigned_div(abs(a), abs(b));
Node out_sign = factory.not_equal(sign(a), sign(b));
return neg_if(factory.extend(abs_y, y_width, false), out_sign);
} else if(cellType == ID($mod)) {
} else if(cellType == TW($mod)) {
// similar to division but output sign == divisor sign
Node abs_y = factory.unsigned_mod(abs(a), abs(b));
return neg_if(factory.extend(abs_y, y_width, false), sign(a));
} else if(cellType == ID($divfloor)) {
} else if(cellType == TW($divfloor)) {
// if b is negative, flip both signs so that b is positive
Node b_sign = sign(b);
Node a1 = neg_if(a, b_sign);
@ -385,7 +385,7 @@ public:
Node y1 = factory.unsigned_div(a2, b1);
Node y2 = factory.extend(y1, y_width, false);
return factory.mux(y2, factory.bitwise_not(y2), a1_sign);
} else if(cellType == ID($modfloor)) {
} else if(cellType == TW($modfloor)) {
// calculate |a| % |b| and then subtract from |b| if input signs differ and the remainder is non-zero
Node abs_b = abs(b);
Node abs_y = factory.unsigned_mod(abs(a), abs_b);
@ -397,34 +397,34 @@ public:
} else
log_error("unhandled cell in CellSimplifier %s\n", cellType);
} else {
if(cellType.in(ID($mod), ID($modfloor)))
if(cellType.in(TW($mod), TW($modfloor)))
return factory.extend(factory.unsigned_mod(a, b), y_width, false);
else
return factory.extend(factory.unsigned_div(a, b), y_width, false);
}
} else if(cellType == ID($pow)) {
} else if(cellType == TW($pow)) {
return handle_pow(inputs.at(TW::A), inputs.at(TW::B), y_width, a_signed && b_signed);
} else if (cellType == ID($lut)) {
} else if (cellType == TW($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(TW::A), 0, 1, width);
} else if (cellType == ID($bwmux)) {
} else if (cellType == TW($bwmux)) {
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)) {
} else if (cellType == TW($bweqx)) {
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)) {
} else if(cellType == TW($bmux)) {
int width = parameters.at(ID(WIDTH)).as_int();
int s_width = parameters.at(ID(S_WIDTH)).as_int();
return handle_bmux(inputs.at(TW::A), inputs.at(TW::S), 0, width, s_width);
} else if(cellType == ID($demux)) {
} else if(cellType == TW($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;
@ -433,31 +433,31 @@ public:
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)) {
} else if(cellType == TW($fa)) {
return handle_fa(inputs.at(TW::A), inputs.at(TW::B), inputs.at(TW::C));
} else if(cellType == ID($lcu)) {
} else if(cellType == TW($lcu)) {
return handle_lcu(inputs.at(TW::P), inputs.at(TW::G), inputs.at(TW::CI));
} else if(cellType == ID($alu)) {
} else if(cellType == TW($alu)) {
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))) {
} else if(cellType.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover))) {
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 {};
} else if(cellType.in(ID($anyconst), ID($allconst), ID($anyseq), ID($allseq))) {
} else if(cellType.in(TW($anyconst), TW($allconst), TW($anyseq), TW($allseq))) {
int width = parameters.at(ID(WIDTH)).as_int();
auto &input = factory.add_input(cellName, cellType, Sort(width));
return factory.value(input);
} else if(cellType == ID($initstate)) {
if(factory.ir().has_state(ID($initstate), ID($state)))
return factory.value(factory.ir().state(ID($initstate)));
} else if(cellType == TW($initstate)) {
if(factory.ir().has_state(TW($initstate), TW($state)))
return factory.value(factory.ir().state(TW($initstate)));
else {
auto &state = factory.add_state(ID($initstate), ID($state), Sort(1));
auto &state = factory.add_state(TW($initstate), TW($state), Sort(1));
state.set_initial_value(RTLIL::Const(State::S1, 1));
state.set_next_value(factory.constant(RTLIL::Const(State::S0, 1)));
return factory.value(state);
}
} else if(cellType == ID($check)) {
} else if(cellType == TW($check)) {
log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName);
} else {
log_error("`%s' cells are not supported by the functional backend\n", cellType);
@ -495,7 +495,7 @@ class FunctionalIRConstruction {
queue.emplace_back(cell);
std::optional<Node> rv;
for(auto const &[name, sigspec] : cell->connections())
if(driver_map.celltypes.cell_output(cell->type, name)) {
if(driver_map.celltypes.cell_output(cell->type.ref(), name)) {
auto node = factory.create_pending(sigspec.size());
factory.suggest_name(node, cell->name.str() + "$" + cell->module->design->twines.str(name));
cell_outputs.emplace({cell, name}, node);
@ -515,17 +515,17 @@ public:
{
driver_map.add(module);
for (auto cell : module->cells()) {
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($check)))
if (cell->type.in(TW($assert), TW($assume), TW($live), TW($fair), TW($cover), TW($check)))
queue.emplace_back(cell);
}
// we are relying here on unsorted pools iterating last-in-first-out
for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) {
auto *wire = module->wire(*riter);
if (wire && wire->port_input) {
factory.add_input(wire->name, ID($input), Sort(wire->width));
factory.add_input(wire->name, TW($input), Sort(wire->width));
}
if (wire && wire->port_output) {
auto &output = factory.add_output(wire->name, ID($output), Sort(wire->width));
auto &output = factory.add_output(wire->name, TW($output), Sort(wire->width));
output.set_value(enqueue(DriveChunk(DriveChunkWire(wire, 0, wire->width))));
}
}
@ -565,14 +565,14 @@ private:
// - Since wr port j can only have priority over wr port i if j > i, if we do writes in
// ascending index order the result will obey the priorty relation.
vector<Node> read_results;
auto &state = factory.add_state(mem->cell->name, ID($state), Sort(ceil_log2(mem->size), mem->width));
auto &state = factory.add_state(mem->cell->name, TW($state), Sort(ceil_log2(mem->size), mem->width));
state.set_initial_value(MemContents(mem));
Node node = factory.value(state);
for (size_t i = 0; i < mem->wr_ports.size(); i++) {
const auto &wr = mem->wr_ports[i];
if (wr.clk_enable)
log_error("Write port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
"Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, mem->memid.unescape());
"Call async2sync or clk2fflogic to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
Node en = enqueue(driver_map(DriveSpec(wr.en)));
Node addr = enqueue(driver_map(DriveSpec(wr.addr)));
Node new_data = enqueue(driver_map(DriveSpec(wr.data)));
@ -582,12 +582,12 @@ private:
}
if (mem->rd_ports.empty())
log_error("Memory %s.%s has no read ports. This is not supported by the functional backend. "
"Call opt_clean to remove it.", mem->module, mem->memid.unescape());
"Call opt_clean to remove it.", mem->module, design->twines.unescaped_str(mem->memid));
for (size_t i = 0; i < mem->rd_ports.size(); i++) {
const auto &rd = mem->rd_ports[i];
if (rd.clk_enable)
log_error("Read port %zd of memory %s.%s is clocked. This is not supported by the functional backend. "
"Call memory_nordff to avoid this error.\n", i, mem->module, mem->memid.unescape());
"Call memory_nordff to avoid this error.\n", i, mem->module, design->twines.unescaped_str(mem->memid));
Node addr = enqueue(driver_map(DriveSpec(rd.addr)));
read_results.push_back(factory.memory_read(node, addr));
}
@ -609,8 +609,8 @@ private:
FfData ff(&ff_initvals, cell);
if (!ff.has_gclk)
log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. "
"Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescape(), cell);
auto &state = factory.add_state(ff.name, ID($state), Sort(ff.width));
"Call async2sync or clk2fflogic to avoid this error.\n", cell->type.unescaped(), cell);
auto &state = factory.add_state(ff.name, TW($state), Sort(ff.width));
Node q_value = factory.value(state);
factory.suggest_name(q_value, ff.name);
factory.update_pending(cell_outputs.at({cell, TW::Q}), q_value);
@ -621,9 +621,9 @@ private:
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)
if(driver_map.celltypes.cell_input(cell->type.ref(), name) && sigspec.size() > 0)
connections.insert({ name, enqueue(DriveChunkPort(cell, {name, sigspec})) });
if(driver_map.celltypes.cell_output(cell->type, name)) {
if(driver_map.celltypes.cell_output(cell->type.ref(), name)) {
output_name = name;
n_outputs++;
}
@ -677,7 +677,7 @@ public:
factory.update_pending(pending, node);
} else {
DriveSpec driver = driver_map(DriveSpec(wire_chunk));
check_undriven(driver, wire_chunk.wire->name.unescape());
check_undriven(driver, design->twines.unescaped_str(wire_chunk.wire->name));
Node node = enqueue(driver);
factory.suggest_name(node, wire_chunk.wire->name);
factory.update_pending(pending, node);
@ -690,7 +690,7 @@ public:
} else if (chunk.is_port()) {
DriveChunkPort port_chunk = chunk.port();
if (port_chunk.is_whole()) {
if (driver_map.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) {
if (driver_map.celltypes.cell_output(port_chunk.cell->type.ref(), port_chunk.port)) {
Node node = enqueue_cell(port_chunk.cell, port_chunk.port);
factory.update_pending(pending, node);
} else {
@ -745,7 +745,7 @@ void IR::topological_sort() {
log_warning("Combinational loop:\n");
for (int *i = begin; i != end; ++i) {
Node node(_graph[*i]);
log("- %s = %s\n", node.name().unescape(), node.to_string());
log("- %s = %s\n", design->twines.unescaped_str(node.name()), node.to_string());
}
log("\n");
scc = true;

File diff suppressed because it is too large Load diff

View file

@ -138,11 +138,11 @@ struct Macc
void from_cell(RTLIL::Cell *cell)
{
if (cell->type == ID($macc)) {
if (cell->type == TW($macc)) {
from_cell_v1(cell);
return;
}
log_assert(cell->type == ID($macc_v2));
log_assert(cell->type == TW($macc_v2));
RTLIL::SigSpec port_a = cell->getPort(TW::A);
RTLIL::SigSpec port_b = cell->getPort(TW::B);

View file

@ -123,7 +123,7 @@ void Mem::emit() {
if (!cell) {
if (memid.empty())
memid = NEW_ID;
cell = module->addCell(Twine{memid.str()}, ID($mem_v2));
cell = module->addCell(Twine{memid.str()}, TW::$mem_v2);
}
cell->type_impl = TW::$mem_v2;
cell->attributes = attributes;
@ -300,7 +300,7 @@ void Mem::emit() {
mem->attributes = attributes;
for (auto &port : rd_ports) {
if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memrd_v2));
port.cell = module->addCell(NEW_TWINE, TW::$memrd_v2);
port.cell->type_impl = TW::$memrd_v2;
port.cell->attributes = port.attributes;
port.cell->parameters[ID::MEMID] = memid.str();
@ -325,7 +325,7 @@ void Mem::emit() {
int idx = 0;
for (auto &port : wr_ports) {
if (!port.cell)
port.cell = module->addCell(NEW_TWINE, ID($memwr_v2));
port.cell = module->addCell(NEW_TWINE, TW::$memwr_v2);
port.cell->type_impl = TW::$memwr_v2;
port.cell->attributes = port.attributes;
if (port.cell->parameters.count(ID::PRIORITY))
@ -346,7 +346,7 @@ void Mem::emit() {
for (auto &init : inits) {
bool v2 = !init.en.is_fully_ones();
if (!init.cell)
init.cell = module->addCell(NEW_TWINE, v2 ? ID($meminit_v2) : ID($meminit));
init.cell = module->addCell(NEW_TWINE, v2 ? TW::$meminit_v2 : TW::$meminit);
else {
if (!v2)
init.cell->unsetPort(TW::EN);
@ -548,11 +548,11 @@ namespace {
dict<IdString, pool<Cell *>> inits;
MemIndex (Module *module) {
for (auto cell: module->cells()) {
if (cell->type.in(ID($memwr), ID($memwr_v2)))
if (cell->type.in(TW($memwr), TW($memwr_v2)))
wr_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
else if (cell->type.in(ID($memrd), ID($memrd_v2)))
else if (cell->type.in(TW($memrd), TW($memrd_v2)))
rd_ports[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
else if (cell->type.in(ID($meminit), ID($meminit_v2)))
else if (cell->type.in(TW($meminit), TW($meminit_v2)))
inits[cell->parameters.at(ID::MEMID).decode_string()].insert(cell);
}
}
@ -568,7 +568,7 @@ namespace {
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);
bool is_compat = cell->type == TW($memrd);
mrd.cell = cell;
mrd.attributes = cell->attributes;
mrd.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
@ -612,7 +612,7 @@ namespace {
std::vector<std::pair<int, MemWr>> ports;
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);
bool is_compat = cell->type == TW($memwr);
mwr.cell = cell;
mwr.attributes = cell->attributes;
mwr.clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
@ -631,7 +631,7 @@ namespace {
}
for (int i = 0; i < GetSize(res.wr_ports); i++) {
auto &port = res.wr_ports[i];
bool is_compat = port.cell->type == ID($memwr);
bool is_compat = port.cell->type == TW($memwr);
if (is_compat) {
port.priority_mask.resize(GetSize(res.wr_ports));
for (int j = 0; j < i; j++) {
@ -667,7 +667,7 @@ namespace {
log_error("Non-constant data %s in memory initialization %s.\n", log_signal(data), cell);
init.addr = addr.as_const();
init.data = data.as_const();
if (cell->type == ID($meminit_v2)) {
if (cell->type == TW($meminit_v2)) {
auto en = cell->getPort(TW::EN);
if (!en.is_fully_const())
log_error("Non-constant enable %s in memory initialization %s.\n", log_signal(en), cell);
@ -683,7 +683,7 @@ namespace {
}
for (int i = 0; i < GetSize(res.rd_ports); i++) {
auto &port = res.rd_ports[i];
bool is_compat = port.cell->type == ID($memrd);
bool is_compat = port.cell->type == TW($memrd);
if (is_compat) {
port.transparency_mask.resize(GetSize(res.wr_ports));
port.collision_x_mask.resize(GetSize(res.wr_ports));
@ -720,7 +720,7 @@ namespace {
cell->parameters.at(ID::OFFSET).as_int(),
cell->parameters.at(ID::SIZE).as_int()
);
bool is_compat = cell->type == ID($mem);
bool is_compat = cell->type == TW($mem);
int abits = cell->parameters.at(ID::ABITS).as_int();
res.packed = true;
res.cell = cell;
@ -860,7 +860,7 @@ std::vector<Mem> Mem::get_all_memories(Module *module) {
res.push_back(mem_from_memory(module, it.second, index));
}
for (auto cell: module->cells()) {
if (cell->type.in(ID($mem), ID($mem_v2)))
if (cell->type.in(TW($mem), TW($mem_v2)))
res.push_back(mem_from_cell(cell));
}
return res;
@ -874,7 +874,7 @@ std::vector<Mem> Mem::get_selected_memories(Module *module) {
res.push_back(mem_from_memory(module, it.second, index));
}
for (auto cell: module->selected_cells()) {
if (cell->type.in(ID($mem), ID($mem_v2)))
if (cell->type.in(TW($mem), TW($mem_v2)))
res.push_back(mem_from_cell(cell));
}
return res;

View file

@ -321,7 +321,7 @@ struct ModIndex : public RTLIL::Monitor
log(" PRIMARY OUTPUT\n");
for (auto &port : it.second.ports)
log(" PORT: %s.%s[%d] (%s)\n", port.cell,
module->design->twines.str(port.port), port.offset, port.cell->type.unescape());
module->design->twines.str(port.port), port.offset, port.cell->module->design->twines.unescaped_str(port.cell->type_impl));
}
}
};
@ -402,11 +402,11 @@ struct ModWalker
void add_cell(RTLIL::Cell *cell)
{
if (ct.cell_known(cell->type)) {
if (ct.cell_known(cell->type.ref())) {
for (auto &conn : cell->connections())
add_cell_port(cell, conn.first, sigmap(conn.second),
ct.cell_output(cell->type, conn.first),
ct.cell_input(cell->type, conn.first));
ct.cell_output(cell->type.ref(), conn.first),
ct.cell_input(cell->type.ref(), conn.first));
} else {
for (auto &conn : cell->connections())
add_cell_port(cell, conn.first, sigmap(conn.second), true, true);
@ -436,7 +436,7 @@ struct ModWalker
for (auto &it : module->wires_)
add_wire(it.second);
for (auto &it : module->cells_)
if (filter_ct == NULL || filter_ct->cell_known(it.second->type))
if (filter_ct == NULL || filter_ct->cell_known(it.second->type.ref()))
add_cell(it.second);
}

View file

@ -555,13 +555,8 @@ struct NewCellType {
};
struct NewCellTypes {
struct IdStringHash {
std::size_t operator()(const IdString id) const {
return static_cast<size_t>(id.hash_top().yield());
}
};
StaticCellTypes::Categories::Category static_cell_types = StaticCellTypes::categories.empty;
std::unordered_map<TwineRef, NewCellType, IdStringHash> custom_cell_types {};
dict<TwineRef, NewCellType> custom_cell_types {};
NewCellTypes() {
static_cell_types = StaticCellTypes::categories.empty;

View file

@ -12,7 +12,7 @@ struct PmuxBPortIterator {
int port_idx;
int port_count;
PmuxBPortIterator(Cell* mux) : cell(mux) {
log_assert(mux->type == ID($mux) || mux->type == ID($pmux));
log_assert(mux->type == TW($mux) || mux->type == TW($pmux));
port_idx = 0;
b = mux->getPort(TW::B).to_sigbit_vector();

View file

@ -77,25 +77,25 @@ void QuickConeSat::prepare()
int QuickConeSat::cell_complexity(RTLIL::Cell *cell)
{
if (cell->type.in(ID($concat), ID($slice), ID($pos), ID($buf), ID($_BUF_)))
if (cell->type.in(TW($concat), TW($slice), TW($pos), TW($buf), TW($_BUF_)))
return 0;
if (cell->type.in(ID($not), ID($and), ID($or), ID($xor), ID($xnor),
ID($reduce_and), ID($reduce_or), ID($reduce_xor),
ID($reduce_xnor), ID($reduce_bool),
ID($logic_not), ID($logic_and), ID($logic_or),
ID($eq), ID($ne), ID($eqx), ID($nex), ID($fa),
ID($mux), ID($pmux), ID($bmux), ID($demux), ID($lut), ID($sop),
ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
ID($_MUX_), ID($_NMUX_), ID($_MUX4_), ID($_MUX8_), ID($_MUX16_),
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
if (cell->type.in(TW($not), TW($and), TW($or), TW($xor), TW($xnor),
TW($reduce_and), TW($reduce_or), TW($reduce_xor),
TW($reduce_xnor), TW($reduce_bool),
TW($logic_not), TW($logic_and), TW($logic_or),
TW($eq), TW($ne), TW($eqx), TW($nex), TW($fa),
TW($mux), TW($pmux), TW($bmux), TW($demux), TW($lut), TW($sop),
TW($_NOT_), TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_),
TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
TW($_MUX_), TW($_NMUX_), TW($_MUX4_), TW($_MUX8_), TW($_MUX16_),
TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)))
return 1;
if (cell->type.in(ID($neg), ID($add), ID($sub), ID($alu), ID($lcu),
ID($lt), ID($le), ID($gt), ID($ge)))
if (cell->type.in(TW($neg), TW($add), TW($sub), TW($alu), TW($lcu),
TW($lt), TW($le), TW($gt), TW($ge)))
return 2;
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx)))
return 3;
if (cell->type.in(ID($mul), ID($macc), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow)))
if (cell->type.in(TW($mul), TW($macc), TW($div), TW($mod), TW($divfloor), TW($modfloor), TW($pow)))
return 4;
// Unknown cell.
return 5;

View file

@ -983,7 +983,7 @@ struct HelpPass : public Pass {
for (auto it : StaticCellTypes::builder.cells) {
if (!StaticCellTypes::categories.is_known(it.type))
continue;
auto name = it.type.str();
auto name = TW::str(it.type);
if (cell_help_messages.contains(name)) {
auto cell_help = cell_help_messages.get(name);
groups[cell_help.group].emplace_back(name);
@ -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(RTLIL::IdString((RTLIL::StaticId)input).str());
inputs.push_back(TW::str(input));
json.name("inputs"); json.value(inputs);
for (auto &output : ct.outputs)
outputs.push_back(RTLIL::IdString((RTLIL::StaticId)output).str());
outputs.push_back(TW::str(output));
json.name("outputs"); json.value(outputs);
vector<string> properties;
// CellType properties

View file

@ -1948,18 +1948,18 @@ bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
return false;
}
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
TwineRef RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
{
if (mayfail)
return IdString();
return Twine::Null;
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
}
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<RTLIL::IdString, RTLIL::Module*> &, const dict<RTLIL::IdString, RTLIL::IdString> &, bool mayfail)
TwineRef RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<TwineRef, RTLIL::Module*> &, const dict<TwineRef, TwineRef> &, bool mayfail)
{
if (mayfail)
return IdString();
return Twine::Null;
log_error("Module `%s' is used with parameters but is not parametric!\n", design->twines.str(meta_->name).c_str());
}
@ -3574,6 +3574,11 @@ TwineRef RTLIL::Module::uniquify(TwineRef name)
return uniquify(name, index);
}
TwineRef RTLIL::Module::uniquify(Twine&& name)
{
return uniquify(design->twines.add(Twine{std::move(name)}));
}
TwineRef RTLIL::Module::uniquify(TwineRef name, int &index)
{
if (index == 0) {
@ -3590,6 +3595,11 @@ TwineRef RTLIL::Module::uniquify(TwineRef name, int &index)
}
}
TwineRef RTLIL::Module::uniquify(Twine&& name, int &index)
{
return uniquify(design->twines.add(Twine{std::move(name)}), index);
}
static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
{
if (a->port_id && !b->port_id)
@ -4524,10 +4534,14 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
return cell;
}
static TwinePool& _cell_adder_twines(RTLIL::Module* m) { return m->design->twines; }
static TwinePool& _cell_adder_twines(RTLIL::Patch* p) { return p->mod->design->twines; }
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSrGate(Twine &&name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr);
cell->setPort(TW::Q, sig_q);
@ -4546,7 +4560,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::D, sig_d);
cell->setPort(TW::Q, sig_q);
@ -4556,7 +4571,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::E, sig_en);
cell->setPort(TW::D, sig_d);
@ -4568,7 +4584,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsrGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr);
@ -4581,7 +4598,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDffsreGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr);
@ -4595,7 +4613,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool clk_polarity, bool arst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_arst);
cell->setPort(TW::D, sig_d);
@ -4607,7 +4626,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_arst);
cell->setPort(TW::E, sig_en);
@ -4620,7 +4640,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::L, sig_aload);
cell->setPort(TW::D, sig_d);
@ -4633,7 +4654,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAldffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::L, sig_aload);
cell->setPort(TW::E, sig_en);
@ -4647,7 +4669,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value, bool clk_polarity, bool srst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst);
cell->setPort(TW::D, sig_d);
@ -4659,7 +4682,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffeGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst);
cell->setPort(TW::E, sig_en);
@ -4672,7 +4696,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addSdffceGate(Twine &&name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::C, sig_clk);
cell->setPort(TW::R, sig_srst);
cell->setPort(TW::E, sig_en);
@ -4684,7 +4709,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en);
cell->setPort(TW::D, sig_d);
cell->setPort(TW::Q, sig_q);
@ -4695,7 +4721,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addAdlatchGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool en_polarity, bool arst_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en);
cell->setPort(TW::R, sig_arst);
cell->setPort(TW::D, sig_d);
@ -4707,7 +4734,8 @@ RTLIL::Process *RTLIL::Module::addProcess(TwineRef name, const RTLIL::Process *o
template<typename Derived> RTLIL::Cell* CellAdderMixin<Derived>::addDlatchsrGate(Twine &&name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, TwineRef src)
{
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), Twine{stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
TwineRef _t = _cell_adder_twines(static_cast<Derived*>(this)).add(Twine{stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')});
RTLIL::Cell *cell = static_cast<Derived*>(this)->addCell(std::move(name), _t);
cell->setPort(TW::E, sig_en);
cell->setPort(TW::S, sig_set);
cell->setPort(TW::R, sig_clr);

View file

@ -743,7 +743,7 @@ constexpr int lookup_well_known_id(std::string_view name)
return -1;
}
// Create a statically allocated IdString object, using for example ID::A or ID($add).
// Create a statically allocated IdString object, using for example ID::A or TW($add).
//
// Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
@ -3026,7 +3026,7 @@ public:
Module();
virtual ~Module();
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<TwineRef, RTLIL::Module*> &interfaces, const dict<TwineRef, TwineRef> &modports, bool mayfail = false);
virtual size_t count_id(TwineRef id);
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual bool reprocess_if_necessary(RTLIL::Design *design);
@ -3158,7 +3158,9 @@ public:
void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2);
TwineRef uniquify(TwineRef name);
TwineRef uniquify(Twine&& name);
TwineRef uniquify(TwineRef name, int &index);
TwineRef uniquify(Twine&& name, int &index);
// Primary overloads: name already interned in design->twines.
RTLIL::Wire *addWire(TwineRef name, int width = 1);
@ -3171,6 +3173,7 @@ public:
RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
// Convenience.
RTLIL::Cell *addCell(Twine name, Twine type);
RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);

View file

@ -81,7 +81,7 @@ struct RTLIL::SigNormIndex
dict<Wire *, Cell *> input_port_cells;
for (auto cell : module->cells()) {
if (cell->type != ID($input_port))
if (cell->type != TW($input_port))
continue;
auto const &sig_y = cell->getPort(TW::Y);
@ -98,7 +98,7 @@ struct RTLIL::SigNormIndex
for (auto portname : module->ports) {
Wire *wire = module->wire(portname);
if (wire->port_input && !wire->port_output && !input_port_cells.count(wire)) {
Cell *cell = module->addCell(NEW_TWINE, ID($input_port));
Cell *cell = module->addCell(NEW_TWINE, TW::$input_port);
cell->setParam(ID::WIDTH, GetSize(wire));
cell->setPort(TW::Y, wire);
input_port_cells.emplace(wire, cell);
@ -195,7 +195,7 @@ struct RTLIL::SigNormIndex
}
if (!connect_lhs.empty()) {
Cell *cell = module->addCell(NEW_TWINE, ID($connect));
Cell *cell = module->addCell(NEW_TWINE, TW::$connect);
xlog("add connect (1) %s\n", cell->name);
cell->setParam(ID::WIDTH, GetSize(connect_lhs));
cell->setPort(TW::A, std::move(connect_lhs));
@ -355,7 +355,7 @@ void RTLIL::Design::sigNormalize(bool enable)
// TODO inefficient?
std::vector<Cell*> cells_snapshot = module->cells();
for (auto cell : cells_snapshot) {
if (cell->type == ID($input_port))
if (cell->type == TW($input_port))
module->remove(cell);
}
}
@ -560,12 +560,12 @@ void RTLIL::Module::bufNormalize()
// Ensure that every enqueued input port is represented by a cell
for (auto wire : buf_norm_wire_queue) {
if (wire->port_input && !wire->port_output) {
if (wire->driverCell_ != nullptr && wire->driverCell_->type != ID($input_port)) {
if (wire->driverCell_ != nullptr && wire->driverCell_->type != TW($input_port)) {
wire->driverCell_ = nullptr;
wire->driverPort_ = Twine::Null;
}
if (wire->driverCell_ == nullptr) {
Cell *input_port_cell = addCell(NEW_TWINE, ID($input_port));
Cell *input_port_cell = addCell(NEW_TWINE, TW::$input_port);
input_port_cell->setParam(ID::WIDTH, GetSize(wire));
input_port_cell->setPort(TW::Y, wire); // this hits the fast path that doesn't mutate the queues
}
@ -621,7 +621,7 @@ void RTLIL::Module::bufNormalize()
if (chunk.is_wire())
wire_queue_entries(chunk.wire);
if (cell->type == ID($buf) && cell->attributes.empty() && !cell->name.isPublic()) {
if (cell->type == TW($buf) && cell->attributes.empty() && !cell->name.isPublic()) {
// For a plain `$buf` cell, we enqueue all wires on its input
// side, bypass it using module level connections (skipping 'z
// bits) and then remove the cell. Eventually the module level
@ -662,7 +662,7 @@ void RTLIL::Module::bufNormalize()
log_assert(GetSize(buf_norm_wire_queue) <= 1);
buf_norm_wire_queue.clear();
return;
} else if (cell->type == ID($input_port)) {
} else if (cell->type == TW($input_port)) {
log_assert(port == TW::Y);
if (sig.is_wire()) {
Wire *w = sig.as_wire();
@ -744,7 +744,7 @@ void RTLIL::Module::bufNormalize()
break;
while (!found->second.empty()) {
Cell *connect_cell = *found->second.begin();
log_assert(connect_cell->type == ID($connect));
log_assert(connect_cell->type == TW($connect));
SigSpec const &sig_a = connect_cell->getPort(TW::A);
SigSpec const &sig_b = connect_cell->getPort(TW::B);
xlog("found $connect cell %s: %s <-> %s\n", connect_cell, log_signal(sig_a), log_signal(sig_b));
@ -769,7 +769,7 @@ void RTLIL::Module::bufNormalize()
// As a first step for re-normalization we add all require intermediate
// wires for cell output and inout ports.
for (auto &[cell, port] : pending_ports) {
log_assert(cell->type != ID($input_port));
log_assert(cell->type != TW($input_port));
log_assert(!cell->type.empty());
log_assert(!pending_deleted_cells.count(cell));
SigSpec const &sig = cell->getPort(port);
@ -848,7 +848,7 @@ void RTLIL::Module::bufNormalize()
auto const &[cell, port] = cellport;
for (int i = 0; i != GetSize(wire); ++i) {
SigBit driver = sigmap(SigBit(wire, i));
if (cell->type == ID($tribuf) || cell->port_dir(port) == RTLIL::PD_INOUT) {
if (cell->type == TW($tribuf) || cell->port_dir(port) == RTLIL::PD_INOUT) {
// We add inout drivers to `driven` in a separate loop below
weakly_driven.insert(driver);
} else {
@ -947,7 +947,7 @@ void RTLIL::Module::bufNormalize()
if (sig_a.empty())
return;
xlog("connect %s <-> %s\n", log_signal(sig_a), log_signal(sig_b));
Cell *connect_cell = addCell(NEW_TWINE, ID($connect));
Cell *connect_cell = addCell(NEW_TWINE, TW::$connect);
connect_cell->setParam(ID::WIDTH, GetSize(sig_a));
connect_cell->setPort(TW::A, sig_a);
connect_cell->setPort(TW::B, sig_b);
@ -1066,7 +1066,7 @@ void RTLIL::Cell::unsetPort(TwineRef portname)
}
}
if (type == ID($connect)) {
if (type == TW($connect)) {
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire)
@ -1097,7 +1097,7 @@ void RTLIL::Cell::unsetPort(TwineRef portname)
static bool ignored_cell(const RTLIL::IdString& type)
{
return type == ID($specify2) || type == ID($specify3) || type == ID($specrule);
return type == TW($specify2) || type == TW($specify3) || type == TW($specrule);
}
void RTLIL::Cell::signorm_index_remove(TwineRef portname, const SigSpec &old_signal, bool is_input)
@ -1167,7 +1167,7 @@ bool RTLIL::Cell::bufnorm_handle_setPort(TwineRef portname, SigSpec &signal, dic
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
Wire *w = signal.as_wire();
if (w->driverCell_ == nullptr &&
(w->port_input && !w->port_output) == (type == ID($input_port))) {
(w->port_input && !w->port_output) == (type == TW($input_port))) {
w->driverCell_ = this;
w->driverPort_ = portname;
conn_it->second = std::move(signal);
@ -1184,7 +1184,7 @@ bool RTLIL::Cell::bufnorm_handle_setPort(TwineRef portname, SigSpec &signal, dic
module->buf_norm_wire_queue.insert(chunk.wire);
}
if (type == ID($connect)) {
if (type == TW($connect)) {
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire) continue;
@ -1229,7 +1229,7 @@ void RTLIL::Cell::initIndex()
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
Wire *w = signal.as_wire();
if (w->driverCell_ == nullptr &&
(w->port_input && !w->port_output) == (type == ID($input_port))) {
(w->port_input && !w->port_output) == (type == TW($input_port))) {
w->driverCell_ = this;
w->driverPort_ = portname;
continue;

View file

@ -26,9 +26,9 @@ USING_YOSYS_NAMESPACE
bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
{
bool arith_undef_handled = false;
bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt));
bool is_arith_compare = cell->type.in(TW($lt), TW($le), TW($ge), TW($gt));
if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor)) || is_arith_compare))
if (model_undef && (cell->type.in(TW($add), TW($sub), TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor)) || is_arith_compare))
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
@ -42,7 +42,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
int undef_y_bit = ez->OR(undef_any_a, undef_any_b);
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor))) {
if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
std::vector<int> b = importSigSpec(cell->getPort(TW::B), timestep);
undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b)));
}
@ -59,8 +59,8 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
arith_undef_handled = true;
}
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub)))
if (cell->type.in(TW($_AND_), TW($_NAND_), TW($_OR_), TW($_NOR_), TW($_XOR_), TW($_XNOR_), TW($_ANDNOT_), TW($_ORNOT_),
TW($and), TW($or), TW($xor), TW($xnor), TW($add), TW($sub)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -69,25 +69,25 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type.in(ID($and), ID($_AND_)))
if (cell->type.in(TW($and), TW($_AND_)))
ez->assume(ez->vec_eq(ez->vec_and(a, b), yy));
if (cell->type == ID($_NAND_))
if (cell->type == TW($_NAND_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy));
if (cell->type.in(ID($or), ID($_OR_)))
if (cell->type.in(TW($or), TW($_OR_)))
ez->assume(ez->vec_eq(ez->vec_or(a, b), yy));
if (cell->type == ID($_NOR_))
if (cell->type == TW($_NOR_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy));
if (cell->type.in(ID($xor), ID($_XOR_)))
if (cell->type.in(TW($xor), TW($_XOR_)))
ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy));
if (cell->type.in(ID($xnor), ID($_XNOR_)))
if (cell->type.in(TW($xnor), TW($_XNOR_)))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy));
if (cell->type == ID($_ANDNOT_))
if (cell->type == TW($_ANDNOT_))
ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy));
if (cell->type == ID($_ORNOT_))
if (cell->type == TW($_ORNOT_))
ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy));
if (cell->type == ID($add))
if (cell->type == TW($add))
ez->assume(ez->vec_eq(ez->vec_add(a, b), yy));
if (cell->type == ID($sub))
if (cell->type == TW($sub))
ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy));
if (model_undef && !arith_undef_handled)
@ -97,30 +97,30 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell, false);
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) {
if (cell->type.in(TW($and), TW($_AND_), TW($_NAND_))) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0)));
ez->assume(ez->vec_eq(yX, undef_y));
}
else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) {
else if (cell->type.in(TW($or), TW($_OR_), TW($_NOR_))) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1)));
ez->assume(ez->vec_eq(yX, undef_y));
}
else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) {
else if (cell->type.in(TW($xor), TW($xnor), TW($_XOR_), TW($_XNOR_))) {
std::vector<int> yX = ez->vec_or(undef_a, undef_b);
ez->assume(ez->vec_eq(yX, undef_y));
}
else if (cell->type == ID($_ANDNOT_)) {
else if (cell->type == TW($_ANDNOT_)) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1)));
ez->assume(ez->vec_eq(yX, undef_y));
}
else if (cell->type == ID($_ORNOT_)) {
else if (cell->type == TW($_ORNOT_)) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0)));
@ -139,10 +139,10 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
if (cell->type.in(TW($_AOI3_), TW($_OAI3_), TW($_AOI4_), TW($_OAI4_)))
{
bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_));
bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_));
bool aoi_mode = cell->type.in(TW($_AOI3_), TW($_AOI4_));
bool three_mode = cell->type.in(TW($_AOI3_), TW($_OAI3_));
int a = importDefSigSpec(cell->getPort(TW::A), timestep).at(0);
int b = importDefSigSpec(cell->getPort(TW::B), timestep).at(0);
@ -151,7 +151,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y;
if (cell->type.in(ID($_AOI3_), ID($_AOI4_)))
if (cell->type.in(TW($_AOI3_), TW($_AOI4_)))
ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy));
else
ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy));
@ -205,7 +205,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($_NOT_), ID($not)))
if (cell->type.in(TW($_NOT_), TW($not)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -224,7 +224,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($bweqx))
if (cell->type == TW($bweqx))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -250,7 +250,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_), ID($bwmux)))
if (cell->type.in(TW($_MUX_), TW($mux), TW($_NMUX_), TW($bwmux)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -258,9 +258,9 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($_NMUX_))
if (cell->type == TW($_NMUX_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
else if (cell->type == ID($bwmux))
else if (cell->type == TW($bwmux))
ez->assume(ez->vec_eq(ez->vec_ite(s, b, a), yy));
else
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
@ -275,7 +275,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
std::vector<int> yX;
if (cell->type == ID($bwmux))
if (cell->type == TW($bwmux))
yX = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a));
else
yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a));
@ -285,7 +285,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($bmux))
if (cell->type == TW($bmux))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep);
@ -333,7 +333,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($demux))
if (cell->type == TW($demux))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> s = importDefSigSpec(cell->getPort(TW::S), timestep);
@ -385,7 +385,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($pmux))
if (cell->type == TW($pmux))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -431,7 +431,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($pos), ID($buf), ID($neg)))
if (cell->type.in(TW($pos), TW($buf), TW($neg)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -439,7 +439,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type.in(ID($pos), ID($buf))) {
if (cell->type.in(TW($pos), TW($buf))) {
ez->assume(ez->vec_eq(a, yy));
} else {
std::vector<int> zero(a.size(), ez->CONST_FALSE);
@ -452,7 +452,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell);
if (cell->type.in(ID($pos), ID($buf))) {
if (cell->type.in(TW($pos), TW($buf))) {
ez->assume(ez->vec_eq(undef_a, undef_y));
} else {
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@ -465,7 +465,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($connect)))
if (cell->type.in(TW($connect)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -485,22 +485,22 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not)))
if (cell->type.in(TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($logic_not)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($reduce_and))
if (cell->type == TW($reduce_and))
ez->SET(ez->expression(ez->OpAnd, a), yy.at(0));
if (cell->type.in(ID($reduce_or), ID($reduce_bool)))
if (cell->type.in(TW($reduce_or), TW($reduce_bool)))
ez->SET(ez->expression(ez->OpOr, a), yy.at(0));
if (cell->type == ID($reduce_xor))
if (cell->type == TW($reduce_xor))
ez->SET(ez->expression(ez->OpXor, a), yy.at(0));
if (cell->type == ID($reduce_xnor))
if (cell->type == TW($reduce_xnor))
ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0));
if (cell->type == ID($logic_not))
if (cell->type == TW($logic_not))
ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0));
for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i));
@ -511,15 +511,15 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
int aX = ez->expression(ezSAT::OpOr, undef_a);
if (cell->type == ID($reduce_and)) {
if (cell->type == TW($reduce_and)) {
int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0)));
}
else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) {
else if (cell->type.in(TW($reduce_or), TW($reduce_bool), TW($logic_not))) {
int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0)));
}
else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
else if (cell->type.in(TW($reduce_xor), TW($reduce_xnor))) {
ez->assume(ez->IFF(aX, undef_y.at(0)));
} else
log_abort();
@ -532,7 +532,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($logic_and), ID($logic_or)))
if (cell->type.in(TW($logic_and), TW($logic_or)))
{
std::vector<int> vec_a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> vec_b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -543,7 +543,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (cell->type == ID($logic_and))
if (cell->type == TW($logic_and))
ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0));
else
ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0));
@ -563,9 +563,9 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
int aX = ez->expression(ezSAT::OpOr, undef_a);
int bX = ez->expression(ezSAT::OpOr, undef_b);
if (cell->type == ID($logic_and))
if (cell->type == TW($logic_and))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0));
else if (cell->type == ID($logic_or))
else if (cell->type == TW($logic_or))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0));
else
log_abort();
@ -578,7 +578,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)))
if (cell->type.in(TW($lt), TW($le), TW($eq), TW($ne), TW($eqx), TW($nex), TW($ge), TW($gt)))
{
bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool();
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
@ -588,7 +588,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
if (model_undef && cell->type.in(ID($eqx), ID($nex))) {
if (model_undef && cell->type.in(TW($eqx), TW($nex))) {
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
extendSignalWidth(undef_a, undef_b, cell, true);
@ -596,29 +596,29 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
b = ez->vec_or(b, undef_b);
}
if (cell->type == ID($lt))
if (cell->type == TW($lt))
ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0));
if (cell->type == ID($le))
if (cell->type == TW($le))
ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0));
if (cell->type.in(ID($eq), ID($eqx)))
if (cell->type.in(TW($eq), TW($eqx)))
ez->SET(ez->vec_eq(a, b), yy.at(0));
if (cell->type.in(ID($ne), ID($nex)))
if (cell->type.in(TW($ne), TW($nex)))
ez->SET(ez->vec_ne(a, b), yy.at(0));
if (cell->type == ID($ge))
if (cell->type == TW($ge))
ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0));
if (cell->type == ID($gt))
if (cell->type == TW($gt))
ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0));
for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i));
if (model_undef && cell->type.in(ID($eqx), ID($nex)))
if (model_undef && cell->type.in(TW($eqx), TW($nex)))
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true);
if (cell->type == ID($eqx))
if (cell->type == TW($eqx))
yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b));
else
yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b));
@ -628,7 +628,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
ez->assume(ez->vec_eq(y, yy));
}
else if (model_undef && cell->type.in(ID($eq), ID($ne)))
else if (model_undef && cell->type.in(TW($eq), TW($ne)))
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
@ -662,7 +662,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr), TW($shift), TW($shiftx)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -681,16 +681,16 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> shifted_a;
if (cell->type.in( ID($shl), ID($sshl)))
if (cell->type.in( TW($shl), TW($sshl)))
shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr))
if (cell->type == TW($shr))
shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr))
if (cell->type == TW($sshr))
shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type.in(ID($shift), ID($shiftx)))
if (cell->type.in(TW($shift), TW($shiftx)))
shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
ez->assume(ez->vec_eq(shifted_a, yy));
@ -702,7 +702,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(TW::Y), timestep);
std::vector<int> undef_a_shifted;
extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
extend_bit = cell->type == TW($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
if (cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = undef_a.back();
@ -711,19 +711,19 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
while (undef_y.size() > undef_a.size())
undef_a.push_back(extend_bit);
if (cell->type.in(ID($shl), ID($sshl)))
if (cell->type.in(TW($shl), TW($sshl)))
undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shr))
if (cell->type == TW($shr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr))
if (cell->type == TW($sshr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shift))
if (cell->type == TW($shift))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shiftx))
if (cell->type == TW($shiftx))
undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
@ -734,7 +734,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($mul))
if (cell->type == TW($mul))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -761,7 +761,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($macc), ID($macc_v2)))
if (cell->type.in(TW($macc), TW($macc_v2)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -811,7 +811,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(TW::B), timestep);
std::vector<int> undef_c;
if (cell->type == ID($macc_v2))
if (cell->type == TW($macc_v2))
undef_c = importUndefSigSpec(cell->getPort(TW::C), timestep);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@ -830,7 +830,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($div), ID($mod), ID($divfloor), ID($modfloor)))
if (cell->type.in(TW($div), TW($mod), TW($divfloor), TW($modfloor)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -878,14 +878,14 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
floored_eq_trunc = ez->CONST_TRUE;
}
if (cell->type == ID($div)) {
if (cell->type == TW($div)) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
else
ez->assume(ez->vec_eq(y_tmp, y_u));
} else if (cell->type == ID($mod)) {
} else if (cell->type == TW($mod)) {
ez->assume(ez->vec_eq(y_tmp, modulo_trunc));
} else if (cell->type == ID($divfloor)) {
} else if (cell->type == TW($divfloor)) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(
ez->XOR(a.back(), b.back()),
@ -898,7 +898,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
)));
else
ez->assume(ez->vec_eq(y_tmp, y_u));
} else if (cell->type == ID($modfloor)) {
} else if (cell->type == TW($modfloor)) {
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(floored_eq_trunc, modulo_trunc, ez->vec_add(modulo_trunc, b))));
}
@ -906,7 +906,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
ez->assume(ez->expression(ezSAT::OpOr, b));
} else {
std::vector<int> div_zero_result;
if (cell->type.in(ID($div), ID($divfloor))) {
if (cell->type.in(TW($div), TW($divfloor))) {
if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) {
std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);
@ -916,7 +916,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
div_zero_result.insert(div_zero_result.end(), cell->getPort(TW::A).size(), ez->CONST_TRUE);
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
}
} else if (cell->type.in(ID($mod), ID($modfloor))) {
} else if (cell->type.in(TW($mod), TW($modfloor))) {
// a mod 0 = a
int copy_a_bits = min(cell->getPort(TW::A).size(), cell->getPort(TW::B).size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
@ -936,7 +936,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($lut))
if (cell->type == TW($lut))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -986,7 +986,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($sop))
if (cell->type == TW($sop))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
int y = importDefSigSpec(cell->getPort(TW::Y), timestep).at(0);
@ -1068,7 +1068,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($fa))
if (cell->type == TW($fa))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -1104,7 +1104,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($lcu))
if (cell->type == TW($lcu))
{
std::vector<int> p = importDefSigSpec(cell->getPort(TW::P), timestep);
std::vector<int> g = importDefSigSpec(cell->getPort(TW::G), timestep);
@ -1136,7 +1136,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($alu))
if (cell->type == TW($alu))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(TW::B), timestep);
@ -1202,7 +1202,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($slice))
if (cell->type == TW($slice))
{
RTLIL::SigSpec a = cell->getPort(TW::A);
RTLIL::SigSpec y = cell->getPort(TW::Y);
@ -1210,7 +1210,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($concat))
if (cell->type == TW($concat))
{
RTLIL::SigSpec a = cell->getPort(TW::A);
RTLIL::SigSpec b = cell->getPort(TW::B);
@ -1223,7 +1223,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (timestep > 0 && (cell->is_builtin_ff() || cell->type == ID($anyinit)))
if (timestep > 0 && (cell->is_builtin_ff() || cell->type == TW($anyinit)))
{
FfData ff(nullptr, cell);
@ -1303,7 +1303,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($anyconst))
if (cell->type == TW($anyconst))
{
if (timestep < 2) {
if (model_undef && def_formal) {
@ -1335,7 +1335,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($anyseq))
if (cell->type == TW($anyseq))
{
if (model_undef && def_formal) {
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(TW::Y), timestep);
@ -1345,7 +1345,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($_BUF_), ID($equiv)))
if (cell->type.in(TW($_BUF_), TW($equiv)))
{
std::vector<int> a = importDefSigSpec(cell->getPort(TW::A), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(TW::Y), timestep);
@ -1364,7 +1364,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($initstate))
if (cell->type == TW($initstate))
{
auto key = make_pair(prefix, timestep);
if (initstates.count(key) == 0)
@ -1383,7 +1383,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($assert))
if (cell->type == TW($assert))
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
asserts_a[pf].append((*sigmap)(cell->getPort(TW::A)));
@ -1391,7 +1391,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type == ID($assume))
if (cell->type == TW($assume))
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
assumes_a[pf].append((*sigmap)(cell->getPort(TW::A)));
@ -1399,7 +1399,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (cell->type.in(ID($scopeinfo), ID($input_port), ID($output_port), ID($public)))
if (cell->type.in(TW($scopeinfo), TW($input_port), TW($output_port), TW($public)))
{
return true;
}
@ -1415,9 +1415,9 @@ void report_missing_model(bool warn_only, RTLIL::Cell* cell)
{
std::string s;
if (cell->is_builtin_ff())
s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", cell, cell->type.unescape());
s = stringf("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", cell, cell->type.unescaped());
else
s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescape());
s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescaped());
if (warn_only) {
log_formatted_warning_noprefix(s);

View file

@ -102,7 +102,7 @@ struct SatGen
else
vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE);
} else {
std::string wire_name = bit.wire->name.unescape();
std::string wire_name = bit.wire->module->design->twines.unescaped_str(bit.wire->meta_->name);
std::string name = pf +
(bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset));
vec.push_back(ez->frozen_literal(name));

View file

@ -55,7 +55,7 @@ void ModuleHdlnameIndex::index_cells()
void ModuleHdlnameIndex::index_scopeinfo_cells()
{
auto cells = module->cells();
index_items(cells.begin(), cells.end(), [](Cell *cell) { return cell->type == ID($scopeinfo); });
index_items(cells.begin(), cells.end(), [](Cell *cell) { return cell->type == TW($scopeinfo); });
}
std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor)
@ -69,7 +69,7 @@ std::vector<std::string> ModuleHdlnameIndex::scope_sources(Cursor cursor)
continue;
}
Cell *cell = cursor.entry().cell();
if (cell == nullptr || cell->type != ID($scopeinfo)) {
if (cell == nullptr || cell->type != TW($scopeinfo)) {
result.push_back("");
result.push_back("");
continue;
@ -99,14 +99,14 @@ static const char *attr_prefix(ScopeinfoAttrs attrs)
bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id)
{
log_assert(scopeinfo->type == ID($scopeinfo));
return scopeinfo->has_attribute(attr_prefix(attrs) + id.unescape());
log_assert(scopeinfo->type == TW($scopeinfo));
return scopeinfo->has_attribute(attr_prefix(attrs) + design->twines.unescaped_str(id));
}
RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id)
{
log_assert(scopeinfo->type == ID($scopeinfo));
auto found = scopeinfo->attributes.find(attr_prefix(attrs) + id.unescape());
log_assert(scopeinfo->type == TW($scopeinfo));
auto found = scopeinfo->attributes.find(attr_prefix(attrs) + design->twines.unescaped_str(id));
if (found == scopeinfo->attributes.end())
return RTLIL::Const();
return found->second;

View file

@ -29,15 +29,15 @@ struct TimingInfo
{
struct NameBit
{
RTLIL::IdString name;
TwineRef name;
int offset;
NameBit() : offset(0) {}
NameBit(const RTLIL::IdString name, int offset) : name(name), offset(offset) {}
explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->name), offset(b.offset) {}
NameBit(TwineRef name, int offset) : name(name), offset(offset) {}
explicit NameBit(const RTLIL::SigBit &b) : name(b.wire->meta_->name), offset(b.offset) {}
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) {
TwineRef port_name = cell->module->design->twines.lookup(name.str());
TwineRef port_name = name;
if (!cell->hasPort(port_name))
return {};
auto &port = cell->getPort(port_name);
@ -71,7 +71,7 @@ struct TimingInfo
bool has_inputs;
};
dict<RTLIL::IdString, ModuleTiming> data;
dict<TwineRef, ModuleTiming> data;
TimingInfo()
{
@ -93,12 +93,12 @@ struct TimingInfo
const ModuleTiming& setup_module(RTLIL::Module *module)
{
auto r = data.insert(RTLIL::IdString(module->design->twines.str(module->meta_->name)));
auto r = data.insert(module->meta_->name);
log_assert(r.second);
auto &t = r.first->second;
for (auto cell : module->cells()) {
if (cell->type == ID($specify2)) {
if (cell->type == TW($specify2)) {
auto en = cell->getPort(TW::EN);
if (en.is_fully_const() && !en.as_bool())
continue;
@ -136,7 +136,7 @@ struct TimingInfo
}
}
}
else if (cell->type == ID($specify3)) {
else if (cell->type == TW($specify3)) {
auto src = cell->getPort(TW::SRC).as_bit();
auto dst = cell->getPort(TW::DST);
if (!src.wire || !src.wire->port_input)
@ -160,9 +160,9 @@ struct TimingInfo
}
}
}
else if (cell->type == ID($specrule)) {
else if (cell->type == TW($specrule)) {
IdString type = cell->getParam(ID::TYPE).decode_string();
if (type != ID($setup) && type != ID($setuphold))
if (type != TW($setup) && type != TW($setuphold))
continue;
auto src = cell->getPort(TW::SRC);
auto dst = cell->getPort(TW::DST).as_bit();
@ -198,10 +198,10 @@ struct TimingInfo
return t;
}
decltype(data)::const_iterator find(RTLIL::IdString module_name) const { return data.find(module_name); }
decltype(data)::const_iterator find(TwineRef module_name) const { return data.find(module_name); }
decltype(data)::const_iterator end() const { return data.end(); }
int count(RTLIL::IdString module_name) const { return data.count(module_name); }
const ModuleTiming& at(RTLIL::IdString module_name) const { return data.at(module_name); }
int count(TwineRef module_name) const { return data.count(module_name); }
const ModuleTiming& at(TwineRef module_name) const { return data.at(module_name); }
};
YOSYS_NAMESPACE_END

View file

@ -91,6 +91,20 @@ struct TW {
throw "unknown twine id";
}
static constexpr const char* static_names[] = {
#define X(N) #N,
#include "kernel/constids.inc"
#undef X
};
static std::string str(TwineRef ref) {
TwineRef idx = ref.untag();
if (idx.value >= STATIC_TWINE_END) return {};
std::string result = ref.is_public() ? "\\" : "";
result += static_names[idx.value];
return result;
}
};
#define TW(id) (size_t)lookup_well_known_id(#id)
@ -102,7 +116,6 @@ struct Twine {
struct Suffix {
TwineRef prefix;
std::string tail;
// TODO check
auto operator<=>(const Suffix&) const = default;
};

View file

@ -76,9 +76,9 @@ public:
RTLIL::Cell *addCell(TwineRef name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, const RTLIL::Cell *other);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
RTLIL::Cell *addCell(Twine &&name, TwineRef type);
RTLIL::Cell *addCell(TwineRef name, Twine &&type);
RTLIL::Cell *addCell(Twine &&name, const RTLIL::Cell *other);
// NEW_ID analog for twine names; see NEW_TWINE in yosys_common.h.
// Returned refs are twine_staging-local and die at the next commit.

View file

@ -964,7 +964,7 @@ static char *readline_obj_generator(const char *text, int state)
RTLIL::Module *module = design->module(design->selected_active_module);
for (auto w : module->wires())
if (w->name.unescape().compare(0, len, text) == 0)
if (design->twines.unescaped_str(w->meta_->name).compare(0, len, text) == 0)
obj_names.push_back(strdup(w->name.unescape().c_str()));
for (auto &it : module->memories) {