赞
踩
目录
当输入数据不为0时,在下一个时钟上升沿输出仲裁后的优先级,且下一次仲裁优先级为此次输出左一位数据。如表1-1所示。
输入数据 | 当前优先级 | 输出数据 | 下一优先级 |
1010 | 0001 | 0010 | 0100 |
0110 | 0100 | 0100 | 1000 |
0111 | 1000 | 0001 | 0010 |
1110 | 0010 | 0010 | 0100 |
思路:当一个数据 a 与一个独热码 b 进行相减取反,在和原数据进行相与时a & ~(a-b),得到从独热码开始第一个1的位置,比如1011_0000和独热码0000_0100操作后,得到的数据为0001_0000。
但是此处出现一个问题,当独热码大于数据时,比如数据为0001_0101,独热码为0010_0000,得到的结果却为0。所以我们需要对原数据进行复制扩展,当数据大于独热码时,输出低8位数据;当数据小于独热码时,输出高8位数据。
- module round_robin_arbiter#(
- parameter DATA_WIDTH = 8 )
- ( input i_clk ,
- input i_rst ,
- input [DATA_WIDTH - 1 : 0] i_data ,
- output [DATA_WIDTH - 1 : 0] o_data );
-
- /*--------------------------------parameter------------------------------*/
-
- /*----------------------------------wire---------------------------------*/
- // 将输入数据复制扩展
- wire [2*DATA_WIDTH - 1 : 0] w_data_copy;
-
- // 数据相减取反再相与
- wire [2*DATA_WIDTH - 1 : 0] w_data_operation;
-
- // 优先级独热码扩展
- wire [2*DATA_WIDTH - 1 : 0] w_priority_extend;
-
- /*----------------------------------reg----------------------------------*/
- // 优先级独热码
- reg [DATA_WIDTH - 1 : 0] r_priority;
-
- // 输出独热码
- reg [DATA_WIDTH - 1 : 0] r_data_out;
-
- /*---------------------------------assign--------------------------------*/
- assign w_data_copy = {i_data,i_data};
-
- assign w_priority_extend = {{(DATA_WIDTH){1'b0}},r_priority};
- assign w_data_operation = (w_data_copy & (~(w_data_copy - w_priority_extend)));
- assign o_data = r_data_out;
- /*---------------------------------always--------------------------------*/
- always @(posedge i_clk or posedge i_rst) begin
- if (i_rst) begin
- r_priority <= 1;
- end
- else if (i_data != 0) begin
- if (i_data >= r_priority) begin
- r_priority <= {w_data_operation[0 +: (DATA_WIDTH - 1)],w_data_operation[DATA_WIDTH - 1]};
- end
- else begin
- r_priority <= {w_data_operation[DATA_WIDTH +: (DATA_WIDTH - 1)],w_data_operation[2*DATA_WIDTH - 1]};
- end
- end
- end
- always @(posedge i_clk or posedge i_rst) begin
- if (i_rst) begin
- r_data_out <= 'b0;
- end
- else if (i_data != 0) begin
- r_data_out <= (i_data >= r_priority) ? w_data_operation[DATA_WIDTH - 1 : 0] : w_data_operation[DATA_WIDTH +: DATA_WIDTH]; // 大于输出低位,小于输出高位
- end
- else begin
- r_data_out <= 'b0;
- end
- end
- endmodule
- module tb();
- parameter DATA_WIDTH = 8;
- reg i_clk ;
- reg i_rst ;
- reg [DATA_WIDTH - 1 : 0] i_data;
- wire [DATA_WIDTH - 1 : 0] o_data;
-
- initial begin
- i_clk = 0;
- i_rst = 1;
- i_data= 0;
- # 10
- i_rst = 0;
- repeat(20) begin
- #({$random}%10) i_data = {$random}%200;
- end
- i_data= 0;
- end
- always # 3 i_clk = ~i_clk;
-
- round_robin_arbiter inst(
- .i_clk (i_clk ),
- .i_rst (i_rst ),
- .i_data (i_data),
- .o_data (o_data));
-
-
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。