如何判断输入是独热码Verilog
问题展现
前几天面试手撕了一个很有意思的代码,如何判断一组输入数据是否是独热码。
我的解答:
1 module cal1num_simple( 2 input wire clk, 3 input wire rst, 4 // input wire valid, 5 input wire [31:0] din, 6 output wire flag 7 ); 8 9 reg [5:0] ones; 10 11 integer i; 12 13 always@(*)begin 14 ones = 0; 15 for(i=0;i<32;i=i+1)begin 16 ones = ones + din[i]; 17 end 18 end 19 20 assign flag = (ones==1); 21 22 endmodule
占用的资源:

这里考虑到对PPA进行优化,我一开始是判断输入是有多少个1然后输出,但是如果位宽比较大就会消耗较多资源,现记录一下另一种方法看看资源情况。
这里简单在ISE上综合看看资源情况,改进后的代码如下:
这里的技巧是先判断输入中是否具有奇数个1,因此用到奇偶校验,再利用独热码独特的性质:其经过一个运算后从1开始那一位及以上的位都为1,再利用独热码取反与其或操作得到一个全1的序列。
如果不是独热码那么经过这个运算后从1开始那位及以上会出现0,原序列取反与其或操作就得到的不是全1了,利用按位与就可以判断了。
1 module cal1num_simple( 2 input wire clk, 3 input wire rst, 4 input wire [31:0] din, 5 output wire flag 6 ); 7 8 wire is_odd; 9 wire [31:0] din_q; 10 11 assign is_odd = (^din)==1; 12 13 assign din_q[0] = din[0]; 14 15 generate 16 genvar i; 17 for(i=1;i<32;i=i+1)begin 18 assign din_q[i] = din_q[i-1] ^ din[i]; 19 end 20 endgenerate 21 22 assign flag = is_odd ? (&((~din) | din_q)==1 ? 1 : 0) : 0; 23 24 endmodule

可以看出两者在输入数据位宽为32位时竟然一样,那么增加位宽为64
第一个资源利用:


第二种资源利用:

LUT用77下降到21,可以看出节约了大量资源!
要点分析


浙公网安备 33010602011771号