MaskRoundRobinArbiter constructor
Round Robin arbiter handles requests by granting each requestor and keeping record of requests already granted, in order to mask it until granting the turn of each request to start again
Implementation
MaskRoundRobinArbiter(super.requests,
{required super.clk, required super.reset}) {
_requestMask = List.generate(count, (i) => Logic(name: 'requestMask$i'));
_grantMask = List.generate(count, (i) => Logic(name: 'grantMask$i'));
Sequential(clk, [
If(reset, then: [
for (var g = 0; g < count; g++) _requestMask[g] < 1,
], orElse: [
// Use [_grants] to turn the bit granted to 0 along with all bits
// to the right to avoid, in case if [_requests] changes, granting a
// previous request
// Example:
// [_grants] [requestMask]
// 00001000 11110000
Case(grants.rswizzle(), conditionalType: ConditionalType.unique, [
for (var i = 0; i < count; i++)
CaseItem(
Const(LogicValue.filled(count, LogicValue.zero)
.withSet(i, LogicValue.one)),
[
for (var g = 0; g < count; g++)
_requestMask[g] < (i < g ? 1 : 0),
])
// In case [_grants] are all 0s, requestMask gets a reset
], defaultItem: [
// leave request mask as-is if there was no grant
])
])
]);
Combinational([
for (var g = 0; g < count; g++)
_grantMask[g] < _requestMask[g] & requests[g],
// CaseZ uses [_grantMask] to set the [_grants] based on the
// least significant bit
CaseZ(
_grantMask.rswizzle(), conditionalType: ConditionalType.priority,
[
for (var i = 0; i < count; i++)
CaseItem(
Const(LogicValue.filled(count, LogicValue.z)
.withSet(i, LogicValue.one)),
[
for (var g = 0; g < count; g++) grants[g] < (i == g ? 1 : 0),
]),
],
// When all bits have been granted, [_grantMask] turns all to 0s because
// of the [_requestMask], therefore logic to define next [_grants]
// relies on [_request] least significant bit
defaultItem: [
for (var g = 0; g < count; g++)
grants[g] <
(g == 0
? requests[g]
: ~requests.rswizzle().getRange(0, g).or() & requests[g]),
],
),
]);
}