[英]VHDL 4-bit binary divider
I am trying to make a binary divider to be part of a calculator using VHDL, I have written the code that I think should work but have been stuck for hours, can someone please help me. 我正在尝试使用VHDL使二进制除法器成为计算器的一部分,我编写了一些代码,虽然我认为它应该可以工作,但是已经停滞了几个小时,请有人帮我。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Div is
Port ( Ain : in STD_LOGIC_VECTOR (3 downto 0);
Bin : in STD_LOGIC_VECTOR (3 downto 0);
Q : out STD_LOGIC_VECTOR (3 downto 0);
R : out STD_LOGIC_VECTOR (3 downto 0));
end Div;
architecture Behavioral of Div is
Signal Atemp : Std_Logic_Vector (3 downto 0);
begin
Proc1: Process (Ain,Bin, Atemp)
variable cnt : STD_LOGIC_Vector(3 downto 0);
begin
if (Ain < Bin) then
cnt := "0000";
Atemp <= Ain;
elsif (Ain = Bin) then
cnt := "0001";
elsif (Ain > Bin) then
cnt := "0001";
Atemp <= (Ain - Bin);
while (Atemp >= Bin) loop
if(Atemp >=Bin) then
Atemp <= (Atemp - Bin);
cnt := cnt + "0001";
end if;
end loop;
end if;
Q <= cnt;
R <= Atemp;
end process Proc1;
end Behavioral;
In the iteration part of the divide process, when Ain > Bin
, the assign Atemp <= (Ain - Bin)
is always performed, even if the iteration should be completed. 在除法过程的迭代部分中,当Ain > Bin
时,即使应完成迭代,也始终执行赋值Atemp <= (Ain - Bin)
。 Process that assign to a signal also in the sensitivity list, is hard to get right. 在灵敏度列表中也分配给信号的过程,很难正确进行。
The code may be updated with Atemp as a variable instead, some other simplifications with removal of unrequired code, and adding value for remainder when Ain = Bin
, resulting in architecture as: 可以使用Atemp作为变量来更新代码,或者通过删除不需要的代码来进行其他一些简化,并在Ain = Bin
时增加余数的值,从而导致体系结构为:
architecture Behavioral of Div is
begin
Proc1 : process (Ain, Bin) is
variable cnt : std_logic_vector(3 downto 0);
variable Atemp : std_logic_vector(3 downto 0);
begin
if (Ain < Bin) then
cnt := "0000";
Atemp := Ain;
elsif (Ain = Bin) then
cnt := "0001";
Atemp := (others => '0'); -- Added to give correct remainder
elsif (Ain > Bin) then
cnt := "0001";
Atemp := (Ain - Bin);
while (Atemp >= Bin) loop
-- Removed trivial true if statement, since condition identical to condition in while
Atemp := (Atemp - Bin);
cnt := cnt + "0001";
end loop;
end if;
Q <= cnt;
R <= Atemp;
end process Proc1;
end Behavioral;
The inner process statements may actually be reduced to: 内部流程语句实际上可以简化为:
cnt := "0000";
Atemp := Ain;
while (Atemp >= Bin) loop
Atemp := (Atemp - Bin);
cnt := cnt + "0001";
end loop;
Q <= cnt;
R <= Atemp;
Whether this will synthesize to the required frequency with the unrolled while
is another question, that depends on the target frequency and technology. 是否将其与展开的while
合成为所需的频率是另一个问题,这取决于目标频率和技术。
An alternative solution, given the short Ain
and Bin
, is to implement the divider using a constant lookup table, with address as Ain & Bin
and output of Q & R
. 给定简短的Ain
和Bin
的另一种解决方案是使用常数查找表来实现除法器,地址为Ain & Bin
并输出Q & R
。 This will evaluate in fixed time, and synthesis is very likely to reduce considerably if made as combinatorial logic. 这将在固定时间内进行评估,并且如果将其作为组合逻辑,则合成很可能会大大减少。
Last comment is that you may also want to handle division by zero, when Bin
is zero. 最后的评论是,当Bin
为零时,您可能还想处理零除。
To prevent mistakes, it is advisable to use explicitly the type unsigned or signed when implementing arithmetic circuits. 为防止错误,建议在实现算术电路时明确使用unsigned或signed类型。 The numeric_std package contains the following arithmetic operators for these types: +, -, *, /, abs, rem, mod. numeric_std软件包包含以下针对这些类型的算术运算符:+,-,*,/,abs,rem,mod。
Below is a suggested code (for unsigned division). 以下是建议的代码(用于无符号除法)。 Note that some lines in the arch can be eliminated, but were used to make the code more "didactic". 请注意,可以消除拱门中的某些行,但这些行用于使代码更具“指导性”。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity divider is
generic (size: natural := 4);
port (
A: in std_logic_vector(size-1 downto 0);
B: in std_logic_vector(size-1 downto 0);
Q: out std_logic_vector(size-1 downto 0);
R: out std_logic_vector(size-1 downto 0));
end entity;
architecture direct of divider is
signal Auns, Buns, Quns, Runs: unsigned(size-1 downto 0);
begin
--Convert inputs to unsigned:
Auns <= unsigned(A);
Buns <= unsigned(B);
--Do the division:
Quns <= Auns/Buns;
Runs <= Auns rem Buns; --Or: Runs <= Auns - resize(Quns*Buns, size);
--Covert results to std_logic_vector:
Q <= std_logic_vector(Quns);
R <= std_logic_vector(Runs);
end architecture
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.