3

大家可能都知道,MIPS 指令集支持 clz(计数前导零),如下所示:

clz $t0,$t1 计数前导零 t0 = # t1 中的前导零

我正在用verilog编写一个单周期数据路径,只是想知道ALU需要支持什么才能让我这样做......有什么想法吗?

4

3 回答 3

4

这是一种可能的方法(我忽略了输入 0 的情况,最好将其视为特殊情况):

  • 32 位数字中前导零的数量是:
    • 如果前 16 位中的任何一个非零,则前 16 位中前导零的数量;或者
    • 16,加上低 16 位前导零的数量,如果高 16 位全为零
  • 这给出了 5 位结果的最高位(忽略输入 0 的特殊情况......)。
  • 现在您需要找到 16 位数字中前导零的数量,因此再次应用相同的原理。
  • 等等

在 Verilog 中,它可能看起来像这样:

result[4] = (value[31:16] == 16'b0);
val16     = result[4] ? value[15:0] : value[31:16];
result[3] = (val16[15:8] == 8'b0);
val8      = result[3] ? val16[7:0] : val16[15:8];
result[2] = (val8[7:4] == 4'b0);
val4      = result[2] ? val8[3:0] : val8[7:4];
result[1] = (val4[3:2] == 2'b0);
result[0] = result[1] ? ~val4[1] : ~val4[3];
于 2010-03-04T02:34:27.920 回答
0

构建一个 clz16 单元,它查看 16 位,并具有 4 位结果 (0..15) 和“allzero”输出。将其中两个放在一起制作 clz32,您需要一个多路复用器来选择哪 4 个低位和高 2 个输出位的逻辑位。

clz16同样由两个clz8组成。clz8由两个clz4组成。clz4 只是 <= 4 个输入的三个布尔函数,所以不管你怎么做,合成器都会把它归结为几个门。

这种分层方法比 Matthew Slattery 的级联多路复用器解决方案要大,但可能不会那么多(它不需要宽门来切换多路复用器),我相信它允许使用较低的道具。延迟。两种方法都可以通过延迟属性很好地扩展到更大的尺寸(例如 64、128 位)。到 log2(n)。

于 2012-10-12T03:21:37.413 回答
0

我能想到的最简单的实现(不是很优化)是根据 32 个(在 32 位的情况下)掩码检查单词,最长的优先,决定哪个最适合并返回它的数字。

类似(伪代码):

if word == 0: return 32
elsif (word & 1) == 0: return 31
elsif (word & 3) == 0: return 30

等等

于 2010-03-03T04:20:25.677 回答