VHDL 中的二进制编码十进制计数器

问题描述 投票:0回答:1

我已经用VHDL编写了这个BCD计数器,但是第10位计数器在每个时钟周期计数而不是一次,所以输出不是从09到10,而是09,19,29,39,...直到bcd1_overflow正如您在屏幕截图中看到的那样,再次“0”。

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

entity Counter7Segments is
  port(
    clk : in std_logic;
    reset : in std_logic;
    segments_1 : out std_logic_vector(6 downto 0);
    segments_10 : out std_logic_vector(6 downto 0)
  );
end Counter7Segments;

architecture rtl of Counter7Segments is

component ClockEnableGenerator is
  generic(
    DIVIDE_BY : integer
  );

  port(
    clk_in : in std_logic;
    clk_en_out : out std_logic;
    reset : in std_logic
  );
end component;

component GenericBCDCounter is
  generic(
    COUNT_MAX : integer
  );

  port(
    clk : in std_logic;
    enable : in std_logic;
    reset : in std_logic;
    count : out std_logic_vector(3 downto 0);
    overflow : out std_logic
  );
end component;

component BCDDecoder is
  port(
    digit : in std_logic_vector(3 downto 0);
    segments : out std_logic_vector(6 downto 0)
  );
end component;

signal clock_seconds : std_logic;
signal count_1 : std_logic_vector(3 downto 0);
signal count_10 : std_logic_vector(3 downto 0);
signal bcd1_overflow : std_logic;

begin

Clock : ClockEnableGenerator
  generic map(
    DIVIDE_BY => 13
  )

  port map(
    clk_in => clk,
    clk_en_out => clock_seconds,
    reset => reset
  );

Counter_1 : GenericBCDCounter
  generic map(
    COUNT_MAX => 9
  )

  port map(
    clk => clk,
    enable => clock_seconds,
    reset => reset,
    count => count_1,
    overflow => bcd1_overflow
  );

Counter_10 : GenericBCDCounter
  generic map(
    COUNT_MAX => 5
  )

  port map( 
    clk => clk,
    enable => bcd1_overflow,
    reset => reset,
    count => count_10,
    overflow => open
  );

Decoder_1 : BCDDecoder
  port map(
    digit => count_1,
    segments => segments_1
  );

Decoder_10 : BCDDecoder
  port map(
    digit => count_10,
    segments => segments_10
  );

end architecture rtl;

我尝试使用同步bcd1_overflow_pulse,但它被一些时钟周期关闭,我还尝试为Counter_10设置条件来计数“bcd1_overflow和clock_seconds”,但这也不起作用。

如果您想尝试使用我的代码,这里是我使用的组件的代码:

library ieee;
use ieee.std_logic_1164.all;

entity BCDDecoder is

port(
  digit : in std_logic_vector(3 downto 0);
  segments : out std_logic_vector(6 downto 0)
);

end BCDDecoder;

architecture rtl of BCDDecoder is

begin

process(digit)
begin
  if(digit = "0000") then
    segments <= "1111110";
  elsif(digit = "0001") then
    segments <= "0110000";
  elsif(digit = "0010") then
    segments <= "1101101";
  elsif(digit = "0011") then
    segments <= "1111001";
  elsif(digit = "0100") then
    segments <= "0110011";
  elsif(digit = "0101") then
    segments <= "1011011";
  elsif(digit = "0110") then
    segments <= "1011111";
  elsif(digit = "0111") then
    segments <= "1110000";
  elsif(digit = "1000") then
    segments <= "1111111";
  elsif(digit = "1001") then
    segments <= "1111011";
  end if;
end process;

end architecture rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ClockEnableGenerator is

generic(
  DIVIDE_BY : integer
);

port(
  clk_in : in std_logic;
  reset : in std_logic;
  clk_en_out : out std_logic
);

end ClockEnableGenerator;

architecture rtl of ClockEnableGenerator is

signal counter : unsigned(3 downto 0) := "0000";

begin

process(clk_in, reset)
begin
  if(reset = '1') then
    clk_en_out <= '0';
    counter <= "0001";
  elsif(rising_edge(clk_in)) then
    if(counter = DIVIDE_BY - 1) then
      counter <= (others => '0');
      clk_en_out <= '1';
    else
      clk_en_out <= '0';
      counter <= counter + 1;
    end if;
  end if;
end process;

end architecture rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity GenericBCDCounter is

generic(
  COUNT_MAX : integer
);

port(
  clk : in std_logic;
  reset : in std_logic;
  enable : in std_logic;
  count : out std_logic_vector(3 downto 0);
  overflow : out std_logic
);

end GenericBCDCounter;

architecture rtl of GenericBCDCounter is

signal value : unsigned(3 downto 0);

begin

process(clk)
begin
  if(reset = '1') then
    value <= (others => '0');
    overflow <= '0';
  elsif(rising_edge(clk)) then
    if(enable = '1') then
      if(value = COUNT_MAX) then
        value <= (others => '0');
      else
        value <= value + 1;
      end if;

      if(value + 1 = COUNT_MAX) then
        overflow <= '1';
      else
        overflow <= '0';
      end if;
    else
      if(value = COUNT_MAX) then
        overflow <= '1';
      else
        overflow <= '0';
      end if;
    end if;
  end if;
end process;

count <= std_logic_vector(value);

end architecture rtl;
vhdl counter bcd
1个回答
0
投票

错误在于您使用

Counter_10
对十位计数器
clk
进行计时,并使用
bcd1_overflow
启用它,即在多个时钟周期内为
1
。正如您所观察到的,每个时钟都会前进。

一种可能的解决方案是在使用它来启用

clock_seconds
之前先对
bcd1_overflow
Counter_10
进行 AND 操作。

© www.soinside.com 2019 - 2024. All rights reserved.