微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 关于case的问题

关于case的问题

时间:10-02 整理:3721RD 点击:

我最近在做一个编码器,用case语句做的,不过条件很多,有64个判断
case(intermediate8)
64'hFFFFFFFFFFFFFFFF: out=6'd0;
64'h7FFFFFFFFFFFFFFF:   out=6'd1;
64'h3FFFFFFFFFFFFFFF:   out=6'd2;
64'h1FFFFFFFFFFFFFFF:   out=6'd3;
64'h0FFFFFFFFFFFFFFF:   out=6'd4;
.
.
.
.
64'h0000000000000001:  out=6'd63;
default:  out=6'd0;
endcase
总共有64个判断项,所以综合出来的电路占用资源多,延时大,求大神指导,如何对这种case语句进行优化


     你可以考虑将这个大的case语句拆成四个小的case语句,再用一个加法器就可以完成了,应该对你有帮助。代码实现如下:

case(intermediate8[63:48])
16'hFFFF: out1=6'd0;
16'h7FFF:   out1=6'd1;
16'h3FFF:   out1=6'd2;
16'h1FFF:   out1=6'd3;
16'h0FFF:   out1=6'd4;
16'h07FF: out1=6'd5;
16'h03FF:   out1=6'd6;
16'h01FF:   out1=6'd7;
16'h00FF: out1=6'd8;
16'h007F:   out1=6'd9;
16'h003F:   out1=6'd10;
16'h001F:   out1=6'd11;
16'h000F:   out1=6'd12;
16'h0007: out1=6'd13;
16'h0003:   out1=6'd14;
16'h0001:   out1=6'd15;.
default:    out1=6'd16;
endcase
case(intermediate8[47:32])
16'hFFFF: out2=6'd0;
16'h7FFF:   out2=6'd1;
16'h3FFF:   out2=6'd2;
16'h1FFF:   out2=6'd3;
16'h0FFF:   out2=6'd4;
16'h07FF: out2=6'd5;
16'h03FF:   out2=6'd6;
16'h01FF:   out2=6'd7;
16'h00FF: out2=6'd8;
16'h007F:   out2=6'd9;
16'h003F:   out2=6'd10;
16'h001F:   out2=6'd11;
16'h000F:   out2=6'd12;
16'h0007: out2=6'd13;
16'h0003:   out2=6'd14;
16'h0001:   out2=6'd15;.
default:    out1=6'd16;
endcase
case(intermediate8[31:16])
16'hFFFF: out3=6'd0;
16'h7FFF:   out3=6'd1;
16'h3FFF:   out3=6'd2;
16'h1FFF:   out3=6'd3;
16'h0FFF:   out3=6'd4;
16'h07FF: out3=6'd5;
16'h03FF:   out3=6'd6;
16'h01FF:   out3=6'd7;
16'h00FF: out3=6'd8;
16'h007F:   out3=6'd9;
16'h003F:   out3=6'd10;
16'h001F:   out3=6'd11;
16'h000F:   out3=6'd12;
16'h0007: out3=6'd13;
16'h0003:   out3=6'd14;
16'h0001:   out3=6'd15;.
default:    out3=6'd16;
endcase

case(intermediate8[15:0])
16'hFFFF: out4=6'd0;
16'h7FFF:   out4=6'd1;
16'h3FFF:   out4=6'd2;
16'h1FFF:   out4=6'd3;
16'h0FFF:   out4=6'd4;
16'h07FF: out4=6'd5;
16'h03FF:   out4=6'd6;
16'h01FF:   out4=6'd7;
16'h00FF: out4=6'd8;
16'h007F:   out4=6'd9;
16'h003F:   out4=6'd10;
16'h001F:   out4=6'd11;
16'h000F:   out4=6'd12;
16'h0007: out4=6'd13;
16'h0003:   out4=6'd14;
16'h0001:   out4=6'd15;.
default:    out4=6'd0;
endcase
assign out = out1 + out2 + out3 + out4;

   错。

我看你64个case就用了64位数据,可不可以将它转换成二进制编码在进行case呢?



   我这个本身就是将其转化为二进制的


请问错在哪?


谢谢

你这样写实在太累人
换个写法
case(1'b1)
intermediate8[63]:  out = 6'd0;
intermediate8[62]:  out = 6'd1;
............
endcase
当然了,这样写还不能减小电路的面积和延时。
你可以手动优化。
从你给出的数据看,其实可以将问题转化成【从最高位开始找1,这个1出现在哪个位置】, 比如7FFFFFFFFFFFFFFF最高位的1出现在第62位,那么63-62==1即可
wire [63:0] temp = intermediate8;
wire temp5_en = |temp[63:32];
wire[31:0] temp5 = temp5_en ? temp[63:32] : temp[31:0];
wire temp4_en = |temp5[31:16];
wire[15:0] temp4 = temp4_en ? temp5[31:16] : temp5[15:0];
wire temp3_en = |temp4[15:8];
wire[7:0] temp3 = temp3_en ? temp4[15:8] : temp4[7:0];
wire temp2_en = |temp3[7:4];
wire[3:0] temp2 = temp2_en ? temp3[7:4] : temp3[3:0];
wire temp1_en = |temp2[3:2];
wire[1:0] temp1 = temp1_en ? temp2[3:2] : temp2[1:0];
wire  temp0_en = temp1[1];
wire [5:0] out_temp = 6'd63 - {temp5_en, temp4_en, temp3_en, temp2_en, temp1_en, temp0_en};
assign out =  (intermediate8==64'b0) ? 6'd0 : out_temp;

都没仔细看小编题目。楼上也错



    我的方法哪里错了啊?求指点


如果值为64'h7fff_0000_0000_0000就不对了,按照原电路DEFAULT值应为0, 而不是1,9楼细心~我提供的方法也有这个问题,编码数据不是ONE-HOT的

感觉可以做移位计算,然后设置一个counter。64‘hFFFFFFFFFFFFFFFF向右移位,每移位一次,counter加1,如果等于intermediate8,则out=counter

向左移位,最后一位移进去1 ;如果移位到第一位是1,其余的  &【62:0】= 1就根据这时的计数器值输出 ,这个方法可能需要较多的周期
另一种就类似二分法,可以运算快些

谢谢分享!



   基于二分法的vongy的代码已经很接近了

  1. input   [63:0]  data_in;
  2. output  [5:0]   data_out;

  3. wire    [31:0]  Temp_32bits;
  4. wire    [15:0]  Temp_16bits;
  5. wire    [7:0]   Temp_8bits;
  6. wire    [3:0]   Temp_4bits;
  7. wire    [1:0]   Temp_2bits;

  8. wire  W32_n, W16_n, W8_n, W4_n, W2_n, W1_n; // negtive of weigh bit of output
  9. wire  RA_32, RA_16, RA_8, RA_4, RA_2, RA_1; // reduction and of down half bits of each bisection operation
  10. wire  G32, G16, G8, G4, G2, G1;   //
  11. wire  AT_4, AT_3, AT_2, AT_1, AT_0;   // And tree

  12. assign RA_32 = & data_in[31:0];
  13. assign RA_16 = & Temp_32bits[15:0];
  14. assign RA_8  = & Temp_16bits[7:0];
  15. assign RA_4  = & Temp_8bits[3:0];
  16. assign RA_2  = & Temp_4bits[1:0];
  17. assign RA_1  = Temp_2bits[0];

  18. assign W32_n = | data_in[63:32];
  19. assign W16_n = | Temp_32bits[31:16];
  20. assign W8_n = | Temp_16bits[15:8];
  21. assign W4_n = | Temp_8bits[7:4];
  22. assign W2_n = | Temp_4bits[3:2];
  23. assign W1_n = Temp_2bits[1];

  24. assign Temp_32bits = W32_n ? data_in[63:32] : data_in[31:0];
  25. assign G32 = W32_n ? RA_32 : 1'b1;
  26. assign Temp_16bits = W16_n ? Temp_32bits[31:16] : Temp_32bits[15:0];
  27. assign G16 = W16_n ? RA_16 : 1'b1;
  28. assign Temp_8bits = W8_n ? Temp_16bits[15:8] : Temp_16bits[7:0];
  29. assign G8 = W8_n ? RA_8 : 1'b1;
  30. assign Temp_4bits = W4_n ? Temp_8bits[7:4] : Temp_8bits[3:0];
  31. assign G4 = W4_n ? RA_4 : 1'b1;
  32. assign Temp_2bits = W2_n ? Temp_4bits[3:2] : Temp_4bits[1:0];
  33. assign G2 = W2_n ? RA_2 : 1'b1;
  34. assign G1 = RA_1;

  35. assign AT_4 = G32 & G16;
  36. assign AT_3 = AT_4 & G8;
  37. assign AT_2 = AT_3 & G4;
  38. assign AT_1 = AT_2 & G2;
  39. assign AT_0 = AT_1 & G1;

  40. assign data_out[5] = (~W32_n) & AT_0;
  41. assign data_out[4] = (~W16_n) & AT_0;
  42. assign data_out[3] = (~W8_n) & AT_0;
  43. assign data_out[2] = (~W4_n) & AT_0;
  44. assign data_out[1] = (~W2_n) & AT_0;
  45. assign data_out[0] = (~W1_n) & AT_0;

复制代码


你的这段程序是用来计算intermediate8中0的个数的吧?
你可以这样:
out0=~intermediate8[63]+~intermediate8[62]+....+~intermediate8[48];
out1=~intermediate8[47]+~intermediate8[46]+....+~intermediate8[32];
out2=~intermediate8[31]+~intermediate8[30]+....+~intermediate8[16];
out3=~intermediate8[15]+~intermediate8[14]+....+~intermediate8[0];
out = out0+out1+out2+out3;
速度不够还可以再拆,注意位数。
2楼做的是对的。9#在装B。

是否可以考虑下看“1”的个数。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top