Verilog | Round_Robin_Arbiter

重写了权重轮询仲裁,添加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

仿真结果:

Verilog | Round_Robin_Arbiter_第1张图片

你可能感兴趣的:(Verilog,fpga开发)