用VHDL实现定点无符号数阵列乘法器
实现阵列乘法器前,我们先想一想如果手算二进制的乘法,是如何进行的呢?下面给出计算过程:
可以看到:我们是把乘数的每一位与被乘数进行相与操作,然后进行相加操作。而实际的阵列乘法器也是这样实现的。我们这里实现一个4*4的阵列乘法器。
容易想到,阵列乘法器是由以下模块拼接而成的:
实现4*4阵列乘法器只需将16个上述模块拼接:
##一、 基本模块说明
一个基本的模块由与门和一位全加器组成。与门不必多说,我们主要想一想一位全加器如何实现。首先一位全加器的输入端口是两个bit位(记为a和b)和低位的进位(记为cin),输出端口是本位和(记为s)以及向高位的进位(记为cout)。以下是一位全加器的真值表:
可以看到当a、b、cin中有奇数个1时,本位和s为1;偶数个1时,本位和s为0,故本位和是三个输入的异或,即s = a xor b xor cin。
而当a、b、cin中至少有两个1时,向高位的进位cout是1,否则是0。故进位表达式为cout = (a and b) or (a and cin) or (b and cin)。
有了以上的基础,我们就可以用硬件描述语言实现基本模块,以下是代码实现:
s <= (a and b) xor p xor cin;
cout <= ((a and b) and p) or ((a and b) and cin) or (p and cin);
二、模块连接
给每一个模块定义用来存储向高位的进位和部分积信息的信号:
signal temp1 : std_logic_vector(3 downto 0);--第1行部分积
signal temp2 : std_logic_vector(3 downto 0);--第2行部分积
signal temp3 : std_logic_vector(3 downto 0);--第3行部分积
signal temp4 : std_logic_vector(3 downto 0);--第4行部分积
signal ctemp1 : std_logic_vector(3 downto 0);--第1行进位
signal ctemp2 : std_logic_vector(3 downto 0);--第2行进位
signal ctemp3 : std_logic_vector(3 downto 0);--第3行进位
signal ctemp4 : std_logic_vector(3 downto 0);--第4行进位
然后将各个模块连接:
其中第一行的部分积都为0,从第二行开始每一行的前3位部分积来自上一行模块的本位和,最后1位部分积来自上一行的最后一个模块的进位。
每一行的进位依次传递,每行最低位的进位是0。
以下是具体代码:
u1 : faddmul port map(x(0),y(0),'0','0',temp1(0),ctemp1(0));
u2 : faddmul port map(x(1),y(0),'0',ctemp1(0),temp1(1),ctemp1(1));
u3 : faddmul port map(x(2),y(0),'0',ctemp1(1),temp1(2),ctemp1(2));
u4 : faddmul port map(x(3),y(0),'0',ctemp1(2),temp1(3),ctemp1(3));
u5 : faddmul port map(x(0),y(1),temp1(1),'0',temp2(0),ctemp2(0));
u6 : faddmul port map(x(1),y(1),temp1(2),ctemp2(0