Я написал этот счетчик BCD на VHDL, но счетчик 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_секунды», но это тоже не сработало.
Если вы хотите попробовать что-нибудь с моим кодом, вот код компонентов, которые я использовал:
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;
count_10 считает несколько раз. Он активируется, когда значение BCD Count_1 равно «1001» (9). Разрешением для count_10 может быть логическое И для включения Count_1 (действительно в течение 1 такта) и выходным сигналом, указывающим «count_1 = 1001», чтобы обеспечить одно приращение count_10. Минимальный воспроизводимый пример предоставит тестовый стенд, позволяющий воспроизвести проблему и продемонстрировать решение. Минимальные реализации BCDDecoder не требуется включать (ни в изображение сигнала, которое может быть заменено конкретной проблемой, описывающей последовательные тактовые сигналы, когда параметр включения count_10 равен «1»). Вы можете ответить себе.
Исключение ответа на проблему, которое невозможно воспроизвести, или решение, проверенное без тестового стенда, дает вам ответ, а что насчет будущих читателей, которые не могут увидеть проблему или решение на практике, не имея возможности? Обратите внимание, что занятая пчела не сообщила вам, что в списке чувствительности процесса GenericBCDCounter отсутствует сброс, часть оператора if не нужна (и почему) и переполнение не должно быть триггером.





Ошибка заключается в том, что вы синхронизируете счетчик десятков Counter_10 с помощью clk и включаете его с помощью bcd1_overflow, то есть 1 в течение нескольких тактов. Как вы заметили, с каждым часом оно продвигается вперед.
Одним из возможных решений является использование AND clock_seconds и bcd1_overflow перед его использованием, чтобы включить Counter_10.
Пожалуйста, предоставьте минимально воспроизводимый пример с акцентом на «полный».