• [HDL]除法器的设计与仿真


    一般来说,FPGA厂商的EDA软件里都有除法器的IP核。以Xilinx为例,Core Generator 里就可以生成除法器,任意位数。不过生成的除法器是流水线形式的。也就是说,如果是有批量的数据做除法,那么肯定是非常快的,只要经过一个固定的Lantency之后,结果就源源不断地出来。

    但是我在做图像压缩算法的时候,遇到了这样一个问题:我需要前一次除法的结果代入到下一次除法里去,这样看来,那个固定的Lantency就成了最大的障碍。所以没办法,就决定自己写一个除法器,以尽管减少时间延迟和FPGA内部资源。

    除法器的思路是这样的,以8位除以4位为例。

    设A=[a0,a1,a2,a3,a4,a5,a6,a7],B=[b0,b1,b2,b3](an,bn分别表示1bit位),商为C。

    第一步,用A与(B<<4)进行比较,如果A比(B<<4)大,则从A中减去(B<<4),然后C+=(1<<4)。直到A小于(B<<4)。

    第二步,用A与(B<<3)进行比较,如果A比(B<<3)大,则从A中减去(B<<3),然后C+=(1<<3)。直到A小于(B<<3)。

    第三步,用A与(B<<2)进行比较,如果A比(B<<2)大,则从A中减去(B<<2),然后C+=(1<<2)。直到A小于(B<<2)。

    第四步,用A与(B<<1)进行比较,如果A比(B<<1)大,则从A中减去(B<<3),然后C+=(1<<1)。直到A小于(B<<1)。

    第五步,用A与B进行比较,如果A比B大,则从A中减去B,然后C+=1。直到A小于B。

    最终C为商,A为余数。

    关键算法的代码如下:

    	if    (CONV_INTEGER(divisor_buf) = 0) then  -- 除数为0
                fra_buf <= (others => '0');
                quo_buf <= (others => '0');
    	elsif (CONV_INTEGER(divisor_buf) = 1) then    -- 除数为1
            fra_buf <= (others => '0');
            quo_buf <= dividend_buf;
            elsif (dividend_buf > (divisor_buf & "0000")) then  --4
               dividend_buf <= dividend_buf - (divisor_buf & "0000");
                quo_cnt <= quo_cnt + "10000";
                state <= st2; 
            elsif (dividend_buf > (divisor_buf & "000")) then  --3
                dividend_buf <= dividend_buf - (divisor_buf & "000");
                quo_cnt <= quo_cnt + "1000";
                state <= st2;   
            elsif (dividend_buf > (divisor_buf & "00")) then  --2
                dividend_buf <= dividend_buf - (divisor_buf & "00");
                quo_cnt <= quo_cnt + "100";
                state <= st2;   
            elsif (dividend_buf > (divisor_buf & "0")) then  --1
                dividend_buf <= dividend_buf - (divisor_buf & "0");
                quo_cnt <= quo_cnt + "10";
                state <= st2;
            elsif (dividend_buf >= divisor_buf ) then  --0
                dividend_buf <= dividend_buf - divisor_buf;
                quo_cnt <= quo_cnt + '1';
                state <= st2;
            else
                fra_buf <= dividend_buf(9 downto 0);
                quo_buf <= quo_cnt;
            end if;
     
    实例仿真图如下:

     image

    完整VHDL代码:

    http://myfpga.googlecode.com/files/divider.vhd

  • 相关阅读:
    换个角度看Salesforce之基础配置学习笔记(二)
    换个角度看Salesforce之基础配置学习笔记(一)
    C# LINQ学习笔记
    Oracle使用总结
    UML图及Visio 2010使用总结
    常见的DOS命令
    ansible笔记
    jsoncpp1.9.4源码解析
    fabric链码
    fabric数据结构
  • 原文地址:https://www.cnblogs.com/craftor/p/1817746.html
Copyright © 2020-2023  润新知