VHDL向上/向下计数器错误计数

时间:2017-06-08 13:55:31

标签: vhdl

我试图制作一个计数最多为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而没有显示中间数字。 有什么问题?

1 个答案:

答案 0 :(得分:4)

您没有查看所有信号:查看down以了解会发生什么。由于您使用的是时钟/同步逻辑,down会在检测到temp的时钟周期内发生变化3,因此它将在一个时钟周期后生效。即当temp为3时,down仍为0,因此(3 + 1)mod 4 = 0.

一种可能的解决方案是领先一步:在down = 2时更改temp 提前一个时钟周期 ....

另一个问题是您将非标准化包STD_LOGIC_ARITHSTD_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空格缩进:(使用4,像每个人一样)