VHDL up/down 计数器错误计数
VHDL up/down counter error counting
我正在尝试制作一个计数器,它可以从 3 开始计数,然后从 0 开始计数,等等。
示例:0 1 2 3 2 1 0 1 2 3 2 1 0...
我做了什么:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
port(
Clock: in std_logic;
Reset: in std_logic;
Output: out std_logic_vector(0 to 1 ));
end Counter;
architecture Behavioral of Counter is
signal temp: std_logic_vector(0 to 1);
signal down: std_logic := '0';
begin process(Clock,Reset)
begin
if Reset='0' then
temp <= "00";
down<= '0';
elsif(rising_edge(Clock)) then
if temp="11" then
down<= '1';
elsif temp="00" then
down<='0';
end if;
if down='0' then
temp <= temp +1;
else
temp <= temp-1;
end if;
end if;
end process;
Output <= temp;
end Behavioral;
不知何故输出从 3 变为 0 而没有显示中间数字..
怎么了?
您没有查看所有信号:查看 down
看看会发生什么。因为你用的是clocked/synchronous逻辑,down
是在检测到temp
的时钟周期3改变的,所以会在一个时钟周期后生效]. IE。当 temp
为 3 时,down
仍为 0,因此 (3+1) mod 4 = 0.
一个可能的解决方案是提前一步:将down
提前一个时钟周期...当temp
=2.
另一个问题是您将非标准化包 STD_LOGIC_ARITH
和 STD_LOGIC_UNSIGNED
与逻辑阵列反向组合。这可能会产生不可预测的结果。请使用标准化包。示例:
library ieee;
use ieee.STD_LOGIC_1164.ALL;
entity counter is
port(
clk : in std_logic;
rst_n : in std_logic;
output : out std_logic_vector(1 downto 0)
);
end entity;
architecture behavioral of counter is
use ieee.numeric_std.ALL;
signal temp : unsigned(output'range) := (others => '0');
signal down : std_logic := '0';
begin
process(clk, rst_n)
begin
if rst_n = '0' then -- why asynchronous reset??
temp <= (others => '0');
down <= '0';
elsif(rising_edge(clk)) then
if temp = 2 then
down <= '1';
elsif temp = 1 then
down <= '0';
end if;
if down = '0' then
temp <= temp + 1;
else
temp <= temp - 1;
end if;
end if;
end process;
output <= std_logic_vector(temp);
end architecture;
-
entity counter_tb is end entity;
library ieee;
use IEEE.STD_LOGIC_1164.ALL;
architecture behavioral of counter_tb is
signal clk : std_logic;
signal rst_n : std_logic;
signal output : std_logic_vector(1 downto 0);
begin
DUT: entity work.Counter
port map(
clk => clk,
rst_n => rst_n,
output => output
);
rst_n <= '1';
process
begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
end architecture;
下次请加上你的测试台配套...
请不要使用 3-space 缩进 :( 使用 4,就像每个人一样)
我正在尝试制作一个计数器,它可以从 3 开始计数,然后从 0 开始计数,等等。 示例:0 1 2 3 2 1 0 1 2 3 2 1 0...
我做了什么:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
port(
Clock: in std_logic;
Reset: in std_logic;
Output: out std_logic_vector(0 to 1 ));
end Counter;
architecture Behavioral of Counter is
signal temp: std_logic_vector(0 to 1);
signal down: std_logic := '0';
begin process(Clock,Reset)
begin
if Reset='0' then
temp <= "00";
down<= '0';
elsif(rising_edge(Clock)) then
if temp="11" then
down<= '1';
elsif temp="00" then
down<='0';
end if;
if down='0' then
temp <= temp +1;
else
temp <= temp-1;
end if;
end if;
end process;
Output <= temp;
end Behavioral;
不知何故输出从 3 变为 0 而没有显示中间数字.. 怎么了?
您没有查看所有信号:查看 down
看看会发生什么。因为你用的是clocked/synchronous逻辑,down
是在检测到temp
的时钟周期3改变的,所以会在一个时钟周期后生效]. IE。当 temp
为 3 时,down
仍为 0,因此 (3+1) mod 4 = 0.
一个可能的解决方案是提前一步:将down
提前一个时钟周期...当temp
=2.
另一个问题是您将非标准化包 STD_LOGIC_ARITH
和 STD_LOGIC_UNSIGNED
与逻辑阵列反向组合。这可能会产生不可预测的结果。请使用标准化包。示例:
library ieee;
use ieee.STD_LOGIC_1164.ALL;
entity counter is
port(
clk : in std_logic;
rst_n : in std_logic;
output : out std_logic_vector(1 downto 0)
);
end entity;
architecture behavioral of counter is
use ieee.numeric_std.ALL;
signal temp : unsigned(output'range) := (others => '0');
signal down : std_logic := '0';
begin
process(clk, rst_n)
begin
if rst_n = '0' then -- why asynchronous reset??
temp <= (others => '0');
down <= '0';
elsif(rising_edge(clk)) then
if temp = 2 then
down <= '1';
elsif temp = 1 then
down <= '0';
end if;
if down = '0' then
temp <= temp + 1;
else
temp <= temp - 1;
end if;
end if;
end process;
output <= std_logic_vector(temp);
end architecture;
-
entity counter_tb is end entity;
library ieee;
use IEEE.STD_LOGIC_1164.ALL;
architecture behavioral of counter_tb is
signal clk : std_logic;
signal rst_n : std_logic;
signal output : std_logic_vector(1 downto 0);
begin
DUT: entity work.Counter
port map(
clk => clk,
rst_n => rst_n,
output => output
);
rst_n <= '1';
process
begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
end architecture;
下次请加上你的测试台配套... 请不要使用 3-space 缩进 :( 使用 4,就像每个人一样)