为什么这个VHDL计数器不会计数

时间:2013-12-08 18:19:43

标签: vhdl

我做了这个计数器,我确信它应该可以工作,但我的矢量波形文件说不然。 Y仅显示为启动器的4位数字,这是没有意义的

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter is generic (
    startnum : natural := 0;
    N : natural := 16
); port ( 
    --Inputs
    EN      : in std_logic;
    synchr  : in std_logic;
    asyncr  : in std_logic;
    dir     : in std_logic; -- 0 for count down 1 for count up.
    clk     : in std_logic;
    --Outputs
    Y       : out natural range startnum to n-1
);
end entity;

architecture counter_v1 of counter is
    signal cntconst :   integer;
begin
    process (dir)               --dir in sensitivity list as when this changes we want this process to run.
    begin
        if (dir = '0') then
            cntconst <= -1;                 --this will count down when added onto to the counter value
        end if;
        if (dir = '1') then
            cntconst <= 1;
        end if;
    end process;

    process (asyncr, clk)
        variable countvar : integer range startnum to n-1;--I tried to just use y but for some reason it won't allow that.
    begin
        if (en = '0') then
        else
            if (asyncr = '1') then
                countvar := 0;
            else
            --if (clk = '1') then
                --if (synchr = '1') then
                    --countvar := 0;
                --end if;
            --end if;
            end if;
            if (cntconst < n-1) then
                if (dir = '1') then
                    countvar := countvar + cntconst;
                end if;
            end if;
            if (cntconst > startnum) then
                if (dir = '0') then
                    countvar := countvar + cntconst;
                end if;
            end if;
        end if;
        y <= cntconst;
    end process;
end counter_v1;

任何帮助都会很棒......我现在完全失去了 谢谢。

3 个答案:

答案 0 :(得分:3)

您错过了对rising_edge(clk)的检查,您的同步过程可以简化。尝试:

architecture counter_v1 of counter is
    signal y_int: natural range y'range;
begin
    y <= y_int;

    process (asyncr, clk)
    begin
        if(asyncr = '1') then
            y_int < = 0;
        elsif(rising_edge(clk)) then
            if(en = '1') then
                if(dir = '1') then
                    if(y_int < y_int'high) then
                        y_int < = y_int + 1;
                    end if;
                else
                    if(y_int > y_int'low) then
                        y_int <= y_int - 1;
                    end if;
                end if;
            end if;
        end if;
    end process;
end architecture;

我做了一些更改,使代码更像FPGA逻辑单元:

  • 删除同步重置:通常,您只需要一种重置
  • en内移动rising_edge(clk)检查:en通常是时钟启用,因此不应影响异步重置

答案 1 :(得分:3)

你已经将Y定义为0到15的自然范围。这很适合4位!

答案 2 :(得分:2)

请注意,在原始代码中,输出Y的驱动基于:

y <= cntconst;

其中cntconst仅由输入dir派生,看起来像是内部方向指示,因此不是应该是计数器状态的countvar。由于cntconst是整数范围,因此会出现范围违规,并且可以为-1,其中Y只是自然范围。