⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdlsiweichufaqi.doc

📁 这是一个利用MAX PULL 制作的VHDL的四位除法器的程序 如果有需要仿真图的 请叫站长联系我
💻 DOC
字号:
VHDL除法运算
2008-05-22 08:55
引言
???? 在数字计算中,加、减、乘、除运算经常使用。在FPGA中,有加、减、乘、除的算法指令,但除法中除数必须为2的幂,因此无法实现除数为任意数的除法;而二进制除法算法中包含了减法、乘法、数的分解与合成、试商的判断等多种操作过程。因此,除法运算过程非常复杂,用VHDL编写除法运算很难实现。因此,作者根据二进制乘法的原理,采用被除数与除数的倒数相乘的方法来实现二进制的除法。
1?? 十六位二进制乘法
???? 二进制乘法是通过逐项移位相加原理来实现的。从被乘数的最低位开始,若为1,则乘数左移后送入寄存器进行累加;若为0,左移后以全零相加。如此往复,直至被乘数的最高位。乘法运算结束后,此时累加器中的输出值即为最后的积。图1所示为乘法原理框图。

图1?? 乘法原理框图
???? 根据上述原理,设计VHDL算法,实现十六位二进制乘法。乘法在一个时钟周期内完成。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY MULTIPLY IS
PORT(CLK:IN STD_LOGIC;
???? A:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
???? //乘数
???? B:IN STD_LOGIC_VECTOR(15 DOWNTO 0);
???? //被乘数
???? START:IN STD_LOGIC;
???? CH:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
???? CL:OUT STD_LOGIC_VECTOR(15 DOWNTO O));
END MULTIPLY;
ARCHITECTURE BEHAV OF MULTIPLY IS
SIGNAL L8:STD_LOGIC_VECTOR(15 DOWNTO O);
BEGIN
PROCESS(CLK)
VARIABLE ACC:STD_LOGIC_VECTOR(31 DOWNTO 0);
VARIABLE N:STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE Q:STD_LOGIC_VECTOR(31 DOWNTO O);
VARIABLE MA:STD_LOGIC_VECTOR(31 DOWNTO O);
BEGIN
IF START='1'THEN
IF CLK'EVENT AND CLK='1'THEN
?? MA(31 DOWNTO 0):="0000000000000000"&A(15
DOWNTO 0);
?? ACC:="00000000000000000000000000000000";
???? FOR I IN 0 TO 15 LOOP
???? FOR JIN 0 TO 31 LOOP
???? Q(J):=B(I) AND MA(J);???? //B(I)与MA相"与"
???? END LOOP;
???? ACC:=ACC+Q;???? //累加
???? MA(31 DOWNTO 0):=MA(30 DOWNTO 0)&MA(31);
???? //左移
ENDLOOP;
CH<=ACC(31 downto 16);?? //乘积的高16位
CL<=ACC(15 downto 0);?? //乘积的低16位
ENDIF;
ENDIF;
END PROCESS;
END BEHAV;

综合后生成的乘法器宏如图2所示。

图2二进制乘法器
2?? 二进制除法的改进
???? 由于在FPGA中实现二进制除法的算法十分复杂,我们在实现二进制除法时,采取被除数与除数的倒数相乘的方法。因此,在给定除数的同时必须计算出除数的倒数,由于除数的倒数是小数形式(除数为1时,倒数为1),因此我们将此倒数的小数部分的16位和整数部分的最后1位(主要考虑除数为1时,倒数的整数部分为1)记录成17位二进制。这样可以与被除数进行二进制乘法运算。乘积的后16位为商的小数部分。前面为商的整数部分。
???? 在FPGA中,我们将除数作为寄存器的地址,其倒数的小数部分作为寄存器的内容。这样,再计算除数的倒数,就相当于一次寄存器的寻址。图3为改进的除法原理框图。

图3改进的除法原理框图
???? 用VHDL设计的查表程序如下(它可在一个时钟周期内将除数B转换成1/B,输出结果M的低16位为倒数的小数部分,M的第17位为倒数的整数部分):

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY TABLE IS
?? PORT(
?? N:IN STD_LOGIC_VECTOR (7 downto 0);
?? CLK:IN STD_LOGIC;
?? READ:IN STD_LOGIC;
?? M:out STD_LOGIC_VECTOR(16 downto 0)//倒数的
???? //整数M(16)和小数部分M(15:0)
?? );
END TABLE;
ARCHITECTURE TABLE_ARCH OF TABLE IS
SIGNAL L8:STD_LOGIC_VECTOR(16 DOWNTO 0);
BEGIN
PROCESS(CLK,READ)
IF READ='l'THEN
IF CLK'EVENT AND CLK='l'THEN
WHEN"00000001"=>L8<="10000000000000000";
WHEN"00000010"=>L8<="01000000000000000";
WHEN"00000011"=>L8<="00101010101010101";
WHEN"00000100"=>L8<="00100000000000000";
WHEN"00000101"=>L8<="00011001100110011";
WHEN"00000110"=>L8<="00010101010101010";
WHEN"00000111"=>L8<="00010010010010010";
WHEN"11111001"=>L8<="00000000100000111";
WHEN"11111010"=>L8<="00000000100000110";
WHEN"11111011"=>L8<="00000000100000101";
WHEN"11111100"=>L8<="00000000100000100";
WHEN"11111101"=>L8<="00000000100000011";
WHEN"11111110"=>L8<="00000000100000010";
WHEN"11111111"=>L8<="00000000100000001";
WHEN OTHERS=>L8<="ZZZZZZZZZZZZZZZZZ";
//以上为1-255的倒数
END CASE;
M<=L8;
ENDIF;
ENDIF;
END PROCESS;
END TABLE_ARCH;

???? 综合后生成倒数转换寄存器的宏如图4所示。

图4除数转化其倒数寄存器
???? 用原理图将上面所生成的宏连接成完整的除法器如图5所示。其中A[15:0]为被除数,B[7:0]为除数,c[31:16]为商的整数部分,C[15:0]为商的小数部分。

图5 完整的二进制除法器
???? 我们选择几对被除数和除数进行了仿真,其结果如图6和表1所示。

表1部分仿真结果
被除数 除数商的整数部分商的小数部分0450 68000A 9CE0003668000084E40256680005 BFA4 025639000A 7BFE016817 000F A668
结语
???? 应用上述的二进制乘法和二进制除法,我们解决了工程中所需的乘法和除法运算问题。其中除法运算的商可以精确到小数点后面16位,达到了工程中对运算精度的要求。二进制乘法可以扩展到任意位数,二进制除法中被除数可以为任意位数。由于本方法中除数转换为其倒数的过程是由作者手工输入,并作为寄存器的内容进行存储的,???? 因此只考虑了除数为8位的情况,当然,也可以完成更高位的寄存器寻址,但工作量很大。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -