我正在实现一个用于浮点的规范化单元,我想知道如何有效地实现前导零计数器?
我知道我可以写以下内容,但我想知道,如果我的目标是低面积和高能效,是否有更好的方法?
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发布于 2013-02-22 21:41:32
在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-03-01 17:12:38
为什么你需要一个前导零计数器?即使你已经计算了前缀中有多少个零,最后你仍然需要比较器和多路复用器来确定你有多少个零并计算输出。由于有许多1'b1加法器、多路复用器和比较器,这可能会浪费更多的性能/面积。
在合成器中,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所以..。您只需使用自己的设计并使用工具的合成/映射命令来查看它可以做些什么来满足您对面积和功率的要求。
https://stackoverflow.com/questions/14970411
复制相似问题