计算机组成原理实验报告_3_不恢复余数阵列除法器
河北大学 计算机组成原理 实验报告
学院 年级 专业 学号 姓名
实验日期 实验地点 指导老师
实验项目 不恢复余数阵列除法器 成绩 一、 实验目的:
理解除法器的原理。
二、实验原理:
这次实验实现原码不恢复余数法的阵列除法器算法(余数左移除数固定),详细计算过程如下。 例题:X=0.10110,y=0.111,求[x/y]原。则[x]补=0.10110,[y*]补=0.111,[-y*]补=1.001
由于除数被除数都为正,因此最后结果为正,直接在最后的结果加上“+”,商为+0.110,但是由于除数在计算的过程中被逻辑左移了3次,所以要乘以2^进行恢复,故余数为0.000 010 000。
-5
原码不恢复余数法原理说明:
①符号位单独处理,参加运算的是除数和被除数的绝对值的补码,除数的绝对值用y*表示; ②合法的除法运算中,被除数必须小于除数,因此第一次上商肯定是r 6=0,否则溢出,停止运算;
③原码恢复余数法来源于手算的竖式除法。若余数为正,表示够减,商上1,左移一位,减去[y*]补,也就是加上[-y*]补;若余数为负,表示不够减,商上0,恢复余数(加上除数),变成减去除数之前的结果,继续左移一位,加上[-y*]补。 ④原码不恢复余数法建立在原码恢复余数法的基础之上,假设当前的余数为R 。当余数大于0时,下一步余数是先左移一位再减去除数,即下一步余数应该为R ’=2R-y*;当余数小于0时先恢复余数,然后再左移一位再减去除数,假设当前余数为R ,那么下一步余数应该为R ’=2(R+y*)-y*=2R+y*。以上两个式子将恢复余数法的步骤定量化了,也就是说,要么左移一位加上y*,要么左移一位减去y*,这就是加减交替的含义。
⑤除数和被除数具有3位尾数的合法的除法,需要逻辑移位3次,上商3+1=4次。可以设置一个计数器count 来控制循环次数,达到3次就停止。
⑥若最后一步为负,表示不够减,商上0,需要恢复余数,即加上除数,否则不需要。 接下来介绍原码不恢复余数阵列除法器 ①可控加法/减法(CAS)单元
原理是利用一个可控加法/减法 CAS 单元所组成的流水阵列来实现的它有四个输出端和 四个输入端。当输入线 P =0 时,CAS 作加法运算;当 P =1 时,CAS 作减法运算。逻辑结构图 如图所示。 不恢复余数阵列除法器的逻辑结构图 CAS 单元的输入与输出的关系可用如下一组逻辑方程来表示:
Si =Ai ⊕(Bi⊕P) ⊕C ,Ci +1=(Ai+Ci)· (Bi⊕P) +AiCi
当 P =0 时,就是一个全加器,如下式: Si =Ai ⊕Bi ⊕Ci ,Ci +1=AiBi +BiCi +AiCi 当 P =1 时, 则得求差公式: Si =Ai ⊕非Bi ⊕Ci ,Ci +1=AiBi +BiCi +AiCi ,其中 非Bi =Bi ⊕1。 在减法情况下, 输入 Ci 称为借位输入, 而 Ci +1 称为借位输出。 ②不恢复余数的除法(加减交替法)
在不恢复余数的除法阵列中,每一行所执行的操作究竟是加法还是减法,取决于前一行输出的符号与被除数的符号是否一致。当出现不够减时, 部分余数相对于被除数来说要改变符号。这时应该产生一个商位“0”,除数首先沿对角线右移,然后加到下一行的部分余数上。当部分余数不改变它的符号时,即产生商位“1”,下一行的操作应该是减法。 本实验就采用加减交替的方法设计这个阵列除法器。
被除数为x= X0.x6x5x4x3x2x1(这里需要右移,是双倍长);除数为y=Y0.y3y2y1。其中 X0 和 Y0 是被除数和除数的符号位,在本次设计中 X0 和 Y0 为零,商的符号位恒为零,商为q4.q3q2q1,余数为0.00r6r5r4r3。字长n+1=4
由图看出,该阵列除法器是用一个可控加法/减法(CAS)单元所组成的流水阵列来实现的。推广到一般情况,一个(n+1) 位除(n+1) 位的加减 交替除法阵列由(n+1)2个CAS 单元组成,其中两个操作数(被除数与除数) 都是正的。
(1)单元之间的互连是用n =3的阵列来表示的。这里被除数x是一 个6位的小数(双倍长度值) :x= X0.x6x5x4x3x2x1它是由顶部一行和最右边的对角线上的垂直输入线来提供的。
(2)除数y是一个3位的小数:y=0.y3y2y1它沿对角线方向进入这个阵列。这是因为,在除法中所需要的部分 余数的左移,可以用下列等效的操作来代替:即让余数保持固定,而将除数沿对角线右移。 (3)商q 是一个3位的小数: q =0.q1q2q3 它在阵列的左边产生。 (4)余数r 是一个6位的小数: r =0.00r3r4r5r6 它在阵列的最下一行产生。
最上面一行所执行的初始操作经常是减法。因此最上面一行的控制 线P 固定置成“1”。减法是用2的补码运算来实现的,这时右端各CAS 单元上的反馈线用作初始的进位输入。每一行最左边的单元的进位输出决定着商的数值。将当前的商反馈到下一行,我们就能确定下一行的操作。由于进位输出信号指示出当前的部分余数的符号,因此,它将决定下一行的操作将进行加法还是减法。
对不恢复余数阵列除法器来说,在进行运算时,沿着每一行都有进位(或借位) 传播,同时所有行在它们的进位链上都是串行连接。而每个CAS 单元的延迟时间为3T 单元,因此,对一个2n 位除以n 位的不恢复余数阵列除法器来说,单元的数量为(n+1) ,考虑最大情况下的信号延迟,其除法执行时间为 td =3(n+1) T
2
2
三、实验步骤:
(1)打开Quartys II。 (2)将子板上的JTAG 端口和PC 机的并行口用下载电缆连接。打开实验台电源。(3)执行Tool →Programmer 命令,将adder8.sof 下载到FPGA 中。注意在执行Programmer 中,应在program/configure下的方框中打钩,然后下载。
(4)在实验台上通过模式开关选择FPGA-CPU 独立调试模式010。
四、实验现象及分析:
本实验实现4位除4位阵列除法器。 输入输出规则对应如下:
(1)输入被乘数A 和乘数B ,A 和B 分别是x= X0.x6x5x4x3x2x1和 y=Y0.y3y2y1 (2)输出的结果是商为q4.q3q2q1,余数为0.00r6r5r4r3。 输入输出范例:
五、实验过程中遇到问题及解决方法:
问题一:阵列除法器采用的过程是什么
解决方法:余数固定除数右移。余数左移除数固定的算法适合除数和被乘数尾数为n 的运算,余数固定除数右移的将例题稍作修改即可。
问题二:阵列除法器是如何做到减去除数,即加上[-y*]补的?
解决方法:变补的法则是:对[y*]补包括符号位“求反且最末位加1”即可得到[-y*]补。阵列除法器只能做加法,通过图中的“非Bi =Bi ⊕1”实现 求反,通过某一行最右侧的Ci (借位输入)为1实现最末位加1。
问题三:实验现象中第一行的运算结果中,余数是1011,是除法器在逗吗?
解决方法:阵列除法器并没有在逗你,采取余数固定除数右移是得到的余数是1.111011,这表明不够减,解决方法是恢复余数,得到余数为0.000 010,或者再算两次,得到余数为0.000 000 01,此时商为0.110 01。而在硬件层面上不实现这个功能。如果允许余数为负数,结果就是对的。 问题四:直接将整个CAS 连接起来可以吗? 解决方法:像
--不恢复余数阵列除法器(4位除4位阵列除法器) library ieee;
use ieee.std_logic_1164.all;
entity composition_7_2_non_restoring_array_divider is
port( x:in std_logic_vector(6 downto 1); --这里编号顺序与课本不同 y: in std_logic_vector(3 downto 1); q: out std_logic_vector(4 downto 1); r:out std_logic_vector(6 downto 3));
end composition_7_2_non_restoring_array_divider;
architecture s_div of composition_7_2_non_restoring_array_divider is component CAS is port( A,B,Ci,P : IN STD_LOGIC; --P ,B :inout std_logic; Pout,Bout,Si,CoPlus : OUT STD_LOGIC );
end component; signal p1out:std_logic_vector(1 to 16); --CAS 的右上部分为加减法控制输出 signal b1out:std_logic_vector(1 to 16); --CAS 的右下部分为输入的B 的输出 signal s1:std_logic_vector(1 to 12); --CAS 的竖线方向为余数输出 signal co1plus:std_logic_vector(1 to 16); --CAS 的左下部分为进位输出 --signal gnd:std_logic := '0'; --'0' begin --cas11:左数第一个,第1行
cas11:CAS port map('0', '0', co1plus(2), '1',p1out(1),b1out(1), s1(1), co1plus(1)); --输出q4
cas31:CAS port map(s1(6), b1out(5),co1plus(10), co1plus(5),p1out(9),b1out(9),s1(9),co1plus(9)); --输出q2 cas32:CAS port map(s1(7), b1out(6),co1plus(11), p1out(9),p1out(10),b1out(10),s1(10),co1plus(10)); cas33:CAS port map(s1(8), b1out(7),co1plus(12), p1out(10),p1out(11),b1out(11),s1(11),co1plus(11)); cas34:CAS port map(x(2), b1out(8),p1out(12), p1out(11),p1out(12),b1out(12),s1(12),co1plus(12)); q(2)
cas41:CAS port map(s1(10), b1out(9),co1plus(14), co1plus(9),p1out(13),b1out(13),r(6),co1plus(13)); --输出q1 cas42:CAS port map(s1(11), b1out(10),co1plus(15), p1out(13),p1out(14),b1out(14),r(5),co1plus(14)); cas43:CAS port map(s1(12), b1out(11),co1plus(16), p1out(14),p1out(15),b1out(15),r(4),co1plus(15)); cas44:CAS port map(x(1), b1out(12),p1out(16), p1out(15),p1out(16),b1out(16),r(3),co1plus(16)); q(1)
--可控加法/减法(CAS)单元controllable_Addition_Unit LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity CAS is port ( A,B,Ci,P : IN STD_LOGIC; --P ,B :inout std_logic; Pout,Bout,Si,CoPlus : OUT STD_LOGIC --输出按图中逆时针方向排列 ); end entity;
ARCHITECTURE rtl OF CAS IS BEGIN Si
CoPlus
做不到按顺序同时地运算,希望有人能解决。
六、实验源码:(加注释)
library ieee;
use ieee.std_logic_1164.all;
entity composition_7_3_non_restoring_array_divider is port( x:in std_logic_vector(6 downto 1); --这里编号顺序与课本不同 y: in std_logic_vector(3 downto 1); q: out std_logic_vector(4 downto 1); r:out std_logic_vector(6 downto 3));
end composition_7_3_non_restoring_array_divider;
architecture s_div of composition_7_3_non_restoring_array_divider is component full_adder is port ( a,b,ci : in std_logic; s,co : out std_logic ); end component; --signal p1out:std_logic_vector(1 to 16); --CAS 的右上部分为加减法控制输出 --signal b1out:std_logic_vector(1 to 16); --CAS 的右下部分为输入的B 的输出 signal s1:std_logic_vector(1 to 12); --CAS 的竖线方向为余数输出 signal co1plus:std_logic_vector(1 to 16); --CAS 的左下部分为进位输出 --signal gnd:std_logic := '0'; --'0' begin
--full_adder11:左数第一个,第1行 full_adder11:full_adder port map('0', ('0' xor'1'), co1plus(2) ,s1(1), co1plus(1)); --输出q4
full_adder24:full_adder port map(x(3), (y(1) xor co1plus(1)),co1plus(1), s1(8),co1plus(8)); q(3)
full_adder31:full_adder port map(s1(6), ('0' xor co1plus(5)),co1plus(10), s1(9),co1plus(9)); --输出q2 full_adder32:full_adder port map(s1(7), (y(3) xor co1plus(5)),co1plus(11), s1(10),co1plus(10)); full_adder33:full_adder port map(s1(8), (y(2) xor co1plus(5)),co1plus(12), s1(11),co1plus(11)); full_adder34:full_adder port map(x(2), (y(1) xor co1plus(5)),co1plus(5), s1(12),co1plus(12)); q(2)
full_adder41:full_adder port map(s1(10), ('0' xor co1plus(9)),co1plus(14), r(6),co1plus(13)); --输出q1 full_adder42:full_adder port map(s1(11), (y(3) xor co1plus(9)),co1plus(15), r(5),co1plus(14)); full_adder43:full_adder port map(s1(12), (y(2) xor co1plus(9)),co1plus(16), r(4),co1plus(15)); full_adder44:full_adder port map(x(1), (y(1) xor co1plus(9)),co1plus(9), r(3),co1plus(16)); q(1)
--全加器FA library ieee;
use ieee.std_logic_1164.all;
entity full_adder is port ( a,b,ci : in std_logic; s,co : out std_logic ); end entity;
architecture rtl of full_adder is begin s