仲裁器的特点:仲裁申请数量参数化,单周期申请(单周期得到仲裁结果),对于多周期的申请,可以设置优先级priority_en=1'b0,以保持当前的授权许可。
仲裁器代码:
`timescale 1ns / 1ps
//
// Company: nssc
// Engineer: liumeng
// Create Date: 2021/12/17 19:07:53
// Module Name: thermo_arbiter_priority_en
// Description: general round robin arbiter
// Revision 0.01 - File Created
//
module thermo_arbiter_priority_en #(
parameter ARBITER_WIDTH = 4
)
(
clk,
reset,
request,
grant,
any_grant,
priority_en
);
input [ARBITER_WIDTH-1 : 0] request;
output [ARBITER_WIDTH-1 : 0] grant;
output any_grant;
input reset,clk;
input priority_en;
wire [ARBITER_WIDTH-1 : 0] termo1,termo2,mux_out,masked_request,edge_mask;
reg [ARBITER_WIDTH-1 : 0] pr;
thermo_gen #(
.WIDTH(ARBITER_WIDTH)
) tm1
(
.in(request),
.out(termo1)
);
thermo_gen #(
.WIDTH(ARBITER_WIDTH)
) tm2
(
.in(masked_request),
.out(termo2)
);
assign mux_out=(termo2[ARBITER_WIDTH-1])? termo2 : termo1;
assign masked_request= request & pr;
assign any_grant=termo1[ARBITER_WIDTH-1];
`ifdef SYNC_RESET_MODE
always @ (posedge clk )begin
`else
always @ (posedge clk or posedge reset)begin
`endif
if(reset) pr<= {ARBITER_WIDTH{1'b1}};
else begin
if(priority_en) pr<= edge_mask;
end
end
assign edge_mask= {mux_out[ARBITER_WIDTH-2:0],1'b0};
assign grant= mux_out ^ edge_mask;
endmodule
温度计码产生子模块:
`timescale 1ns / 1ps
//
// Company: nssc
// Engineer: liumeng
// Create Date: 2021/12/17 19:07:53
// Module Name: thermo_gen
// Description: thermo_arbiter RRA
// Revision 0.01 - File Created
//
module thermo_gen #(
parameter WIDTH=16
)(
input[WIDTH-1 : 0] in,
output[WIDTH-1 : 0] out
);
genvar i;
generate
for(i=0;i<WIDTH;i=i+1)begin :lp
assign out[i] = |in[i:0];
end
endgenerate
endmodule
测试代码:
`timescale 1ns / 1ps
//
// Company: nssc
// Engineer: liumeng
// Create Date: 2021/12/20 14:07:53
// Module Name: sim_thermo_arbiter_priority_en
// Description: general round robin arbiter
// Revision 0.01 - File Created
//
module sim_thermo_arbiter_priority_en;
parameter ARBITER_WIDTH = 7;
reg clk,reset;
reg[ARBITER_WIDTH-1 : 0] request;
wire[ARBITER_WIDTH-1 : 0] grant;
wire any_grant;
reg priority_en;
integer seed_dis = 99;
reg request_change;
always #10 clk = ~clk;
initial begin
clk = 0;
reset = 0;
#100;
reset = 1;
#100;
reset = 0;
end
genvar i;
generate;
for (i=0;i<ARBITER_WIDTH;i=i+1) begin :loop
always @ (posedge clk or posedge reset)begin
if(reset) begin
request[i] <= 1'b0;
end else if (request_change & (~any_grant | grant[i])) begin
request[i] <= $dist_uniform(seed_dis, 0, 1);//data_uniform <= $dist_uniform(seed_dis, MIN_NUM, MAX_NUM);
end else begin
request[i] <= request[i];
end
end
end
endgenerate
initial begin
priority_en = 1'b1;
request_change = 1'b0;
repeat(200) begin
@(posedge clk) request_change = 1'b1;
@(posedge clk) request_change = 1'b0;
#100;
end
#100;
priority_en = 1'b0;
repeat(200) begin
@(posedge clk) request_change = 1'b1;
@(posedge clk) request_change = 1'b0;
#100;
end
#500;
repeat(100) begin
@(posedge clk) request_change = 1'b1;
@(posedge clk) request_change = 1'b0;
end
end
thermo_arbiter_priority_en#(
.ARBITER_WIDTH ( ARBITER_WIDTH )
)u_thermo_arbiter_priority_en(
.clk ( clk ),
.reset ( reset ),
.request ( request ),
.grant ( grant ),
.any_grant ( any_grant ),
.priority_en ( priority_en )
);
endmodule
仿真结果如下:
1.单周期申请(priority_en=1'b1,多申请同时持续时,授权按周期不停轮转)
2、 多周期申请(priority_en=1'b0,多申请同时持续时,授权在申请结束后才轮转)