VHDL 4位二​​进制分频器

时间:2013-11-25 21:08:44

标签: binary vhdl divider

我正在尝试使用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;

2 个答案:

答案 0 :(得分:3)

在除法过程的迭代部分,当Ain > Bin时,分配 始终执行Atemp <= (Ain - Bin),即使迭代应该是 完成。在灵敏度列表中也分配给信号的过程是 很难做对。

代码可以用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;

内部流程语句实际上可以简化为:

cnt   := "0000";
Atemp := Ain;
while (Atemp >= Bin) loop
  Atemp := (Atemp - Bin);
  cnt   := cnt + "0001";
end loop;
Q <= cnt;
R <= Atemp;

这是否会在展开时合成到所需的频率 while是另一个问题,取决于目标频率和 技术

给定短AinBin的替代解决方案是实现 divider使用常量查找表,地址为Ain & Bin并输出 Q & R。这将在固定时间内进行评估,并且很可能合成 如果作为组合逻辑而大大减少。

最后一条评论是您可能还希望在Bin时处理除零 是零。

答案 1 :(得分:2)

为防止出错,建议在实现运算电路时明确使用unsigned或signed类型。 numeric_std包包含以下这些类型的算术运算符:+, - ,*,/,abs,rem,mod。

以下是建议的代码(用于无符号除法)。请注意,拱门中的某些线条可以被删除,但用于使代码更“教诲”。

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