mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
afdae7b87e
commit
c3ffbf6fae
229 changed files with 3902 additions and 3835 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
26
kernel/ff.cc
26
kernel/ff.cc
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
1276
kernel/functional.h
1276
kernel/functional.h
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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> ¶meters, bool mayfail = false);
|
||||
virtual TwineRef derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, 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> ¶meters, 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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
198
kernel/satgen.cc
198
kernel/satgen.cc
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue