最近在做一个对同一个RAM访问的 Aribiter,由此想到了一些有关arbiter仲裁方案的思考。下面介绍几种方案,并分析其中的优劣。
方案一:固定优先级轮询
比如我有8个 port 同时向 Aribiter 发送请求,Arbiter的总裁波形有两种情况,如下:
情况一:
情况二:
考虑最 worse 的情况,根据上面冲裁方案(情况一),由于port8的优先级最低,最worse情况如下:
1)当前port1、…port7 同时request,进入仲裁后,下一拍 port8 request 信号拉高;
2)此时port8 request 信号需要 hang 住9拍(方案1)或10拍(方案2);
3) 此时,若其他 port 又可以重新发起request请求,port8 request 信号需要继续hang住。即若每个 port 的下次 request 在7拍以内,就会继续先给其他 port 权限。
从上面最 worse 的情况分析来看,每个 port 的 coner case都不同,应用场景会很复杂,这样就不便于我们去验证这个模块。并且,由于某些优先级高的 port 会持续处于高速繁忙的状态,而芯片在工作时是会放热的,某个port的持续工作会使得芯片的负荷不均,对 port 的寿命影响很大。但是好处是每一拍都可以处理一个来自port的请求,没有时间空闲,处理的效率很高。
方案二:时分复用
从上面的分析来看,采用固定优先级轮询的机制进行仲裁,会使得测试场景变得很复杂,不便于我们分析。为了避免这种复杂场景的构建,我们可以采用时分复用的方式,即固定给每个port一个时间段,这个时间段只处理该 port 的请求。步骤如下:
1)给每个 port 一个全局可见的 toggle 信号,这个信号随 clk 不断地计数加1。有多少个port,这个 toggle 计数器就计到该数后归0。
2)每个 port 要发送请求时,都会查看这个 toggle 的值。
3)当 toggle 的值与 port 对应时,该 port 就会发出一个 request 信号。
4)当 toggle 的值与 port 对应时,该 port 就会 hang 住,等待toggle的值翻转到对应的 port_id ,才会发出一个request信号。
其实通俗一点地说,你们寝室7个人合伙买了台游戏机,星期一我玩 ,星期二张三玩,星期三老四玩,…,星期天宋七万。如果星期一的时候李四游戏瘾来了,想玩游戏,他就必须要苦等到周三才能给他玩。同理,每个人等待玩游戏的概率都是一样的。
使用这种仲裁方式就会使每个人玩游戏的概率都一样,那么换到芯片上,也就是每个 port 的 Corner case 都是一样的,测试的场景就不会那么的复杂。但是也是牺牲了处理效率,因为很多时候 port 需要 hang 住,等到 toggle 计数器的翻转。