Use ID() macro

This commit is contained in:
Eddie Hung 2019-08-16 14:01:55 -07:00
parent a29814ca3f
commit 3d3779b037
1 changed files with 110 additions and 118 deletions

View File

@ -83,52 +83,51 @@ struct ExtSigSpec {
bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; } bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; }
}; };
#define BITWISE_OPS "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$and", "$or", "$xor", "$xnor" #define BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor)
#define REDUCTION_OPS "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$reduce_nand" #define REDUCTION_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($reduce_nand)
#define LOGICAL_OPS "$logic_and", "$logic_or" #define LOGICAL_OPS ID($logic_and), ID($logic_or)
#define SHIFT_OPS "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx" #define SHIFT_OPS ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)
#define RELATIONAL_OPS "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt" #define RELATIONAL_OPS ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)
bool cell_supported(RTLIL::Cell *cell) bool cell_supported(RTLIL::Cell *cell)
{ {
if (cell->type.in(ID($alu))) {
if (cell->type.in("$alu")) { RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
RTLIL::SigSpec sig_ci = cell->getPort("\\CI");
if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci) if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci)
return true; return true;
} else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, "$add", "$sub", "$mul", "$div", "$mod", "$concat")) { } else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($concat))) {
return true; return true;
} }
return false; return false;
} }
std::map<std::string, std::string> mergeable_type_map{ std::map<IdString, IdString> mergeable_type_map{
{"$sub", "$add"}, {ID($sub), ID($add)},
}; };
bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b)
{ {
auto a_type = a->type; auto a_type = a->type;
if (mergeable_type_map.count(a_type.str())) if (mergeable_type_map.count(a_type))
a_type = mergeable_type_map.at(a_type.str()); a_type = mergeable_type_map.at(a_type);
auto b_type = b->type; auto b_type = b->type;
if (mergeable_type_map.count(b_type.str())) if (mergeable_type_map.count(b_type))
b_type = mergeable_type_map.at(b_type.str()); b_type = mergeable_type_map.at(b_type);
return a_type == b_type; return a_type == b_type;
} }
RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name) RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name)
{ {
if (cell->type.in("$lt", "$le", "$ge", "$gt", "$div", "$mod", "$concat", SHIFT_OPS) && port_name == "\\B") if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID(B))
return port_name; return port_name;
return ""; return "";
@ -136,9 +135,9 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na
RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) {
if (cell->type == "$alu" && port_name == "\\B") if (cell->type == ID($alu) && port_name == ID(B))
return cell->getPort("\\BI"); return cell->getPort(ID(BI));
else if (cell->type == "$sub" && port_name == "\\B") else if (cell->type == ID($sub) && port_name == ID(B))
return RTLIL::Const(1, 1); return RTLIL::Const(1, 1);
return RTLIL::Const(0, 1); return RTLIL::Const(0, 1);
@ -153,7 +152,6 @@ bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name)
return cell->getParam(port_name.str() + "_SIGNED").as_bool(); return cell->getParam(port_name.str() + "_SIGNED").as_bool();
return false; return false;
} }
ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap)
@ -170,15 +168,14 @@ ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sig
void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<OpMuxConn> &ports, const ExtSigSpec &operand) void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<OpMuxConn> &ports, const ExtSigSpec &operand)
{ {
std::vector<ExtSigSpec> muxed_operands; std::vector<ExtSigSpec> muxed_operands;
int max_width = 0; int max_width = 0;
for (const auto& p : ports) { for (const auto& p : ports) {
auto op = p.op; auto op = p.op;
RTLIL::IdString muxed_port_name = "\\A"; RTLIL::IdString muxed_port_name = ID(A);
if (decode_port(op, "\\A", &assign_map) == operand) if (decode_port(op, ID(A), &assign_map) == operand)
muxed_port_name = "\\B"; muxed_port_name = ID(B);
auto operand = decode_port(op, muxed_port_name, &assign_map); auto operand = decode_port(op, muxed_port_name, &assign_map);
if (operand.sig.size() > max_width) if (operand.sig.size() > max_width)
@ -190,8 +187,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
auto shared_op = ports[0].op; auto shared_op = ports[0].op;
if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; })) if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; }))
if (max_width < shared_op->getParam("\\Y_WIDTH").as_int()) max_width = std::max(max_width, shared_op->getParam(ID(Y_WIDTH)).as_int());
max_width = shared_op->getParam("\\Y_WIDTH").as_int();
for (auto &operand : muxed_operands) for (auto &operand : muxed_operands)
@ -208,11 +204,10 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
if (muxed_op.sign != muxed_operands[0].sign) if (muxed_op.sign != muxed_operands[0].sign)
muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed));
RTLIL::SigSpec mux_y = mux->getPort(ID(Y));
RTLIL::SigSpec mux_y = mux->getPort("\\Y"); RTLIL::SigSpec mux_a = mux->getPort(ID(A));
RTLIL::SigSpec mux_a = mux->getPort("\\A"); RTLIL::SigSpec mux_b = mux->getPort(ID(B));
RTLIL::SigSpec mux_b = mux->getPort("\\B"); RTLIL::SigSpec mux_s = mux->getPort(ID(S));
RTLIL::SigSpec mux_s = mux->getPort("\\S");
RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width);
RTLIL::SigSpec shared_pmux_b; RTLIL::SigSpec shared_pmux_b;
@ -221,49 +216,48 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
int conn_width = ports[0].sig.size(); int conn_width = ports[0].sig.size();
int conn_offset = ports[0].mux_port_offset; int conn_offset = ports[0].mux_port_offset;
shared_op->setPort("\\Y", shared_op->getPort("\\Y").extract(0, conn_width)); shared_op->setPort(ID(Y), shared_op->getPort(ID(Y)).extract(0, conn_width));
if (mux->type == "$pmux") { if (mux->type == ID($pmux)) {
shared_pmux_s = RTLIL::SigSpec(); shared_pmux_s = RTLIL::SigSpec();
for (const auto &p : ports) { for (const auto &p : ports) {
shared_pmux_s.append(mux_s[p.mux_port_id]); shared_pmux_s.append(mux_s[p.mux_port_id]);
mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort("\\Y")); mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID(Y)));
} }
} else { } else {
shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)};
mux_a.replace(conn_offset, shared_op->getPort("\\Y")); mux_a.replace(conn_offset, shared_op->getPort(ID(Y)));
mux_b.replace(conn_offset, shared_op->getPort("\\Y")); mux_b.replace(conn_offset, shared_op->getPort(ID(Y)));
} }
mux->setPort("\\A", mux_a); mux->setPort(ID(A), mux_a);
mux->setPort("\\B", mux_b); mux->setPort(ID(B), mux_b);
mux->setPort("\\Y", mux_y); mux->setPort(ID(Y), mux_y);
mux->setPort("\\S", mux_s); mux->setPort(ID(S), mux_s);
for (const auto &op : muxed_operands) for (const auto &op : muxed_operands)
shared_pmux_b.append(op.sig); shared_pmux_b.append(op.sig);
auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s);
if (shared_op->type.in("$alu")) { if (shared_op->type.in(ID($alu))) {
RTLIL::SigSpec alu_x = shared_op->getPort("\\X"); RTLIL::SigSpec alu_x = shared_op->getPort(ID(X));
RTLIL::SigSpec alu_co = shared_op->getPort("\\CO"); RTLIL::SigSpec alu_co = shared_op->getPort(ID(CO));
shared_op->setPort("\\X", alu_x.extract(0, conn_width)); shared_op->setPort(ID(X), alu_x.extract(0, conn_width));
shared_op->setPort("\\CO", alu_co.extract(0, conn_width)); shared_op->setPort(ID(CO), alu_co.extract(0, conn_width));
} }
shared_op->setParam("\\Y_WIDTH", conn_width); shared_op->setParam(ID(Y_WIDTH), conn_width);
if (decode_port(shared_op, "\\A", &assign_map) == operand) { if (decode_port(shared_op, ID(A), &assign_map) == operand) {
shared_op->setPort("\\B", mux_to_oper); shared_op->setPort(ID(B), mux_to_oper);
shared_op->setParam("\\B_WIDTH", max_width); shared_op->setParam(ID(B_WIDTH), max_width);
} else { } else {
shared_op->setPort("\\A", mux_to_oper); shared_op->setPort(ID(A), mux_to_oper);
shared_op->setParam("\\A_WIDTH", max_width); shared_op->setParam(ID(A_WIDTH), max_width);
} }
} }
typedef struct { typedef struct {
@ -285,7 +279,6 @@ template <typename T> void remove_val(std::vector<T> &v, const std::vector<T> &v
void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpec &shared_operand) void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpec &shared_operand)
{ {
auto it = ports.begin(); auto it = ports.begin();
ExtSigSpec seed; ExtSigSpec seed;
@ -293,9 +286,9 @@ void check_muxed_operands(std::vector<const OpMuxConn *> &ports, const ExtSigSpe
auto p = *it; auto p = *it;
auto op = p->op; auto op = p->op;
RTLIL::IdString muxed_port_name = "\\A"; RTLIL::IdString muxed_port_name = ID(A);
if (decode_port(op, "\\A", &assign_map) == shared_operand) { if (decode_port(op, ID(A), &assign_map) == shared_operand) {
muxed_port_name = "\\B"; muxed_port_name = ID(B);
} }
auto operand = decode_port(op, muxed_port_name, &assign_map); auto operand = decode_port(op, muxed_port_name, &assign_map);
@ -322,7 +315,7 @@ ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector<const OpMuxCon
auto op_a = seed->op; auto op_a = seed->op;
for (RTLIL::IdString port_name : {"\\A", "\\B"}) { for (RTLIL::IdString port_name : {ID(A), ID(B)}) {
oper = decode_port(op_a, port_name, &assign_map); oper = decode_port(op_a, port_name, &assign_map);
auto operand_users = operand_to_users.at(oper); auto operand_users = operand_to_users.at(oper);
@ -362,24 +355,23 @@ dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, d
std::function<void(RTLIL::SigBit)> remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) { std::function<void(RTLIL::SigBit)> remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) {
auto aux_outsig = op_aux_to_outsig.at(auxbit); auto aux_outsig = op_aux_to_outsig.at(auxbit);
auto op = outsig_to_operator.at(aux_outsig); auto op = outsig_to_operator.at(aux_outsig);
auto op_outsig = assign_map(op->getPort("\\Y")); auto op_outsig = assign_map(op->getPort(ID(Y)));
remove_outsig(op_outsig); remove_outsig(op_outsig);
for (auto aux_outbit : aux_outsig) for (auto aux_outbit : aux_outsig)
op_aux_to_outsig.erase(aux_outbit); op_aux_to_outsig.erase(aux_outbit);
}; };
std::function<void(RTLIL::Cell *)> std::function<void(RTLIL::Cell *)> find_op_mux_conns = [&](RTLIL::Cell *mux) {
find_op_mux_conns = [&](RTLIL::Cell *mux) {
RTLIL::SigSpec sig; RTLIL::SigSpec sig;
int mux_port_size; int mux_port_size;
if (mux->type.in("$mux", "$_MUX_")) { if (mux->type.in(ID($mux), ID($_MUX_))) {
mux_port_size = mux->getPort("\\A").size(); mux_port_size = mux->getPort(ID(A)).size();
sig = RTLIL::SigSpec{mux->getPort("\\B"), mux->getPort("\\A")}; sig = RTLIL::SigSpec{mux->getPort(ID(B)), mux->getPort(ID(A))};
} else { } else {
mux_port_size = mux->getPort("\\A").size(); mux_port_size = mux->getPort(ID(A)).size();
sig = mux->getPort("\\B"); sig = mux->getPort(ID(B));
} }
auto mux_insig = assign_map(sig); auto mux_insig = assign_map(sig);
@ -451,8 +443,8 @@ dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, d
}; };
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (cell->type.in("$mux", "$_MUX_", "$pmux")) { if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) {
remove_connected_ops(cell->getPort("\\S")); remove_connected_ops(cell->getPort(ID(S)));
find_op_mux_conns(cell); find_op_mux_conns(cell);
} else { } else {
for (auto &conn : cell->connections()) for (auto &conn : cell->connections())
@ -509,8 +501,8 @@ struct OptSharePass : public Pass {
if (!cell_supported(cell)) if (!cell_supported(cell))
continue; continue;
if (cell->type == "$alu") { if (cell->type == ID($alu)) {
for (RTLIL::IdString port_name : {"\\X", "\\CO"}) { for (RTLIL::IdString port_name : {ID(X), ID(CO)}) {
auto mux_insig = assign_map(cell->getPort(port_name)); auto mux_insig = assign_map(cell->getPort(port_name));
outsig_to_operator[mux_insig] = cell; outsig_to_operator[mux_insig] = cell;
for (auto outbit : mux_insig) for (auto outbit : mux_insig)
@ -518,12 +510,12 @@ struct OptSharePass : public Pass {
} }
} }
auto mux_insig = assign_map(cell->getPort("\\Y")); auto mux_insig = assign_map(cell->getPort(ID(Y)));
outsig_to_operator[mux_insig] = cell; outsig_to_operator[mux_insig] = cell;
for (auto outbit : mux_insig) for (auto outbit : mux_insig)
op_outbit_to_outsig[outbit] = mux_insig; op_outbit_to_outsig[outbit] = mux_insig;
for (RTLIL::IdString port_name : {"\\A", "\\B"}) { for (RTLIL::IdString port_name : {ID(A), ID(B)}) {
auto op_insig = decode_port(cell, port_name, &assign_map); auto op_insig = decode_port(cell, port_name, &assign_map);
op_insigs.push_back(op_insig); op_insigs.push_back(op_insig);
operand_to_users[op_insig].insert(cell); operand_to_users[op_insig].insert(cell);
@ -549,10 +541,10 @@ struct OptSharePass : public Pass {
if (mux_port_conns.size() == 0) { if (mux_port_conns.size() == 0) {
int mux_port_num; int mux_port_num;
if (p.mux->type.in("$mux", "$_MUX_")) if (p.mux->type.in(ID($mux), ID($_MUX_)))
mux_port_num = 2; mux_port_num = 2;
else else
mux_port_num = p.mux->getPort("\\S").size(); mux_port_num = p.mux->getPort(ID(S)).size();
mux_port_conns.resize(mux_port_num); mux_port_conns.resize(mux_port_num);
} }