mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-29 07:27:58 +00:00
Add pmgen slices and choices
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
fe1b2337fd
commit
adb81ba386
5 changed files with 277 additions and 28 deletions
|
@ -60,8 +60,8 @@ code portname
|
|||
endcode
|
||||
|
||||
match next
|
||||
select nusers(port(next, \Y)) == 2
|
||||
select next->type.in($_AND_, $_OR_, $_XOR_)
|
||||
select nusers(port(next, \Y)) == 2
|
||||
index <IdString> next->type === first->type
|
||||
index <SigSpec> port(next, \Y) === port(first, portname)
|
||||
endmatch
|
||||
|
@ -77,8 +77,8 @@ arg first
|
|||
|
||||
match next
|
||||
semioptional
|
||||
select nusers(port(next, \Y)) == 2
|
||||
select next->type.in($_AND_, $_OR_, $_XOR_)
|
||||
select nusers(port(next, \Y)) == 2
|
||||
index <IdString> next->type === chain.back().first->type
|
||||
index <SigSpec> port(next, \Y) === port(chain.back().first, chain.back().second)
|
||||
generate 10
|
||||
|
@ -104,3 +104,86 @@ finally
|
|||
if (next)
|
||||
chain.pop_back();
|
||||
endcode
|
||||
|
||||
// ==================================================================
|
||||
|
||||
pattern eqpmux
|
||||
|
||||
state <bool> eq_ne_signed
|
||||
state <SigSpec> eq_inA eq_inB
|
||||
state <int> pmux_slice_eq pmux_slice_ne
|
||||
|
||||
match eq
|
||||
select eq->type == $eq
|
||||
choice <IdString> AB {\A, \B}
|
||||
define <IdString> BA AB == \A ? \B : \A
|
||||
set eq_inA port(eq, \A)
|
||||
set eq_inB port(eq, \B)
|
||||
set eq_ne_signed param(eq, \A_SIGNED).as_bool()
|
||||
generate 100 10
|
||||
SigSpec A = module->addWire(NEW_ID, rng(7)+1);
|
||||
SigSpec B = module->addWire(NEW_ID, rng(7)+1);
|
||||
SigSpec Y = module->addWire(NEW_ID);
|
||||
module->addEq(NEW_ID, A, B, Y, rng(2));
|
||||
endmatch
|
||||
|
||||
match pmux
|
||||
select pmux->type == $pmux
|
||||
slice idx GetSize(port(pmux, \S))
|
||||
index <SigBit> port(pmux, \S)[idx] === port(eq, \Y)
|
||||
set pmux_slice_eq idx
|
||||
generate 100 10
|
||||
int width = rng(7) + 1;
|
||||
int numsel = rng(4) + 1;
|
||||
int idx = rng(numsel);
|
||||
|
||||
SigSpec A = module->addWire(NEW_ID, width);
|
||||
SigSpec Y = module->addWire(NEW_ID, width);
|
||||
|
||||
SigSpec B, S;
|
||||
for (int i = 0; i < numsel; i++) {
|
||||
B.append(module->addWire(NEW_ID, width));
|
||||
S.append(i == idx ? port(eq, \Y) : module->addWire(NEW_ID));
|
||||
}
|
||||
|
||||
module->addPmux(NEW_ID, A, B, S, Y);
|
||||
endmatch
|
||||
|
||||
match ne
|
||||
select ne->type == $ne
|
||||
choice <IdString> AB {\A, \B}
|
||||
define <IdString> BA (AB == \A ? \B : \A)
|
||||
index <SigSpec> port(ne, AB) === eq_inA
|
||||
index <SigSpec> port(ne, BA) === eq_inB
|
||||
index <int> param(ne, \A_SIGNED).as_bool() === eq_ne_signed
|
||||
generate 100 10
|
||||
SigSpec A = eq_inA, B = eq_inB, Y;
|
||||
if (rng(2)) {
|
||||
std::swap(A, B);
|
||||
}
|
||||
if (rng(2)) {
|
||||
for (auto bit : port(pmux, \S)) {
|
||||
if (nusers(bit) < 2)
|
||||
Y.append(bit);
|
||||
}
|
||||
if (GetSize(Y))
|
||||
Y = Y[rng(GetSize(Y))];
|
||||
else
|
||||
Y = module->addWire(NEW_ID);
|
||||
} else {
|
||||
Y = module->addWire(NEW_ID);
|
||||
}
|
||||
module->addNe(NEW_ID, A, B, Y, rng(2));
|
||||
endmatch
|
||||
|
||||
match pmux2
|
||||
select pmux2->type == $pmux
|
||||
slice idx GetSize(port(pmux2, \S))
|
||||
index <Cell*> pmux2 === pmux
|
||||
index <SigBit> port(pmux2, \S)[idx] === port(ne, \Y)
|
||||
set pmux_slice_ne idx
|
||||
endmatch
|
||||
|
||||
code
|
||||
accept;
|
||||
endcode
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue