仲裁器
(1)固定优先级仲裁
- 题目描述:请使用Verilog语言,考虑三个主设备,设计固定优先级仲裁器,该仲裁器默认时的总线控制的优先级永远保持为为A>B>C。如果有两个模块同时产生request,那么优先级高的模块可以获得grant。假设有三个模块分别为CBA,用3-bit 的request表示它们的请求,令越低的位优先级越高,即当request = 3’b111时,A优先级最高,所以grant=3’b001,将总线控制权交给模块A。
- 分析:从低位往高位看,只要看到1,就将grant给该位,其他高位不看。
- verilog
方法一:casex语句
module round_robin_arb(
input[2:0] request,
output[2:0] grant
);
always@(*)begin
casex(request)
3'bxx1: grant = 3'b001;
3'bx10: grant = 3'b010;
3'b100: grant = 3'b100;
default: grant = 3'b000;
endcase
end
endmodule
方法二:补码相与法
- 注意: 一个数和它的补码相与,得到的结果是一个独热码,独热码为1的那一位是这个数最低的1
- 仿真结果
(2)循环优先级仲裁
题目描述:使用Verilog语言,完成轮询仲裁器,其中输入端为4-bit的request,输出端为4-bit的独热码grant(独热码意味着只存在4种grant的结果如下1000,0100,0010,0001),默认时总线优先级为A>B>C>D,其中的ABCD分别代表request[0],request[1],request[2],request[3],即从低到高依次排列,根据轮询算法,当其中的某一位被选中后,它在下一次request到来时它的优先级最低(3),而它左边的相邻位优先级变为最高(0),从左边相邻位至最高位,优先级依次降低,回旋至最低位,此为轮询算法。
- 推广:若有N个request,则当第i个获得仲裁,则优先级排列如下:
(i+1)>(i+2)>...>(N-1)>0>1...>(i-1)>i
分析:可见,优先级是不断变化的且收到上一次仲裁结果grant的影响。可以采取以下步骤:
- ①先根据上一下grant的值和本次request的值得到新的shift_req的值(即将真正要仲裁的位移到最低位);
- ②再采用固定优先级仲裁中补码相与法,根据shift_req的值得到一个prio_grant(此时的prio_grant并不是真正的grant);
- ③根据grant和prio_grant的值计算出shift_len,即真正仲裁的位置;
- ④根据shift_len的值给出grant;
-
verilog
-
仿真结果