mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
aiger2: Ingest $pmux
This commit is contained in:
parent
9db1ca83fc
commit
6c1fa45995
|
@ -42,7 +42,7 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
// TODO
|
// TODO
|
||||||
//#define ARITH_OPS ID($add), ID($sub), ID($neg)
|
//#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>
|
template<typename Writer, typename Lit>
|
||||||
struct Index {
|
struct Index {
|
||||||
|
@ -199,6 +199,28 @@ struct Index {
|
||||||
return OR(AND(a, b), AND(c, OR(a, b)));
|
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)
|
Lit impl_op(HierCursor &cursor, Cell *cell, IdString oport, int obit)
|
||||||
{
|
{
|
||||||
if (cell->type.in(REDUCE_OPS, LOGIC_OPS, CMP_OPS) && obit != 0) {
|
if (cell->type.in(REDUCE_OPS, LOGIC_OPS, CMP_OPS) && obit != 0) {
|
||||||
|
@ -360,6 +382,23 @@ struct Index {
|
||||||
log_abort();
|
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 {
|
} else {
|
||||||
log_abort();
|
log_abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,3 +165,31 @@ read_aiger -module_name test aiger2_ops.aig
|
||||||
select -assert-none test/t:$_AND_ test/t:$_NOT_ %% test/c:* %D
|
select -assert-none test/t:$_AND_ test/t:$_NOT_ %% test/c:* %D
|
||||||
miter -equiv -flatten gold test miter
|
miter -equiv -flatten gold test miter
|
||||||
sat -verify -prove trigger 0 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
|
||||||
|
|
Loading…
Reference in a new issue