关于case的问题
我最近在做一个编码器,用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的代码已经很接近了
- input [63:0] data_in;
- output [5:0] data_out;
- wire [31:0] Temp_32bits;
- wire [15:0] Temp_16bits;
- wire [7:0] Temp_8bits;
- wire [3:0] Temp_4bits;
- wire [1:0] Temp_2bits;
- wire W32_n, W16_n, W8_n, W4_n, W2_n, W1_n; // negtive of weigh bit of output
- wire RA_32, RA_16, RA_8, RA_4, RA_2, RA_1; // reduction and of down half bits of each bisection operation
- wire G32, G16, G8, G4, G2, G1; //
- wire AT_4, AT_3, AT_2, AT_1, AT_0; // And tree
- assign RA_32 = & data_in[31:0];
- assign RA_16 = & Temp_32bits[15:0];
- assign RA_8 = & Temp_16bits[7:0];
- assign RA_4 = & Temp_8bits[3:0];
- assign RA_2 = & Temp_4bits[1:0];
- assign RA_1 = Temp_2bits[0];
- assign W32_n = | data_in[63:32];
- assign W16_n = | Temp_32bits[31:16];
- assign W8_n = | Temp_16bits[15:8];
- assign W4_n = | Temp_8bits[7:4];
- assign W2_n = | Temp_4bits[3:2];
- assign W1_n = Temp_2bits[1];
- assign Temp_32bits = W32_n ? data_in[63:32] : data_in[31:0];
- assign G32 = W32_n ? RA_32 : 1'b1;
- assign Temp_16bits = W16_n ? Temp_32bits[31:16] : Temp_32bits[15:0];
- assign G16 = W16_n ? RA_16 : 1'b1;
- assign Temp_8bits = W8_n ? Temp_16bits[15:8] : Temp_16bits[7:0];
- assign G8 = W8_n ? RA_8 : 1'b1;
- assign Temp_4bits = W4_n ? Temp_8bits[7:4] : Temp_8bits[3:0];
- assign G4 = W4_n ? RA_4 : 1'b1;
- assign Temp_2bits = W2_n ? Temp_4bits[3:2] : Temp_4bits[1:0];
- assign G2 = W2_n ? RA_2 : 1'b1;
- assign G1 = RA_1;
- assign AT_4 = G32 & G16;
- assign AT_3 = AT_4 & G8;
- assign AT_2 = AT_3 & G4;
- assign AT_1 = AT_2 & G2;
- assign AT_0 = AT_1 & G1;
- assign data_out[5] = (~W32_n) & AT_0;
- assign data_out[4] = (~W16_n) & AT_0;
- assign data_out[3] = (~W8_n) & AT_0;
- assign data_out[2] = (~W4_n) & AT_0;
- assign data_out[1] = (~W2_n) & AT_0;
- 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”的个数。
