VHDL__原码一位乘
摘要:记录用VHDL实现原码一位乘的过程,包括模块的分析以及给出端口定义,实体说明,因为比较简单,并未给出完整代码。另外,这篇文章在代码段的显示上有问题,好像识别不了代码段结束符,导致从第一段代码开始一直到文末我找不到原因,希望有大佬知道的告诉我一下。
自己琢磨的过程还是比较难受的,虽然是一个简单的知识点,但VHDL是一回事,原码一位乘的原理是一回事,用VHDL实现原码一位乘又是一回事,但是毕竟是基础,理解整个过程对以后都有好处,二位乘也只是选择的条件和选择相加的对象改一下,整体小改即可,后续会加入博客中供参考,废话少说,下面开始。
一、原码一位乘原理:
以8位相乘的过程为例,可能更好理解过程
乘数是 Y:1001 0101(95)
被乘数是 X:1111 0110(F6)
相乘结果是(1000 1111 0010 1110)(8f2e)
二、VHDL设计
- 移位寄存器设计
先从简单的开始,可以看到表格右侧的操作是对乘数作右移操作,然后根据移出位作判断下一步是作+X还是+0,这里可以设置移位模块,由时钟驱动,输入为乘数,乘法开始后进行n-1次右移操作,输出为移出位。
下面是实体部分
component SREG8B is
port(clk : in STD_LOGIC;
LOAD : in STD_LOGIC;
DIN : in STD_LOGIC_VECTOR(7 downto 0);
QB : OUT STD_LOGIC);
end component;
```
2. 加法器
  可以看到每次都有加法操作,加法操作实际上是部分积的高8位和乘数(这里是1111 0110)相加,结果存在新的部分积,进位存在新的部分积最高位。因此为了方便模块间交互,这里将加法器的输出设置为9位,第九位存放进位.
  
下面是实体部分
```VHDL
component adder_8B is
port(a : in STD_LOGIC_VECTOR(7 downto 0);
b : in STD_LOGIC_VECTOR(7 downto 0);
cin : in STD_LOGIC;
cout : out STD_LOGIC;
sum : out STD_LOGIC_VECTOR(8 downto 0));
end component;
```
3. 选择器(得到被乘数)
  前面也看到了,需要根据移位移出位来判断是+X还是+0,实际上移出位是0或者1,只需要将移出位和被除数相与即可得到本次操作的被乘数。
下面是实体部分
```VHDL
component ANDARITH is
port(ABIN : in STD_LOGIC;
DIN : in STD_LOGIC_VECTOR(7 downto 0);
DOUT : out STD_LOGIC_VECTOR(7 downto 0));
end component;
```
4. 16位移位寄存器
  实际上很容易看出最后的结果,最低位是由D的部分移位来的,与A的部分没有关系(都被移出去了)。
  再重新看这个图,分析结果的构成,发现,结果是由加法器的结果构成高9位,低7位是由上一次D+A(不包括A0)的(7 downto 1)构成的,这就很好实现了。
  
下面是实体部分
```VHDL
component REG16B is
port(clk : in STD_LOGIC;
CLR : in STD_LOGIC;
D : in STD_LOGIC_VECTOR(8 downto 0);
Q : out STD_LOGIC_VECTOR(15 downto 0));
end component;
```
5. 控制器
  上面只是单个功能的分析和实现,都比较容易,那整体来看呢,移位模块不可能一直移位啊,选择器也不会一直工作,自然,就会想到用计数器控制整个乘法周期,8次操作一个周期,整个操作都完成了输出done信号,底下不需要一直工作的模块用控制器生成的时钟控制,乘法完成后,时钟置0,等待下一次乘法指令的开始信号到来,本次的乘法开始信号也可以作为下面16位寄存器的清零信号以及移位寄存器的输入使能。
下面是实体部分
```VHDL
component ARICTL is
port(clk : in STD_LOGIC;
START : in STD_LOGIC;
CLKOUT,RESTALL,DONE:OUT STD_LOGIC);
end component;
仿真结果
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 不听话的兔子君!