独热码检测

最近秋招遇到了一个比较常见的问题是独热码的检测。

问题

该问题有多个表述,给定一个Nbit向量

  • 检测是否是独热码
  • 检测该信号是否为2的幂次

思路

独热码的特点是只有1bit为1,其余均为0。 假设独热码为:0b00010000,将该数字减去1得到0b00001111, 进行简单的一个与操作可以得到

1
2
3
0b00010000 &
0b00001111 =
0b00000000

利用利用这刚好错开的位置来完成1bit的检测。 发现结果是全0,检查边界条件发现全0输入也能满足上述运算过程,因此需要额外进行判断,参考代码如下

1
assign is_one_hot_code =  (vec&(vec-1) == 0) && (vec!=0) ; 

分析

在上面这个问题里面,能发现的是一个比较有意思的操作,减法,得到的是0b000...011...11类似于这种形式的信号,非常适合用于当mask信号。

这里插一个题外话,即补码,给定一个向量,计算其补码,书上讲的方法是,从低位开始找到第一个1,将这个1保持不变,更高位的信号全部取反即可。 0b101000 ->0b011000,这两个信号与在一起得到的是独热码,而且这个独热码是原始信号中最低位的1。于是我们有了这个操作:vec & (-vec)。 这个操作根据Gemini的回答叫做隔离最低位的1。 于是可以根据得到的独热码来生成类似的mask信号。总结下来有如下的几种信号形式

  1. random vector
  2. one hot code
  3. 前面为0后面为1的mask向量,分为是否包含one_hot那一位2种情况
  4. 前面为1后面为0的mask向量,分为是否包含one_hot那一位2种情况

若不考虑输入向量为全0的情况,那么

1
2
3
4
5
assign one_hot = vec & (-vec);
assign mask1 = (one_hot - 1);
assign mask2 = (one_hot - 1) | one_hot;
assign mask3 = ~mask1;
assign mask4 = ~mask2;

于是我们就能从一个任意的向量,生成对应的这类信号,反过来,当要生成这些信号的时候,无非就2个操作,vec-1vec&(-vec),当然这里的取负数可以用取反加一的方式来进行。 至此,独热码检测以及相关的逻辑便结束了。


独热码检测
https://blog.zorogh.top/2025/08/27/one-hot-detection/
作者
ZoroGH
发布于
2025年8月28日
更新于
2025年9月7日
许可协议