MaskRoundRobinArbiter constructor

MaskRoundRobinArbiter(
  1. List<Logic> requests, {
  2. required Logic clk,
  3. required Logic reset,
})

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]),
      ],
    ),
  ]);
}