RecursiveModulePriorityEncoderNode constructor
Construct the Node for a Recursive Priority Tree.
Implementation
RecursiveModulePriorityEncoderNode(
Logic seq, {
super.name = 'priority_encode_node',
int depth = 0,
super.reserveName,
super.reserveDefinitionName,
String? definitionName,
}) : super(
definitionName:
definitionName ?? 'PriorityEncodeNode_W${seq.width}') {
seq = addInput('seq', seq, width: seq.width);
if (seq.width == 1) {
addOutput('ret') <= ~seq[0];
} else if (seq.width == 2) {
final l = seq[0].named('leftLeafLead');
final r = seq[1].named('rightLeafLead');
addOutput('ret', width: 2);
Combinational([
If.block([
Iff(l, [
ret < Const(0, width: 2),
]),
ElseIf(r, [
ret < [Const(0), Const(1)].swizzle(),
]),
Else([
ret < [Const(1), Const(0)].swizzle(),
]),
]),
]);
} else {
final divisor = (log(seq.width - 1) / log(2)).floor();
final split = pow(2.0, divisor).toInt();
final left = RecursiveModulePriorityEncoderNode(seq.getRange(0, split),
name: 'left', depth: depth + 1)
.ret;
var right = RecursiveModulePriorityEncoderNode(
seq.getRange(split, seq.width),
name: 'right',
depth: depth + 1)
.ret;
if (right.width < left.width) {
right = right.zeroExtend(left.width);
}
final l = left[-1].named('leftLead');
final r = right[-1].named('rightLead');
addOutput('ret', width: right.width + 1);
final rhs = ((right.width > 1)
? [Const(0), Const(1), right.slice(-2, 0)]
.swizzle()
.named('zo_right')
: [Const(0), Const(1)].swizzle().named('zo'))
.named('rhs');
Combinational([
If.block([
Iff(l & r, [
ret <
[Const(1), Const(0, width: right.width)].swizzle().named('lr'),
]),
ElseIf(~l, [
ret < [Const(0), left.slice(-1, 0)].swizzle().named('zl'),
]),
Else([
ret < rhs,
]),
]),
]);
}
}