在 VHDL 中实现计数器

Implementing a counter in VHDL

下面的代码实现了一个两位数的计数器并在七段上显示输出。可以看出,在每个时钟周期中,该值都必须更改,但仿真结果并未显示这种情况。为了减少代码量,我在七段驱动中只放了0和1。

library ieee;
use ieee.std_logic_1164.all;

entity two_digit_counter is
    port( clk: in std_logic;
          x, y: out std_logic_vector( 6 downto 0 ));
end;

architecture x of two_digit_counter is
begin
    process( clk )
        variable d1 : integer range 0 to 9 := 0;
        variable d2 : integer range 0 to 9 := 0;
    begin
        if (clk'event and clk = '1') then
            if d1 = 9 then
                d1 := 0;
                d2 := d2 + 1;
            elsif d2 = 9 then
                d2 := 0;
                d1 := 0;
            else
                d1 := d1 + 1;
            end if;
        end if;

        case d1 is
            when 0   =>    x <= "1111110";  -- 7E
            when 1   =>    x <= "0110000";  -- 30
        end case;
        case d2 is
            when 0   =>    x <= "1111110";
            when 1   =>    x <= "0110000";
        end case;
    end process;
end;

你不是说:

    case d2 is
        when 0   =>    y <= "1111110";
        when 1   =>    y <= "0110000";
    end case;
    --                 ^
    --                 |
    --        shouldn't this be y ?

您的意思是 case d2 覆盖 case d1 语句分配给 x 的值吗?或者你的意思是 y?

如果从 d1 和 d2 导出 x 和 y 的逻辑是纯组合的,您可以将其移出进程。

不幸的是,除了缺少对 y 的分配外,您的 d2 计数器无法正常工作:

d2 底部跟踪应保存 d1 的 10 个计数的每个值(这里显示为十秒。if 语句不全面,应该更改。d1 也显示不正确。

通过嵌套两个计数器 if 语句来解决这个问题:

    process (clk)
        variable d1 : integer range 0 to 9 := 0;
        variable d2 : integer range 0 to 9 := 0;
    begin
        if rising_edge(clk) then
            -- if d1 = 9 then
            --     d1 := 0;
            --     d2 := d2 + 1;
            -- elsif d2 = 9 then
            --     d2 := 0;
            --     d1 := 0;
            -- else
            --     d1 := d1 + 1;
            -- end if;
            if d1 = 9 then       -- nested if statements
                d1 := 0;
                if d2 = 9 then
                    d2 := 0;
                else
                    d2 := d2 + 1;
                end if;
            else
                d1 := d1 + 1;
            end if;
        end if; 
        case d1 is
            when 0   =>    x <= "1111110";  -- 7E
            when 1   =>    x <= "0110000";  -- 30
            when 2   =>    x <= "1101101";  -- 6D
            when 3   =>    x <= "1111001";  -- 79
            when 4   =>    x <= "0110011";  -- 33
            when 5   =>    x <= "1011011";  -- 5B
            when 6   =>    x <= "1011111";  -- 5F
            when 7   =>    x <= "1110000";  -- 70
            when 8   =>    x <= "1111111";  -- 7F
            when 9   =>    x <= "1111011";  -- 7B
        end case;
        case d2 is
            when 0   =>    y <= "1111110";   -- WAS assignment to x
            when 1   =>    y <= "0110000";   -- ""
            when 2   =>    y <= "1101101";
            when 3   =>    y <= "1111001";
            when 4   =>    y <= "0110011";
            when 5   =>    y <= "1011011";
            when 6   =>    y <= "1011111";
            when 7   =>    y <= "1110000";
            when 8   =>    y <= "1111111";
            when 9   =>    y <= "1111011";
        end case;
    end process;

这会产生:

如果您的问题提供了 Minimal, Complete and Verifiable example.

,您的问题的其他答案可能会指出这一点