当前位置:   article > 正文

向量前导1检测器的3种verilog实现方案

向量前导1检测器

一、要求

设计一个组合逻辑电路,检测输入320/1向量中从高到低第一个1出现的位置,如果向量为全0则输出32。例如:

输入00011000 10000000 00000000 00000000,输出3;

输入00000000 11111111 00000000 00000000,输出8;

输入00000000 00000000 00000000 00001010,输出28.

模块输入输出功能定义:

名称

方向

位宽

描述

data_in

I

32

输入0/1向量

pos_out

O

6

前导1出现位置,取值范围0 ~ 32

设计要求:

Verilog实现代码可综合,逻辑延迟越小越好,给出仿真结果。

 二、实现

 1.casex/casez

代码实现如下:

  1. module seq_head_detect(
  2. input [31:0] data_in,
  3. output pos_out
  4. );
  5. reg [31:0] tmp;
  6. reg [5:0] pos_out_tmp;
  7. reg [5:0] pos_out;
  8. always @(*) begin
  9. tmp = data_in;
  10. casex(tmp)
  11. 32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd0;
  12. 32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd1;
  13. 32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd2;
  14. 32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd3; //4位为1
  15. 32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd4;
  16. 32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd5;
  17. 32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd6;
  18. 32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd7; //8
  19. 32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd8;
  20. 32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd9;
  21. 32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd10;
  22. 32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd11; //12
  23. 32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd12;
  24. 32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd13;
  25. 32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd14;
  26. 32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd15; //16
  27. 32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd16;
  28. 32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : pos_out_tmp = 6'd17;
  29. 32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : pos_out_tmp = 6'd18;
  30. 32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : pos_out_tmp = 6'd19; //20
  31. 32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : pos_out_tmp = 6'd20;
  32. 32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : pos_out_tmp = 6'd21;
  33. 32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : pos_out_tmp = 6'd22;
  34. 32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : pos_out_tmp = 6'd23; //24
  35. 32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : pos_out_tmp = 6'd24;
  36. 32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : pos_out_tmp = 6'd25;
  37. 32'b0000_0000_0000_0000_0000_0000_001x_xxxx : pos_out_tmp = 6'd26;
  38. 32'b0000_0000_0000_0000_0000_0000_0001_xxxx : pos_out_tmp = 6'd27; //28
  39. 32'b0000_0000_0000_0000_0000_0000_0000_1xxx : pos_out_tmp = 6'd28;
  40. 32'b0000_0000_0000_0000_0000_0000_0000_01xx : pos_out_tmp = 6'd29;
  41. 32'b0000_0000_0000_0000_0000_0000_0000_001x : pos_out_tmp = 6'd30;
  42. 32'b0000_0000_0000_0000_0000_0000_0000_0001 : pos_out_tmp = 6'd31; //32
  43. default : pos_out_tmp = 6'd32; //全0
  44. endcase
  45. pos_out = pos_out_tmp;
  46. end
  47. endmodule

2.逐项比较if...else...

  1. module seq_head_detect(
  2. input [31:0] data_in,
  3. output pos_out
  4. );
  5. reg [31:0] tmp;
  6. reg [5:0] pos_out_tmp;
  7. reg [5:0] pos_out;
  8. always @(*) begin
  9. tmp = data_in;
  10. if(tmp[31]) pos_out_tmp = 6'd0;
  11. else if(tmp[30]) pos_out_tmp = 6'd1;
  12. else if(tmp[29]) pos_out_tmp = 6'd2;
  13. else if(tmp[28]) pos_out_tmp = 6'd3;
  14. else if(tmp[27]) pos_out_tmp = 6'd4;
  15. else if(tmp[26]) pos_out_tmp = 6'd5;
  16. else if(tmp[25]) pos_out_tmp = 6'd6;
  17. else if(tmp[24]) pos_out_tmp = 6'd7;
  18. else if(tmp[23]) pos_out_tmp = 6'd8;
  19. else if(tmp[22]) pos_out_tmp = 6'd9;
  20. else if(tmp[21]) pos_out_tmp = 6'd10;
  21. else if(tmp[20]) pos_out_tmp = 6'd11;
  22. else if(tmp[19]) pos_out_tmp = 6'd12;
  23. else if(tmp[18]) pos_out_tmp = 6'd13;
  24. else if(tmp[17]) pos_out_tmp = 6'd14;
  25. else if(tmp[16]) pos_out_tmp = 6'd15;
  26. else if(tmp[15]) pos_out_tmp = 6'd16;
  27. else if(tmp[14]) pos_out_tmp = 6'd17;
  28. else if(tmp[13]) pos_out_tmp = 6'd18;
  29. else if(tmp[12]) pos_out_tmp = 6'd19;
  30. else if(tmp[11]) pos_out_tmp = 6'd20;
  31. else if(tmp[10]) pos_out_tmp = 6'd21;
  32. else if(tmp[9]) pos_out_tmp = 6'd22;
  33. else if(tmp[8]) pos_out_tmp = 6'd23;
  34. else if(tmp[7]) pos_out_tmp = 6'd24;
  35. else if(tmp[6]) pos_out_tmp = 6'd25;
  36. else if(tmp[5]) pos_out_tmp = 6'd26;
  37. else if(tmp[4]) pos_out_tmp = 6'd27;
  38. else if(tmp[3]) pos_out_tmp = 6'd28;
  39. else if(tmp[2]) pos_out_tmp = 6'd29;
  40. else if(tmp[1]) pos_out_tmp = 6'd30;
  41. else if(tmp[0]) pos_out_tmp = 6'd31;
  42. else pos_out_tmp = 6'd32;
  43. pos_out = pos_out_tmp;
  44. end
  45. endmodule

 3.二分法

  1. module seq_head_detect(
  2. input [31:0] data_in,
  3. output [ 5:0] pos_out
  4. );
  5. //mark:assign不能给reg赋值,只能赋给wire
  6. wire [4:0] data_chk;
  7. wire [15:0] data_1;
  8. wire [7:0] data_2;
  9. wire [3:0] data_3;
  10. wire [1:0] data_4;
  11. assign data_chk[4] = |data_in[31:16];//16位相或,依此类推
  12. assign data_chk[3] = |data_1[15:8];
  13. assign data_chk[2] = |data_2[7:4];
  14. assign data_chk[1] = |data_3[3:2];
  15. assign data_chk[0] = |data_4[1];
  16. assign data_1 = (data_chk[4]) ? data_in[31:16] : data_in[15:0]; //data_in16位有1,则data1取其高16位,否则取低16
  17. assign data_2 = (data_chk[3]) ? data_1[15:8] : data_1[7:0]; //data_18位有1,则data2取其高8位,否则取低8
  18. assign data_3 = (data_chk[2]) ? data_2[7:4] : data_2[3:0]; //data_24位有1,则data3取其高4位,否则取低4
  19. assign data_4 = (data_chk[1]) ? data_3[3:2] : data_3[1:0]; //data_32位有1,则data4取其高2位,否则取低2
  20. assign pos_out = (|data_in) ? {1'b0, ~data_chk} : 6'd32; //data_in为全0,posout = 6'd32
  21. /*data_in中有1时,用低5位表示足够,则最高位为0*/
  22. /*假定data_in首位为1,则data_chk = 11111,应有pos_out = 00000,类推可知data_chk取反*/
  23. endmodule

三、仿真

 testbench

  1. `timescale 1ns / 1ps
  2. module tb_seq_head_detect();
  3. reg [31:0] data_in;
  4. wire [5:0] pos_out;
  5. initial begin
  6. data_in = 32'b0000_0000_0000_0000_0000_0000_0000_0000;
  7. #100
  8. data_in = 32'b0000_0001_0000_0000_0000_0000_0000_1101;//8位,pos_out = 7
  9. #100
  10. data_in = 32'b0000_0000_0000_0000_0010_0000_0000_1101;//第19位,pos_out = 18
  11. end
  12. seq_head_detect u_seq_head_detect(
  13. .data_in (data_in),
  14. .pos_out (pos_out)
  15. );
  16. endmodule

仿真结果:

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

闽ICP备14008679号