重写了权重轮询仲裁,添加lock输入信号,表示请求方收到了仲裁许可,在对应的lock拉低之前,仲裁器不可以开启新的仲裁。
Generics
Generic name Type Value Description N 4
Ports
Port name Direction Type Description clk input rst_n input request input [N-1:0] lock input [N-1:0] grant output [N-1:0]
Verilog实现
rtl代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/07/20 16:11:36
// Design Name:
// Module Name: round_robin_arb
// ===================================================================================
// 功能:
// -1- Round Robin 仲裁器
// -2- 仲裁请求个数N可变
// -3- 加入lock机制
// -4- 复位时的最高优先级定为 0 ,次优先级:1 -> 2 …… -> N-2 -> N-1
//
// ===================================================================================module Round_Robin_Arbiter #(parameter N = 4 //仲裁请求个数
) (input clk,input rst_n,input [N-1:0] request,input [N-1:0] lock,output [N-1:0] grant //one-hot
);// 存储移位后上一次仲裁结果reg aaa;wire bbb;reg [N-1:0] last_state;reg [N-1:0] grant_r;assign bbb = ~|(lock & grant);assign grant = grant_r;always @(posedge clk or negedge rst_n)if (!rst_n) aaa <= 0;else aaa <= |request & ~(|(lock & grant));always @(posedge clk or negedge rst_n) beginif (!rst_n) last_state <= 4'b0001; // 默认值,表示最低位的优先级最高else if (aaa) last_state <= {grant[N-2:0], grant[N-1]}; // 有仲裁请求,根据上一次的仲裁结果,左移1bit后用于控制新的优先级else last_state <= last_state; // 无仲裁请求时,pre_state不更新end// 如果最左侧几个高优先级主机都为发起仲裁请求,需要从最低位开始轮询。// 此处通过两个request拼接,将右侧低位拼接到左侧,即可实现对低位的判断。wire [2*N-1:0] grant_ext;assign grant_ext = {request, request} & ~({request, request} - last_state);//得到的grant_ext必定为一个独热码,但是置高位可能在代表低位的高4bit中,因此进行求或运算always @(posedge clk or negedge rst_n) beginif (!rst_n) begingrant_r <= 0;// grant_ext <= 0;end else if (bbb) begin// grant_ext <= {request,request} & ~({request,request} - last_state);grant_r <= grant_ext[N-1:0] | grant_ext[2*N-1:N];endend// wire aaa;// assign aaa = (|request & ~(|(lock & grant)));// wire [3:0] last_state;// assign last_state = rst_n ? aaa ? {grant[N-2:0], grant[N-1]} : last_state : 'b0001;// assign grant = bbb ? grant_ext[N-1:0] | grant_ext[2N-1:N] : grant;
endmodule
tb代码
// =====================================================================
// 功能:测试模块 Round_Robin_Arbiter 功能
// =====================================================================`timescale 1ns / 1ps
module TB_Round_Robin_Arbiter();parameter N = 4; //仲裁请求个数reg clock;
reg reset_b;
reg [N-1:0] request;
reg [N-1:0] lock;
wire [N-1:0] grant;//one-hotinitial clock = 0;
always #10 clock = ~clock;initial
beginreset_b <= 1'b0;request <= 0;lock <= 0;#20;reset_b <= 1'b1;@(posedge clock)request <= 2;lock <= 2;@(posedge clock)request <= 0;@(posedge clock)request <= 5;lock <= 7;@(posedge clock)lock <= 5;@(posedge clock)request <= 1;@(posedge clock)lock <= 1;@(posedge clock)request <= 0;@(posedge clock)lock <= 0;#40;@(posedge clock)request <= 0;lock <= 2;@(posedge clock)request <= 0;@(posedge clock)request <= 5;lock <= 7;@(posedge clock)lock <= 5;@(posedge clock)request <= 1;@(posedge clock)lock <= 1;@(posedge clock)request <= 0;@(posedge clock)lock <= 0;#100;$finish;
endRound_Robin_Arbiter #(.N(N)) inst_Round_Robin_Arbiter (.clk (clock),.rst_n (reset_b),.request (request),.lock (lock),.grant (grant));endmodule
仿真结果: