aiger2: Ingest `$pmux`

This commit is contained in:
Martin Povišer 2024-09-16 17:20:34 +02:00
parent 9db1ca83fc
commit 6c1fa45995
2 changed files with 68 additions and 1 deletions

View File

@ -42,7 +42,7 @@ PRIVATE_NAMESPACE_BEGIN
// TODO
//#define ARITH_OPS ID($add), ID($sub), ID($neg)
#define KNOWN_OPS BITWISE_OPS, REDUCE_OPS, LOGIC_OPS, GATE_OPS, ID($pos), CMP_OPS /*, ARITH_OPS*/
#define KNOWN_OPS BITWISE_OPS, REDUCE_OPS, LOGIC_OPS, GATE_OPS, ID($pos), CMP_OPS, ID($pmux) /*, ARITH_OPS*/
template<typename Writer, typename Lit>
struct Index {
@ -199,6 +199,28 @@ struct Index {
return OR(AND(a, b), AND(c, OR(a, b)));
}
Lit REDUCE(std::vector<Lit> lits, bool op_xor=false)
{
std::vector<Lit> next;
while (lits.size() > 1) {
next.clear();
for (int i = 0; i < lits.size(); i += 2) {
if (i + 1 >= lits.size()) {
next.push_back(lits[i]);
} else {
Lit a = lits[i], b = lits[i + 1];
next.push_back(op_xor ? XOR(a, b) : AND(a, b));
}
}
next.swap(lits);
}
if (lits.empty())
return op_xor ? CFALSE : CTRUE;
else
return lits.front();
}
Lit impl_op(HierCursor &cursor, Cell *cell, IdString oport, int obit)
{
if (cell->type.in(REDUCE_OPS, LOGIC_OPS, CMP_OPS) && obit != 0) {
@ -360,6 +382,23 @@ struct Index {
log_abort();
}
}
} else if (cell->type == ID($pmux)) {
SigSpec aport = cell->getPort(ID::A);
SigSpec bport = cell->getPort(ID::B);
SigSpec sport = cell->getPort(ID::S);
int width = aport.size();
Lit a = visit(cursor, aport[obit]);
std::vector<Lit> bar, sels;
for (int i = 0; i < sport.size(); i++) {
Lit s = visit(cursor, sport[i]);
Lit b = visit(cursor, bport[width * i + obit]);
bar.push_back(NOT(AND(s, b)));
sels.push_back(NOT(s));
}
return OR(AND(REDUCE(sels), a), NOT(REDUCE(bar)));
} else {
log_abort();
}

View File

@ -165,3 +165,31 @@ read_aiger -module_name test aiger2_ops.aig
select -assert-none test/t:$_AND_ test/t:$_NOT_ %% test/c:* %D
miter -equiv -flatten gold test miter
sat -verify -prove trigger 0 miter
design -reset
read_verilog -icells <<EOF
module test();
wire [1:0] pmux_a, pmux_s, pmux_y;
wire [3:0] pmux_b;
\$pmux #(
.S_WIDTH(2),
.WIDTH(2)
) pmux(.A(pmux_a), .B(pmux_b), .S(pmux_s), .Y(pmux_y));
endmodule
EOF
expose -input c:* %ci* w:* %i
expose c:* %co* w:* %i
splitnets -ports
opt_clean
copy test gold
select test
write_aiger2 aiger2_xmodel.aig
select -clear
delete test
read_aiger -module_name test aiger2_xmodel.aig
select -assert-none test/t:$_AND_ test/t:$_NOT_ %% test/c:* %D
equiv_make gold test equiv
equiv_induct -undef equiv
equiv_status -assert equiv