2013-02-20 61 views
3

我正在实现一个浮点标准化单元,我想知道如何有效地实现一个前导零计数器?前导零计数器

我知道我可以写下面的,但我不知道是否有更好的方法,如果我定位的是低区和高能源效率?:

always @(mantissa) begin 
    case(mantissa) 
    25'b1????????????????????????: newmant = mantissa[24:1]; 
    25'b01???????????????????????: newmant = mantissa[23:0]; 
    25'b001??????????????????????: newmant = {mantissa[22:0],1'b0}; 
    25'b0001?????????????????????: newmant = {mantissa[21:0],2'b0}; 
    // ... (details ommited for brevity) 
    endcase 
end 
+0

您的硬件设计是否需要快速桶式移位器?如果是这样,你可以分离出找到要移位的位数,并进行转换。 – 2013-02-20 02:39:20

+0

不,它不。它专注于低功耗,低面积高能效。但是你建议使用管道吗? – Veridian 2013-02-20 04:08:52

+0

我不确定流水线如何能满足您的低功耗要求。您是否考虑了多阶段前导零计数 - 例如在至少有16个前导零的任何事物上有16位左移,然后在第一步后至少有8位前导零的任何事物上左移8位。它将有更长的路径,但比分别处理每个案例的扇出更少。 – 2013-02-20 04:13:58

回答

-1

在VHDL(这应该是很容易移植到Verilog的):

process 
    variable leading_zeros : natural; 
begin 
    leading_zeros := 0; 
    for i in input_vector'range loop 
     if input_vector(i) = '1' then 
     break; 
     end if; 
     leading_zeros := leading_zeros + 1; 
    end for; 
end process; 

对于非VHDL扬声器,所有这样做是循环遍历input_vector所有的位由左到右,每次看到一个0时间递增计数器。一旦找到第一个1,它就会退出循环,使计数器包含前导零的数量。

要了解这是否足够高效,您必须尝试综合 - 让我们知道!

+0

谢谢你的回答。但我不知道VHDL。 – Veridian 2013-02-22 16:29:41

+0

此外,行为模型=错误的做法IMO – Veridian 2013-02-24 22:54:33

+0

@starbox:您能否扩展“行为模型=糟糕的做法”的含义?如果你的意思是“上面的代码效率低下”,那么请演示它。根据我的经验,它产生与其他各种编码风格相同的逻辑。我宁愿去阅读比复杂。除非你是一位真正的大师级专家,否则这些天通常很难击败合成器(以前并不真实,但是有很多宿醉......) – 2013-02-25 14:30:40

-1

为什么你需要一个领先的零计数器?即使您已经计算了前缀中有多少个零,最后仍然需要比较器和MUX来确定您拥有多少个零并计算输出。由于许多1'b1加法器,MUX和比较器,它可能会浪费更多的性能/面积。

for/while循环将展开到合成器中的25个步骤(根据宽度)。 如果使用前导零个柜台,你的架构变得像

// you will have 25 mux and adders 
always @(mantissa) begin 
    leading_zeros = 0; 
    // for-loop expanded 
    if (mantissa[24] == 1) 
    disable count_n_2; 
    else begin : count_n_2 
    leading_zeros ++; 
    if (mantissa[23] == 1) 
     disable count_n_3; 
    else begin : count_n_3 
     leading_zeros ++; 
     ... 
    end 
    end 
end // always 

// you will have 25 comparator and mux 
always @(leading_zeros) begin 
    case(leading_zeros) 
    5'd0: newmant = mantissa[24:1]; 
    5'd1: newmant = mantissa[23:0]; 
    5'd2: newmant = {mantissa[22:0],1'b0}; 
    5'd25: ... 
    endcase 
end 

所以......你只需要使用自己的设计和使用的工具的合成/映射命令来查看它能做什么来实现你的面积和功耗的要求。