当前位置:   article > 正文

轮询仲裁器Verilog设计与仿真_verilog仲裁器设计验证

verilog仲裁器设计验证

目录

基本原理

设计代码

ModelSim仿真

基本原理

当输入数据不为0时,在下一个时钟上升沿输出仲裁后的优先级,且下一次仲裁优先级为此次输出左一位数据。如表1-1所示。

仲裁器示例
输入数据当前优先级输出数据下一优先级
1010000100100100
0110010001001000
0111100000010010
1110001000100100

思路:当一个数据 a 与一个独热码 b 进行相减取反,在和原数据进行相与时a & ~(a-b),得到从独热码开始第一个1的位置,比如1011_0000和独热码0000_0100操作后,得到的数据为0001_0000。

但是此处出现一个问题,当独热码大于数据时,比如数据为0001_0101,独热码为0010_0000,得到的结果却为0。所以我们需要对原数据进行复制扩展,当数据大于独热码时,输出低8位数据;当数据小于独热码时,输出高8位数据。

设计代码

  1. module round_robin_arbiter#(
  2. parameter DATA_WIDTH = 8 )
  3. ( input i_clk ,
  4. input i_rst ,
  5. input [DATA_WIDTH - 1 : 0] i_data ,
  6. output [DATA_WIDTH - 1 : 0] o_data );
  7. /*--------------------------------parameter------------------------------*/
  8. /*----------------------------------wire---------------------------------*/
  9. // 将输入数据复制扩展
  10. wire [2*DATA_WIDTH - 1 : 0] w_data_copy;
  11. // 数据相减取反再相与
  12. wire [2*DATA_WIDTH - 1 : 0] w_data_operation;
  13. // 优先级独热码扩展
  14. wire [2*DATA_WIDTH - 1 : 0] w_priority_extend;
  15. /*----------------------------------reg----------------------------------*/
  16. // 优先级独热码
  17. reg [DATA_WIDTH - 1 : 0] r_priority;
  18. // 输出独热码
  19. reg [DATA_WIDTH - 1 : 0] r_data_out;
  20. /*---------------------------------assign--------------------------------*/
  21. assign w_data_copy = {i_data,i_data};
  22. assign w_priority_extend = {{(DATA_WIDTH){1'b0}},r_priority};
  23. assign w_data_operation = (w_data_copy & (~(w_data_copy - w_priority_extend)));
  24. assign o_data = r_data_out;
  25. /*---------------------------------always--------------------------------*/
  26. always @(posedge i_clk or posedge i_rst) begin
  27. if (i_rst) begin
  28. r_priority <= 1;
  29. end
  30. else if (i_data != 0) begin
  31. if (i_data >= r_priority) begin
  32. r_priority <= {w_data_operation[0 +: (DATA_WIDTH - 1)],w_data_operation[DATA_WIDTH - 1]};
  33. end
  34. else begin
  35. r_priority <= {w_data_operation[DATA_WIDTH +: (DATA_WIDTH - 1)],w_data_operation[2*DATA_WIDTH - 1]};
  36. end
  37. end
  38. end
  39. always @(posedge i_clk or posedge i_rst) begin
  40. if (i_rst) begin
  41. r_data_out <= 'b0;
  42. end
  43. else if (i_data != 0) begin
  44. r_data_out <= (i_data >= r_priority) ? w_data_operation[DATA_WIDTH - 1 : 0] : w_data_operation[DATA_WIDTH +: DATA_WIDTH]; // 大于输出低位,小于输出高位
  45. end
  46. else begin
  47. r_data_out <= 'b0;
  48. end
  49. end
  50. endmodule

ModelSim仿真

  1. module tb();
  2. parameter DATA_WIDTH = 8;
  3. reg i_clk ;
  4. reg i_rst ;
  5. reg [DATA_WIDTH - 1 : 0] i_data;
  6. wire [DATA_WIDTH - 1 : 0] o_data;
  7. initial begin
  8. i_clk = 0;
  9. i_rst = 1;
  10. i_data= 0;
  11. # 10
  12. i_rst = 0;
  13. repeat(20) begin
  14. #({$random}%10) i_data = {$random}%200;
  15. end
  16. i_data= 0;
  17. end
  18. always # 3 i_clk = ~i_clk;
  19. round_robin_arbiter inst(
  20. .i_clk (i_clk ),
  21. .i_rst (i_rst ),
  22. .i_data (i_data),
  23. .o_data (o_data));
  24. endmodule

仿真结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/802626
推荐阅读
相关标签
  

闽ICP备14008679号