最近需要实现这个模块功能,但是博客上的没有一个代码是能直接拿过来用的,而且误导了我一两天(那代码里都组合逻辑坏了),挺难蚌的。
于是结合一个非常正确的文章(代码逻辑很清晰,但是思路逻辑太巧妙了,感觉很难正向想到):https://m.elecfans.com/article/2260239.html
不知道这两篇谁是原创:https://blog.csdn.net/icxiaoge/article/details/104522982
写了一个直接拿过来用的代码(注意,这里默认每个时钟周期发送一个请求req,testbench的时候要注意):
module scheduler_rr#(
parameter NUM_REQ = 2
)(
input wire clk,
input wire rst_n,
input wire [NUM_REQ-1:0]req,
output wire [NUM_REQ-1:0]grant //grant的值,grant_tm的最低有效位
);
reg [NUM_REQ-1:0] mask; //掩码
reg [NUM_REQ-1:0] r_mask; //掩码有效值,掩码的反转
reg [NUM_REQ-1:0] pre_grant; //锁存上一轮请求的grant
reg [NUM_REQ-1:0] grant_tm; //与掩码后,得到的请求,也是grant的前置值
always@(posedge clk or negedge rst_n) pre_grant <= grant; //锁存上一轮请求的grant
always@(*)begin
if(!rst_n)begin
mask <= {NUM_REQ{1'b1}};
r_mask <= {NUM_REQ{1'b0}};
end
else if(|req)begin
mask <= {pre_grant[NUM_REQ-2:0],pre_grant[NUM_REQ-1]}-1'b1;
r_mask <= ~({pre_grant[NUM_REQ-2:0],pre_grant[NUM_REQ-1]}-1'b1);
end
else begin
mask <= mask;
r_mask <= r_mask;
end
end
always@(*)begin
if((req&r_mask)!= 0)
grant_tm <= req & r_mask;
else
grant_tm <= req & mask;
end
assign grant = grant_tm&(~grant_tm+1'b1);
endmodule
自取