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
4

2 回答 2

-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,它就会退出循环,留下包含前导零数量的计数器。

要确定这是否足够高效,您必须尝试合成 - 让我们知道!

于 2013-02-22T13:41:31.970 回答
-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

所以...您只需使用自己的设计并使用工具的综合/映射命令来查看它可以做什么来满足您对面积和功率的要求。

于 2013-03-01T09:12:37.850 回答