重写了权重轮询仲裁,添加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) begin
if (!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) begin
if (!rst_n) begin
grant_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];
end
end
// 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-hot
initial clock = 0;
always #10 clock = ~clock;
initial
begin
reset_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;
end
Round_Robin_Arbiter #(
.N(N)
) inst_Round_Robin_Arbiter (
.clk (clock),
.rst_n (reset_b),
.request (request),
.lock (lock),
.grant (grant)
);
endmodule
仿真结果: