SpinalHDL roundRobin注解

了解spinal.lib.OHMasking.roundRobin

  class RoundRobin(n: Int) extends Component{
    val io = new Bundle{
      val req = in Bits(4 bit)
      val pio = in Bits(4 bit)
      val sel = out Bits(4 bit)
    }
    io.sel := OHMasking.roundRobin(io.req, io.pio)
  }

其中 req 为请求,可以是并行的几个同时来, io.pio为优先级选中bit, 只有1bit 有效,全0或者多bit就无意义。从pio第一个比特开始查找高bit为第一个出现的位置作为输出。
所以不同的pio输入会实现不同的调度策略。但是在pio固定的前提下,从低到高环装查询。也就是所谓的RoundRobin调度。

轮询调度

pio一般选择轮询策略,比如7bit的req, pio 从 0b0000001 循环左移即可。

时序仿真:
在这里插入图片描述

权重轮询调度

在一个调度周期内按权重将令牌分给调度器。权重体现在一个大的调度周期内,并不是说单次调度的权重。
比如20个req,4个通道A,B,C,D,安全中分配
A: 10个令牌
B: 5 个令牌
C: 3个令牌
D: 2个令牌

令牌重置条件.
准则:
1: 首先保证带宽不浪费(不能站着茅坑不拉屎)
2: 其次按权重调度

val  tokenReset = !(request & tokens).orR

具体到实际情况就分为以下两种情况:

  • 低权重通道有请求,但没令牌,高权重通道有令牌,但没请求,这是需要令牌重置。
  • 所有通道令牌都消耗完,重置
    在这里插入图片描述
优先级抢占调度
  1. 按优先级通道无脑抢占,导致低优先级饿死
  2. 按优先级通道抢占n次(可配)后释放一次给低优先级,低优先级调度一次后复位高优先级抢占令牌(这样可以保证高优先级不会连续抢占地通道优先级)(权重调度的特殊情况)
  3. 一般化的多通道优先级抢占调度 相当于带权重的令牌调度。
优先级和轮询调度结合

round-ribon算法的好处是所有总线主设备得到总线的机会均等,缺点是对于及时得到总线主设备需要排队,影响系统效率。
而多久优先级算法的有点在于他能够保证优先级设备快速访问总线,但是会造成低优先级设备一直得不到总线的控制权。
为了克服以上两种算法的缺点可以采用两种算法结合,,两组设备内使用RoundRobin算法。组件使用优先级。这样既能保证主设备1,2能够及时得到总线,又能保证低优先级的设备不会失去访问机会。
在这里插入图片描述
在这里插入图片描述
http://www.doc88.com/p-2661096550414.html

总线仲裁

一般总线分为前向命令通道,包括读命令,写命令, 另外还有后向回读数据通道。
前向命令通道通过roundRobin 给出仲裁, 选择其中的master发起命令,并且要在ID fifo中记录到底是哪个命令。到读通道返回的时候把对于master的rdvalid要置位,其他master rdvalid 置无效

在这里插入图片描述

roundRobin 源码

  def roundRobin[T <: Data](requests : T,ohPriority : T) : T = {
    val width = requests.getBitsWidth
    val uRequests = requests.asBits.asUInt
    val uGranted = ohPriority.asBits.asUInt

    val doubleRequests = uRequests @@ uRequests
    val doubleGrant = doubleRequests & ~(doubleRequests-uGranted)
    val masked = doubleGrant(width,width bits) | doubleGrant(0,width bits)

    val ret = cloneOf(requests)
    ret.assignFromBits(masked.asBits)
    ret
  }

RR(roundRobin)算法注解:

    val width = io.request.getBitsWidth
    val uRequests = io.request.asBits.asUInt
    val uGranted = io.ohpriorty.asBits.asUInt

    val doubleRequests = uRequests @@ uRequests        //向上copy 复制,保证低位也能出现在高位置
    val doubleReqCompPrio = (doubleRequests-uGranted)  // 相减,req 和 pio 位置重合,则减掉,否则向上借位
    val reverserDoubleReqCP = ~ doubleReqCompPrio      // bit 翻转
    val doubleGrant = doubleRequests & reverserDoubleReqCP //相与
    val masked = doubleGrant(width,width bits) | doubleGrant(0,width bits) // 上下两半合并,使得借位的位置都回到n比特内

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值