计算单周期数据路径中的前导零

时间:2010-03-03 04:09:17

标签: assembly mips verilog

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

  

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

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

3 个答案:

答案 0 :(得分: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];

答案 1 :(得分:0)

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

像(伪代码):

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

答案 2 :(得分:0)

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

clz16以相同的方式由两个clz8组成。 clz8由两个clz4组成。 clz4只是< = 4输入的三个布尔函数,所以你如何做它并不重要,合成器将它归结为几个门。

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