реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Clock multiplexing в VHDL, Или "как менять один сигнал в двух процессах"
drozel
сообщение Feb 3 2011, 18:45
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Начал изучать VHDL. Первая мысль стандартна - сделать часы. Причем не просто часы, примеров коих много, а часы с подстройкой.
Инкрементор секунд тактируется 1 герцовым сигналом.
Хотелось также инкрементироватьь его кнопкой - подстройка на лету. Нет, нельзя менять один сигнал из двух процессов - ошибка драйверов.
Вторая идея - тактировать двумя сигналами - и тактовым и кнопкой. Так тоже нельзя.
Наконец сделал мультиплексирование тактового импульса. В режиме работы - это 1герц, в режиме настройки - кнопка. Выбор - переключателем.
Quartus ругается варнингом на мультиплексирование клока. Но уже лучше.

Как это делается по-человечески?

Код
BEGIN
    status<="00" WHEN SW(0)='1' else
            "11" WHEN SW(0)='0';
    
    clock<=clk_1hz WHEN status="11" else
            not KEY(3) WHEN status="00";
    
    ledg(8)<= clock;    
    
    timer: process(clock)
    begin
        if (clock='1' and clock'event) then
            if (status="11") then
                --I?eaaaeyai naeoiau. Anee naeoiau = 59, iaioeyai e i?iaa?yai ieioou. Eo io?ii i?eaaaeyou, a anee e ieioou = 59, i?iaa?yai ?anu.
                if (sec=59) then
                    sec:=0;
                    if(min=59) then
                        min:=0;
                        if(hour=23) then
                            hour:=0;
                        else
                            hour:=hour+1;
                        end if;
                    else
                        min:=min+1;
                    end if;
                else
                    sec:=sec+1;
                end if;
            
            elsif (status="00") then
                if(KEY(3)='0') then
                    hour:=hour+1;
                end if;
            end if;
            
            
            shour<=hour;
            smin<=min;
            ssec<=sec;
            
            --I?aia?acoai naeoiau integer a vector e BCD
            HEX3<=numTo7Seg(binToBCD(ssec)(4 to 7)); --ia 7 eiaeeaoi? - noa?oea aeou BCD
            HEX2<=numTo7Seg(binToBCD(ssec)(0 to 3)); --ia 6 - ieaaoea
            
            --Ii aiaeiaee - ?anu e ieioou
            HEX5<=numTo7Seg(binToBCD(smin)(4 to 7));
            HEX4<=numTo7Seg(binToBCD(smin)(0 to 3));
            
            HEX7<=numTo7Seg(binToBCD(shour)(4 to 7));
            HEX6<=numTo7Seg(binToBCD(shour)(0 to 3));
            
            HEX1<="1111111";
            HEX0<="1111111";
            
            
        end if;
    end process timer;
Go to the top of the page
 
+Quote Post
yuri_d
сообщение Feb 3 2011, 22:07
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 28-01-05
Из: МО, Мытищи
Пользователь №: 2 274



Цитата(drozel @ Feb 3 2011, 21:45) *
Как это делается по-человечески?

Проще всего прибавлять N, а не 1. Если подстройка не нужна, тогда N=1, если нужна, тогда всё что угодно (например N=2 приведёт к подстройке на 1 секунду каждую секунду).

Мулитиплексировать тактовый сигнал не стоит. В простых проектах может и пройдёт, но в реальных скорее всего вылезут сложноустранимые ошибки.
Go to the top of the page
 
+Quote Post
drozel
сообщение Feb 4 2011, 05:32
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Цитата(yuri_d @ Feb 4 2011, 04:07) *
Проще всего прибавлять N, а не 1. Если подстройка не нужна, тогда N=1, если нужна, тогда всё что угодно (например N=2 приведёт к подстройке на 1 секунду каждую секунду).


Тогда прибавляться будет только по такту секунды, а не по нажатию. В часах прибавляется по нажатию.
Go to the top of the page
 
+Quote Post
yuri_d
сообщение Feb 4 2011, 14:16
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 28-01-05
Из: МО, Мытищи
Пользователь №: 2 274



Цитата(drozel @ Feb 4 2011, 08:32) *
Тогда прибавляться будет только по такту секунды, а не по нажатию. В часах прибавляется по нажатию.

У Вас в условии что написано? Выдержка из первого сообщения:
Цитата(drozel @ Feb 3 2011, 21:45) *
Инкрементор секунд тактируется 1 герцовым сигналом.


Поднимите скорость тактового сигнала (например до 8 Гц). Прибавляйте единицу раз в секунду в нормальном режиме (один раз 1 и семь раз 0).
Отслеживайте нажатие, не забывая про дребезг контактов, и прибавляйте 1 во время ближайшего фронта тактового сигнала. Логику работы на этом принципе можно придумать какую угодно.
Go to the top of the page
 
+Quote Post
drozel
сообщение Feb 4 2011, 15:21
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



yuri_d, да, собственно, к этому я и пришел. Только загонять в if sigal'event quartus не дает ( как я понял, невозможно отследить фронт в время другого фронта), пришлось делать триггер, защелкивающийся по нажатию и выключающийся по отжатию кнопки. Когда триггер защелкнут, второго прибавления не происходит.
Код
--Высокочастотный клок
if (clock_27='1' and clock_27'event) then
            
if (clk_1hz='1') then
                --I?eaaaeyai naeoiau. Anee naeoiau = 59, iaioeyai e i?iaa?yai ieioou. Eo io?ii i?eaaaeyou, a anee e ieioou = 59, i?iaa?yai ?anu.
                if (sec=59) then
                    sec<=0;
                    if(min=59) then
                        min<=0;
                        if(hour=23) then
                            hour<=0;
                        else
                            hour<=hour+1;
                        end if;
                    else
                        min<=min+1;
                    end if;
                else
                    sec<=sec+1;
                end if;
            
            elsif(KEY(3)='0' and set='1') then
                if (hour=23) then
                    hour<=0;
                else
                    hour<=hour+1;
                end if;
                
                set<='0';
                
            elsif(KEY(3)='1') then
                set<='1';


Есть какие-то варианты отследить фронт сигнала еще?
Go to the top of the page
 
+Quote Post
Александр77
сообщение Feb 6 2011, 07:49
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 608
Регистрация: 10-07-09
Из: Дубна, Московская область
Пользователь №: 51 111



Цитата(drozel @ Feb 4 2011, 18:21) *
Есть какие-то варианты отследить фронт сигнала еще?

Делал так
Код
PROCESS(clk,clr)
    variable a:std_logic_vector(1 downto 0);
    BEGIN
    
        if(clr='0')then
            a:="10";
        else
            if(rising_edge(clk))then
                a(1):=a(0);
                a(0):=D;
            end if;
        end if;
    q<=a(0) or(not a(1));    
    end process;

Формировал из одного фронта импульс, длительностью в 1 период тактового сигнала
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 09:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.0142 секунд с 7
ELECTRONIX ©2004-2016