领先的零点计数器

时间:2013-02-20 00:48:21

标签: floating-point hardware verilog system-verilog hdl

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

我知道我可以写下面的内容,但我想知道如果我的目标是低面积和高能效,是否有更好的方法?:

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

2 个答案:

答案 0 :(得分:-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,它就会退出循环,让计数器包含前导零的数量。

要了解这是否足够高效,您必须尝试合成 - 请告诉我们!

答案 1 :(得分:-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

所以...你只需使用自己的设计并使用工具的综合/映射命令来了解它可以做些什么来实现你对面积和功率的要求。