Реализация цифровых часов в VHDL - PullRequest
1 голос
/ 24 мая 2011

Я пытаюсь сделать цифровые часы, используя VHDL, и я хочу отобразить результат на экране VGA.Но я застрял с мыслью, что как я могу преобразовать целочисленный тип в BCD?Потому что сейчас я получаю данные о часах, минутах и ​​секундах в виде целого числа, и я хотел бы реализовать их так, чтобы я мог использовать их в своем компоненте VGA наиболее эффективным способом.Что бы вы предложили для этого?

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 25 мая 2011

Если вам нужны таймеры отдельно, вы можете использовать операторы деления и по модулю для преобразования целых чисел в BCD.Тем не менее, это, скорее всего, будет синтезировать довольно плохо.Вместо этого вы можете просто реализовать шесть счетчиков, что-то вроде этого:

library ieee;
use ieee.std_logic_1164.all;

entity clock is
        port (
                resetAX : in std_logic; -- Asynchronous reset, active low
                clk : in std_logic;  -- Clock signal, runs faster than 1/second
                second_enable : in std_logic; -- Signal active (high) only when seconds to be incremented
                h_ms : out std_logic_vector(1 downto 0); -- MS digit of hour (0, 1, 2)
                h_ls : out std_logic_vector(3 downto 0); -- LS digit of hour (0-9)
                m_ms : out std_logic_vector(2 downto 0); -- MS digit of minute (0-5)
                m_ls : out std_logic_vector(3 downto 0); -- LS digit of minute (0-9)
                s_ms : out std_logic_vector(2 downto 0); -- MS digit of second (0-5)
                s_ls : out std_logic_vector(3 downto 0)  -- LS digit of second (0-9)
        );
end clock;

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

architecture rtl of clock is
        signal h_ms_int : integer range 0 to 2;
        signal h_ls_int : integer range 0 to 9;
        signal m_ms_int : integer range 0 to 5;
        signal m_ls_int : integer range 0 to 9;
        signal s_ms_int : integer range 0 to 5;
        signal s_ls_int : integer range 0 to 9;
begin

        COUNT: process(resetAX, clk)
        begin
                if resetAX = '0' then
                        h_ms_int <= 0;
                        h_ls_int <= 0;
                        m_ms_int <= 0;
                        m_ls_int <= 0;
                        s_ms_int <= 0;
                        s_ls_int <= 0;
                elsif clk'event and clk='1' then
                        if second_enable = '1' then
                                if s_ls_int = 9 then
                                        if s_ms_int = 5 then
                                                if m_ls_int = 9 then
                                                        if m_ms_int = 5 then
                                                                if (h_ls_int = 9 or (h_ls_int=3 and h_ms_int=2)) then
                                                                        if (h_ls_int=3 and h_ms_int=2) then
                                                                                h_ms_int <= 0;
                                                                        else
                                                                                h_ms_int <= h_ms_int + 1;
                                                                        end if;
                                                                        h_ls_int <= 0;
                                                                else
                                                                        h_ls_int <= h_ls_int + 1;
                                                                end if;
                                                                m_ms_int <= 0;
                                                        else
                                                                m_ms_int <= m_ms_int + 1;
                                                        end if;
                                                        m_ls_int <= 0;
                                                else
                                                        m_ls_int <= m_ls_int + 1;
                                                end if;
                                                s_ms_int <= 0;
                                        else
                                                s_ms_int <= s_ms_int + 1;
                                        end if;
                                        s_ls_int <= 0;
                                else
                                        s_ls_int <= s_ls_int + 1;
                                end if;
                        end if;
                end if;
        end process COUNT;

        h_ms <= std_logic_vector(to_unsigned(h_ms_int, h_ms'length));
        h_ls <= std_logic_vector(to_unsigned(h_ls_int, h_ls'length));
        m_ms <= std_logic_vector(to_unsigned(m_ms_int, m_ms'length));
        m_ls <= std_logic_vector(to_unsigned(m_ls_int, m_ls'length));
        s_ms <= std_logic_vector(to_unsigned(s_ms_int, s_ms'length));
        s_ls <= std_logic_vector(to_unsigned(s_ls_int, s_ls'length));

end rtl;

Это довольно маленькие счетчики, поэтому они не должны быть слишком большими даже при слегка сложной логике обертывания.Я не могу проверить его размер дома, поскольку у меня нет доступных инструментов синтеза, но я ожидаю, что он должен быть меньше, чем логика деления на десять и по модулю десять.

2 голосов
/ 25 мая 2011

Что вы подразумеваете под «реализовать наиболее адекватным (эффективным?) Способом»? Вы имеете в виду не использовать 32 бита X 3 для хранения времени?

Это должно быть в BCD? Вы можете просто ограничить размер целых чисел: 5 бит для часа, 6 бит для минуты и 6 бит для секунды:

SIGNAL hour: INTEGER RANGE 0 TO 23;
SIGNAL minute: INTEGER RANGE 0 TO 59;
SIGNAL second: INTEGER RANGE 0 TO 59;

Если все они должны быть в одной переменной, вы можете поместить их все в битовый вектор из 17 бит.

SIGNAL time: BIT_VECTOR( 16 DOWNTO 0 );
time( 16 DOWNTO 12) <= hour;
time( 11 DOWNTO 6) <= minute;
time( 5 DOWNTO 0) <= second;
...