mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1275 from YosysHQ/clifford/ids
New ID() macro and now also use it
This commit is contained in:
commit
704686774e
|
@ -268,9 +268,9 @@ Aig::Aig(Cell *cell)
|
|||
cell->parameters.sort();
|
||||
for (auto p : cell->parameters)
|
||||
{
|
||||
if (p.first == "\\A_WIDTH" && mkname_a_signed) {
|
||||
if (p.first == ID(A_WIDTH) && mkname_a_signed) {
|
||||
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
|
||||
} else if (p.first == "\\B_WIDTH" && mkname_b_signed) {
|
||||
} else if (p.first == ID(B_WIDTH) && mkname_b_signed) {
|
||||
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
|
||||
} else {
|
||||
mkname_last = name;
|
||||
|
@ -280,183 +280,183 @@ Aig::Aig(Cell *cell)
|
|||
mkname_a_signed = false;
|
||||
mkname_b_signed = false;
|
||||
mkname_is_signed = false;
|
||||
if (p.first == "\\A_SIGNED") {
|
||||
if (p.first == ID(A_SIGNED)) {
|
||||
mkname_a_signed = true;
|
||||
mkname_is_signed = p.second.as_bool();
|
||||
}
|
||||
if (p.first == "\\B_SIGNED") {
|
||||
if (p.first == ID(B_SIGNED)) {
|
||||
mkname_b_signed = true;
|
||||
mkname_is_signed = p.second.as_bool();
|
||||
}
|
||||
}
|
||||
|
||||
if (cell->type.in("$not", "$_NOT_", "$pos", "$_BUF_"))
|
||||
if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_)))
|
||||
{
|
||||
for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
|
||||
int A = mk.inport("\\A", i);
|
||||
int Y = cell->type.in("$not", "$_NOT_") ? mk.not_gate(A) : A;
|
||||
mk.outport(Y, "\\Y", i);
|
||||
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) {
|
||||
int A = mk.inport(ID(A), i);
|
||||
int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
|
||||
mk.outport(Y, ID(Y), i);
|
||||
}
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
{
|
||||
for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
|
||||
int A = mk.inport("\\A", i);
|
||||
int B = mk.inport("\\B", i);
|
||||
int Y = cell->type.in("$and", "$_AND_") ? mk.and_gate(A, B) :
|
||||
cell->type.in("$_NAND_") ? mk.nand_gate(A, B) :
|
||||
cell->type.in("$or", "$_OR_") ? mk.or_gate(A, B) :
|
||||
cell->type.in("$_NOR_") ? mk.nor_gate(A, B) :
|
||||
cell->type.in("$xor", "$_XOR_") ? mk.xor_gate(A, B) :
|
||||
cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) :
|
||||
cell->type.in("$_ANDNOT_") ? mk.andnot_gate(A, B) :
|
||||
cell->type.in("$_ORNOT_") ? mk.ornot_gate(A, B) : -1;
|
||||
mk.outport(Y, "\\Y", i);
|
||||
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) {
|
||||
int A = mk.inport(ID(A), i);
|
||||
int B = mk.inport(ID(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;
|
||||
mk.outport(Y, ID(Y), i);
|
||||
}
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$mux", "$_MUX_"))
|
||||
if (cell->type.in(ID($mux), ID($_MUX_)))
|
||||
{
|
||||
int S = mk.inport("\\S");
|
||||
for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
|
||||
int A = mk.inport("\\A", i);
|
||||
int B = mk.inport("\\B", i);
|
||||
int S = mk.inport(ID(S));
|
||||
for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) {
|
||||
int A = mk.inport(ID(A), i);
|
||||
int B = mk.inport(ID(B), i);
|
||||
int Y = mk.mux_gate(A, B, S);
|
||||
if (cell->type == "$_NMUX_")
|
||||
if (cell->type == ID($_NMUX_))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport(Y, "\\Y", i);
|
||||
mk.outport(Y, ID(Y), i);
|
||||
}
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool"))
|
||||
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)))
|
||||
{
|
||||
int Y = mk.inport("\\A", 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) {
|
||||
int A = mk.inport("\\A", i);
|
||||
if (cell->type == "$reduce_and") Y = mk.and_gate(A, Y);
|
||||
if (cell->type == "$reduce_or") Y = mk.or_gate(A, Y);
|
||||
if (cell->type == "$reduce_bool") Y = mk.or_gate(A, Y);
|
||||
if (cell->type == "$reduce_xor") Y = mk.xor_gate(A, Y);
|
||||
if (cell->type == "$reduce_xnor") Y = mk.xor_gate(A, Y);
|
||||
int Y = mk.inport(ID(A), 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) {
|
||||
int A = mk.inport(ID(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 == "$reduce_xnor")
|
||||
if (cell->type == ID($reduce_xnor))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport(Y, "\\Y", 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort("\\Y")); i++)
|
||||
mk.outport(mk.bool_node(false), "\\Y", i);
|
||||
mk.outport(Y, ID(Y), 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(ID(Y))); i++)
|
||||
mk.outport(mk.bool_node(false), ID(Y), i);
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$logic_not", "$logic_and", "$logic_or"))
|
||||
if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
|
||||
{
|
||||
int A = mk.inport("\\A", 0), Y = -1;
|
||||
for (int i = 1; i < GetSize(cell->getPort("\\A")); i++)
|
||||
A = mk.or_gate(mk.inport("\\A", i), A);
|
||||
if (cell->type.in("$logic_and", "$logic_or")) {
|
||||
int B = mk.inport("\\B", 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort("\\B")); i++)
|
||||
B = mk.or_gate(mk.inport("\\B", i), B);
|
||||
if (cell->type == "$logic_and") Y = mk.and_gate(A, B);
|
||||
if (cell->type == "$logic_or") Y = mk.or_gate(A, B);
|
||||
int A = mk.inport(ID(A), 0), Y = -1;
|
||||
for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++)
|
||||
A = mk.or_gate(mk.inport(ID(A), i), A);
|
||||
if (cell->type.in(ID($logic_and), ID($logic_or))) {
|
||||
int B = mk.inport(ID(B), 0);
|
||||
for (int i = 1; i < GetSize(cell->getPort(ID(B))); i++)
|
||||
B = mk.or_gate(mk.inport(ID(B), i), B);
|
||||
if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B);
|
||||
if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B);
|
||||
} else {
|
||||
if (cell->type == "$logic_not") Y = mk.not_gate(A);
|
||||
if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
|
||||
}
|
||||
mk.outport_bool(Y, "\\Y");
|
||||
mk.outport_bool(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$add", "$sub"))
|
||||
if (cell->type.in(ID($add), ID($sub)))
|
||||
{
|
||||
int width = GetSize(cell->getPort("\\Y"));
|
||||
vector<int> A = mk.inport_vec("\\A", width);
|
||||
vector<int> B = mk.inport_vec("\\B", width);
|
||||
int width = GetSize(cell->getPort(ID(Y)));
|
||||
vector<int> A = mk.inport_vec(ID(A), width);
|
||||
vector<int> B = mk.inport_vec(ID(B), width);
|
||||
int carry = mk.bool_node(false);
|
||||
if (cell->type == "$sub") {
|
||||
if (cell->type == ID($sub)) {
|
||||
for (auto &n : B)
|
||||
n = mk.not_gate(n);
|
||||
carry = mk.not_gate(carry);
|
||||
}
|
||||
vector<int> Y = mk.adder(A, B, carry);
|
||||
mk.outport_vec(Y, "\\Y");
|
||||
mk.outport_vec(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == "$alu")
|
||||
if (cell->type == ID($alu))
|
||||
{
|
||||
int width = GetSize(cell->getPort("\\Y"));
|
||||
vector<int> A = mk.inport_vec("\\A", width);
|
||||
vector<int> B = mk.inport_vec("\\B", width);
|
||||
int carry = mk.inport("\\CI");
|
||||
int binv = mk.inport("\\BI");
|
||||
int width = GetSize(cell->getPort(ID(Y)));
|
||||
vector<int> A = mk.inport_vec(ID(A), width);
|
||||
vector<int> B = mk.inport_vec(ID(B), width);
|
||||
int carry = mk.inport(ID(CI));
|
||||
int binv = mk.inport(ID(BI));
|
||||
for (auto &n : B)
|
||||
n = mk.xor_gate(n, binv);
|
||||
vector<int> X(width), CO(width);
|
||||
vector<int> Y = mk.adder(A, B, carry, &X, &CO);
|
||||
for (int i = 0; i < width; i++)
|
||||
X[i] = mk.xor_gate(A[i], B[i]);
|
||||
mk.outport_vec(Y, "\\Y");
|
||||
mk.outport_vec(X, "\\X");
|
||||
mk.outport_vec(CO, "\\CO");
|
||||
mk.outport_vec(Y, ID(Y));
|
||||
mk.outport_vec(X, ID(X));
|
||||
mk.outport_vec(CO, ID(CO));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$eq", "$ne"))
|
||||
if (cell->type.in(ID($eq), ID($ne)))
|
||||
{
|
||||
int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
|
||||
vector<int> A = mk.inport_vec("\\A", width);
|
||||
vector<int> B = mk.inport_vec("\\B", width);
|
||||
int width = max(GetSize(cell->getPort(ID(A))), GetSize(cell->getPort(ID(B))));
|
||||
vector<int> A = mk.inport_vec(ID(A), width);
|
||||
vector<int> B = mk.inport_vec(ID(B), width);
|
||||
int Y = mk.bool_node(false);
|
||||
for (int i = 0; i < width; i++)
|
||||
Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i]));
|
||||
if (cell->type == "$eq")
|
||||
if (cell->type == ID($eq))
|
||||
Y = mk.not_gate(Y);
|
||||
mk.outport_bool(Y, "\\Y");
|
||||
mk.outport_bool(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == "$_AOI3_")
|
||||
if (cell->type == ID($_AOI3_))
|
||||
{
|
||||
int A = mk.inport("\\A");
|
||||
int B = mk.inport("\\B");
|
||||
int C = mk.inport("\\C");
|
||||
int A = mk.inport(ID(A));
|
||||
int B = mk.inport(ID(B));
|
||||
int C = mk.inport(ID(C));
|
||||
int Y = mk.nor_gate(mk.and_gate(A, B), C);
|
||||
mk.outport(Y, "\\Y");
|
||||
mk.outport(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == "$_OAI3_")
|
||||
if (cell->type == ID($_OAI3_))
|
||||
{
|
||||
int A = mk.inport("\\A");
|
||||
int B = mk.inport("\\B");
|
||||
int C = mk.inport("\\C");
|
||||
int A = mk.inport(ID(A));
|
||||
int B = mk.inport(ID(B));
|
||||
int C = mk.inport(ID(C));
|
||||
int Y = mk.nand_gate(mk.or_gate(A, B), C);
|
||||
mk.outport(Y, "\\Y");
|
||||
mk.outport(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == "$_AOI4_")
|
||||
if (cell->type == ID($_AOI4_))
|
||||
{
|
||||
int A = mk.inport("\\A");
|
||||
int B = mk.inport("\\B");
|
||||
int C = mk.inport("\\C");
|
||||
int D = mk.inport("\\D");
|
||||
int A = mk.inport(ID(A));
|
||||
int B = mk.inport(ID(B));
|
||||
int C = mk.inport(ID(C));
|
||||
int D = mk.inport(ID(D));
|
||||
int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D));
|
||||
mk.outport(Y, "\\Y");
|
||||
mk.outport(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type == "$_OAI4_")
|
||||
if (cell->type == ID($_OAI4_))
|
||||
{
|
||||
int A = mk.inport("\\A");
|
||||
int B = mk.inport("\\B");
|
||||
int C = mk.inport("\\C");
|
||||
int D = mk.inport("\\D");
|
||||
int A = mk.inport(ID(A));
|
||||
int B = mk.inport(ID(B));
|
||||
int C = mk.inport(ID(C));
|
||||
int D = mk.inport(ID(D));
|
||||
int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
|
||||
mk.outport(Y, "\\Y");
|
||||
mk.outport(Y, ID(Y));
|
||||
goto optimize;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ PRIVATE_NAMESPACE_BEGIN
|
|||
|
||||
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", Y = "\\Y";
|
||||
IdString A = ID(A), Y = ID(Y);
|
||||
|
||||
bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
|
||||
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int y_width = GetSize(cell->getPort(Y));
|
||||
|
||||
|
@ -41,14 +41,14 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", B = "\\B", Y = "\\Y";
|
||||
IdString A = ID(A), B = ID(B), Y = ID(Y);
|
||||
|
||||
bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
|
||||
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int b_width = GetSize(cell->getPort(B));
|
||||
int y_width = GetSize(cell->getPort(Y));
|
||||
|
||||
if (cell->type == "$and" && !is_signed) {
|
||||
if (cell->type == ID($and) && !is_signed) {
|
||||
if (a_width > b_width)
|
||||
a_width = b_width;
|
||||
else
|
||||
|
@ -71,9 +71,9 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", Y = "\\Y";
|
||||
IdString A = ID(A), Y = ID(Y);
|
||||
|
||||
bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
|
||||
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int y_width = GetSize(cell->getPort(Y));
|
||||
|
||||
|
@ -87,14 +87,14 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", B = "\\B", Y = "\\Y";
|
||||
IdString A = ID(A), B = ID(B), Y = ID(Y);
|
||||
|
||||
bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
|
||||
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int b_width = GetSize(cell->getPort(B));
|
||||
int y_width = GetSize(cell->getPort(Y));
|
||||
|
||||
if (!is_signed && cell->type != "$sub") {
|
||||
if (!is_signed && cell->type != ID($sub)) {
|
||||
int ab_width = std::max(a_width, b_width);
|
||||
y_width = std::min(y_width, ab_width+1);
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", Y = "\\Y";
|
||||
IdString A = ID(A), Y = ID(Y);
|
||||
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
|
||||
|
@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", B = "\\B", Y = "\\Y";
|
||||
IdString A = ID(A), B = ID(B), Y = ID(Y);
|
||||
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int b_width = GetSize(cell->getPort(B));
|
||||
|
@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
|||
|
||||
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
|
||||
{
|
||||
IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y";
|
||||
IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y);
|
||||
|
||||
int a_width = GetSize(cell->getPort(A));
|
||||
int b_width = GetSize(cell->getPort(B));
|
||||
|
@ -160,43 +160,43 @@ PRIVATE_NAMESPACE_END
|
|||
|
||||
bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)
|
||||
{
|
||||
if (cell->type.in("$not", "$pos")) {
|
||||
if (cell->type.in(ID($not), ID($pos))) {
|
||||
bitwise_unary_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$and", "$or", "$xor", "$xnor")) {
|
||||
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
|
||||
bitwise_binary_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == "$neg") {
|
||||
if (cell->type == ID($neg)) {
|
||||
arith_neg_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$add", "$sub")) {
|
||||
if (cell->type.in(ID($add), ID($sub))) {
|
||||
arith_binary_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not")) {
|
||||
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) {
|
||||
reduce_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
// if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) {
|
||||
// if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
|
||||
// shift_op(this, cell);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) {
|
||||
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
|
||||
compare_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$mux", "$pmux")) {
|
||||
if (cell->type.in(ID($mux), ID($pmux))) {
|
||||
mux_op(this, cell);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -84,46 +84,46 @@ struct CellTypes
|
|||
{
|
||||
setup_internals_eval();
|
||||
|
||||
IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y";
|
||||
IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT";
|
||||
IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST";
|
||||
IdString A = ID(A), B = ID(B), EN = ID(EN), Y = ID(Y);
|
||||
IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT);
|
||||
IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST);
|
||||
|
||||
setup_type("$tribuf", {A, EN}, {Y}, true);
|
||||
setup_type(ID($tribuf), {A, EN}, {Y}, true);
|
||||
|
||||
setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type("$equiv", {A, B}, {Y}, true);
|
||||
setup_type("$specify2", {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$specify3", {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
|
||||
setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true);
|
||||
setup_type(ID($equiv), {A, B}, {Y}, true);
|
||||
setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
|
||||
setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
|
||||
}
|
||||
|
||||
void setup_internals_eval()
|
||||
{
|
||||
std::vector<RTLIL::IdString> unary_ops = {
|
||||
"$not", "$pos", "$neg",
|
||||
"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
|
||||
"$logic_not", "$slice", "$lut", "$sop"
|
||||
ID($not), ID($pos), ID($neg),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($logic_not), ID($slice), ID($lut), ID($sop)
|
||||
};
|
||||
|
||||
std::vector<RTLIL::IdString> binary_ops = {
|
||||
"$and", "$or", "$xor", "$xnor",
|
||||
"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
|
||||
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
|
||||
"$add", "$sub", "$mul", "$div", "$mod", "$pow",
|
||||
"$logic_and", "$logic_or", "$concat", "$macc"
|
||||
ID($and), ID($or), ID($xor), ID($xnor),
|
||||
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
|
||||
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
|
||||
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow),
|
||||
ID($logic_and), ID($logic_or), ID($concat), ID($macc)
|
||||
};
|
||||
IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y";
|
||||
IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X";
|
||||
IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN";
|
||||
IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y);
|
||||
IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X);
|
||||
IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);
|
||||
|
||||
for (auto type : unary_ops)
|
||||
setup_type(type, {A}, {Y}, true);
|
||||
|
@ -131,27 +131,27 @@ struct CellTypes
|
|||
for (auto type : binary_ops)
|
||||
setup_type(type, {A, B}, {Y}, true);
|
||||
|
||||
for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"}))
|
||||
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))
|
||||
setup_type(type, {A, B, S}, {Y}, true);
|
||||
|
||||
setup_type("$lcu", {P, G, CI}, {CO}, true);
|
||||
setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true);
|
||||
setup_type("$fa", {A, B, C}, {X, Y}, true);
|
||||
setup_type(ID($lcu), {P, G, CI}, {CO}, true);
|
||||
setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true);
|
||||
setup_type(ID($fa), {A, B, C}, {X, Y}, true);
|
||||
}
|
||||
|
||||
void setup_internals_ff()
|
||||
{
|
||||
IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
|
||||
IdString Q = "\\Q", D = "\\D";
|
||||
IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
|
||||
IdString Q = ID(Q), D = ID(D);
|
||||
|
||||
setup_type("$sr", {SET, CLR}, {Q});
|
||||
setup_type("$ff", {D}, {Q});
|
||||
setup_type("$dff", {CLK, D}, {Q});
|
||||
setup_type("$dffe", {CLK, EN, D}, {Q});
|
||||
setup_type("$dffsr", {CLK, SET, CLR, D}, {Q});
|
||||
setup_type("$adff", {CLK, ARST, D}, {Q});
|
||||
setup_type("$dlatch", {EN, D}, {Q});
|
||||
setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q});
|
||||
setup_type(ID($sr), {SET, CLR}, {Q});
|
||||
setup_type(ID($ff), {D}, {Q});
|
||||
setup_type(ID($dff), {CLK, D}, {Q});
|
||||
setup_type(ID($dffe), {CLK, EN, D}, {Q});
|
||||
setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q});
|
||||
setup_type(ID($adff), {CLK, ARST, D}, {Q});
|
||||
setup_type(ID($dlatch), {EN, D}, {Q});
|
||||
setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q});
|
||||
|
||||
}
|
||||
|
||||
|
@ -159,63 +159,63 @@ struct CellTypes
|
|||
{
|
||||
setup_internals_ff();
|
||||
|
||||
IdString CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
|
||||
IdString ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN";
|
||||
IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN";
|
||||
IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA";
|
||||
IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
|
||||
IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
|
||||
IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN);
|
||||
IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN);
|
||||
IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA);
|
||||
IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT);
|
||||
|
||||
setup_type("$memrd", {CLK, EN, ADDR}, {DATA});
|
||||
setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
|
||||
setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>());
|
||||
setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
|
||||
setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA});
|
||||
setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
|
||||
setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>());
|
||||
setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
|
||||
|
||||
setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT});
|
||||
setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT});
|
||||
}
|
||||
|
||||
void setup_stdcells()
|
||||
{
|
||||
setup_stdcells_eval();
|
||||
|
||||
IdString A = "\\A", E = "\\E", Y = "\\Y";
|
||||
IdString A = ID(A), E = ID(E), Y = ID(Y);
|
||||
|
||||
setup_type("$_TBUF_", {A, E}, {Y}, true);
|
||||
setup_type(ID($_TBUF_), {A, E}, {Y}, true);
|
||||
}
|
||||
|
||||
void setup_stdcells_eval()
|
||||
{
|
||||
IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D";
|
||||
IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H";
|
||||
IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L";
|
||||
IdString M = "\\M", N = "\\N", O = "\\O", P = "\\P";
|
||||
IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V";
|
||||
IdString Y = "\\Y";
|
||||
IdString A = ID(A), B = ID(B), C = ID(C), D = ID(D);
|
||||
IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H);
|
||||
IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L);
|
||||
IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P);
|
||||
IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V);
|
||||
IdString Y = ID(Y);
|
||||
|
||||
setup_type("$_BUF_", {A}, {Y}, true);
|
||||
setup_type("$_NOT_", {A}, {Y}, true);
|
||||
setup_type("$_AND_", {A, B}, {Y}, true);
|
||||
setup_type("$_NAND_", {A, B}, {Y}, true);
|
||||
setup_type("$_OR_", {A, B}, {Y}, true);
|
||||
setup_type("$_NOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_XOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_XNOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_ANDNOT_", {A, B}, {Y}, true);
|
||||
setup_type("$_ORNOT_", {A, B}, {Y}, true);
|
||||
setup_type("$_MUX_", {A, B, S}, {Y}, true);
|
||||
setup_type("$_NMUX_", {A, B, S}, {Y}, true);
|
||||
setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true);
|
||||
setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
|
||||
setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
|
||||
setup_type("$_AOI3_", {A, B, C}, {Y}, true);
|
||||
setup_type("$_OAI3_", {A, B, C}, {Y}, true);
|
||||
setup_type("$_AOI4_", {A, B, C, D}, {Y}, true);
|
||||
setup_type("$_OAI4_", {A, B, C, D}, {Y}, true);
|
||||
setup_type(ID($_BUF_), {A}, {Y}, true);
|
||||
setup_type(ID($_NOT_), {A}, {Y}, true);
|
||||
setup_type(ID($_AND_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_NAND_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_OR_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_NOR_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_XOR_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_XNOR_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_ANDNOT_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_ORNOT_), {A, B}, {Y}, true);
|
||||
setup_type(ID($_MUX_), {A, B, S}, {Y}, true);
|
||||
setup_type(ID($_NMUX_), {A, B, S}, {Y}, true);
|
||||
setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true);
|
||||
setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
|
||||
setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
|
||||
setup_type(ID($_AOI3_), {A, B, C}, {Y}, true);
|
||||
setup_type(ID($_OAI3_), {A, B, C}, {Y}, true);
|
||||
setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true);
|
||||
setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true);
|
||||
}
|
||||
|
||||
void setup_stdcells_mem()
|
||||
{
|
||||
IdString S = "\\S", R = "\\R", C = "\\C";
|
||||
IdString D = "\\D", Q = "\\Q", E = "\\E";
|
||||
IdString S = ID(S), R = ID(R), C = ID(C);
|
||||
IdString D = ID(D), Q = ID(Q), E = ID(E);
|
||||
|
||||
std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
|
||||
|
||||
|
@ -223,7 +223,7 @@ struct CellTypes
|
|||
for (auto c2 : list_np)
|
||||
setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q});
|
||||
|
||||
setup_type("$_FF_", {D}, {Q});
|
||||
setup_type(ID($_FF_), {D}, {Q});
|
||||
|
||||
for (auto c1 : list_np)
|
||||
setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q});
|
||||
|
@ -289,13 +289,13 @@ struct CellTypes
|
|||
|
||||
static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
|
||||
{
|
||||
if (type == "$sshr" && !signed1)
|
||||
type = "$shr";
|
||||
if (type == "$sshl" && !signed1)
|
||||
type = "$shl";
|
||||
if (type == ID($sshr) && !signed1)
|
||||
type = ID($shr);
|
||||
if (type == ID($sshl) && !signed1)
|
||||
type = ID($shl);
|
||||
|
||||
if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" &&
|
||||
type != "$pos" && type != "$neg" && type != "$not") {
|
||||
if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) &&
|
||||
type != ID($pos) && type != ID($neg) && type != ID($not)) {
|
||||
if (!signed1 || !signed2)
|
||||
signed1 = false, signed2 = false;
|
||||
}
|
||||
|
@ -338,25 +338,25 @@ struct CellTypes
|
|||
HANDLE_CELL_TYPE(neg)
|
||||
#undef HANDLE_CELL_TYPE
|
||||
|
||||
if (type == "$_BUF_")
|
||||
if (type == ID($_BUF_))
|
||||
return arg1;
|
||||
if (type == "$_NOT_")
|
||||
if (type == ID($_NOT_))
|
||||
return eval_not(arg1);
|
||||
if (type == "$_AND_")
|
||||
if (type == ID($_AND_))
|
||||
return const_and(arg1, arg2, false, false, 1);
|
||||
if (type == "$_NAND_")
|
||||
if (type == ID($_NAND_))
|
||||
return eval_not(const_and(arg1, arg2, false, false, 1));
|
||||
if (type == "$_OR_")
|
||||
if (type == ID($_OR_))
|
||||
return const_or(arg1, arg2, false, false, 1);
|
||||
if (type == "$_NOR_")
|
||||
if (type == ID($_NOR_))
|
||||
return eval_not(const_or(arg1, arg2, false, false, 1));
|
||||
if (type == "$_XOR_")
|
||||
if (type == ID($_XOR_))
|
||||
return const_xor(arg1, arg2, false, false, 1);
|
||||
if (type == "$_XNOR_")
|
||||
if (type == ID($_XNOR_))
|
||||
return const_xnor(arg1, arg2, false, false, 1);
|
||||
if (type == "$_ANDNOT_")
|
||||
if (type == ID($_ANDNOT_))
|
||||
return const_and(arg1, eval_not(arg2), false, false, 1);
|
||||
if (type == "$_ORNOT_")
|
||||
if (type == ID($_ORNOT_))
|
||||
return const_or(arg1, eval_not(arg2), false, false, 1);
|
||||
|
||||
if (errp != nullptr) {
|
||||
|
@ -369,25 +369,25 @@ struct CellTypes
|
|||
|
||||
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
|
||||
{
|
||||
if (cell->type == "$slice") {
|
||||
if (cell->type == ID($slice)) {
|
||||
RTLIL::Const ret;
|
||||
int width = cell->parameters.at("\\Y_WIDTH").as_int();
|
||||
int offset = cell->parameters.at("\\OFFSET").as_int();
|
||||
int width = cell->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
int offset = cell->parameters.at(ID(OFFSET)).as_int();
|
||||
ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cell->type == "$concat") {
|
||||
if (cell->type == ID($concat)) {
|
||||
RTLIL::Const ret = arg1;
|
||||
ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cell->type == "$lut")
|
||||
if (cell->type == ID($lut))
|
||||
{
|
||||
int width = cell->parameters.at("\\WIDTH").as_int();
|
||||
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||
|
||||
std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits;
|
||||
std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits;
|
||||
while (GetSize(t) < (1 << width))
|
||||
t.push_back(State::S0);
|
||||
t.resize(1 << width);
|
||||
|
@ -409,11 +409,11 @@ struct CellTypes
|
|||
return t;
|
||||
}
|
||||
|
||||
if (cell->type == "$sop")
|
||||
if (cell->type == ID($sop))
|
||||
{
|
||||
int width = cell->parameters.at("\\WIDTH").as_int();
|
||||
int depth = cell->parameters.at("\\DEPTH").as_int();
|
||||
std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits;
|
||||
int width = cell->parameters.at(ID(WIDTH)).as_int();
|
||||
int depth = cell->parameters.at(ID(DEPTH)).as_int();
|
||||
std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits;
|
||||
|
||||
while (GetSize(t) < width*depth*2)
|
||||
t.push_back(State::S0);
|
||||
|
@ -447,15 +447,15 @@ struct CellTypes
|
|||
return default_ret;
|
||||
}
|
||||
|
||||
bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
|
||||
bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
|
||||
int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1;
|
||||
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();
|
||||
int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1;
|
||||
return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
|
||||
}
|
||||
|
||||
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
|
||||
{
|
||||
if (cell->type.in("$mux", "$pmux", "$_MUX_")) {
|
||||
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
|
||||
RTLIL::Const ret = arg1;
|
||||
for (size_t i = 0; i < arg3.bits.size(); i++)
|
||||
if (arg3.bits[i] == RTLIL::State::S1) {
|
||||
|
@ -465,9 +465,9 @@ struct CellTypes
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (cell->type == "$_AOI3_")
|
||||
if (cell->type == ID($_AOI3_))
|
||||
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
|
||||
if (cell->type == "$_OAI3_")
|
||||
if (cell->type == ID($_OAI3_))
|
||||
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
|
||||
|
||||
log_assert(arg3.bits.size() == 0);
|
||||
|
@ -476,9 +476,9 @@ struct CellTypes
|
|||
|
||||
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
|
||||
{
|
||||
if (cell->type == "$_AOI4_")
|
||||
if (cell->type == ID($_AOI4_))
|
||||
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
|
||||
if (cell->type == "$_OAI4_")
|
||||
if (cell->type == ID($_OAI4_))
|
||||
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));
|
||||
|
||||
log_assert(arg4.bits.size() == 0);
|
||||
|
|
|
@ -89,12 +89,12 @@ struct ConstEval
|
|||
|
||||
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
|
||||
{
|
||||
if (cell->type == "$lcu")
|
||||
if (cell->type == ID($lcu))
|
||||
{
|
||||
RTLIL::SigSpec sig_p = cell->getPort("\\P");
|
||||
RTLIL::SigSpec sig_g = cell->getPort("\\G");
|
||||
RTLIL::SigSpec sig_ci = cell->getPort("\\CI");
|
||||
RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO")));
|
||||
RTLIL::SigSpec sig_p = cell->getPort(ID(P));
|
||||
RTLIL::SigSpec sig_g = cell->getPort(ID(G));
|
||||
RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
|
||||
RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO))));
|
||||
|
||||
if (sig_co.is_fully_const())
|
||||
return true;
|
||||
|
@ -128,24 +128,24 @@ struct ConstEval
|
|||
|
||||
RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y;
|
||||
|
||||
log_assert(cell->hasPort("\\Y"));
|
||||
sig_y = values_map(assign_map(cell->getPort("\\Y")));
|
||||
log_assert(cell->hasPort(ID(Y)));
|
||||
sig_y = values_map(assign_map(cell->getPort(ID(Y))));
|
||||
if (sig_y.is_fully_const())
|
||||
return true;
|
||||
|
||||
if (cell->hasPort("\\S")) {
|
||||
sig_s = cell->getPort("\\S");
|
||||
if (cell->hasPort(ID(S))) {
|
||||
sig_s = cell->getPort(ID(S));
|
||||
if (!eval(sig_s, undef, cell))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cell->hasPort("\\A"))
|
||||
sig_a = cell->getPort("\\A");
|
||||
if (cell->hasPort(ID(A)))
|
||||
sig_a = cell->getPort(ID(A));
|
||||
|
||||
if (cell->hasPort("\\B"))
|
||||
sig_b = cell->getPort("\\B");
|
||||
if (cell->hasPort(ID(B)))
|
||||
sig_b = cell->getPort(ID(B));
|
||||
|
||||
if (cell->type.in("$mux", "$pmux", "$_MUX_", "$_NMUX_"))
|
||||
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
|
||||
{
|
||||
std::vector<RTLIL::SigSpec> y_candidates;
|
||||
int count_maybe_set_s_bits = 0;
|
||||
|
@ -175,7 +175,7 @@ struct ConstEval
|
|||
for (auto &yc : y_candidates) {
|
||||
if (!eval(yc, undef, cell))
|
||||
return false;
|
||||
if (cell->type == "$_NMUX_")
|
||||
if (cell->type == ID($_NMUX_))
|
||||
y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc)));
|
||||
else
|
||||
y_values.push_back(yc.as_const());
|
||||
|
@ -198,10 +198,10 @@ struct ConstEval
|
|||
else
|
||||
set(sig_y, y_values.front());
|
||||
}
|
||||
else if (cell->type == "$fa")
|
||||
else if (cell->type == ID($fa))
|
||||
{
|
||||
RTLIL::SigSpec sig_c = cell->getPort("\\C");
|
||||
RTLIL::SigSpec sig_x = cell->getPort("\\X");
|
||||
RTLIL::SigSpec sig_c = cell->getPort(ID(C));
|
||||
RTLIL::SigSpec sig_x = cell->getPort(ID(X));
|
||||
int width = GetSize(sig_c);
|
||||
|
||||
if (!eval(sig_a, undef, cell))
|
||||
|
@ -227,13 +227,13 @@ struct ConstEval
|
|||
set(sig_y, val_y);
|
||||
set(sig_x, val_x);
|
||||
}
|
||||
else if (cell->type == "$alu")
|
||||
else if (cell->type == ID($alu))
|
||||
{
|
||||
bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
|
||||
bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
|
||||
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();
|
||||
|
||||
RTLIL::SigSpec sig_ci = cell->getPort("\\CI");
|
||||
RTLIL::SigSpec sig_bi = cell->getPort("\\BI");
|
||||
RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
|
||||
RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
|
||||
|
||||
if (!eval(sig_a, undef, cell))
|
||||
return false;
|
||||
|
@ -247,8 +247,8 @@ struct ConstEval
|
|||
if (!eval(sig_bi, undef, cell))
|
||||
return false;
|
||||
|
||||
RTLIL::SigSpec sig_x = cell->getPort("\\X");
|
||||
RTLIL::SigSpec sig_co = cell->getPort("\\CO");
|
||||
RTLIL::SigSpec sig_x = cell->getPort(ID(X));
|
||||
RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
|
||||
|
||||
bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def());
|
||||
sig_a.extend_u0(GetSize(sig_y), signed_a);
|
||||
|
@ -283,7 +283,7 @@ struct ConstEval
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (cell->type == "$macc")
|
||||
else if (cell->type == ID($macc))
|
||||
{
|
||||
Macc macc;
|
||||
macc.from_cell(cell);
|
||||
|
@ -298,21 +298,21 @@ struct ConstEval
|
|||
return false;
|
||||
}
|
||||
|
||||
RTLIL::Const result(0, GetSize(cell->getPort("\\Y")));
|
||||
RTLIL::Const result(0, GetSize(cell->getPort(ID(Y))));
|
||||
if (!macc.eval(result))
|
||||
log_abort();
|
||||
|
||||
set(cell->getPort("\\Y"), result);
|
||||
set(cell->getPort(ID(Y)), result);
|
||||
}
|
||||
else
|
||||
{
|
||||
RTLIL::SigSpec sig_c, sig_d;
|
||||
|
||||
if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) {
|
||||
if (cell->hasPort("\\C"))
|
||||
sig_c = cell->getPort("\\C");
|
||||
if (cell->hasPort("\\D"))
|
||||
sig_d = cell->getPort("\\D");
|
||||
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
|
||||
if (cell->hasPort(ID(C)))
|
||||
sig_c = cell->getPort(ID(C));
|
||||
if (cell->hasPort(ID(D)))
|
||||
sig_d = cell->getPort(ID(D));
|
||||
}
|
||||
|
||||
if (sig_a.size() > 0 && !eval(sig_a, undef, cell))
|
||||
|
|
|
@ -28,44 +28,44 @@ struct CellCosts
|
|||
{
|
||||
static const dict<RTLIL::IdString, int>& default_gate_cost() {
|
||||
static const dict<RTLIL::IdString, int> db = {
|
||||
{ "$_BUF_", 1 },
|
||||
{ "$_NOT_", 2 },
|
||||
{ "$_AND_", 4 },
|
||||
{ "$_NAND_", 4 },
|
||||
{ "$_OR_", 4 },
|
||||
{ "$_NOR_", 4 },
|
||||
{ "$_ANDNOT_", 4 },
|
||||
{ "$_ORNOT_", 4 },
|
||||
{ "$_XOR_", 5 },
|
||||
{ "$_XNOR_", 5 },
|
||||
{ "$_AOI3_", 6 },
|
||||
{ "$_OAI3_", 6 },
|
||||
{ "$_AOI4_", 7 },
|
||||
{ "$_OAI4_", 7 },
|
||||
{ "$_MUX_", 4 },
|
||||
{ "$_NMUX_", 4 }
|
||||
{ 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 }
|
||||
};
|
||||
return db;
|
||||
}
|
||||
|
||||
static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
|
||||
static const dict<RTLIL::IdString, int> db = {
|
||||
{ "$_BUF_", 1 },
|
||||
{ "$_NOT_", 2 },
|
||||
{ "$_AND_", 6 },
|
||||
{ "$_NAND_", 4 },
|
||||
{ "$_OR_", 6 },
|
||||
{ "$_NOR_", 4 },
|
||||
{ "$_ANDNOT_", 6 },
|
||||
{ "$_ORNOT_", 6 },
|
||||
{ "$_XOR_", 12 },
|
||||
{ "$_XNOR_", 12 },
|
||||
{ "$_AOI3_", 6 },
|
||||
{ "$_OAI3_", 6 },
|
||||
{ "$_AOI4_", 8 },
|
||||
{ "$_OAI4_", 8 },
|
||||
{ "$_MUX_", 12 },
|
||||
{ "$_NMUX_", 10 }
|
||||
{ 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 }
|
||||
};
|
||||
return db;
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ struct CellCosts
|
|||
{
|
||||
RTLIL::Module *mod = design->module(cell->type);
|
||||
|
||||
if (mod->attributes.count("\\cost"))
|
||||
return mod->attributes.at("\\cost").as_int();
|
||||
if (mod->attributes.count(ID(cost)))
|
||||
return mod->attributes.at(ID(cost)).as_int();
|
||||
|
||||
if (mod_cost_cache.count(mod->name))
|
||||
return mod_cost_cache.at(mod->name);
|
||||
|
|
|
@ -99,16 +99,16 @@ struct Macc
|
|||
|
||||
void from_cell(RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec port_a = cell->getPort("\\A");
|
||||
RTLIL::SigSpec port_a = cell->getPort(ID(A));
|
||||
|
||||
ports.clear();
|
||||
bit_ports = cell->getPort("\\B");
|
||||
bit_ports = cell->getPort(ID(B));
|
||||
|
||||
std::vector<RTLIL::State> config_bits = cell->getParam("\\CONFIG").bits;
|
||||
std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;
|
||||
int config_cursor = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
int config_width = cell->getParam("\\CONFIG_WIDTH").as_int();
|
||||
int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();
|
||||
log_assert(GetSize(config_bits) >= config_width);
|
||||
#endif
|
||||
|
||||
|
@ -191,12 +191,12 @@ struct Macc
|
|||
port_a.append(port.in_b);
|
||||
}
|
||||
|
||||
cell->setPort("\\A", port_a);
|
||||
cell->setPort("\\B", bit_ports);
|
||||
cell->setParam("\\CONFIG", config_bits);
|
||||
cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits));
|
||||
cell->setParam("\\A_WIDTH", GetSize(port_a));
|
||||
cell->setParam("\\B_WIDTH", GetSize(bit_ports));
|
||||
cell->setPort(ID(A), port_a);
|
||||
cell->setPort(ID(B), bit_ports);
|
||||
cell->setParam(ID(CONFIG), config_bits);
|
||||
cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
|
||||
cell->setParam(ID(A_WIDTH), GetSize(port_a));
|
||||
cell->setParam(ID(B_WIDTH), GetSize(bit_ports));
|
||||
}
|
||||
|
||||
bool eval(RTLIL::Const &result) const
|
||||
|
|
1151
kernel/rtlil.cc
1151
kernel/rtlil.cc
File diff suppressed because it is too large
Load Diff
127
kernel/rtlil.h
127
kernel/rtlil.h
|
@ -78,6 +78,8 @@ namespace RTLIL
|
|||
{
|
||||
#undef YOSYS_XTRACE_GET_PUT
|
||||
#undef YOSYS_SORT_ID_FREE_LIST
|
||||
#undef YOSYS_USE_STICKY_IDS
|
||||
#undef YOSYS_NO_IDS_REFCNT
|
||||
|
||||
// the global id string cache
|
||||
|
||||
|
@ -87,13 +89,17 @@ namespace RTLIL
|
|||
~destruct_guard_t() { ok = false; }
|
||||
} destruct_guard;
|
||||
|
||||
static std::vector<int> global_refcount_storage_;
|
||||
static std::vector<char*> global_id_storage_;
|
||||
static dict<char*, int, hash_cstr_ops> global_id_index_;
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
static std::vector<int> global_refcount_storage_;
|
||||
static std::vector<int> global_free_idx_list_;
|
||||
#endif
|
||||
|
||||
#ifdef YOSYS_USE_STICKY_IDS
|
||||
static int last_created_idx_ptr_;
|
||||
static int last_created_idx_[8];
|
||||
#endif
|
||||
|
||||
static inline void xtrace_db_dump()
|
||||
{
|
||||
|
@ -110,12 +116,14 @@ namespace RTLIL
|
|||
|
||||
static inline void checkpoint()
|
||||
{
|
||||
#ifdef YOSYS_USE_STICKY_IDS
|
||||
last_created_idx_ptr_ = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (last_created_idx_[i])
|
||||
put_reference(last_created_idx_[i]);
|
||||
last_created_idx_[i] = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef YOSYS_SORT_ID_FREE_LIST
|
||||
std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>());
|
||||
#endif
|
||||
|
@ -123,36 +131,47 @@ namespace RTLIL
|
|||
|
||||
static inline int get_reference(int idx)
|
||||
{
|
||||
global_refcount_storage_.at(idx)++;
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace) {
|
||||
log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
}
|
||||
if (idx) {
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
global_refcount_storage_[idx]++;
|
||||
#endif
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
#endif
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static inline int get_reference(const char *p)
|
||||
static int get_reference(const char *p)
|
||||
{
|
||||
log_assert(destruct_guard.ok);
|
||||
|
||||
if (p[0]) {
|
||||
log_assert(p[1] != 0);
|
||||
log_assert(p[0] == '$' || p[0] == '\\');
|
||||
}
|
||||
if (!p[0])
|
||||
return 0;
|
||||
|
||||
log_assert(p[0] == '$' || p[0] == '\\');
|
||||
log_assert(p[1] != 0);
|
||||
|
||||
auto it = global_id_index_.find((char*)p);
|
||||
if (it != global_id_index_.end()) {
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
global_refcount_storage_.at(it->second)++;
|
||||
#endif
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace) {
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second));
|
||||
}
|
||||
#endif
|
||||
return it->second;
|
||||
}
|
||||
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
if (global_free_idx_list_.empty()) {
|
||||
if (global_id_storage_.empty()) {
|
||||
global_refcount_storage_.push_back(0);
|
||||
global_id_storage_.push_back((char*)"");
|
||||
global_id_index_[global_id_storage_.back()] = 0;
|
||||
}
|
||||
log_assert(global_id_storage_.size() < 0x40000000);
|
||||
global_free_idx_list_.push_back(global_id_storage_.size());
|
||||
global_id_storage_.push_back(nullptr);
|
||||
|
@ -164,13 +183,15 @@ namespace RTLIL
|
|||
global_id_storage_.at(idx) = strdup(p);
|
||||
global_id_index_[global_id_storage_.at(idx)] = idx;
|
||||
global_refcount_storage_.at(idx)++;
|
||||
|
||||
// Avoid Create->Delete->Create pattern
|
||||
if (last_created_idx_[last_created_idx_ptr_])
|
||||
put_reference(last_created_idx_[last_created_idx_ptr_]);
|
||||
last_created_idx_[last_created_idx_ptr_] = idx;
|
||||
get_reference(last_created_idx_[last_created_idx_ptr_]);
|
||||
last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7;
|
||||
#else
|
||||
if (global_id_storage_.empty()) {
|
||||
global_id_storage_.push_back((char*)"");
|
||||
global_id_index_[global_id_storage_.back()] = 0;
|
||||
}
|
||||
int idx = global_id_storage_.size();
|
||||
global_id_storage_.push_back(strdup(p));
|
||||
global_id_index_[global_id_storage_.back()] = idx;
|
||||
#endif
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# New IdString '%s' with index %d.\n", p, idx);
|
||||
|
@ -178,18 +199,28 @@ namespace RTLIL
|
|||
}
|
||||
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace) {
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef YOSYS_USE_STICKY_IDS
|
||||
// Avoid Create->Delete->Create pattern
|
||||
if (last_created_idx_[last_created_idx_ptr_])
|
||||
put_reference(last_created_idx_[last_created_idx_ptr_]);
|
||||
last_created_idx_[last_created_idx_ptr_] = idx;
|
||||
get_reference(last_created_idx_[last_created_idx_ptr_]);
|
||||
last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7;
|
||||
#endif
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
static inline void put_reference(int idx)
|
||||
{
|
||||
// put_reference() may be called from destructors after the destructor of
|
||||
// global_refcount_storage_ has been run. in this case we simply do nothing.
|
||||
if (!destruct_guard.ok)
|
||||
if (!destruct_guard.ok || !idx)
|
||||
return;
|
||||
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
|
@ -198,11 +229,13 @@ namespace RTLIL
|
|||
}
|
||||
#endif
|
||||
|
||||
log_assert(global_refcount_storage_.at(idx) > 0);
|
||||
int &refcount = global_refcount_storage_[idx];
|
||||
|
||||
if (--global_refcount_storage_.at(idx) != 0)
|
||||
if (--refcount > 0)
|
||||
return;
|
||||
|
||||
log_assert(refcount == 0);
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
|
@ -213,46 +246,50 @@ namespace RTLIL
|
|||
global_id_storage_.at(idx) = nullptr;
|
||||
global_free_idx_list_.push_back(idx);
|
||||
}
|
||||
#else
|
||||
static inline void put_reference(int) { }
|
||||
#endif
|
||||
|
||||
// the actual IdString object is just is a single int
|
||||
|
||||
int index_;
|
||||
|
||||
IdString() : index_(get_reference("")) { }
|
||||
IdString(const char *str) : index_(get_reference(str)) { }
|
||||
IdString(const IdString &str) : index_(get_reference(str.index_)) { }
|
||||
IdString(const std::string &str) : index_(get_reference(str.c_str())) { }
|
||||
~IdString() { put_reference(index_); }
|
||||
inline IdString() : index_(0) { }
|
||||
inline IdString(const char *str) : index_(get_reference(str)) { }
|
||||
inline IdString(const IdString &str) : index_(get_reference(str.index_)) { }
|
||||
inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; }
|
||||
inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { }
|
||||
inline ~IdString() { put_reference(index_); }
|
||||
|
||||
void operator=(const IdString &rhs) {
|
||||
inline void operator=(const IdString &rhs) {
|
||||
put_reference(index_);
|
||||
index_ = get_reference(rhs.index_);
|
||||
}
|
||||
|
||||
void operator=(const char *rhs) {
|
||||
inline void operator=(const char *rhs) {
|
||||
IdString id(rhs);
|
||||
*this = id;
|
||||
}
|
||||
|
||||
void operator=(const std::string &rhs) {
|
||||
inline void operator=(const std::string &rhs) {
|
||||
IdString id(rhs);
|
||||
*this = id;
|
||||
}
|
||||
|
||||
const char *c_str() const {
|
||||
inline const char *c_str() const {
|
||||
return global_id_storage_.at(index_);
|
||||
}
|
||||
|
||||
std::string str() const {
|
||||
inline std::string str() const {
|
||||
return std::string(global_id_storage_.at(index_));
|
||||
}
|
||||
|
||||
bool operator<(const IdString &rhs) const {
|
||||
inline bool operator<(const IdString &rhs) const {
|
||||
return index_ < rhs.index_;
|
||||
}
|
||||
|
||||
bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
|
||||
bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
|
||||
inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
|
||||
inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
|
||||
|
||||
// The methods below are just convenience functions for better compatibility with std::string.
|
||||
|
||||
|
@ -332,6 +369,14 @@ namespace RTLIL
|
|||
bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
|
||||
};
|
||||
|
||||
namespace ID {
|
||||
// defined in rtlil.cc, initialized in yosys.cc
|
||||
extern IdString A, B, Y;
|
||||
extern IdString keep;
|
||||
extern IdString whitebox;
|
||||
extern IdString blackbox;
|
||||
};
|
||||
|
||||
static inline std::string escape_id(std::string str) {
|
||||
if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
|
||||
return "\\" + str;
|
||||
|
@ -604,7 +649,7 @@ struct RTLIL::AttrObject
|
|||
bool get_bool_attribute(RTLIL::IdString id) const;
|
||||
|
||||
bool get_blackbox_attribute(bool ignore_wb=false) const {
|
||||
return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox"));
|
||||
return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox));
|
||||
}
|
||||
|
||||
void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
|
||||
|
@ -1339,8 +1384,8 @@ public:
|
|||
void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);
|
||||
|
||||
bool has_keep_attr() const {
|
||||
return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) &&
|
||||
module->design->module(type)->get_bool_attribute("\\keep"));
|
||||
return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) &&
|
||||
module->design->module(type)->get_bool_attribute(ID::keep));
|
||||
}
|
||||
|
||||
template<typename T> void rewrite_sigspecs(T &functor);
|
||||
|
|
520
kernel/satgen.h
520
kernel/satgen.h
File diff suppressed because it is too large
Load Diff
|
@ -510,10 +510,13 @@ void yosys_setup()
|
|||
if(already_setup)
|
||||
return;
|
||||
already_setup = true;
|
||||
// if there are already IdString objects then we have a global initialization order bug
|
||||
IdString empty_id;
|
||||
log_assert(empty_id.index_ == 0);
|
||||
IdString::get_reference(empty_id.index_);
|
||||
|
||||
RTLIL::ID::A = "\\A";
|
||||
RTLIL::ID::B = "\\B";
|
||||
RTLIL::ID::Y = "\\Y";
|
||||
RTLIL::ID::keep = "\\keep";
|
||||
RTLIL::ID::whitebox = "\\whitebox";
|
||||
RTLIL::ID::blackbox = "\\blackbox";
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
|
||||
|
@ -575,9 +578,6 @@ void yosys_shutdown()
|
|||
#ifdef WITH_PYTHON
|
||||
Py_Finalize();
|
||||
#endif
|
||||
|
||||
IdString empty_id;
|
||||
IdString::put_reference(empty_id.index_);
|
||||
}
|
||||
|
||||
RTLIL::IdString new_id(std::string file, int line, std::string func)
|
||||
|
|
|
@ -305,8 +305,16 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);
|
|||
#define NEW_ID \
|
||||
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define ID(_str) \
|
||||
([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })()
|
||||
// Create a statically allocated IdString object, using for example ID(A) or ID($add).
|
||||
//
|
||||
// Recipe for Converting old code that is using conversion of strings like "\\A" and
|
||||
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
|
||||
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
|
||||
//
|
||||
// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
|
||||
//
|
||||
#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
|
||||
static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })()
|
||||
|
||||
RTLIL::Design *yosys_get_design();
|
||||
std::string proc_self_dirname();
|
||||
|
|
|
@ -37,22 +37,22 @@ struct ExclusiveDatabase
|
|||
SigBit y_port;
|
||||
pool<Cell*> reduce_or;
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == "$eq") {
|
||||
nonconst_sig = sigmap(cell->getPort("\\A"));
|
||||
const_sig = sigmap(cell->getPort("\\B"));
|
||||
if (cell->type == ID($eq)) {
|
||||
nonconst_sig = sigmap(cell->getPort(ID(A)));
|
||||
const_sig = sigmap(cell->getPort(ID(B)));
|
||||
if (!const_sig.is_fully_const()) {
|
||||
if (!nonconst_sig.is_fully_const())
|
||||
continue;
|
||||
std::swap(nonconst_sig, const_sig);
|
||||
}
|
||||
y_port = sigmap(cell->getPort("\\Y"));
|
||||
y_port = sigmap(cell->getPort(ID(Y)));
|
||||
}
|
||||
else if (cell->type == "$logic_not") {
|
||||
nonconst_sig = sigmap(cell->getPort("\\A"));
|
||||
else if (cell->type == ID($logic_not)) {
|
||||
nonconst_sig = sigmap(cell->getPort(ID(A)));
|
||||
const_sig = Const(State::S0, GetSize(nonconst_sig));
|
||||
y_port = sigmap(cell->getPort("\\Y"));
|
||||
y_port = sigmap(cell->getPort(ID(Y)));
|
||||
}
|
||||
else if (cell->type == "$reduce_or") {
|
||||
else if (cell->type == ID($reduce_or)) {
|
||||
reduce_or.insert(cell);
|
||||
continue;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ struct ExclusiveDatabase
|
|||
for (auto cell : reduce_or) {
|
||||
nonconst_sig = SigSpec();
|
||||
std::vector<Const> values;
|
||||
SigSpec a_port = sigmap(cell->getPort("\\A"));
|
||||
SigSpec a_port = sigmap(cell->getPort(ID(A)));
|
||||
for (auto bit : a_port) {
|
||||
auto it = sig_cmp_prev.find(bit);
|
||||
if (it == sig_cmp_prev.end()) {
|
||||
|
@ -84,7 +84,7 @@ struct ExclusiveDatabase
|
|||
}
|
||||
if (nonconst_sig.empty())
|
||||
continue;
|
||||
y_port = sigmap(cell->getPort("\\Y"));
|
||||
y_port = sigmap(cell->getPort(ID(Y)));
|
||||
sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values));
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ struct MuxpackWorker
|
|||
{
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
if (wire->port_output || wire->get_bool_attribute("\\keep")) {
|
||||
if (wire->port_output || wire->get_bool_attribute(ID(keep))) {
|
||||
for (auto bit : sigmap(wire))
|
||||
sigbit_with_non_chain_users.insert(bit);
|
||||
}
|
||||
|
@ -143,13 +143,13 @@ struct MuxpackWorker
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type.in("$mux", "$pmux") && !cell->get_bool_attribute("\\keep"))
|
||||
if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID(keep)))
|
||||
{
|
||||
SigSpec a_sig = sigmap(cell->getPort("\\A"));
|
||||
SigSpec a_sig = sigmap(cell->getPort(ID(A)));
|
||||
SigSpec b_sig;
|
||||
if (cell->type == "$mux")
|
||||
b_sig = sigmap(cell->getPort("\\B"));
|
||||
SigSpec y_sig = sigmap(cell->getPort("\\Y"));
|
||||
if (cell->type == ID($mux))
|
||||
b_sig = sigmap(cell->getPort(ID(B)));
|
||||
SigSpec y_sig = sigmap(cell->getPort(ID(Y)));
|
||||
|
||||
if (sig_chain_next.count(a_sig))
|
||||
for (auto a_bit : a_sig.bits())
|
||||
|
@ -186,16 +186,16 @@ struct MuxpackWorker
|
|||
{
|
||||
log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type));
|
||||
|
||||
SigSpec a_sig = sigmap(cell->getPort("\\A"));
|
||||
if (cell->type == "$mux") {
|
||||
SigSpec b_sig = sigmap(cell->getPort("\\B"));
|
||||
SigSpec a_sig = sigmap(cell->getPort(ID(A)));
|
||||
if (cell->type == ID($mux)) {
|
||||
SigSpec b_sig = sigmap(cell->getPort(ID(B)));
|
||||
if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1)
|
||||
goto start_cell;
|
||||
|
||||
if (!sig_chain_prev.count(a_sig))
|
||||
a_sig = b_sig;
|
||||
}
|
||||
else if (cell->type == "$pmux") {
|
||||
else if (cell->type == ID($pmux)) {
|
||||
if (!sig_chain_prev.count(a_sig))
|
||||
goto start_cell;
|
||||
}
|
||||
|
@ -208,8 +208,8 @@ struct MuxpackWorker
|
|||
{
|
||||
Cell *prev_cell = sig_chain_prev.at(a_sig);
|
||||
log_assert(prev_cell);
|
||||
SigSpec s_sig = sigmap(cell->getPort("\\S"));
|
||||
s_sig.append(sigmap(prev_cell->getPort("\\S")));
|
||||
SigSpec s_sig = sigmap(cell->getPort(ID(S)));
|
||||
s_sig.append(sigmap(prev_cell->getPort(ID(S))));
|
||||
if (!excl_db.query(s_sig))
|
||||
goto start_cell;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ struct MuxpackWorker
|
|||
{
|
||||
chain.push_back(c);
|
||||
|
||||
SigSpec y_sig = sigmap(c->getPort("\\Y"));
|
||||
SigSpec y_sig = sigmap(c->getPort(ID(Y)));
|
||||
|
||||
if (sig_chain_next.count(y_sig) == 0)
|
||||
break;
|
||||
|
@ -269,29 +269,29 @@ struct MuxpackWorker
|
|||
mux_count += cases;
|
||||
pmux_count += 1;
|
||||
|
||||
first_cell->type = "$pmux";
|
||||
SigSpec b_sig = first_cell->getPort("\\B");
|
||||
SigSpec s_sig = first_cell->getPort("\\S");
|
||||
first_cell->type = ID($pmux);
|
||||
SigSpec b_sig = first_cell->getPort(ID(B));
|
||||
SigSpec s_sig = first_cell->getPort(ID(S));
|
||||
|
||||
for (int i = 1; i < cases; i++) {
|
||||
Cell* prev_cell = chain[cursor+i-1];
|
||||
Cell* cursor_cell = chain[cursor+i];
|
||||
if (sigmap(prev_cell->getPort("\\Y")) == sigmap(cursor_cell->getPort("\\A"))) {
|
||||
b_sig.append(cursor_cell->getPort("\\B"));
|
||||
s_sig.append(cursor_cell->getPort("\\S"));
|
||||
if (sigmap(prev_cell->getPort(ID(Y))) == sigmap(cursor_cell->getPort(ID(A)))) {
|
||||
b_sig.append(cursor_cell->getPort(ID(B)));
|
||||
s_sig.append(cursor_cell->getPort(ID(S)));
|
||||
}
|
||||
else {
|
||||
log_assert(cursor_cell->type == "$mux");
|
||||
b_sig.append(cursor_cell->getPort("\\A"));
|
||||
s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort("\\S")));
|
||||
log_assert(cursor_cell->type == ID($mux));
|
||||
b_sig.append(cursor_cell->getPort(ID(A)));
|
||||
s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S))));
|
||||
}
|
||||
remove_cells.insert(cursor_cell);
|
||||
}
|
||||
|
||||
first_cell->setPort("\\B", b_sig);
|
||||
first_cell->setPort("\\S", s_sig);
|
||||
first_cell->setParam("\\S_WIDTH", GetSize(s_sig));
|
||||
first_cell->setPort("\\Y", last_cell->getPort("\\Y"));
|
||||
first_cell->setPort(ID(B), b_sig);
|
||||
first_cell->setPort(ID(S), s_sig);
|
||||
first_cell->setParam(ID(S_WIDTH), GetSize(s_sig));
|
||||
first_cell->setPort(ID(Y), last_cell->getPort(ID(Y)));
|
||||
|
||||
cursor += cases;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ struct keep_cache_t
|
|||
return cache.at(module);
|
||||
|
||||
cache[module] = true;
|
||||
if (!module->get_bool_attribute("\\keep")) {
|
||||
if (!module->get_bool_attribute(ID(keep))) {
|
||||
bool found_keep = false;
|
||||
for (auto cell : module->cells())
|
||||
if (query(cell)) found_keep = true;
|
||||
|
@ -64,7 +64,7 @@ struct keep_cache_t
|
|||
|
||||
bool query(Cell *cell)
|
||||
{
|
||||
if (cell->type.in("$memwr", "$meminit", "$assert", "$assume", "$live", "$fair", "$cover", "$specify2", "$specify3", "$specrule"))
|
||||
if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover), ID($specify2), ID($specify3), ID($specrule)))
|
||||
return true;
|
||||
|
||||
if (cell->has_keep_attr())
|
||||
|
@ -122,7 +122,7 @@ void rmunused_module_cells(Module *module, bool verbose)
|
|||
|
||||
for (auto &it : module->wires_) {
|
||||
Wire *wire = it.second;
|
||||
if (wire->port_output || wire->get_bool_attribute("\\keep")) {
|
||||
if (wire->port_output || wire->get_bool_attribute(ID(keep))) {
|
||||
for (auto bit : sigmap(wire))
|
||||
for (auto c : wire2driver[bit])
|
||||
queue.insert(c), unused.erase(c);
|
||||
|
@ -177,8 +177,8 @@ void rmunused_module_cells(Module *module, bool verbose)
|
|||
int count_nontrivial_wire_attrs(RTLIL::Wire *w)
|
||||
{
|
||||
int count = w->attributes.size();
|
||||
count -= w->attributes.count("\\src");
|
||||
count -= w->attributes.count("\\unused_bits");
|
||||
count -= w->attributes.count(ID(src));
|
||||
count -= w->attributes.count(ID(unused_bits));
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
|
|||
if (!wire->port_input)
|
||||
used_signals_nodrivers.add(sig);
|
||||
}
|
||||
if (wire->get_bool_attribute("\\keep")) {
|
||||
if (wire->get_bool_attribute(ID(keep))) {
|
||||
RTLIL::SigSpec sig = RTLIL::SigSpec(wire);
|
||||
assign_map.apply(sig);
|
||||
used_signals.add(sig);
|
||||
|
@ -311,19 +311,19 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
|
|||
log_assert(GetSize(s1) == GetSize(s2));
|
||||
|
||||
Const initval;
|
||||
if (wire->attributes.count("\\init"))
|
||||
initval = wire->attributes.at("\\init");
|
||||
if (wire->attributes.count(ID(init)))
|
||||
initval = wire->attributes.at(ID(init));
|
||||
if (GetSize(initval) != GetSize(wire))
|
||||
initval.bits.resize(GetSize(wire), State::Sx);
|
||||
if (initval.is_fully_undef())
|
||||
wire->attributes.erase("\\init");
|
||||
wire->attributes.erase(ID(init));
|
||||
|
||||
if (GetSize(wire) == 0) {
|
||||
// delete zero-width wires, unless they are module ports
|
||||
if (wire->port_id == 0)
|
||||
goto delete_this_wire;
|
||||
} else
|
||||
if (wire->port_id != 0 || wire->get_bool_attribute("\\keep") || !initval.is_fully_undef()) {
|
||||
if (wire->port_id != 0 || wire->get_bool_attribute(ID(keep)) || !initval.is_fully_undef()) {
|
||||
// do not delete anything with "keep" or module ports or initialized wires
|
||||
} else
|
||||
if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) {
|
||||
|
@ -357,9 +357,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
|
|||
}
|
||||
if (new_conn.first.size() > 0) {
|
||||
if (initval.is_fully_undef())
|
||||
wire->attributes.erase("\\init");
|
||||
wire->attributes.erase(ID(init));
|
||||
else
|
||||
wire->attributes.at("\\init") = initval;
|
||||
wire->attributes.at(ID(init)) = initval;
|
||||
used_signals.add(new_conn.first);
|
||||
used_signals.add(new_conn.second);
|
||||
module->connect(new_conn);
|
||||
|
@ -377,11 +377,11 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
|
|||
}
|
||||
}
|
||||
if (unused_bits.empty() || wire->port_id != 0)
|
||||
wire->attributes.erase("\\unused_bits");
|
||||
wire->attributes.erase(ID(unused_bits));
|
||||
else
|
||||
wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits);
|
||||
wire->attributes[ID(unused_bits)] = RTLIL::Const(unused_bits);
|
||||
} else {
|
||||
wire->attributes.erase("\\unused_bits");
|
||||
wire->attributes.erase(ID(unused_bits));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,18 +413,18 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
|
|||
dict<SigBit, State> qbits;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (fftypes.cell_known(cell->type) && cell->hasPort("\\Q"))
|
||||
if (fftypes.cell_known(cell->type) && cell->hasPort(ID(Q)))
|
||||
{
|
||||
SigSpec sig = cell->getPort("\\Q");
|
||||
SigSpec sig = cell->getPort(ID(Q));
|
||||
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
{
|
||||
SigBit bit = sig[i];
|
||||
|
||||
if (bit.wire == nullptr || bit.wire->attributes.count("\\init") == 0)
|
||||
if (bit.wire == nullptr || bit.wire->attributes.count(ID(init)) == 0)
|
||||
continue;
|
||||
|
||||
Const init = bit.wire->attributes.at("\\init");
|
||||
Const init = bit.wire->attributes.at(ID(init));
|
||||
|
||||
if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz)
|
||||
continue;
|
||||
|
@ -439,10 +439,10 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
|
|||
if (!purge_mode && wire->name[0] == '\\')
|
||||
continue;
|
||||
|
||||
if (wire->attributes.count("\\init") == 0)
|
||||
if (wire->attributes.count(ID(init)) == 0)
|
||||
continue;
|
||||
|
||||
Const init = wire->attributes.at("\\init");
|
||||
Const init = wire->attributes.at(ID(init));
|
||||
|
||||
for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++)
|
||||
{
|
||||
|
@ -465,7 +465,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
|
|||
if (verbose)
|
||||
log_debug(" removing redundant init attribute on %s.\n", log_id(wire));
|
||||
|
||||
wire->attributes.erase("\\init");
|
||||
wire->attributes.erase(ID(init));
|
||||
did_something = true;
|
||||
next_wire:;
|
||||
}
|
||||
|
@ -480,10 +480,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
|
|||
|
||||
std::vector<RTLIL::Cell*> delcells;
|
||||
for (auto cell : module->cells())
|
||||
if (cell->type.in("$pos", "$_BUF_") && !cell->has_keep_attr()) {
|
||||
bool is_signed = cell->type == "$pos" && cell->getParam("\\A_SIGNED").as_bool();
|
||||
RTLIL::SigSpec a = cell->getPort("\\A");
|
||||
RTLIL::SigSpec y = cell->getPort("\\Y");
|
||||
if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) {
|
||||
bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool();
|
||||
RTLIL::SigSpec a = cell->getPort(ID(A));
|
||||
RTLIL::SigSpec y = cell->getPort(ID(Y));
|
||||
a.extend_u0(GetSize(y), is_signed);
|
||||
module->connect(y, a);
|
||||
delcells.push_back(cell);
|
||||
|
@ -491,7 +491,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
|
|||
for (auto cell : delcells) {
|
||||
if (verbose)
|
||||
log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(),
|
||||
log_signal(cell->getPort("\\Y")), log_signal(cell->getPort("\\A")));
|
||||
log_signal(cell->getPort(ID(Y))), log_signal(cell->getPort(ID(A))));
|
||||
module->remove(cell);
|
||||
}
|
||||
if (!delcells.empty())
|
||||
|
|
|
@ -35,10 +35,10 @@ void demorgan_worker(
|
|||
//TODO: Add support for reduce_xor
|
||||
//DeMorgan of XOR is either XOR (if even number of inputs) or XNOR (if odd number)
|
||||
|
||||
if( (cell->type != "$reduce_and") && (cell->type != "$reduce_or") )
|
||||
if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) )
|
||||
return;
|
||||
|
||||
auto insig = sigmap(cell->getPort("\\A"));
|
||||
auto insig = sigmap(cell->getPort(ID(A)));
|
||||
log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig));
|
||||
int num_inverted = 0;
|
||||
for(int i=0; i<GetSize(insig); i++)
|
||||
|
@ -51,7 +51,7 @@ void demorgan_worker(
|
|||
bool inverted = false;
|
||||
for(auto x : ports)
|
||||
{
|
||||
if(x.port == "\\Y" && x.cell->type == "$_NOT_")
|
||||
if(x.port == ID(Y) && x.cell->type == ID($_NOT_))
|
||||
{
|
||||
inverted = true;
|
||||
break;
|
||||
|
@ -85,7 +85,7 @@ void demorgan_worker(
|
|||
RTLIL::Cell* srcinv = NULL;
|
||||
for(auto x : ports)
|
||||
{
|
||||
if(x.port == "\\Y" && x.cell->type == "$_NOT_")
|
||||
if(x.port == ID(Y) && x.cell->type == ID($_NOT_))
|
||||
{
|
||||
srcinv = x.cell;
|
||||
break;
|
||||
|
@ -103,7 +103,7 @@ void demorgan_worker(
|
|||
//We ARE inverted - bypass it
|
||||
//Don't automatically delete the inverter since other stuff might still use it
|
||||
else
|
||||
insig[i] = srcinv->getPort("\\A");
|
||||
insig[i] = srcinv->getPort(ID(A));
|
||||
}
|
||||
|
||||
//Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it
|
||||
|
@ -151,20 +151,20 @@ void demorgan_worker(
|
|||
}
|
||||
|
||||
//Push the new input signal back to the reduction (after bypassing/adding inverters)
|
||||
cell->setPort("\\A", insig);
|
||||
cell->setPort(ID(A), insig);
|
||||
|
||||
//Change the cell type
|
||||
if(cell->type == "$reduce_and")
|
||||
cell->type = "$reduce_or";
|
||||
else if(cell->type == "$reduce_or")
|
||||
cell->type = "$reduce_and";
|
||||
if(cell->type == ID($reduce_and))
|
||||
cell->type = ID($reduce_or);
|
||||
else if(cell->type == ID($reduce_or))
|
||||
cell->type = ID($reduce_and);
|
||||
//don't change XOR
|
||||
|
||||
//Add an inverter to the output
|
||||
auto inverted_output = cell->getPort("\\Y");
|
||||
auto inverted_output = cell->getPort(ID(Y));
|
||||
auto uninverted_output = m->addWire(NEW_ID);
|
||||
m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output);
|
||||
cell->setPort("\\Y", uninverted_output);
|
||||
cell->setPort(ID(Y), uninverted_output);
|
||||
}
|
||||
|
||||
struct OptDemorganPass : public Pass {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -40,9 +40,9 @@ struct OptLutWorker
|
|||
|
||||
bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs)
|
||||
{
|
||||
SigSpec lut_input = sigmap(lut->getPort("\\A"));
|
||||
int lut_width = lut->getParam("\\WIDTH").as_int();
|
||||
Const lut_table = lut->getParam("\\LUT");
|
||||
SigSpec lut_input = sigmap(lut->getPort(ID(A)));
|
||||
int lut_width = lut->getParam(ID(WIDTH)).as_int();
|
||||
Const lut_table = lut->getParam(ID(LUT));
|
||||
int lut_index = 0;
|
||||
|
||||
for (int i = 0; i < lut_width; i++)
|
||||
|
@ -99,16 +99,16 @@ struct OptLutWorker
|
|||
log("Discovering LUTs.\n");
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type == "$lut")
|
||||
if (cell->type == ID($lut))
|
||||
{
|
||||
if (cell->has_keep_attr())
|
||||
continue;
|
||||
SigBit lut_output = cell->getPort("\\Y");
|
||||
if (lut_output.wire->get_bool_attribute("\\keep"))
|
||||
SigBit lut_output = cell->getPort(ID(Y));
|
||||
if (lut_output.wire->get_bool_attribute(ID(keep)))
|
||||
continue;
|
||||
|
||||
int lut_width = cell->getParam("\\WIDTH").as_int();
|
||||
SigSpec lut_input = cell->getPort("\\A");
|
||||
int lut_width = cell->getParam(ID(WIDTH)).as_int();
|
||||
SigSpec lut_input = cell->getPort(ID(A));
|
||||
int lut_arity = 0;
|
||||
|
||||
log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell));
|
||||
|
@ -205,7 +205,7 @@ struct OptLutWorker
|
|||
}
|
||||
|
||||
auto lut = worklist.pop();
|
||||
SigSpec lut_input = sigmap(lut->getPort("\\A"));
|
||||
SigSpec lut_input = sigmap(lut->getPort(ID(A)));
|
||||
pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut];
|
||||
|
||||
vector<SigBit> lut_inputs;
|
||||
|
@ -267,7 +267,7 @@ struct OptLutWorker
|
|||
log_debug(" Not eliminating cell (connected to dedicated logic).\n");
|
||||
else
|
||||
{
|
||||
SigSpec lut_output = lut->getPort("\\Y");
|
||||
SigSpec lut_output = lut->getPort(ID(Y));
|
||||
for (auto &port : index.query_ports(lut_output))
|
||||
{
|
||||
if (port.cell != lut && luts.count(port.cell))
|
||||
|
@ -303,13 +303,13 @@ struct OptLutWorker
|
|||
}
|
||||
|
||||
auto lutA = worklist.pop();
|
||||
SigSpec lutA_input = sigmap(lutA->getPort("\\A"));
|
||||
SigSpec lutA_output = sigmap(lutA->getPort("\\Y")[0]);
|
||||
int lutA_width = lutA->getParam("\\WIDTH").as_int();
|
||||
SigSpec lutA_input = sigmap(lutA->getPort(ID(A)));
|
||||
SigSpec lutA_output = sigmap(lutA->getPort(ID(Y))[0]);
|
||||
int lutA_width = lutA->getParam(ID(WIDTH)).as_int();
|
||||
int lutA_arity = luts_arity[lutA];
|
||||
pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA];
|
||||
|
||||
auto lutA_output_ports = index.query_ports(lutA->getPort("\\Y"));
|
||||
auto lutA_output_ports = index.query_ports(lutA->getPort(ID(Y)));
|
||||
if (lutA_output_ports.size() != 2)
|
||||
continue;
|
||||
|
||||
|
@ -321,15 +321,15 @@ struct OptLutWorker
|
|||
if (luts.count(port.cell))
|
||||
{
|
||||
auto lutB = port.cell;
|
||||
SigSpec lutB_input = sigmap(lutB->getPort("\\A"));
|
||||
SigSpec lutB_output = sigmap(lutB->getPort("\\Y")[0]);
|
||||
int lutB_width = lutB->getParam("\\WIDTH").as_int();
|
||||
SigSpec lutB_input = sigmap(lutB->getPort(ID(A)));
|
||||
SigSpec lutB_output = sigmap(lutB->getPort(ID(Y))[0]);
|
||||
int lutB_width = lutB->getParam(ID(WIDTH)).as_int();
|
||||
int lutB_arity = luts_arity[lutB];
|
||||
pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB];
|
||||
|
||||
log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB));
|
||||
|
||||
if (index.query_is_output(lutA->getPort("\\Y")))
|
||||
if (index.query_is_output(lutA->getPort(ID(Y))))
|
||||
{
|
||||
log_debug(" Not combining LUTs (cascade connection feeds module output).\n");
|
||||
continue;
|
||||
|
@ -372,7 +372,7 @@ struct OptLutWorker
|
|||
log_debug(" Not combining LUTs into cell A (combined LUT wider than cell A).\n");
|
||||
else if (lutB_dlogic_inputs.size() > 0)
|
||||
log_debug(" Not combining LUTs into cell A (cell B is connected to dedicated logic).\n");
|
||||
else if (lutB->get_bool_attribute("\\lut_keep"))
|
||||
else if (lutB->get_bool_attribute(ID(lut_keep)))
|
||||
log_debug(" Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n");
|
||||
else
|
||||
combine_mask |= COMBINE_A;
|
||||
|
@ -380,7 +380,7 @@ struct OptLutWorker
|
|||
log_debug(" Not combining LUTs into cell B (combined LUT wider than cell B).\n");
|
||||
else if (lutA_dlogic_inputs.size() > 0)
|
||||
log_debug(" Not combining LUTs into cell B (cell A is connected to dedicated logic).\n");
|
||||
else if (lutA->get_bool_attribute("\\lut_keep"))
|
||||
else if (lutA->get_bool_attribute(ID(lut_keep)))
|
||||
log_debug(" Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n");
|
||||
else
|
||||
combine_mask |= COMBINE_B;
|
||||
|
@ -440,8 +440,8 @@ struct OptLutWorker
|
|||
lutR_unique.insert(bit);
|
||||
}
|
||||
|
||||
int lutM_width = lutM->getParam("\\WIDTH").as_int();
|
||||
SigSpec lutM_input = sigmap(lutM->getPort("\\A"));
|
||||
int lutM_width = lutM->getParam(ID(WIDTH)).as_int();
|
||||
SigSpec lutM_input = sigmap(lutM->getPort(ID(A)));
|
||||
std::vector<SigBit> lutM_new_inputs;
|
||||
for (int i = 0; i < lutM_width; i++)
|
||||
{
|
||||
|
@ -482,13 +482,13 @@ struct OptLutWorker
|
|||
lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs);
|
||||
}
|
||||
|
||||
log_debug(" Cell A truth table: %s.\n", lutA->getParam("\\LUT").as_string().c_str());
|
||||
log_debug(" Cell B truth table: %s.\n", lutB->getParam("\\LUT").as_string().c_str());
|
||||
log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID(LUT)).as_string().c_str());
|
||||
log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID(LUT)).as_string().c_str());
|
||||
log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str());
|
||||
|
||||
lutM->setParam("\\LUT", lutM_new_table);
|
||||
lutM->setPort("\\A", lutM_new_inputs);
|
||||
lutM->setPort("\\Y", lutB_output);
|
||||
lutM->setParam(ID(LUT), lutM_new_table);
|
||||
lutM->setPort(ID(A), lutM_new_inputs);
|
||||
lutM->setPort(ID(Y), lutB_output);
|
||||
|
||||
luts_arity[lutM] = lutM_arity;
|
||||
luts.erase(lutR);
|
||||
|
|
|
@ -47,8 +47,8 @@ struct OptMergeWorker
|
|||
|
||||
static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
|
||||
{
|
||||
SigSpec sig_s = conn.at("\\S");
|
||||
SigSpec sig_b = conn.at("\\B");
|
||||
SigSpec sig_s = conn.at(ID(S));
|
||||
SigSpec sig_b = conn.at(ID(B));
|
||||
|
||||
int s_width = GetSize(sig_s);
|
||||
int width = GetSize(sig_b) / s_width;
|
||||
|
@ -59,12 +59,12 @@ struct OptMergeWorker
|
|||
|
||||
std::sort(sb_pairs.begin(), sb_pairs.end());
|
||||
|
||||
conn["\\S"] = SigSpec();
|
||||
conn["\\B"] = SigSpec();
|
||||
conn[ID(S)] = SigSpec();
|
||||
conn[ID(B)] = SigSpec();
|
||||
|
||||
for (auto &it : sb_pairs) {
|
||||
conn["\\S"].append(it.first);
|
||||
conn["\\B"].append(it.second);
|
||||
conn[ID(S)].append(it.first);
|
||||
conn[ID(B)].append(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,32 +94,32 @@ struct OptMergeWorker
|
|||
const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections();
|
||||
dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
|
||||
|
||||
if (cell->type.in("$and", "$or", "$xor", "$xnor", "$add", "$mul",
|
||||
"$logic_and", "$logic_or", "$_AND_", "$_OR_", "$_XOR_")) {
|
||||
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul),
|
||||
ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) {
|
||||
alt_conn = *conn;
|
||||
if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) {
|
||||
alt_conn["\\A"] = conn->at("\\B");
|
||||
alt_conn["\\B"] = conn->at("\\A");
|
||||
if (assign_map(alt_conn.at(ID(A))) < assign_map(alt_conn.at(ID(B)))) {
|
||||
alt_conn[ID(A)] = conn->at(ID(B));
|
||||
alt_conn[ID(B)] = conn->at(ID(A));
|
||||
}
|
||||
conn = &alt_conn;
|
||||
} else
|
||||
if (cell->type.in("$reduce_xor", "$reduce_xnor")) {
|
||||
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
|
||||
alt_conn = *conn;
|
||||
assign_map.apply(alt_conn.at("\\A"));
|
||||
alt_conn.at("\\A").sort();
|
||||
assign_map.apply(alt_conn.at(ID(A)));
|
||||
alt_conn.at(ID(A)).sort();
|
||||
conn = &alt_conn;
|
||||
} else
|
||||
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool")) {
|
||||
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) {
|
||||
alt_conn = *conn;
|
||||
assign_map.apply(alt_conn.at("\\A"));
|
||||
alt_conn.at("\\A").sort_and_unify();
|
||||
assign_map.apply(alt_conn.at(ID(A)));
|
||||
alt_conn.at(ID(A)).sort_and_unify();
|
||||
conn = &alt_conn;
|
||||
} else
|
||||
if (cell->type == "$pmux") {
|
||||
if (cell->type == ID($pmux)) {
|
||||
alt_conn = *conn;
|
||||
assign_map.apply(alt_conn.at("\\A"));
|
||||
assign_map.apply(alt_conn.at("\\B"));
|
||||
assign_map.apply(alt_conn.at("\\S"));
|
||||
assign_map.apply(alt_conn.at(ID(A)));
|
||||
assign_map.apply(alt_conn.at(ID(B)));
|
||||
assign_map.apply(alt_conn.at(ID(S)));
|
||||
sort_pmux_conn(alt_conn);
|
||||
conn = &alt_conn;
|
||||
}
|
||||
|
@ -189,28 +189,28 @@ struct OptMergeWorker
|
|||
assign_map.apply(it.second);
|
||||
}
|
||||
|
||||
if (cell1->type == "$and" || cell1->type == "$or" || cell1->type == "$xor" || cell1->type == "$xnor" || cell1->type == "$add" || cell1->type == "$mul" ||
|
||||
cell1->type == "$logic_and" || cell1->type == "$logic_or" || cell1->type == "$_AND_" || cell1->type == "$_OR_" || cell1->type == "$_XOR_") {
|
||||
if (conn1.at("\\A") < conn1.at("\\B")) {
|
||||
RTLIL::SigSpec tmp = conn1["\\A"];
|
||||
conn1["\\A"] = conn1["\\B"];
|
||||
conn1["\\B"] = tmp;
|
||||
if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) ||
|
||||
cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) {
|
||||
if (conn1.at(ID(A)) < conn1.at(ID(B))) {
|
||||
RTLIL::SigSpec tmp = conn1[ID(A)];
|
||||
conn1[ID(A)] = conn1[ID(B)];
|
||||
conn1[ID(B)] = tmp;
|
||||
}
|
||||
if (conn2.at("\\A") < conn2.at("\\B")) {
|
||||
RTLIL::SigSpec tmp = conn2["\\A"];
|
||||
conn2["\\A"] = conn2["\\B"];
|
||||
conn2["\\B"] = tmp;
|
||||
if (conn2.at(ID(A)) < conn2.at(ID(B))) {
|
||||
RTLIL::SigSpec tmp = conn2[ID(A)];
|
||||
conn2[ID(A)] = conn2[ID(B)];
|
||||
conn2[ID(B)] = tmp;
|
||||
}
|
||||
} else
|
||||
if (cell1->type == "$reduce_xor" || cell1->type == "$reduce_xnor") {
|
||||
conn1["\\A"].sort();
|
||||
conn2["\\A"].sort();
|
||||
if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) {
|
||||
conn1[ID(A)].sort();
|
||||
conn2[ID(A)].sort();
|
||||
} else
|
||||
if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") {
|
||||
conn1["\\A"].sort_and_unify();
|
||||
conn2["\\A"].sort_and_unify();
|
||||
if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) {
|
||||
conn1[ID(A)].sort_and_unify();
|
||||
conn2[ID(A)].sort_and_unify();
|
||||
} else
|
||||
if (cell1->type == "$pmux") {
|
||||
if (cell1->type == ID($pmux)) {
|
||||
sort_pmux_conn(conn1);
|
||||
sort_pmux_conn(conn2);
|
||||
}
|
||||
|
@ -222,9 +222,9 @@ struct OptMergeWorker
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell1->type.begins_with("$") && conn1.count("\\Q") != 0) {
|
||||
std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector();
|
||||
if (cell1->type.begins_with("$") && conn1.count(ID(Q)) != 0) {
|
||||
std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort(ID(Q))).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort(ID(Q))).to_sigbit_vector();
|
||||
for (size_t i = 0; i < q1.size(); i++)
|
||||
if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) {
|
||||
lt = q1.at(i) < q2.at(i);
|
||||
|
@ -271,24 +271,24 @@ struct OptMergeWorker
|
|||
ct.setup_stdcells_mem();
|
||||
|
||||
if (mode_nomux) {
|
||||
ct.cell_types.erase("$mux");
|
||||
ct.cell_types.erase("$pmux");
|
||||
ct.cell_types.erase(ID($mux));
|
||||
ct.cell_types.erase(ID($pmux));
|
||||
}
|
||||
|
||||
ct.cell_types.erase("$tribuf");
|
||||
ct.cell_types.erase("$_TBUF_");
|
||||
ct.cell_types.erase("$anyseq");
|
||||
ct.cell_types.erase("$anyconst");
|
||||
ct.cell_types.erase("$allseq");
|
||||
ct.cell_types.erase("$allconst");
|
||||
ct.cell_types.erase(ID($tribuf));
|
||||
ct.cell_types.erase(ID($_TBUF_));
|
||||
ct.cell_types.erase(ID($anyseq));
|
||||
ct.cell_types.erase(ID($anyconst));
|
||||
ct.cell_types.erase(ID($allseq));
|
||||
ct.cell_types.erase(ID($allconst));
|
||||
|
||||
log("Finding identical cells in module `%s'.\n", module->name.c_str());
|
||||
assign_map.set(module);
|
||||
|
||||
dff_init_map.set(module);
|
||||
for (auto &it : module->wires_)
|
||||
if (it.second->attributes.count("\\init") != 0) {
|
||||
Const initval = it.second->attributes.at("\\init");
|
||||
if (it.second->attributes.count(ID(init)) != 0) {
|
||||
Const initval = it.second->attributes.at(ID(init));
|
||||
for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++)
|
||||
if (initval[i] == State::S0 || initval[i] == State::S1)
|
||||
dff_init_map.add(SigBit(it.second, i), initval[i]);
|
||||
|
|
|
@ -84,12 +84,12 @@ struct OptMuxtreeWorker
|
|||
// .const_deactivated
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type.in("$mux", "$pmux"))
|
||||
if (cell->type.in(ID($mux), ID($pmux)))
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort("\\A");
|
||||
RTLIL::SigSpec sig_b = cell->getPort("\\B");
|
||||
RTLIL::SigSpec sig_s = cell->getPort("\\S");
|
||||
RTLIL::SigSpec sig_y = cell->getPort("\\Y");
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID(A));
|
||||
RTLIL::SigSpec sig_b = cell->getPort(ID(B));
|
||||
RTLIL::SigSpec sig_s = cell->getPort(ID(S));
|
||||
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
|
||||
|
||||
muxinfo_t muxinfo;
|
||||
muxinfo.cell = cell;
|
||||
|
@ -137,7 +137,7 @@ struct OptMuxtreeWorker
|
|||
}
|
||||
}
|
||||
for (auto wire : module->wires()) {
|
||||
if (wire->port_output || wire->get_bool_attribute("\\keep"))
|
||||
if (wire->port_output || wire->get_bool_attribute(ID(keep)))
|
||||
for (int idx : sig2bits(RTLIL::SigSpec(wire)))
|
||||
bit2info[idx].seen_non_mux = true;
|
||||
}
|
||||
|
@ -227,10 +227,10 @@ struct OptMuxtreeWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec sig_a = mi.cell->getPort("\\A");
|
||||
RTLIL::SigSpec sig_b = mi.cell->getPort("\\B");
|
||||
RTLIL::SigSpec sig_s = mi.cell->getPort("\\S");
|
||||
RTLIL::SigSpec sig_y = mi.cell->getPort("\\Y");
|
||||
RTLIL::SigSpec sig_a = mi.cell->getPort(ID(A));
|
||||
RTLIL::SigSpec sig_b = mi.cell->getPort(ID(B));
|
||||
RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S));
|
||||
RTLIL::SigSpec sig_y = mi.cell->getPort(ID(Y));
|
||||
|
||||
RTLIL::SigSpec sig_ports = sig_b;
|
||||
sig_ports.append(sig_a);
|
||||
|
@ -255,14 +255,14 @@ struct OptMuxtreeWorker
|
|||
}
|
||||
}
|
||||
|
||||
mi.cell->setPort("\\A", new_sig_a);
|
||||
mi.cell->setPort("\\B", new_sig_b);
|
||||
mi.cell->setPort("\\S", new_sig_s);
|
||||
mi.cell->setPort(ID(A), new_sig_a);
|
||||
mi.cell->setPort(ID(B), new_sig_b);
|
||||
mi.cell->setPort(ID(S), new_sig_s);
|
||||
if (GetSize(new_sig_s) == 1) {
|
||||
mi.cell->type = "$mux";
|
||||
mi.cell->parameters.erase("\\S_WIDTH");
|
||||
mi.cell->type = ID($mux);
|
||||
mi.cell->parameters.erase(ID(S_WIDTH));
|
||||
} else {
|
||||
mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(GetSize(new_sig_s));
|
||||
mi.cell->parameters[ID(S_WIDTH)] = RTLIL::Const(GetSize(new_sig_s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,9 +364,9 @@ struct OptMuxtreeWorker
|
|||
|
||||
int width = 0;
|
||||
idict<int> ctrl_bits;
|
||||
if (portname == "\\B")
|
||||
width = GetSize(muxinfo.cell->getPort("\\A"));
|
||||
for (int bit : sig2bits(muxinfo.cell->getPort("\\S"), false))
|
||||
if (portname == ID(B))
|
||||
width = GetSize(muxinfo.cell->getPort(ID(A)));
|
||||
for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false))
|
||||
ctrl_bits(bit);
|
||||
|
||||
int port_idx = 0, port_off = 0;
|
||||
|
@ -414,8 +414,8 @@ struct OptMuxtreeWorker
|
|||
|
||||
// set input ports to constants if we find known active or inactive signals
|
||||
if (do_replace_known) {
|
||||
replace_known(knowledge, muxinfo, "\\A");
|
||||
replace_known(knowledge, muxinfo, "\\B");
|
||||
replace_known(knowledge, muxinfo, ID(A));
|
||||
replace_known(knowledge, muxinfo, ID(B));
|
||||
}
|
||||
|
||||
// if there is a constant activated port we just use it
|
||||
|
|
|
@ -43,13 +43,13 @@ struct OptReduceWorker
|
|||
return;
|
||||
cells.erase(cell);
|
||||
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A)));
|
||||
pool<RTLIL::SigBit> new_sig_a_bits;
|
||||
|
||||
for (auto &bit : sig_a.to_sigbit_set())
|
||||
{
|
||||
if (bit == RTLIL::State::S0) {
|
||||
if (cell->type == "$reduce_and") {
|
||||
if (cell->type == ID($reduce_and)) {
|
||||
new_sig_a_bits.clear();
|
||||
new_sig_a_bits.insert(RTLIL::State::S0);
|
||||
break;
|
||||
|
@ -57,7 +57,7 @@ struct OptReduceWorker
|
|||
continue;
|
||||
}
|
||||
if (bit == RTLIL::State::S1) {
|
||||
if (cell->type == "$reduce_or") {
|
||||
if (cell->type == ID($reduce_or)) {
|
||||
new_sig_a_bits.clear();
|
||||
new_sig_a_bits.insert(RTLIL::State::S1);
|
||||
break;
|
||||
|
@ -73,8 +73,8 @@ struct OptReduceWorker
|
|||
for (auto child_cell : drivers.find(bit)) {
|
||||
if (child_cell->type == cell->type) {
|
||||
opt_reduce(cells, drivers, child_cell);
|
||||
if (child_cell->getPort("\\Y")[0] == bit) {
|
||||
pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort("\\A")).to_sigbit_pool();
|
||||
if (child_cell->getPort(ID(Y))[0] == bit) {
|
||||
pool<RTLIL::SigBit> child_sig_a_bits = assign_map(child_cell->getPort(ID(A))).to_sigbit_pool();
|
||||
new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end());
|
||||
} else
|
||||
new_sig_a_bits.insert(RTLIL::State::S0);
|
||||
|
@ -87,22 +87,22 @@ struct OptReduceWorker
|
|||
|
||||
RTLIL::SigSpec new_sig_a(new_sig_a_bits);
|
||||
|
||||
if (new_sig_a != sig_a || sig_a.size() != cell->getPort("\\A").size()) {
|
||||
if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID(A)).size()) {
|
||||
log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a));
|
||||
did_something = true;
|
||||
total_count++;
|
||||
}
|
||||
|
||||
cell->setPort("\\A", new_sig_a);
|
||||
cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size());
|
||||
cell->setPort(ID(A), new_sig_a);
|
||||
cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size());
|
||||
return;
|
||||
}
|
||||
|
||||
void opt_mux(RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
|
||||
RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B"));
|
||||
RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S"));
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A)));
|
||||
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B)));
|
||||
RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S)));
|
||||
|
||||
RTLIL::SigSpec new_sig_b, new_sig_s;
|
||||
pool<RTLIL::SigSpec> handled_sig;
|
||||
|
@ -123,15 +123,15 @@ struct OptReduceWorker
|
|||
|
||||
if (this_s.size() > 1)
|
||||
{
|
||||
RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or");
|
||||
reduce_or_cell->setPort("\\A", this_s);
|
||||
reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
|
||||
reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size());
|
||||
reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
|
||||
RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or));
|
||||
reduce_or_cell->setPort(ID(A), this_s);
|
||||
reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0);
|
||||
reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size());
|
||||
reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1);
|
||||
|
||||
RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID);
|
||||
this_s = RTLIL::SigSpec(reduce_or_wire);
|
||||
reduce_or_cell->setPort("\\Y", this_s);
|
||||
reduce_or_cell->setPort(ID(Y), this_s);
|
||||
}
|
||||
|
||||
new_sig_b.append(this_b);
|
||||
|
@ -147,28 +147,28 @@ struct OptReduceWorker
|
|||
|
||||
if (new_sig_s.size() == 0)
|
||||
{
|
||||
module->connect(RTLIL::SigSig(cell->getPort("\\Y"), cell->getPort("\\A")));
|
||||
assign_map.add(cell->getPort("\\Y"), cell->getPort("\\A"));
|
||||
module->connect(RTLIL::SigSig(cell->getPort(ID(Y)), cell->getPort(ID(A))));
|
||||
assign_map.add(cell->getPort(ID(Y)), cell->getPort(ID(A)));
|
||||
module->remove(cell);
|
||||
}
|
||||
else
|
||||
{
|
||||
cell->setPort("\\B", new_sig_b);
|
||||
cell->setPort("\\S", new_sig_s);
|
||||
cell->setPort(ID(B), new_sig_b);
|
||||
cell->setPort(ID(S), new_sig_s);
|
||||
if (new_sig_s.size() > 1) {
|
||||
cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size());
|
||||
cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size());
|
||||
} else {
|
||||
cell->type = "$mux";
|
||||
cell->parameters.erase("\\S_WIDTH");
|
||||
cell->type = ID($mux);
|
||||
cell->parameters.erase(ID(S_WIDTH));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void opt_mux_bits(RTLIL::Cell *cell)
|
||||
{
|
||||
std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort("\\A")).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort("\\B")).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort("\\Y")).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> sig_a = assign_map(cell->getPort(ID(A))).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> sig_b = assign_map(cell->getPort(ID(B))).to_sigbit_vector();
|
||||
std::vector<RTLIL::SigBit> sig_y = assign_map(cell->getPort(ID(Y))).to_sigbit_vector();
|
||||
|
||||
std::vector<RTLIL::SigBit> new_sig_y;
|
||||
RTLIL::SigSig old_sig_conn;
|
||||
|
@ -209,29 +209,29 @@ struct OptReduceWorker
|
|||
if (new_sig_y.size() != sig_y.size())
|
||||
{
|
||||
log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str());
|
||||
log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")),
|
||||
log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y")));
|
||||
log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))),
|
||||
log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y))));
|
||||
|
||||
cell->setPort("\\A", RTLIL::SigSpec());
|
||||
cell->setPort(ID(A), RTLIL::SigSpec());
|
||||
for (auto &in_tuple : consolidated_in_tuples) {
|
||||
RTLIL::SigSpec new_a = cell->getPort("\\A");
|
||||
RTLIL::SigSpec new_a = cell->getPort(ID(A));
|
||||
new_a.append(in_tuple.at(0));
|
||||
cell->setPort("\\A", new_a);
|
||||
cell->setPort(ID(A), new_a);
|
||||
}
|
||||
|
||||
cell->setPort("\\B", RTLIL::SigSpec());
|
||||
for (int i = 1; i <= cell->getPort("\\S").size(); i++)
|
||||
cell->setPort(ID(B), RTLIL::SigSpec());
|
||||
for (int i = 1; i <= cell->getPort(ID(S)).size(); i++)
|
||||
for (auto &in_tuple : consolidated_in_tuples) {
|
||||
RTLIL::SigSpec new_b = cell->getPort("\\B");
|
||||
RTLIL::SigSpec new_b = cell->getPort(ID(B));
|
||||
new_b.append(in_tuple.at(i));
|
||||
cell->setPort("\\B", new_b);
|
||||
cell->setPort(ID(B), new_b);
|
||||
}
|
||||
|
||||
cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size());
|
||||
cell->setPort("\\Y", new_sig_y);
|
||||
cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size());
|
||||
cell->setPort(ID(Y), new_sig_y);
|
||||
|
||||
log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")),
|
||||
log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y")));
|
||||
log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))),
|
||||
log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y))));
|
||||
log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second));
|
||||
|
||||
module->connect(old_sig_conn);
|
||||
|
@ -253,15 +253,15 @@ struct OptReduceWorker
|
|||
SigPool mem_wren_sigs;
|
||||
for (auto &cell_it : module->cells_) {
|
||||
RTLIL::Cell *cell = cell_it.second;
|
||||
if (cell->type == "$mem")
|
||||
mem_wren_sigs.add(assign_map(cell->getPort("\\WR_EN")));
|
||||
if (cell->type == "$memwr")
|
||||
mem_wren_sigs.add(assign_map(cell->getPort("\\EN")));
|
||||
if (cell->type == ID($mem))
|
||||
mem_wren_sigs.add(assign_map(cell->getPort(ID(WR_EN))));
|
||||
if (cell->type == ID($memwr))
|
||||
mem_wren_sigs.add(assign_map(cell->getPort(ID(EN))));
|
||||
}
|
||||
for (auto &cell_it : module->cells_) {
|
||||
RTLIL::Cell *cell = cell_it.second;
|
||||
if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Q"))))
|
||||
mem_wren_sigs.add(assign_map(cell->getPort("\\D")));
|
||||
if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Q)))))
|
||||
mem_wren_sigs.add(assign_map(cell->getPort(ID(D))));
|
||||
}
|
||||
|
||||
bool keep_expanding_mem_wren_sigs = true;
|
||||
|
@ -269,12 +269,12 @@ struct OptReduceWorker
|
|||
keep_expanding_mem_wren_sigs = false;
|
||||
for (auto &cell_it : module->cells_) {
|
||||
RTLIL::Cell *cell = cell_it.second;
|
||||
if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) {
|
||||
if (!mem_wren_sigs.check_all(assign_map(cell->getPort("\\A"))) ||
|
||||
!mem_wren_sigs.check_all(assign_map(cell->getPort("\\B"))))
|
||||
if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) {
|
||||
if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(A)))) ||
|
||||
!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(B)))))
|
||||
keep_expanding_mem_wren_sigs = true;
|
||||
mem_wren_sigs.add(assign_map(cell->getPort("\\A")));
|
||||
mem_wren_sigs.add(assign_map(cell->getPort("\\B")));
|
||||
mem_wren_sigs.add(assign_map(cell->getPort(ID(A))));
|
||||
mem_wren_sigs.add(assign_map(cell->getPort(ID(B))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ struct OptReduceWorker
|
|||
// merge trees of reduce_* cells to one single cell and unify input vectors
|
||||
// (only handle reduce_and and reduce_or for various reasons)
|
||||
|
||||
const char *type_list[] = { "$reduce_or", "$reduce_and" };
|
||||
const IdString type_list[] = { ID($reduce_or), ID($reduce_and) };
|
||||
for (auto type : type_list)
|
||||
{
|
||||
SigSet<RTLIL::Cell*> drivers;
|
||||
|
@ -296,7 +296,7 @@ struct OptReduceWorker
|
|||
RTLIL::Cell *cell = cell_it.second;
|
||||
if (cell->type != type || !design->selected(module, cell))
|
||||
continue;
|
||||
drivers.insert(assign_map(cell->getPort("\\Y")), cell);
|
||||
drivers.insert(assign_map(cell->getPort(ID(Y))), cell);
|
||||
cells.insert(cell);
|
||||
}
|
||||
|
||||
|
@ -311,14 +311,14 @@ struct OptReduceWorker
|
|||
std::vector<RTLIL::Cell*> cells;
|
||||
|
||||
for (auto &it : module->cells_)
|
||||
if ((it.second->type == "$mux" || it.second->type == "$pmux") && design->selected(module, it.second))
|
||||
if ((it.second->type == ID($mux) || it.second->type == ID($pmux)) && design->selected(module, it.second))
|
||||
cells.push_back(it.second);
|
||||
|
||||
for (auto cell : cells)
|
||||
{
|
||||
// this optimization is to aggressive for most coarse-grain applications.
|
||||
// but we always want it for multiplexers driving write enable ports.
|
||||
if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y"))))
|
||||
if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y)))))
|
||||
opt_mux_bits(cell);
|
||||
|
||||
opt_mux(cell);
|
||||
|
|
|
@ -41,7 +41,7 @@ void remove_init_attr(SigSpec sig)
|
|||
for (auto bit : assign_map(sig))
|
||||
if (init_attributes.count(bit))
|
||||
for (auto wbit : init_attributes.at(bit))
|
||||
wbit.wire->attributes.at("\\init")[wbit.offset] = State::Sx;
|
||||
wbit.wire->attributes.at(ID(init))[wbit.offset] = State::Sx;
|
||||
}
|
||||
|
||||
bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
||||
|
@ -49,17 +49,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
|||
SigSpec sig_set, sig_clr;
|
||||
State pol_set, pol_clr;
|
||||
|
||||
if (cell->hasPort("\\S"))
|
||||
sig_set = cell->getPort("\\S");
|
||||
if (cell->hasPort(ID(S)))
|
||||
sig_set = cell->getPort(ID(S));
|
||||
|
||||
if (cell->hasPort("\\R"))
|
||||
sig_clr = cell->getPort("\\R");
|
||||
if (cell->hasPort(ID(R)))
|
||||
sig_clr = cell->getPort(ID(R));
|
||||
|
||||
if (cell->hasPort("\\SET"))
|
||||
sig_set = cell->getPort("\\SET");
|
||||
if (cell->hasPort(ID(SET)))
|
||||
sig_set = cell->getPort(ID(SET));
|
||||
|
||||
if (cell->hasPort("\\CLR"))
|
||||
sig_clr = cell->getPort("\\CLR");
|
||||
if (cell->hasPort(ID(CLR)))
|
||||
sig_clr = cell->getPort(ID(CLR));
|
||||
|
||||
log_assert(GetSize(sig_set) == GetSize(sig_clr));
|
||||
|
||||
|
@ -71,17 +71,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
|||
pol_set = cell->type[12] == 'P' ? State::S1 : State::S0;
|
||||
pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0;
|
||||
} else
|
||||
if (cell->type.in("$dffsr", "$dlatchsr")) {
|
||||
pol_set = cell->parameters["\\SET_POLARITY"].as_bool() ? State::S1 : State::S0;
|
||||
pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool() ? State::S1 : State::S0;
|
||||
if (cell->type.in(ID($dffsr), ID($dlatchsr))) {
|
||||
pol_set = cell->parameters[ID(SET_POLARITY)].as_bool() ? State::S1 : State::S0;
|
||||
pol_clr = cell->parameters[ID(CLR_POLARITY)].as_bool() ? State::S1 : State::S0;
|
||||
} else
|
||||
log_abort();
|
||||
|
||||
State npol_set = pol_set == State::S0 ? State::S1 : State::S0;
|
||||
State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0;
|
||||
|
||||
SigSpec sig_d = cell->getPort("\\D");
|
||||
SigSpec sig_q = cell->getPort("\\Q");
|
||||
SigSpec sig_d = cell->getPort(ID(D));
|
||||
SigSpec sig_q = cell->getPort(ID(Q));
|
||||
|
||||
bool did_something = false;
|
||||
bool proper_sr = false;
|
||||
|
@ -137,20 +137,20 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$dffsr", "$dlatchsr"))
|
||||
if (cell->type.in(ID($dffsr), ID($dlatchsr)))
|
||||
{
|
||||
cell->setParam("\\WIDTH", GetSize(sig_d));
|
||||
cell->setPort("\\SET", sig_set);
|
||||
cell->setPort("\\CLR", sig_clr);
|
||||
cell->setPort("\\D", sig_d);
|
||||
cell->setPort("\\Q", sig_q);
|
||||
cell->setParam(ID(WIDTH), GetSize(sig_d));
|
||||
cell->setPort(ID(SET), sig_set);
|
||||
cell->setPort(ID(CLR), sig_clr);
|
||||
cell->setPort(ID(D), sig_d);
|
||||
cell->setPort(ID(Q), sig_q);
|
||||
}
|
||||
else
|
||||
{
|
||||
cell->setPort("\\S", sig_set);
|
||||
cell->setPort("\\R", sig_clr);
|
||||
cell->setPort("\\D", sig_d);
|
||||
cell->setPort("\\Q", sig_q);
|
||||
cell->setPort(ID(S), sig_set);
|
||||
cell->setPort(ID(R), sig_clr);
|
||||
cell->setPort(ID(D), sig_d);
|
||||
cell->setPort(ID(Q), sig_q);
|
||||
}
|
||||
|
||||
if (proper_sr)
|
||||
|
@ -159,36 +159,36 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
|||
if (used_pol_set && used_pol_clr && pol_set != pol_clr)
|
||||
return did_something;
|
||||
|
||||
if (cell->type == "$dlatchsr")
|
||||
if (cell->type == ID($dlatchsr))
|
||||
return did_something;
|
||||
|
||||
State unified_pol = used_pol_set ? pol_set : pol_clr;
|
||||
|
||||
if (cell->type == "$dffsr")
|
||||
if (cell->type == ID($dffsr))
|
||||
{
|
||||
if (hasreset)
|
||||
{
|
||||
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod));
|
||||
|
||||
cell->type = "$adff";
|
||||
cell->setParam("\\ARST_POLARITY", unified_pol);
|
||||
cell->setParam("\\ARST_VALUE", reset_val);
|
||||
cell->setPort("\\ARST", sig_reset);
|
||||
cell->type = ID($adff);
|
||||
cell->setParam(ID(ARST_POLARITY), unified_pol);
|
||||
cell->setParam(ID(ARST_VALUE), reset_val);
|
||||
cell->setPort(ID(ARST), sig_reset);
|
||||
|
||||
cell->unsetParam("\\SET_POLARITY");
|
||||
cell->unsetParam("\\CLR_POLARITY");
|
||||
cell->unsetPort("\\SET");
|
||||
cell->unsetPort("\\CLR");
|
||||
cell->unsetParam(ID(SET_POLARITY));
|
||||
cell->unsetParam(ID(CLR_POLARITY));
|
||||
cell->unsetPort(ID(SET));
|
||||
cell->unsetPort(ID(CLR));
|
||||
}
|
||||
else
|
||||
{
|
||||
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod));
|
||||
|
||||
cell->type = "$dff";
|
||||
cell->unsetParam("\\SET_POLARITY");
|
||||
cell->unsetParam("\\CLR_POLARITY");
|
||||
cell->unsetPort("\\SET");
|
||||
cell->unsetPort("\\CLR");
|
||||
cell->type = ID($dff);
|
||||
cell->unsetParam(ID(SET_POLARITY));
|
||||
cell->unsetParam(ID(CLR_POLARITY));
|
||||
cell->unsetPort(ID(SET));
|
||||
cell->unsetPort(ID(CLR));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -208,8 +208,8 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
|
|||
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod));
|
||||
|
||||
cell->type = new_type;
|
||||
cell->unsetPort("\\S");
|
||||
cell->unsetPort("\\R");
|
||||
cell->unsetPort(ID(S));
|
||||
cell->unsetPort(ID(R));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -222,18 +222,18 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
|
|||
SigSpec sig_e;
|
||||
State on_state, off_state;
|
||||
|
||||
if (dlatch->type == "$dlatch") {
|
||||
sig_e = assign_map(dlatch->getPort("\\EN"));
|
||||
on_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S1 : State::S0;
|
||||
off_state = dlatch->getParam("\\EN_POLARITY").as_bool() ? State::S0 : State::S1;
|
||||
if (dlatch->type == ID($dlatch)) {
|
||||
sig_e = assign_map(dlatch->getPort(ID(EN)));
|
||||
on_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S1 : State::S0;
|
||||
off_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S0 : State::S1;
|
||||
} else
|
||||
if (dlatch->type == "$_DLATCH_P_") {
|
||||
sig_e = assign_map(dlatch->getPort("\\E"));
|
||||
if (dlatch->type == ID($_DLATCH_P_)) {
|
||||
sig_e = assign_map(dlatch->getPort(ID(E)));
|
||||
on_state = State::S1;
|
||||
off_state = State::S0;
|
||||
} else
|
||||
if (dlatch->type == "$_DLATCH_N_") {
|
||||
sig_e = assign_map(dlatch->getPort("\\E"));
|
||||
if (dlatch->type == ID($_DLATCH_N_)) {
|
||||
sig_e = assign_map(dlatch->getPort(ID(E)));
|
||||
on_state = State::S0;
|
||||
off_state = State::S1;
|
||||
} else
|
||||
|
@ -242,15 +242,15 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
|
|||
if (sig_e == off_state)
|
||||
{
|
||||
RTLIL::Const val_init;
|
||||
for (auto bit : dff_init_map(dlatch->getPort("\\Q")))
|
||||
for (auto bit : dff_init_map(dlatch->getPort(ID(Q))))
|
||||
val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx);
|
||||
mod->connect(dlatch->getPort("\\Q"), val_init);
|
||||
mod->connect(dlatch->getPort(ID(Q)), val_init);
|
||||
goto delete_dlatch;
|
||||
}
|
||||
|
||||
if (sig_e == on_state)
|
||||
{
|
||||
mod->connect(dlatch->getPort("\\Q"), dlatch->getPort("\\D"));
|
||||
mod->connect(dlatch->getPort(ID(Q)), dlatch->getPort(ID(D)));
|
||||
goto delete_dlatch;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
|
|||
|
||||
delete_dlatch:
|
||||
log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod));
|
||||
remove_init_attr(dlatch->getPort("\\Q"));
|
||||
remove_init_attr(dlatch->getPort(ID(Q)));
|
||||
mod->remove(dlatch);
|
||||
return true;
|
||||
}
|
||||
|
@ -268,24 +268,24 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
RTLIL::SigSpec sig_d, sig_q, sig_c, sig_r, sig_e;
|
||||
RTLIL::Const val_cp, val_rp, val_rv, val_ep;
|
||||
|
||||
if (dff->type == "$_FF_") {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
if (dff->type == ID($_FF_)) {
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
}
|
||||
else if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\C");
|
||||
val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1);
|
||||
else if (dff->type == ID($_DFF_N_) || dff->type == ID($_DFF_P_)) {
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(C));
|
||||
val_cp = RTLIL::Const(dff->type == ID($_DFF_P_), 1);
|
||||
}
|
||||
else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 &&
|
||||
(dff->type[6] == 'N' || dff->type[6] == 'P') &&
|
||||
(dff->type[7] == 'N' || dff->type[7] == 'P') &&
|
||||
(dff->type[8] == '0' || dff->type[8] == '1')) {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\C");
|
||||
sig_r = dff->getPort("\\R");
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(C));
|
||||
sig_r = dff->getPort(ID(R));
|
||||
val_cp = RTLIL::Const(dff->type[6] == 'P', 1);
|
||||
val_rp = RTLIL::Const(dff->type[7] == 'P', 1);
|
||||
val_rv = RTLIL::Const(dff->type[8] == '1', 1);
|
||||
|
@ -293,39 +293,39 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 &&
|
||||
(dff->type[7] == 'N' || dff->type[7] == 'P') &&
|
||||
(dff->type[8] == 'N' || dff->type[8] == 'P')) {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\C");
|
||||
sig_e = dff->getPort("\\E");
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(C));
|
||||
sig_e = dff->getPort(ID(E));
|
||||
val_cp = RTLIL::Const(dff->type[7] == 'P', 1);
|
||||
val_ep = RTLIL::Const(dff->type[8] == 'P', 1);
|
||||
}
|
||||
else if (dff->type == "$ff") {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
else if (dff->type == ID($ff)) {
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
}
|
||||
else if (dff->type == "$dff") {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\CLK");
|
||||
val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1);
|
||||
else if (dff->type == ID($dff)) {
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(CLK));
|
||||
val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
|
||||
}
|
||||
else if (dff->type == "$dffe") {
|
||||
sig_e = dff->getPort("\\EN");
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\CLK");
|
||||
val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1);
|
||||
val_ep = RTLIL::Const(dff->parameters["\\EN_POLARITY"].as_bool(), 1);
|
||||
else if (dff->type == ID($dffe)) {
|
||||
sig_e = dff->getPort(ID(EN));
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(CLK));
|
||||
val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
|
||||
val_ep = RTLIL::Const(dff->parameters[ID(EN_POLARITY)].as_bool(), 1);
|
||||
}
|
||||
else if (dff->type == "$adff") {
|
||||
sig_d = dff->getPort("\\D");
|
||||
sig_q = dff->getPort("\\Q");
|
||||
sig_c = dff->getPort("\\CLK");
|
||||
sig_r = dff->getPort("\\ARST");
|
||||
val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1);
|
||||
val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1);
|
||||
val_rv = dff->parameters["\\ARST_VALUE"];
|
||||
else if (dff->type == ID($adff)) {
|
||||
sig_d = dff->getPort(ID(D));
|
||||
sig_q = dff->getPort(ID(Q));
|
||||
sig_c = dff->getPort(ID(CLK));
|
||||
sig_r = dff->getPort(ID(ARST));
|
||||
val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
|
||||
val_rp = RTLIL::Const(dff->parameters[ID(ARST_POLARITY)].as_bool(), 1);
|
||||
val_rv = dff->parameters[ID(ARST_VALUE)];
|
||||
}
|
||||
else
|
||||
log_abort();
|
||||
|
@ -343,12 +343,12 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
val_init.bits.push_back(bit.wire == NULL ? bit.data : RTLIL::State::Sx);
|
||||
}
|
||||
|
||||
if (dff->type.in("$ff", "$dff") && mux_drivers.has(sig_d)) {
|
||||
if (dff->type.in(ID($ff), ID($dff)) && mux_drivers.has(sig_d)) {
|
||||
std::set<RTLIL::Cell*> muxes;
|
||||
mux_drivers.find(sig_d, muxes);
|
||||
for (auto mux : muxes) {
|
||||
RTLIL::SigSpec sig_a = assign_map(mux->getPort("\\A"));
|
||||
RTLIL::SigSpec sig_b = assign_map(mux->getPort("\\B"));
|
||||
RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID(A)));
|
||||
RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID(B)));
|
||||
if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) {
|
||||
mod->connect(sig_q, sig_b);
|
||||
goto delete_dff;
|
||||
|
@ -420,17 +420,17 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
|
||||
log("Removing unused reset from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod));
|
||||
|
||||
if (dff->type == "$adff") {
|
||||
dff->type = "$dff";
|
||||
dff->unsetPort("\\ARST");
|
||||
dff->unsetParam("\\ARST_POLARITY");
|
||||
dff->unsetParam("\\ARST_VALUE");
|
||||
if (dff->type == ID($adff)) {
|
||||
dff->type = ID($dff);
|
||||
dff->unsetPort(ID(ARST));
|
||||
dff->unsetParam(ID(ARST_POLARITY));
|
||||
dff->unsetParam(ID(ARST_VALUE));
|
||||
return true;
|
||||
}
|
||||
|
||||
log_assert(dff->type.begins_with("$_DFF_"));
|
||||
dff->type = stringf("$_DFF_%c_", + dff->type[6]);
|
||||
dff->unsetPort("\\R");
|
||||
dff->unsetPort(ID(R));
|
||||
}
|
||||
|
||||
// If enable signal is present, and is fully constant
|
||||
|
@ -445,16 +445,16 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
|
||||
log("Removing unused enable from %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod));
|
||||
|
||||
if (dff->type == "$dffe") {
|
||||
dff->type = "$dff";
|
||||
dff->unsetPort("\\EN");
|
||||
dff->unsetParam("\\EN_POLARITY");
|
||||
if (dff->type == ID($dffe)) {
|
||||
dff->type = ID($dff);
|
||||
dff->unsetPort(ID(EN));
|
||||
dff->unsetParam(ID(EN_POLARITY));
|
||||
return true;
|
||||
}
|
||||
|
||||
log_assert(dff->type.begins_with("$_DFFE_"));
|
||||
dff->type = stringf("$_DFF_%c_", + dff->type[7]);
|
||||
dff->unsetPort("\\E");
|
||||
dff->unsetPort(ID(E));
|
||||
}
|
||||
|
||||
if (sat && has_init && (!sig_r.size() || val_init == val_rv))
|
||||
|
@ -509,9 +509,9 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0,
|
||||
position, log_id(dff), log_id(dff->type), log_id(mod));
|
||||
|
||||
SigSpec tmp = dff->getPort("\\D");
|
||||
SigSpec tmp = dff->getPort(ID(D));
|
||||
tmp[position] = sigbit_init_val;
|
||||
dff->setPort("\\D", tmp);
|
||||
dff->setPort(ID(D), tmp);
|
||||
|
||||
removed_sigbits = true;
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
|
|||
|
||||
delete_dff:
|
||||
log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod));
|
||||
remove_init_attr(dff->getPort("\\Q"));
|
||||
remove_init_attr(dff->getPort(ID(Q)));
|
||||
mod->remove(dff);
|
||||
|
||||
for (auto &entry : bit2driver)
|
||||
|
@ -588,8 +588,8 @@ struct OptRmdffPass : public Pass {
|
|||
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
if (wire->attributes.count("\\init") != 0) {
|
||||
Const initval = wire->attributes.at("\\init");
|
||||
if (wire->attributes.count(ID(init)) != 0) {
|
||||
Const initval = wire->attributes.at(ID(init));
|
||||
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
|
||||
if (initval[i] == State::S0 || initval[i] == State::S1)
|
||||
dff_init_map.add(SigBit(wire, i), initval[i]);
|
||||
|
@ -624,29 +624,29 @@ struct OptRmdffPass : public Pass {
|
|||
}
|
||||
}
|
||||
|
||||
if (cell->type.in("$mux", "$pmux")) {
|
||||
if (cell->getPort("\\A").size() == cell->getPort("\\B").size())
|
||||
mux_drivers.insert(assign_map(cell->getPort("\\Y")), cell);
|
||||
if (cell->type.in(ID($mux), ID($pmux))) {
|
||||
if (cell->getPort(ID(A)).size() == cell->getPort(ID(B)).size())
|
||||
mux_drivers.insert(assign_map(cell->getPort(ID(Y))), cell);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!design->selected(module, cell))
|
||||
continue;
|
||||
|
||||
if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_",
|
||||
"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_", "$dffsr",
|
||||
"$_DLATCHSR_NNN_", "$_DLATCHSR_NNP_", "$_DLATCHSR_NPN_", "$_DLATCHSR_NPP_",
|
||||
"$_DLATCHSR_PNN_", "$_DLATCHSR_PNP_", "$_DLATCHSR_PPN_", "$_DLATCHSR_PPP_", "$dlatchsr"))
|
||||
if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
|
||||
ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), ID($dffsr),
|
||||
ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_),
|
||||
ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_), ID($dlatchsr)))
|
||||
dffsr_list.push_back(cell->name);
|
||||
|
||||
if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_",
|
||||
"$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
|
||||
"$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_",
|
||||
"$_DFFE_NN_", "$_DFFE_NP_", "$_DFFE_PN_", "$_DFFE_PP_",
|
||||
"$ff", "$dff", "$dffe", "$adff"))
|
||||
if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_),
|
||||
ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
|
||||
ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_),
|
||||
ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_),
|
||||
ID($ff), ID($dff), ID($dffe), ID($adff)))
|
||||
dff_list.push_back(cell->name);
|
||||
|
||||
if (cell->type.in("$dlatch", "$_DLATCH_P_", "$_DLATCH_N_"))
|
||||
if (cell->type.in(ID($dlatch), ID($_DLATCH_P_), ID($_DLATCH_N_)))
|
||||
dlatch_list.push_back(cell->name);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ struct OnehotDatabase
|
|||
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
auto it = wire->attributes.find("\\init");
|
||||
auto it = wire->attributes.find(ID(init));
|
||||
if (it == wire->attributes.end())
|
||||
continue;
|
||||
|
||||
|
@ -63,19 +63,19 @@ struct OnehotDatabase
|
|||
vector<SigSpec> inputs;
|
||||
SigSpec output;
|
||||
|
||||
if (cell->type.in("$adff", "$dff", "$dffe", "$dlatch", "$ff"))
|
||||
if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff)))
|
||||
{
|
||||
output = cell->getPort("\\Q");
|
||||
if (cell->type == "$adff")
|
||||
inputs.push_back(cell->getParam("\\ARST_VALUE"));
|
||||
inputs.push_back(cell->getPort("\\D"));
|
||||
output = cell->getPort(ID(Q));
|
||||
if (cell->type == ID($adff))
|
||||
inputs.push_back(cell->getParam(ID(ARST_VALUE)));
|
||||
inputs.push_back(cell->getPort(ID(D)));
|
||||
}
|
||||
|
||||
if (cell->type.in("$mux", "$pmux"))
|
||||
if (cell->type.in(ID($mux), ID($pmux)))
|
||||
{
|
||||
output = cell->getPort("\\Y");
|
||||
inputs.push_back(cell->getPort("\\A"));
|
||||
SigSpec B = cell->getPort("\\B");
|
||||
output = cell->getPort(ID(Y));
|
||||
inputs.push_back(cell->getPort(ID(A)));
|
||||
SigSpec B = cell->getPort(ID(B));
|
||||
for (int i = 0; i < GetSize(B); i += GetSize(output))
|
||||
inputs.push_back(B.extract(i, GetSize(output)));
|
||||
}
|
||||
|
@ -292,23 +292,23 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == "$eq")
|
||||
if (cell->type == ID($eq))
|
||||
{
|
||||
dict<SigBit, State> bits;
|
||||
|
||||
SigSpec A = sigmap(cell->getPort("\\A"));
|
||||
SigSpec B = sigmap(cell->getPort("\\B"));
|
||||
SigSpec A = sigmap(cell->getPort(ID(A)));
|
||||
SigSpec B = sigmap(cell->getPort(ID(B)));
|
||||
|
||||
int a_width = cell->getParam("\\A_WIDTH").as_int();
|
||||
int b_width = cell->getParam("\\B_WIDTH").as_int();
|
||||
int a_width = cell->getParam(ID(A_WIDTH)).as_int();
|
||||
int b_width = cell->getParam(ID(B_WIDTH)).as_int();
|
||||
|
||||
if (a_width < b_width) {
|
||||
bool a_signed = cell->getParam("\\A_SIGNED").as_int();
|
||||
bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
|
||||
A.extend_u0(b_width, a_signed);
|
||||
}
|
||||
|
||||
if (b_width < a_width) {
|
||||
bool b_signed = cell->getParam("\\B_SIGNED").as_int();
|
||||
bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
|
||||
B.extend_u0(a_width, b_signed);
|
||||
}
|
||||
|
||||
|
@ -335,15 +335,15 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
entry.second.bits.push_back(it.second);
|
||||
}
|
||||
|
||||
eqdb[sigmap(cell->getPort("\\Y")[0])] = entry;
|
||||
eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry;
|
||||
goto next_cell;
|
||||
}
|
||||
|
||||
if (cell->type == "$logic_not")
|
||||
if (cell->type == ID($logic_not))
|
||||
{
|
||||
dict<SigBit, State> bits;
|
||||
|
||||
SigSpec A = sigmap(cell->getPort("\\A"));
|
||||
SigSpec A = sigmap(cell->getPort(ID(A)));
|
||||
|
||||
for (int i = 0; i < GetSize(A); i++)
|
||||
bits[A[i]] = State::S0;
|
||||
|
@ -356,7 +356,7 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
entry.second.bits.push_back(it.second);
|
||||
}
|
||||
|
||||
eqdb[sigmap(cell->getPort("\\Y")[0])] = entry;
|
||||
eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry;
|
||||
goto next_cell;
|
||||
}
|
||||
next_cell:;
|
||||
|
@ -364,11 +364,11 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type != "$pmux")
|
||||
if (cell->type != ID($pmux))
|
||||
continue;
|
||||
|
||||
string src = cell->get_src_attribute();
|
||||
int width = cell->getParam("\\WIDTH").as_int();
|
||||
int width = cell->getParam(ID(WIDTH)).as_int();
|
||||
int width_bits = ceil_log2(width);
|
||||
int extwidth = width;
|
||||
|
||||
|
@ -377,9 +377,9 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
|
||||
dict<SigSpec, pool<int>> seldb;
|
||||
|
||||
SigSpec A = cell->getPort("\\A");
|
||||
SigSpec B = cell->getPort("\\B");
|
||||
SigSpec S = sigmap(cell->getPort("\\S"));
|
||||
SigSpec A = cell->getPort(ID(A));
|
||||
SigSpec B = cell->getPort(ID(B));
|
||||
SigSpec S = sigmap(cell->getPort(ID(S)));
|
||||
for (int i = 0; i < GetSize(S); i++)
|
||||
{
|
||||
if (!eqdb.count(S[i]))
|
||||
|
@ -400,8 +400,8 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
log(" data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits);
|
||||
}
|
||||
|
||||
SigSpec updated_S = cell->getPort("\\S");
|
||||
SigSpec updated_B = cell->getPort("\\B");
|
||||
SigSpec updated_S = cell->getPort(ID(S));
|
||||
SigSpec updated_B = cell->getPort(ID(B));
|
||||
|
||||
while (!seldb.empty())
|
||||
{
|
||||
|
@ -727,9 +727,9 @@ struct Pmux2ShiftxPass : public Pass {
|
|||
}
|
||||
|
||||
// update $pmux cell
|
||||
cell->setPort("\\S", updated_S);
|
||||
cell->setPort("\\B", updated_B);
|
||||
cell->setParam("\\S_WIDTH", GetSize(updated_S));
|
||||
cell->setPort(ID(S), updated_S);
|
||||
cell->setPort(ID(B), updated_B);
|
||||
cell->setParam(ID(S_WIDTH), GetSize(updated_S));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -779,22 +779,22 @@ struct OnehotPass : public Pass {
|
|||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type != "$eq")
|
||||
if (cell->type != ID($eq))
|
||||
continue;
|
||||
|
||||
SigSpec A = sigmap(cell->getPort("\\A"));
|
||||
SigSpec B = sigmap(cell->getPort("\\B"));
|
||||
SigSpec A = sigmap(cell->getPort(ID(A)));
|
||||
SigSpec B = sigmap(cell->getPort(ID(B)));
|
||||
|
||||
int a_width = cell->getParam("\\A_WIDTH").as_int();
|
||||
int b_width = cell->getParam("\\B_WIDTH").as_int();
|
||||
int a_width = cell->getParam(ID(A_WIDTH)).as_int();
|
||||
int b_width = cell->getParam(ID(B_WIDTH)).as_int();
|
||||
|
||||
if (a_width < b_width) {
|
||||
bool a_signed = cell->getParam("\\A_SIGNED").as_int();
|
||||
bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
|
||||
A.extend_u0(b_width, a_signed);
|
||||
}
|
||||
|
||||
if (b_width < a_width) {
|
||||
bool b_signed = cell->getParam("\\B_SIGNED").as_int();
|
||||
bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
|
||||
B.extend_u0(a_width, b_signed);
|
||||
}
|
||||
|
||||
|
@ -830,7 +830,7 @@ struct OnehotPass : public Pass {
|
|||
continue;
|
||||
}
|
||||
|
||||
SigSpec Y = cell->getPort("\\Y");
|
||||
SigSpec Y = cell->getPort(ID(Y));
|
||||
|
||||
if (not_onehot)
|
||||
{
|
||||
|
|
|
@ -89,8 +89,8 @@ struct ShareWorker
|
|||
queue_bits.clear();
|
||||
|
||||
for (auto &pbit : portbits) {
|
||||
if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") {
|
||||
pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort("\\S")).to_sigbit_pool();
|
||||
if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) {
|
||||
pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool();
|
||||
terminal_bits.insert(bits.begin(), bits.end());
|
||||
queue_bits.insert(bits.begin(), bits.end());
|
||||
visited_cells.insert(pbit.cell);
|
||||
|
@ -128,7 +128,7 @@ struct ShareWorker
|
|||
static int bits_macc(RTLIL::Cell *c)
|
||||
{
|
||||
Macc m(c);
|
||||
int width = GetSize(c->getPort("\\Y"));
|
||||
int width = GetSize(c->getPort(ID(Y)));
|
||||
return bits_macc(m, width);
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ struct ShareWorker
|
|||
{
|
||||
Macc m1(c1), m2(c2), supermacc;
|
||||
|
||||
int w1 = GetSize(c1->getPort("\\Y")), w2 = GetSize(c2->getPort("\\Y"));
|
||||
int w1 = GetSize(c1->getPort(ID(Y))), w2 = GetSize(c2->getPort(ID(Y)));
|
||||
int width = max(w1, w2);
|
||||
|
||||
m1.optimize(w1);
|
||||
|
@ -328,11 +328,11 @@ struct ShareWorker
|
|||
{
|
||||
RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width);
|
||||
|
||||
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort("\\Y")));
|
||||
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort("\\Y")));
|
||||
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID(Y))));
|
||||
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID(Y))));
|
||||
|
||||
supercell->setParam("\\Y_WIDTH", width);
|
||||
supercell->setPort("\\Y", sig_y);
|
||||
supercell->setParam(ID(Y_WIDTH), width);
|
||||
supercell->setPort(ID(Y), sig_y);
|
||||
|
||||
supermacc.optimize(width);
|
||||
supermacc.to_cell(supercell);
|
||||
|
@ -368,22 +368,22 @@ struct ShareWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type == "$memrd") {
|
||||
if (cell->parameters.at("\\CLK_ENABLE").as_bool())
|
||||
if (cell->type == ID($memrd)) {
|
||||
if (cell->parameters.at(ID(CLK_ENABLE)).as_bool())
|
||||
continue;
|
||||
if (config.opt_aggressive || !modwalker.sigmap(cell->getPort("\\ADDR")).is_fully_const())
|
||||
if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const())
|
||||
shareable_cells.insert(cell);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in("$mul", "$div", "$mod")) {
|
||||
if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4)
|
||||
if (cell->type.in(ID($mul), ID($div), ID($mod))) {
|
||||
if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4)
|
||||
shareable_cells.insert(cell);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) {
|
||||
if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8)
|
||||
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
|
||||
if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8)
|
||||
shareable_cells.insert(cell);
|
||||
continue;
|
||||
}
|
||||
|
@ -401,9 +401,9 @@ struct ShareWorker
|
|||
if (c1->type != c2->type)
|
||||
return false;
|
||||
|
||||
if (c1->type == "$memrd")
|
||||
if (c1->type == ID($memrd))
|
||||
{
|
||||
if (c1->parameters.at("\\MEMID").decode_string() != c2->parameters.at("\\MEMID").decode_string())
|
||||
if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -413,11 +413,11 @@ struct ShareWorker
|
|||
{
|
||||
if (!config.opt_aggressive)
|
||||
{
|
||||
int a1_width = c1->parameters.at("\\A_WIDTH").as_int();
|
||||
int y1_width = c1->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
int a2_width = c2->parameters.at("\\A_WIDTH").as_int();
|
||||
int y2_width = c2->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
|
||||
if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
|
||||
|
@ -426,17 +426,17 @@ struct ShareWorker
|
|||
return true;
|
||||
}
|
||||
|
||||
if (config.generic_bin_ops.count(c1->type) || c1->type == "$alu")
|
||||
if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu))
|
||||
{
|
||||
if (!config.opt_aggressive)
|
||||
{
|
||||
int a1_width = c1->parameters.at("\\A_WIDTH").as_int();
|
||||
int b1_width = c1->parameters.at("\\B_WIDTH").as_int();
|
||||
int y1_width = c1->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
|
||||
int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
int a2_width = c2->parameters.at("\\A_WIDTH").as_int();
|
||||
int b2_width = c2->parameters.at("\\B_WIDTH").as_int();
|
||||
int y2_width = c2->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
|
||||
int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
|
||||
if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false;
|
||||
|
@ -450,13 +450,13 @@ struct ShareWorker
|
|||
{
|
||||
if (!config.opt_aggressive)
|
||||
{
|
||||
int a1_width = c1->parameters.at("\\A_WIDTH").as_int();
|
||||
int b1_width = c1->parameters.at("\\B_WIDTH").as_int();
|
||||
int y1_width = c1->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
|
||||
int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
int a2_width = c2->parameters.at("\\A_WIDTH").as_int();
|
||||
int b2_width = c2->parameters.at("\\B_WIDTH").as_int();
|
||||
int y2_width = c2->parameters.at("\\Y_WIDTH").as_int();
|
||||
int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
|
||||
int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
|
||||
int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
|
||||
|
||||
int min1_width = min(a1_width, b1_width);
|
||||
int max1_width = max(a1_width, b1_width);
|
||||
|
@ -472,7 +472,7 @@ struct ShareWorker
|
|||
return true;
|
||||
}
|
||||
|
||||
if (c1->type == "$macc")
|
||||
if (c1->type == ID($macc))
|
||||
{
|
||||
if (!config.opt_aggressive)
|
||||
if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false;
|
||||
|
@ -510,27 +510,27 @@ struct ShareWorker
|
|||
|
||||
if (config.generic_uni_ops.count(c1->type))
|
||||
{
|
||||
if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool())
|
||||
if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
|
||||
{
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1;
|
||||
RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A");
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
|
||||
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A));
|
||||
new_a.append_bit(RTLIL::State::S0);
|
||||
unsigned_cell->setPort("\\A", new_a);
|
||||
unsigned_cell->setPort(ID(A), new_a);
|
||||
}
|
||||
unsigned_cell->parameters.at("\\A_SIGNED") = true;
|
||||
unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
|
||||
unsigned_cell->check();
|
||||
}
|
||||
|
||||
bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool();
|
||||
log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool());
|
||||
bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
|
||||
log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
|
||||
|
||||
RTLIL::SigSpec a1 = c1->getPort("\\A");
|
||||
RTLIL::SigSpec y1 = c1->getPort("\\Y");
|
||||
RTLIL::SigSpec a1 = c1->getPort(ID(A));
|
||||
RTLIL::SigSpec y1 = c1->getPort(ID(Y));
|
||||
|
||||
RTLIL::SigSpec a2 = c2->getPort("\\A");
|
||||
RTLIL::SigSpec y2 = c2->getPort("\\Y");
|
||||
RTLIL::SigSpec a2 = c2->getPort(ID(A));
|
||||
RTLIL::SigSpec y2 = c2->getPort(ID(Y));
|
||||
|
||||
int a_width = max(a1.size(), a2.size());
|
||||
int y_width = max(y1.size(), y2.size());
|
||||
|
@ -544,11 +544,11 @@ struct ShareWorker
|
|||
RTLIL::Wire *y = module->addWire(NEW_ID, y_width);
|
||||
|
||||
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
|
||||
supercell->parameters["\\A_SIGNED"] = a_signed;
|
||||
supercell->parameters["\\A_WIDTH"] = a_width;
|
||||
supercell->parameters["\\Y_WIDTH"] = y_width;
|
||||
supercell->setPort("\\A", a);
|
||||
supercell->setPort("\\Y", y);
|
||||
supercell->parameters[ID(A_SIGNED)] = a_signed;
|
||||
supercell->parameters[ID(A_WIDTH)] = a_width;
|
||||
supercell->parameters[ID(Y_WIDTH)] = y_width;
|
||||
supercell->setPort(ID(A), a);
|
||||
supercell->setPort(ID(Y), y);
|
||||
|
||||
supercell_aux.insert(module->addPos(NEW_ID, y, y1));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, y, y2));
|
||||
|
@ -557,54 +557,54 @@ struct ShareWorker
|
|||
return supercell;
|
||||
}
|
||||
|
||||
if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == "$alu")
|
||||
if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu))
|
||||
{
|
||||
bool modified_src_cells = false;
|
||||
|
||||
if (config.generic_cbin_ops.count(c1->type))
|
||||
{
|
||||
int score_unflipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()) +
|
||||
max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int());
|
||||
int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) +
|
||||
max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int());
|
||||
|
||||
int score_flipped = max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()) +
|
||||
max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int());
|
||||
int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) +
|
||||
max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int());
|
||||
|
||||
if (score_flipped < score_unflipped)
|
||||
{
|
||||
RTLIL::SigSpec tmp = c2->getPort("\\A");
|
||||
c2->setPort("\\A", c2->getPort("\\B"));
|
||||
c2->setPort("\\B", tmp);
|
||||
RTLIL::SigSpec tmp = c2->getPort(ID(A));
|
||||
c2->setPort(ID(A), c2->getPort(ID(B)));
|
||||
c2->setPort(ID(B), tmp);
|
||||
|
||||
std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH"));
|
||||
std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED"));
|
||||
std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH)));
|
||||
std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED)));
|
||||
modified_src_cells = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool())
|
||||
if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
|
||||
|
||||
{
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1;
|
||||
RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A");
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
|
||||
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A));
|
||||
new_a.append_bit(RTLIL::State::S0);
|
||||
unsigned_cell->setPort("\\A", new_a);
|
||||
unsigned_cell->setPort(ID(A), new_a);
|
||||
}
|
||||
unsigned_cell->parameters.at("\\A_SIGNED") = true;
|
||||
unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
|
||||
modified_src_cells = true;
|
||||
}
|
||||
|
||||
if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool())
|
||||
if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool())
|
||||
{
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort("\\B").to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1;
|
||||
RTLIL::SigSpec new_b = unsigned_cell->getPort("\\B");
|
||||
RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1;
|
||||
if (unsigned_cell->getPort(ID(B)).to_sigbit_vector().back() != RTLIL::State::S0) {
|
||||
unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1;
|
||||
RTLIL::SigSpec new_b = unsigned_cell->getPort(ID(B));
|
||||
new_b.append_bit(RTLIL::State::S0);
|
||||
unsigned_cell->setPort("\\B", new_b);
|
||||
unsigned_cell->setPort(ID(B), new_b);
|
||||
}
|
||||
unsigned_cell->parameters.at("\\B_SIGNED") = true;
|
||||
unsigned_cell->parameters.at(ID(B_SIGNED)) = true;
|
||||
modified_src_cells = true;
|
||||
}
|
||||
|
||||
|
@ -613,28 +613,28 @@ struct ShareWorker
|
|||
c2->check();
|
||||
}
|
||||
|
||||
bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool();
|
||||
bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool();
|
||||
bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
|
||||
bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool();
|
||||
|
||||
log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool());
|
||||
log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool());
|
||||
log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
|
||||
log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool());
|
||||
|
||||
if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr")
|
||||
if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
|
||||
b_signed = false;
|
||||
|
||||
RTLIL::SigSpec a1 = c1->getPort("\\A");
|
||||
RTLIL::SigSpec b1 = c1->getPort("\\B");
|
||||
RTLIL::SigSpec y1 = c1->getPort("\\Y");
|
||||
RTLIL::SigSpec a1 = c1->getPort(ID(A));
|
||||
RTLIL::SigSpec b1 = c1->getPort(ID(B));
|
||||
RTLIL::SigSpec y1 = c1->getPort(ID(Y));
|
||||
|
||||
RTLIL::SigSpec a2 = c2->getPort("\\A");
|
||||
RTLIL::SigSpec b2 = c2->getPort("\\B");
|
||||
RTLIL::SigSpec y2 = c2->getPort("\\Y");
|
||||
RTLIL::SigSpec a2 = c2->getPort(ID(A));
|
||||
RTLIL::SigSpec b2 = c2->getPort(ID(B));
|
||||
RTLIL::SigSpec y2 = c2->getPort(ID(Y));
|
||||
|
||||
int a_width = max(a1.size(), a2.size());
|
||||
int b_width = max(b1.size(), b2.size());
|
||||
int y_width = max(y1.size(), y2.size());
|
||||
|
||||
if (c1->type == "$shr" && a_signed)
|
||||
if (c1->type == ID($shr) && a_signed)
|
||||
{
|
||||
a_width = max(y_width, a_width);
|
||||
|
||||
|
@ -660,43 +660,43 @@ struct ShareWorker
|
|||
supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b));
|
||||
|
||||
RTLIL::Wire *y = module->addWire(NEW_ID, y_width);
|
||||
RTLIL::Wire *x = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr;
|
||||
RTLIL::Wire *co = c1->type == "$alu" ? module->addWire(NEW_ID, y_width) : nullptr;
|
||||
RTLIL::Wire *x = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;
|
||||
RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;
|
||||
|
||||
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
|
||||
supercell->parameters["\\A_SIGNED"] = a_signed;
|
||||
supercell->parameters["\\B_SIGNED"] = b_signed;
|
||||
supercell->parameters["\\A_WIDTH"] = a_width;
|
||||
supercell->parameters["\\B_WIDTH"] = b_width;
|
||||
supercell->parameters["\\Y_WIDTH"] = y_width;
|
||||
supercell->setPort("\\A", a);
|
||||
supercell->setPort("\\B", b);
|
||||
supercell->setPort("\\Y", y);
|
||||
if (c1->type == "$alu") {
|
||||
supercell->parameters[ID(A_SIGNED)] = a_signed;
|
||||
supercell->parameters[ID(B_SIGNED)] = b_signed;
|
||||
supercell->parameters[ID(A_WIDTH)] = a_width;
|
||||
supercell->parameters[ID(B_WIDTH)] = b_width;
|
||||
supercell->parameters[ID(Y_WIDTH)] = y_width;
|
||||
supercell->setPort(ID(A), a);
|
||||
supercell->setPort(ID(B), b);
|
||||
supercell->setPort(ID(Y), y);
|
||||
if (c1->type == ID($alu)) {
|
||||
RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID);
|
||||
supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\CI"), c1->getPort("\\CI"), act, ci));
|
||||
supercell_aux.insert(module->addMux(NEW_ID, c2->getPort("\\BI"), c1->getPort("\\BI"), act, bi));
|
||||
supercell->setPort("\\CI", ci);
|
||||
supercell->setPort("\\BI", bi);
|
||||
supercell->setPort("\\CO", co);
|
||||
supercell->setPort("\\X", x);
|
||||
supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci));
|
||||
supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi));
|
||||
supercell->setPort(ID(CI), ci);
|
||||
supercell->setPort(ID(BI), bi);
|
||||
supercell->setPort(ID(CO), co);
|
||||
supercell->setPort(ID(X), x);
|
||||
}
|
||||
supercell->check();
|
||||
|
||||
supercell_aux.insert(module->addPos(NEW_ID, y, y1));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, y, y2));
|
||||
if (c1->type == "$alu") {
|
||||
supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort("\\CO")));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort("\\CO")));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort("\\X")));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort("\\X")));
|
||||
if (c1->type == ID($alu)) {
|
||||
supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO))));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO))));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X))));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X))));
|
||||
}
|
||||
|
||||
supercell_aux.insert(supercell);
|
||||
return supercell;
|
||||
}
|
||||
|
||||
if (c1->type == "$macc")
|
||||
if (c1->type == ID($macc))
|
||||
{
|
||||
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
|
||||
supercell_aux.insert(supercell);
|
||||
|
@ -705,18 +705,18 @@ struct ShareWorker
|
|||
return supercell;
|
||||
}
|
||||
|
||||
if (c1->type == "$memrd")
|
||||
if (c1->type == ID($memrd))
|
||||
{
|
||||
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1);
|
||||
RTLIL::SigSpec addr1 = c1->getPort("\\ADDR");
|
||||
RTLIL::SigSpec addr2 = c2->getPort("\\ADDR");
|
||||
RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR));
|
||||
RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR));
|
||||
if (GetSize(addr1) < GetSize(addr2))
|
||||
addr1.extend_u0(GetSize(addr2));
|
||||
else
|
||||
addr2.extend_u0(GetSize(addr1));
|
||||
supercell->setPort("\\ADDR", addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
|
||||
supercell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr1));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort("\\DATA"), c2->getPort("\\DATA")));
|
||||
supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
|
||||
supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1));
|
||||
supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA))));
|
||||
supercell_aux.insert(supercell);
|
||||
return supercell;
|
||||
}
|
||||
|
@ -747,8 +747,8 @@ struct ShareWorker
|
|||
modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]);
|
||||
|
||||
for (auto &bit : pbits) {
|
||||
if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S")
|
||||
forbidden_controls_cache[cell].insert(bit.cell->getPort("\\S").extract(bit.offset, 1));
|
||||
if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S))
|
||||
forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1));
|
||||
consumer_cells.insert(bit.cell);
|
||||
}
|
||||
|
||||
|
@ -874,7 +874,7 @@ struct ShareWorker
|
|||
}
|
||||
for (auto &pbit : modwalker.signal_consumers[bit]) {
|
||||
log_assert(fwd_ct.cell_known(pbit.cell->type));
|
||||
if ((pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") && (pbit.port == "\\A" || pbit.port == "\\B"))
|
||||
if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID(A) || pbit.port == ID(B)))
|
||||
driven_data_muxes.insert(pbit.cell);
|
||||
else
|
||||
driven_cells.insert(pbit.cell);
|
||||
|
@ -890,10 +890,10 @@ struct ShareWorker
|
|||
bool used_in_a = false;
|
||||
std::set<int> used_in_b_parts;
|
||||
|
||||
int width = c->parameters.at("\\WIDTH").as_int();
|
||||
std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort("\\A"));
|
||||
std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort("\\B"));
|
||||
std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort("\\S"));
|
||||
int width = c->parameters.at(ID(WIDTH)).as_int();
|
||||
std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID(A)));
|
||||
std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID(B)));
|
||||
std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S)));
|
||||
|
||||
for (auto &bit : sig_a)
|
||||
if (cell_out_bits.count(bit))
|
||||
|
@ -1132,14 +1132,14 @@ struct ShareWorker
|
|||
fwd_ct.setup_internals();
|
||||
|
||||
cone_ct.setup_internals();
|
||||
cone_ct.cell_types.erase("$mul");
|
||||
cone_ct.cell_types.erase("$mod");
|
||||
cone_ct.cell_types.erase("$div");
|
||||
cone_ct.cell_types.erase("$pow");
|
||||
cone_ct.cell_types.erase("$shl");
|
||||
cone_ct.cell_types.erase("$shr");
|
||||
cone_ct.cell_types.erase("$sshl");
|
||||
cone_ct.cell_types.erase("$sshr");
|
||||
cone_ct.cell_types.erase(ID($mul));
|
||||
cone_ct.cell_types.erase(ID($mod));
|
||||
cone_ct.cell_types.erase(ID($div));
|
||||
cone_ct.cell_types.erase(ID($pow));
|
||||
cone_ct.cell_types.erase(ID($shl));
|
||||
cone_ct.cell_types.erase(ID($shr));
|
||||
cone_ct.cell_types.erase(ID($sshl));
|
||||
cone_ct.cell_types.erase(ID($sshr));
|
||||
|
||||
modwalker.setup(design, module);
|
||||
|
||||
|
@ -1153,9 +1153,9 @@ struct ShareWorker
|
|||
GetSize(shareable_cells), log_id(module));
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (cell->type == "$pmux")
|
||||
for (auto bit : cell->getPort("\\S"))
|
||||
for (auto other_bit : cell->getPort("\\S"))
|
||||
if (cell->type == ID($pmux))
|
||||
for (auto bit : cell->getPort(ID(S)))
|
||||
for (auto other_bit : cell->getPort(ID(S)))
|
||||
if (bit < other_bit)
|
||||
exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit));
|
||||
|
||||
|
@ -1466,43 +1466,43 @@ struct SharePass : public Pass {
|
|||
config.opt_aggressive = false;
|
||||
config.opt_fast = false;
|
||||
|
||||
config.generic_uni_ops.insert("$not");
|
||||
// config.generic_uni_ops.insert("$pos");
|
||||
config.generic_uni_ops.insert("$neg");
|
||||
config.generic_uni_ops.insert(ID($not));
|
||||
// config.generic_uni_ops.insert(ID($pos));
|
||||
config.generic_uni_ops.insert(ID($neg));
|
||||
|
||||
config.generic_cbin_ops.insert("$and");
|
||||
config.generic_cbin_ops.insert("$or");
|
||||
config.generic_cbin_ops.insert("$xor");
|
||||
config.generic_cbin_ops.insert("$xnor");
|
||||
config.generic_cbin_ops.insert(ID($and));
|
||||
config.generic_cbin_ops.insert(ID($or));
|
||||
config.generic_cbin_ops.insert(ID($xor));
|
||||
config.generic_cbin_ops.insert(ID($xnor));
|
||||
|
||||
config.generic_bin_ops.insert("$shl");
|
||||
config.generic_bin_ops.insert("$shr");
|
||||
config.generic_bin_ops.insert("$sshl");
|
||||
config.generic_bin_ops.insert("$sshr");
|
||||
config.generic_bin_ops.insert(ID($shl));
|
||||
config.generic_bin_ops.insert(ID($shr));
|
||||
config.generic_bin_ops.insert(ID($sshl));
|
||||
config.generic_bin_ops.insert(ID($sshr));
|
||||
|
||||
config.generic_bin_ops.insert("$lt");
|
||||
config.generic_bin_ops.insert("$le");
|
||||
config.generic_bin_ops.insert("$eq");
|
||||
config.generic_bin_ops.insert("$ne");
|
||||
config.generic_bin_ops.insert("$eqx");
|
||||
config.generic_bin_ops.insert("$nex");
|
||||
config.generic_bin_ops.insert("$ge");
|
||||
config.generic_bin_ops.insert("$gt");
|
||||
config.generic_bin_ops.insert(ID($lt));
|
||||
config.generic_bin_ops.insert(ID($le));
|
||||
config.generic_bin_ops.insert(ID($eq));
|
||||
config.generic_bin_ops.insert(ID($ne));
|
||||
config.generic_bin_ops.insert(ID($eqx));
|
||||
config.generic_bin_ops.insert(ID($nex));
|
||||
config.generic_bin_ops.insert(ID($ge));
|
||||
config.generic_bin_ops.insert(ID($gt));
|
||||
|
||||
config.generic_cbin_ops.insert("$add");
|
||||
config.generic_cbin_ops.insert("$mul");
|
||||
config.generic_cbin_ops.insert(ID($add));
|
||||
config.generic_cbin_ops.insert(ID($mul));
|
||||
|
||||
config.generic_bin_ops.insert("$sub");
|
||||
config.generic_bin_ops.insert("$div");
|
||||
config.generic_bin_ops.insert("$mod");
|
||||
// config.generic_bin_ops.insert("$pow");
|
||||
config.generic_bin_ops.insert(ID($sub));
|
||||
config.generic_bin_ops.insert(ID($div));
|
||||
config.generic_bin_ops.insert(ID($mod));
|
||||
// config.generic_bin_ops.insert(ID($pow));
|
||||
|
||||
config.generic_uni_ops.insert("$logic_not");
|
||||
config.generic_cbin_ops.insert("$logic_and");
|
||||
config.generic_cbin_ops.insert("$logic_or");
|
||||
config.generic_uni_ops.insert(ID($logic_not));
|
||||
config.generic_cbin_ops.insert(ID($logic_and));
|
||||
config.generic_cbin_ops.insert(ID($logic_or));
|
||||
|
||||
config.generic_other_ops.insert("$alu");
|
||||
config.generic_other_ops.insert("$macc");
|
||||
config.generic_other_ops.insert(ID($alu));
|
||||
config.generic_other_ops.insert(ID($macc));
|
||||
|
||||
log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n");
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ struct WreduceConfig
|
|||
WreduceConfig()
|
||||
{
|
||||
supported_cell_types = pool<IdString>({
|
||||
"$not", "$pos", "$neg",
|
||||
"$and", "$or", "$xor", "$xnor",
|
||||
"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
|
||||
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
|
||||
"$add", "$sub", "$mul", // "$div", "$mod", "$pow",
|
||||
"$mux", "$pmux",
|
||||
"$dff", "$adff"
|
||||
ID($not), ID($pos), ID($neg),
|
||||
ID($and), ID($or), ID($xor), ID($xnor),
|
||||
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
|
||||
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
|
||||
ID($add), ID($sub), ID($mul), // ID($div), ID($mod), ID($pow),
|
||||
ID($mux), ID($pmux),
|
||||
ID($dff), ID($adff)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -64,10 +64,10 @@ struct WreduceWorker
|
|||
{
|
||||
// Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused
|
||||
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort("\\A"));
|
||||
SigSpec sig_b = mi.sigmap(cell->getPort("\\B"));
|
||||
SigSpec sig_s = mi.sigmap(cell->getPort("\\S"));
|
||||
SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A)));
|
||||
SigSpec sig_b = mi.sigmap(cell->getPort(ID(B)));
|
||||
SigSpec sig_s = mi.sigmap(cell->getPort(ID(S)));
|
||||
SigSpec sig_y = mi.sigmap(cell->getPort(ID(Y)));
|
||||
std::vector<SigBit> bits_removed;
|
||||
|
||||
if (sig_y.has_const())
|
||||
|
@ -130,9 +130,9 @@ struct WreduceWorker
|
|||
for (auto bit : new_work_queue_bits)
|
||||
work_queue_bits.insert(bit);
|
||||
|
||||
cell->setPort("\\A", new_sig_a);
|
||||
cell->setPort("\\B", new_sig_b);
|
||||
cell->setPort("\\Y", new_sig_y);
|
||||
cell->setPort(ID(A), new_sig_a);
|
||||
cell->setPort(ID(B), new_sig_b);
|
||||
cell->setPort(ID(Y), new_sig_y);
|
||||
cell->fixup_parameters();
|
||||
|
||||
module->connect(sig_y.extract(n_kept, n_removed), sig_removed);
|
||||
|
@ -142,8 +142,8 @@ struct WreduceWorker
|
|||
{
|
||||
// Reduce size of FF if inputs are just sign/zero extended or output bit is not used
|
||||
|
||||
SigSpec sig_d = mi.sigmap(cell->getPort("\\D"));
|
||||
SigSpec sig_q = mi.sigmap(cell->getPort("\\Q"));
|
||||
SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
|
||||
SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
|
||||
Const initval;
|
||||
|
||||
int width_before = GetSize(sig_q);
|
||||
|
@ -214,14 +214,14 @@ struct WreduceWorker
|
|||
work_queue_bits.insert(bit);
|
||||
|
||||
// Narrow ARST_VALUE parameter to new size.
|
||||
if (cell->parameters.count("\\ARST_VALUE")) {
|
||||
Const arst_value = cell->getParam("\\ARST_VALUE");
|
||||
if (cell->parameters.count(ID(ARST_VALUE))) {
|
||||
Const arst_value = cell->getParam(ID(ARST_VALUE));
|
||||
arst_value.bits.resize(GetSize(sig_q));
|
||||
cell->setParam("\\ARST_VALUE", arst_value);
|
||||
cell->setParam(ID(ARST_VALUE), arst_value);
|
||||
}
|
||||
|
||||
cell->setPort("\\D", sig_d);
|
||||
cell->setPort("\\Q", sig_q);
|
||||
cell->setPort(ID(D), sig_d);
|
||||
cell->setPort(ID(Q), sig_q);
|
||||
cell->fixup_parameters();
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ struct WreduceWorker
|
|||
port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
|
||||
SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port)));
|
||||
|
||||
if (port == 'B' && cell->type.in("$shl", "$shr", "$sshl", "$sshr"))
|
||||
if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr)))
|
||||
port_signed = false;
|
||||
|
||||
int bits_removed = 0;
|
||||
|
@ -264,13 +264,13 @@ struct WreduceWorker
|
|||
if (!cell->type.in(config->supported_cell_types))
|
||||
return;
|
||||
|
||||
if (cell->type.in("$mux", "$pmux"))
|
||||
if (cell->type.in(ID($mux), ID($pmux)))
|
||||
return run_cell_mux(cell);
|
||||
|
||||
if (cell->type.in("$dff", "$adff"))
|
||||
if (cell->type.in(ID($dff), ID($adff)))
|
||||
return run_cell_dff(cell);
|
||||
|
||||
SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
|
||||
SigSpec sig = mi.sigmap(cell->getPort(ID(Y)));
|
||||
|
||||
if (sig.has_const())
|
||||
return;
|
||||
|
@ -278,10 +278,10 @@ struct WreduceWorker
|
|||
|
||||
// Reduce size of ports A and B based on constant input bits and size of output port
|
||||
|
||||
int max_port_a_size = cell->hasPort("\\A") ? GetSize(cell->getPort("\\A")) : -1;
|
||||
int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1;
|
||||
int max_port_a_size = cell->hasPort(ID(A)) ? GetSize(cell->getPort(ID(A))) : -1;
|
||||
int max_port_b_size = cell->hasPort(ID(B)) ? GetSize(cell->getPort(ID(B))) : -1;
|
||||
|
||||
if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) {
|
||||
if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) {
|
||||
max_port_a_size = min(max_port_a_size, GetSize(sig));
|
||||
max_port_b_size = min(max_port_b_size, GetSize(sig));
|
||||
}
|
||||
|
@ -289,32 +289,32 @@ struct WreduceWorker
|
|||
bool port_a_signed = false;
|
||||
bool port_b_signed = false;
|
||||
|
||||
if (max_port_a_size >= 0 && cell->type != "$shiftx")
|
||||
if (max_port_a_size >= 0 && cell->type != ID($shiftx))
|
||||
run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something);
|
||||
|
||||
if (max_port_b_size >= 0)
|
||||
run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something);
|
||||
|
||||
if (cell->hasPort("\\A") && cell->hasPort("\\B") && port_a_signed && port_b_signed) {
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort("\\A")), sig_b = mi.sigmap(cell->getPort("\\B"));
|
||||
if (cell->hasPort(ID(A)) && cell->hasPort(ID(B)) && port_a_signed && port_b_signed) {
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))), sig_b = mi.sigmap(cell->getPort(ID(B)));
|
||||
if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 &&
|
||||
GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) {
|
||||
log("Converting cell %s.%s (%s) from signed to unsigned.\n",
|
||||
log_id(module), log_id(cell), log_id(cell->type));
|
||||
cell->setParam("\\A_SIGNED", 0);
|
||||
cell->setParam("\\B_SIGNED", 0);
|
||||
cell->setParam(ID(A_SIGNED), 0);
|
||||
cell->setParam(ID(B_SIGNED), 0);
|
||||
port_a_signed = false;
|
||||
port_b_signed = false;
|
||||
did_something = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell->hasPort("\\A") && !cell->hasPort("\\B") && port_a_signed) {
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort("\\A"));
|
||||
if (cell->hasPort(ID(A)) && !cell->hasPort(ID(B)) && port_a_signed) {
|
||||
SigSpec sig_a = mi.sigmap(cell->getPort(ID(A)));
|
||||
if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) {
|
||||
log("Converting cell %s.%s (%s) from signed to unsigned.\n",
|
||||
log_id(module), log_id(cell), log_id(cell->type));
|
||||
cell->setParam("\\A_SIGNED", 0);
|
||||
cell->setParam(ID(A_SIGNED), 0);
|
||||
port_a_signed = false;
|
||||
did_something = true;
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ struct WreduceWorker
|
|||
// Reduce size of port Y based on sizes for A and B and unused bits in Y
|
||||
|
||||
int bits_removed = 0;
|
||||
if (port_a_signed && cell->type == "$shr") {
|
||||
if (port_a_signed && cell->type == ID($shr)) {
|
||||
// do not reduce size of output on $shr cells with signed A inputs
|
||||
} else {
|
||||
while (GetSize(sig) > 0)
|
||||
|
@ -342,20 +342,20 @@ struct WreduceWorker
|
|||
}
|
||||
}
|
||||
|
||||
if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor", "$sub"))
|
||||
if (cell->type.in(ID($pos), ID($add), ID($mul), ID($and), ID($or), ID($xor), ID($sub)))
|
||||
{
|
||||
bool is_signed = cell->getParam("\\A_SIGNED").as_bool() || cell->type == "$sub";
|
||||
bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub);
|
||||
|
||||
int a_size = 0, b_size = 0;
|
||||
if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A"));
|
||||
if (cell->hasPort("\\B")) b_size = GetSize(cell->getPort("\\B"));
|
||||
if (cell->hasPort(ID(A))) a_size = GetSize(cell->getPort(ID(A)));
|
||||
if (cell->hasPort(ID(B))) b_size = GetSize(cell->getPort(ID(B)));
|
||||
|
||||
int max_y_size = max(a_size, b_size);
|
||||
|
||||
if (cell->type.in("$add", "$sub"))
|
||||
if (cell->type.in(ID($add), ID($sub)))
|
||||
max_y_size++;
|
||||
|
||||
if (cell->type == "$mul")
|
||||
if (cell->type == ID($mul))
|
||||
max_y_size = a_size + b_size;
|
||||
|
||||
while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) {
|
||||
|
@ -374,7 +374,7 @@ struct WreduceWorker
|
|||
if (bits_removed) {
|
||||
log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n",
|
||||
bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type));
|
||||
cell->setPort("\\Y", sig);
|
||||
cell->setPort(ID(Y), sig);
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
|
@ -387,8 +387,8 @@ struct WreduceWorker
|
|||
static int count_nontrivial_wire_attrs(RTLIL::Wire *w)
|
||||
{
|
||||
int count = w->attributes.size();
|
||||
count -= w->attributes.count("\\src");
|
||||
count -= w->attributes.count("\\unused_bits");
|
||||
count -= w->attributes.count(ID(src));
|
||||
count -= w->attributes.count(ID(unused_bits));
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -398,11 +398,11 @@ struct WreduceWorker
|
|||
SigMap init_attr_sigmap = mi.sigmap;
|
||||
|
||||
for (auto w : module->wires()) {
|
||||
if (w->get_bool_attribute("\\keep"))
|
||||
if (w->get_bool_attribute(ID(keep)))
|
||||
for (auto bit : mi.sigmap(w))
|
||||
keep_bits.insert(bit);
|
||||
if (w->attributes.count("\\init")) {
|
||||
Const initval = w->attributes.at("\\init");
|
||||
if (w->attributes.count(ID(init))) {
|
||||
Const initval = w->attributes.at(ID(init));
|
||||
SigSpec initsig = init_attr_sigmap(w);
|
||||
int width = std::min(GetSize(initval), GetSize(initsig));
|
||||
for (int i = 0; i < width; i++)
|
||||
|
@ -459,8 +459,8 @@ struct WreduceWorker
|
|||
|
||||
if (!remove_init_bits.empty()) {
|
||||
for (auto w : module->wires()) {
|
||||
if (w->attributes.count("\\init")) {
|
||||
Const initval = w->attributes.at("\\init");
|
||||
if (w->attributes.count(ID(init))) {
|
||||
Const initval = w->attributes.at(ID(init));
|
||||
Const new_initval(State::Sx, GetSize(w));
|
||||
SigSpec initsig = init_attr_sigmap(w);
|
||||
int width = std::min(GetSize(initval), GetSize(initsig));
|
||||
|
@ -468,7 +468,7 @@ struct WreduceWorker
|
|||
if (!remove_init_bits.count(initsig[i]))
|
||||
new_initval[i] = initval[i];
|
||||
}
|
||||
w->attributes.at("\\init") = new_initval;
|
||||
w->attributes.at(ID(init)) = new_initval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -528,23 +528,23 @@ struct WreducePass : public Pass {
|
|||
|
||||
for (auto c : module->selected_cells())
|
||||
{
|
||||
if (c->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
|
||||
"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
|
||||
"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
|
||||
SigSpec sig = c->getPort("\\Y");
|
||||
if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
|
||||
ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID(Y))) > 1) {
|
||||
SigSpec sig = c->getPort(ID(Y));
|
||||
if (!sig.has_const()) {
|
||||
c->setPort("\\Y", sig[0]);
|
||||
c->setParam("\\Y_WIDTH", 1);
|
||||
c->setPort(ID(Y), sig[0]);
|
||||
c->setParam(ID(Y_WIDTH), 1);
|
||||
sig.remove(0);
|
||||
module->connect(sig, Const(0, GetSize(sig)));
|
||||
}
|
||||
}
|
||||
|
||||
if (c->type.in("$div", "$mod", "$pow"))
|
||||
if (c->type.in(ID($div), ID($mod), ID($pow)))
|
||||
{
|
||||
SigSpec A = c->getPort("\\A");
|
||||
SigSpec A = c->getPort(ID(A));
|
||||
int original_a_width = GetSize(A);
|
||||
if (c->getParam("\\A_SIGNED").as_bool()) {
|
||||
if (c->getParam(ID(A_SIGNED)).as_bool()) {
|
||||
while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0)
|
||||
A.remove(GetSize(A)-1, 1);
|
||||
} else {
|
||||
|
@ -554,13 +554,13 @@ struct WreducePass : public Pass {
|
|||
if (original_a_width != GetSize(A)) {
|
||||
log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n",
|
||||
original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type));
|
||||
c->setPort("\\A", A);
|
||||
c->setParam("\\A_WIDTH", GetSize(A));
|
||||
c->setPort(ID(A), A);
|
||||
c->setParam(ID(A_WIDTH), GetSize(A));
|
||||
}
|
||||
|
||||
SigSpec B = c->getPort("\\B");
|
||||
SigSpec B = c->getPort(ID(B));
|
||||
int original_b_width = GetSize(B);
|
||||
if (c->getParam("\\B_SIGNED").as_bool()) {
|
||||
if (c->getParam(ID(B_SIGNED)).as_bool()) {
|
||||
while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0)
|
||||
B.remove(GetSize(B)-1, 1);
|
||||
} else {
|
||||
|
@ -570,24 +570,24 @@ struct WreducePass : public Pass {
|
|||
if (original_b_width != GetSize(B)) {
|
||||
log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n",
|
||||
original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type));
|
||||
c->setPort("\\B", B);
|
||||
c->setParam("\\B_WIDTH", GetSize(B));
|
||||
c->setPort(ID(B), B);
|
||||
c->setParam(ID(B_WIDTH), GetSize(B));
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt_memx && c->type.in("$memrd", "$memwr", "$meminit")) {
|
||||
IdString memid = c->getParam("\\MEMID").decode_string();
|
||||
if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
|
||||
IdString memid = c->getParam(ID(MEMID)).decode_string();
|
||||
RTLIL::Memory *mem = module->memories.at(memid);
|
||||
if (mem->start_offset >= 0) {
|
||||
int cur_addrbits = c->getParam("\\ABITS").as_int();
|
||||
int cur_addrbits = c->getParam(ID(ABITS)).as_int();
|
||||
int max_addrbits = ceil_log2(mem->start_offset + mem->size);
|
||||
if (cur_addrbits > max_addrbits) {
|
||||
log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n",
|
||||
cur_addrbits-max_addrbits, cur_addrbits,
|
||||
c->type == "$memrd" ? "read" : c->type == "$memwr" ? "write" : "init",
|
||||
c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init",
|
||||
log_id(module), log_id(c), log_id(memid));
|
||||
c->setParam("\\ABITS", max_addrbits);
|
||||
c->setPort("\\ADDR", c->getPort("\\ADDR").extract(0, max_addrbits));
|
||||
c->setParam(ID(ABITS), max_addrbits);
|
||||
c->setPort(ID(ADDR), c->getPort(ID(ADDR)).extract(0, max_addrbits));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue