固定优先级仲裁器设计

前言

仲裁器Arbiter是数字设计中非常常见的模块,应用也非常广泛。定义就是当有两个或两个以上的模块需要占用同一个资源的时候,我们需要由仲裁器arbiter来决定哪一个模块来占有这个资源。一般来说,提出占有资源的模块要产生一个请求(request),所有的请求送给仲裁器之后,仲裁器要返回一个许可(grant)。

固定优先级仲裁器(fixed priority)

固定优先级,每个模块的优先级是固定的,是提前分配好的,如果有两个模块同时产生request,那么优先级高的模块可以获得grant。假设有三个模块分别为CBA,用3bit 的request表示它们的请求,令越低的位优先级越高,即当request = 3'b011时,A优先级最高,所以grant=3'b001,将总线控制权交给模块A。

1.casex语句的固定优先仲裁

可以使用casex语句,来进行固定优先级仲裁,verilog代码如下:

1.1代码

module fixed_arbiter(
    input              rstn    ,
    input              clk     ,
    input      [2:0]   request ,
    
    output reg [2:0]   grant
);

always @(posedge clk)begin
    if(!rstn)begin
        grant <= 3'b000;
    end 
    else begin
        casex(request)
            3'b??1: grant <= 3'b001;
            3'b?10: grant <= 3'b010;
            3'b100: grant <= 3'b100;
            default: grant <= 3'b000;
        endcase
    end
end

endmodule

casez语句和case语句的用法非常相似,其唯一的区别在于,状态z在casez语句中不会被视为正常的z状态,而是将表达式中,标记为z的那个(或那些)bit视为不在乎(dont care)。casex语句和casez语句的用法非常相似,其唯一的区别在于,casex可以同时将状态x和状态z均视为不在乎(dont care)。

正如上面的代码,当最低位为1时,不在乎前2bit是什么,只要最低位为1,那么就给grant赋值3'b001.

1.2testbench

module fixed_arbiter_tb();

reg clk, rstn;
wire [2:0] grant;

reg [2:0] request;
initial begin
    forever #5 clk <= ~clk;
end
initial begin
    clk  <= 1'b0;
    rstn <= 1'b0;
    #15
    rstn <= 1'b1;
    request <= 3'b110;
    #10
    request <= #1 3'b011;
    #10
    request <= #1 3'b111;
    #10
    request <= #1 3'b010;
    #50
    $finish();
end

fixed_arbiter u_fixed_arbiter(
    .clk        (clk)       ,
    .rstn       (rstn)      ,
    .request    (request)   ,
    .grant      (grant)
);

initial begin
    $fsdbDumpfile("fixed_arbiter.fsdb");
    $fsdbDumpvars(0);
end 

endmodule

波形

2.利用补码特点,判断优先级。

一个数和它的补码相与,得到的结果是一个独热码,独热码为1的那一位是这个数最低的1

例如a=4'b1011,a的补码为:~(a-1)=4'b0101。a和它的补码相与得到:4'b0001。

例如a=4'b1010,a的补码为:~(a-1)=4'b0110。a和它的补码相与得到:4'b0010。

利用这个特点,我们可以得到一个很简单的固定优先级仲裁器写法(使用按位运算符):

2.1代码

module fixed_arbiter(
    input              rstn    ,
    input              clk     ,
    input      [2:0]   request ,
    
    output reg [2:0]   grant
);

always @(posedge clk)begin
    if(!rstn)begin
        grant <= 3'b000;
    end 
    else begin
        grant <= request & (~(request-1));
    end
end

endmodule

其实就是利用了一个特性:一个数和它的补码相与,得到的结果是一个独热码,独热码为1的那一位是这个数最低的1

猜你喜欢

转载自blog.csdn.net/qq_57502075/article/details/129767386
今日推荐