Перейти к содержанию
    

Генерация импульсов на VHDL

Доброго всем времени суток!

В общем опишу задачу: есть меандр частотой 80кГц. Необходимо генерировать импульсы (POUT) длительностью 1мкс. по фронту и спаду этого сигнала, т.е. в момент изменения уровней сигнала (MEANDR). Тактирование происходит от генератора 36Мгц.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;


entity PULSE_GENERATOR is        
port (    MEANDR:    in std_logic;--МЕАНДР
        CLK:         in std_logic;--Тактовый сигнал
        ENABLE:     in std_logic;--Сигнал общего разрешения
        POUT:    out std_logic);
end PULSE_GENERATOR;

architecture A_cpugen of PULSE_GENERATOR is
begin
    process(CLK, MEANDR, ENABLE)
    variable i: integer range 0 to 255:= 0;
    variable step: integer range 0 to 2:= 1;
    begin
    
        if (ENABLE='1')
        then 
            --=====================================================
            if (rising_edge(CLK)) 
            then
                if (step=0)
                then
                    if (i=180)--через некоторое время смотрим уровень сигнала
                    then
                        if (MEANDR='0')--ловить будем фронт
                        then
                            step:=1;
                            
                        elsif (MEANDR='1')--ловить будем спад
                        then
                            step:=2;
                            
                        end if;
                    else
                        i:=i+1;
                                                --++++++ЗДЕСЬ РАБОТАЕТ НЕ КОРРЕКТНО!!!++++++++++++++++++++++++
                    end if;
                    
                    --======================================
                            --Генерация импульса
                    if ((i>=0) and (i < 36))
                    then
                        POUT <= '1';
                    else
                        POUT <= '0';
                    end if;    
                    --======================================
                elsif(((step=1)and(MEANDR='1')) or ((step=2)and(MEANDR='0')))
                then
                    i:=0;
                    step:=0;
                end if;
                                                
                                                --++++++ЗДЕСЬ РАБОТАЕТ НЕ КОРРЕКТНО!!!++++++++++++++++++++++++        
            end if;
                                                --++++++ЗДЕСЬ РАБОТАЕТ НЕ КОРРЕКТНО!!!++++++++++++++++++++++++
        else
            POUT <= '0';
        end if;
        
    end process;
end A_cpugen;

Все работает, все проверено, но, если перенести код "Генерация импульса" в места помеченные "--++++++", то импульсы периодически пропадают. Не могу понять - что от этого меняется - подскажите пожалуйста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Variable никогда не будут на выходе триггера, замените их на signal. Ваш счетчик i как-то умудряется считать без элементов памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Variable никогда не будут на выходе триггера, замените их на signal. Ваш счетчик i как-то умудряется считать без элементов памяти.

Не совсем Вас понял. Выход здесь POUT, он описан как std_logic. А переменные i и step являются вспомогательными. на i реализован счетчик, а переменная step используется для того, чтобы определить по какому событию генерировать импульс: фронту или спаду. О каких элементах памяти Вы говорите?

Изменено пользователем Sprite

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз повторяю: variable не будет на выходе триггера, то есть элемента памяти. Как вы себе представляете счетчик без триггеров?

По ENABLE = 0 я так понимаю будет асинхронный сброс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз повторяю: variable не будет на выходе триггера, то есть элемента памяти. Как вы себе представляете счетчик без триггеров?

По ENABLE = 0 я так понимаю будет асинхронный сброс?

Да, по ENABLE происходит асинхронный сброс. Но с variable я так и не понял. Скажите конкретнее, в чем ошибка? В том, что i и step нужно объявить как signal, а не variable? Повторюсь, описанный код успешно работает - проверено лично, но при определенных ситуациях (при переносе кода "Генерация импульса" в места помеченные "--++++++") импульсы теряются. Вопрос на засыпку: зачем тогда нужны variable?

Изменено пользователем Sprite

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Sprite

Есть мнение, что если переносить этот кусок кода под разные условия (if, else) программы, то и срабатывать он будет только если выполняются соответствующие условия, т.е. не всегда в одинаковые моменты времени. Поэтому и импульсы могут пропадать, имхо.

Изменено пользователем yume

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз повторяю: variable не будет на выходе триггера, то есть элемента памяти. Как вы себе представляете счетчик без триггеров?

По ENABLE = 0 я так понимаю будет асинхронный сброс?

Вы не правы,variable вполне может быть выходом триггера.Правда,чтобы это сделать нужно выполнить некоторые правила. :laughing:

У автора как раз с этим проблемы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы не правы,variable вполне может быть выходом триггера.Правда,чтобы это сделать нужно выполнить некоторые правила. :laughing:

У автора как раз с этим проблемы.

О каких правилах Вы говорите? У меня весь код выполняется по условию if (rising_edge(CLK)), т.е. переменная i и step в момент прихода очередного фронта CLK меняет значение только один раз. Ветки step поставлены в условия if-elsif, т.е. исключают друг друга. Ничего понять не могу! Кстати, пробовал объявлять переменные step и i как сигналы - ничего не получилось - импульсы по прежнему теряются ;(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О каких правилах Вы говорите? У меня весь код выполняется по условию if (rising_edge(CLK)), т.е. переменная i и step в момент прихода очередного фронта CLK меняет значение только один раз. Ветки step поставлены в условия if-elsif, т.е. исключают друг друга. Ничего понять не могу! Кстати, пробовал объявлять переменные step и i как сигналы - ничего не получилось - импульсы по прежнему теряются ;(

MEANDR привязан к клоку?

А правила работы с variable простые:

 

          i:=i+1;
                   if ((i>=0) and (i < 36))

 

         if ((i>=0) and (i < 36))
                  i:=i+1;

 

В первом случае i будет без триггера,во втором с триггером.

 

Sorry,пример видимо не совсем удачный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В подобных случаях я рекомендую нарисовать на бумажке то, что хотят получить и то, что написано.

Не мешайте все в одну кучу - структурируйте код, разбейте на блоки, и, все будет работать с "листа".

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я собрал проект, действительно, триггеры на счетчик выделены.

 

MEANDR привязан к клоку?

Наверное не привязан. Sprite, почему Вы так редко опрашиваете меандр - каждые 5 микросекунд. Период меандра 12,5 микросекунд. Может быть почаще надо его опрашивать, чтобы выделить фронт и срез?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Sprite, почему Вы так редко опрашиваете меандр - каждые 5 микросекунд. Период меандра 12,5 микросекунд. Может быть почаще надо его опрашивать, чтобы выделить фронт и срез?

Интересная мысль. Дело в том, что сигнал приходит иногда с незначительными помехами/наводками. В случае, если через 180 тактов определен неверный уровень сигнала - пропажа импульсов вещь вполне закономерная. Есть идея завести еще одну переменную - накопитель и плюсовать ее при наличии положительного уровня MEANDR в промежутке времени 160-180 тактов. Кстати, если переименовать переменные в сигналы - то ресурсов ПЛИС требуется значительно меньше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я имею ввиду, что длительность полупериода меандра 12,5 / 2 = 6,25 микросекунд, а Вы делаете опрос каждые 5 микросекунд. Все будет съезжать!

Если меандр не привязан к клоку, то при защелкивании меандра триггером могут возникать метастабильные состояния. Я в этом не разбираюсь, но рекомендуется поставить два триггера последовательно.

 

По поводу наводок. Возможно следует сделать подобно приемнику UART: берем несколько отсчетов и путем голосования определяем уровень сигнала. Если выяснили, что уровень изменился, значит поймали фронт или срез.

 

Кстати, если переименовать переменные в сигналы - то ресурсов ПЛИС требуется значительно меньше.

Странно, такого быть не должно. :05:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопросик: можно ли представленный на VHDL код как-то отобразить в виде логических элементов? Существует ли подобная функция представления в Quartus 9?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопросик: можно ли представленный на VHDL код как-то отобразить в виде логических элементов? Существует ли подобная функция представления в Quartus 9?

Попробуйте Technology Map Viewer.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...