本文主要介绍【verilog仲裁器设计】和【】,有兴趣的朋友可以看下由【闲庭信步sss】投稿的技术文章,希望该技术和经验能帮到你解决你所遇的相关问题。
本篇文章转载自仲裁器设计
仲裁器介绍仲裁器Arbiter是数字设计中非常常见的模块,应用也非常广泛。定义就是当有两个或两个以上的模块需要占用同一个资源的时候,我们需要由仲裁器arbiter来决定哪一个模块来占有这个资源。一般来说,提出占有资源的模块要产生一个请求(request),所有的请求送给仲裁器之后,仲裁器要返回一个许可(grant)。
仲裁器很重要的一点是只能让一个模块得到许可,因为这个资源某一时刻只能由一个模块占用。在数字电路中,总线仲裁是一个常见的例子,比如多个master要占用总线来去写数据,那么需要仲裁器来许可哪个master来占用总线。
固定优先级仲裁器(fixed priority)固定优先级,顾名思义,就是说每个模块的优先级是固定的,是提前分配好的,如果有两个模块同时产生request,那么优先级高的模块可以获得grant。
回到仲裁器本身,如果我们要设计一个fixed priority arbiter,输入是一个multibit request,每一个bit代表一个模块的request, 输出一个multibit grant,每个bit代表给对应的模块的grant信号。我们可以把优先级这样安排,最低位优先级最高,最高位优先级最低。
我们先以3个模块产生request为例,大家一般在面试的时候都会碰到给定模块数目,比如3,让你设计。咱们就直接上code来表示一种写法:
module fixed_pri_arb(
input [2:0] req;
output reg [2:0] grant
);
always@(*)begin
case(1'b1)
req[0]:grant = 3'b001;
req[1]:grant = 3'b010;
req[2]:grant = 3'b100;
default: grant = 3'b000;
endcase
end
endmodule
这里的技巧是利用verilog中的case语句,可以比用if else简洁,而且利用了case里的按顺序evaluate语法规则来实现了优先级。
那如何设计有个参数化的模块呢。
因为参数化的话,不能使用case语句,因此首先想到的是for循环语句。
思路其实非常直接,从低位到高位依次去判断,借助一个pre_req来记录低位是否已经有了request, 如果第i位有了request,那么第i+1位一直到最高位的pre_req都是1。
pre_req是为了记录低位是否已经有了request,例如当pre_req[4]=1时,即说明req的低五位已经有了request,即此时grant[5] = 0;
module fixed_pri_arb#(
parameter REQ_WIDTH = 16)
(
input [ REQ_WIDTH-1:0] req;
output reg [ REQ_WIDTH-1:0] grant
);
reg [REQ_WIDTH-1] pre_req;//为了记录低位是否已经有了request。
always@(*)begin
pre_req[0] = req[0];
gtant = req[0];
for(int i = 1;i
版权声明:本文来源于网络,如有侵权请E-mail联系 ufidawhy 站长 ufidawhy@vip.qq.com!