我正在尝试使用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;
答案 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
是另一个问题,取决于目标频率和
技术
给定短Ain
和Bin
的替代解决方案是实现
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