I have written this BCD-Counter in VHDL but the 10th place counter counts up every clock cylce instead of once, so instead of going from 09 to 10, the output is 09,19,29,39,... until bcd1_overflow is '0' again as you can see in the screenshot.
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;
I tried having a synchronous bcd1_overflow_pulse, but it was off by some clock cyles, also I tried making the condition for Counter_10 to count up "bcd1_overflow and clock_seconds" but that didn't work either.
If you want to try something out with my code, here is the code for the components I used:
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;
The error is that you clock the tens' counter Counter_10
with clk
and enable it with bcd1_overflow
, which is 1
during multiple clock cycles. With each clock it advances, as you observed.
One possible solution is to AND clock_seconds
and bcd1_overflow
before using it to enable Counter_10
.