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

    

Измерение длительности полупериодов

Всем здравствуйте, подскажите пожалуйста как оптимизировать вот такой код для измерения полупериодов входного сигнала. Первое что хотелось бы сделать это перейти на версию с одним счетчиком полупериодов и одним регистром хранения результата для экономии ресурсов MAXII. Писал версию с одним счетчиком и одним регистром хранения, но как выяснилось позже она повела себя не совсем стабильно как в симуляции так и в железе, скорее всего я не совсем корректно реализовал. Как правильно сделать чтобы был один счетчик и один регистра на измерение полупериода высокого и низкого уровня. А вторая проблема для записи в регистр хранения я использую edge_detector по его импульсам и для надежной записи приходится использовать длительность импульса edge detectora равную 2м периодам тактовой частоты. Подскажите пожалуйста есть ли какая то возможность избавиться от edge_detector или ускорить быстродействие на запись результата в регистр,  так как после окончания измеряемого полупериода сигнала происходит задержка на вывод результата измерения из за этого детектора, в такой реализации где то по симуляции я посмотрел задержка составляет 70 - 80 нс тут задержка на синхронизацию с клоком потом ожидание в течении 2х тактов на запись результатов + другие участки кода, а мне после вывода результата надо еще сравнить результат с константами и отреагировать определенным событием на изменение этого сигнала и задержка в 70-80 нс уже очень мешает в плане реакции на дальнейшую обработку сигнала, и если произойдет отклонение от нормы то сигнал надо подменить сигналом такой же частоты, но стабильным и надо сделать переход от одного сигнала к другому как можно меньше, чтобы на выходе был практически незаметен переход, а для этого мне нужно уменьшить задержку как можно меньше. В итоге на осцилограмме при тестах у меня переход получился больше 100 нс на стабилизированный сигнал при переходе. Может есть какие то боле быстрые реализации дизаина для измерителя полупериодов.

 

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

entity PULSE_MEASHURE is
generic (
  N               : integer:=511;        -- Размерность счетчика
  FREQ_CLK	      : natural := 48000000  -- Тактовая частота плис (Hz)
  );

port (
  clk                      : in  std_logic; -- тактовая частота
  reset                    : in  std_logic; -- сигнал сброса и выключения
  signal                   : in  std_logic; -- измеряемый сигнал, измеряется каждый полупериод
  len_pulse                : out integer    -- вывод числа тиков измеренного каждого полупериода
     );
end PULSE_MEASHURE;

architecture Behavioral of PULSE_MEASHURE is

signal r_count_hi          : integer range 0 to N := 0;      
signal r_count_lo          : integer range 0 to N := 0;
signal r_count_hi_ena      : std_logic;
signal r_count_lo_ena      : std_logic;
signal r_rise              : std_logic;
signal r_fall              : std_logic;
signal r0_input            : std_logic;
signal r1_input            : std_logic;
signal r2_input            : std_logic;

begin

edge_detector : process(clk,reset)    -- детектор фронтов вырабатывает короткие импульсы равные 2 периода клока 
begin
  if(reset='0') then
     r0_input           <= '0';
     r1_input           <= '0';
     r2_input           <= '0';
     r_rise               <= '0';
     r_fall                <= '0';
  elsif(rising_edge(clk)) then
     r0_input           <= signal;        --  _____-------_________   измеряемый сигнал 
     r1_input           <= r0_input;
	  r2_input           <= r1_input;
  end if;
  	 r_rise <=  r0_input and not r3_input;  --  ____п_______________    выдает короткий импульс равный 2 такта по возрастающему фронту
	 r_fall  <=  r3_input and not r0_input; --  ___________п________    выдает короткий импульс равный 2 такта по возрастающему фронту
end process edge_detector

 
len_pulse_counter : process(clk,reset)
begin
  if(reset='0') then        -- обнуление всех сигналов и счетчиков при 0 сигнала Reset
    r_count_hi_ena  <= '0';
    r_count_lo_ena  <= '0';
    r_count_hi      <= 0;
    r_count_lo      <= 0;
    len_pulse  <= 0;
  elsif(rising_edge(clk)) then   
    if(r_rise='1') then          -- установка сигналов запуска счетчиков и остановки 
      r_count_hi_ena  <= '1';
      r_count_lo_ena  <= '0';
      len_pulse  <= r_count_lo;  -- запись в регистр хранения данных счетчика низкого уровня сигнала
  elsif(r_fall='1') then         -- установка сигналов запуска счетчиков и остановки 
      r_count_hi_ena  <= '0';
      r_count_lo_ena  <= '1';
      len_pulse  <= r_count_hi;  -- запись в регистр хранения данных счетчика высокого уровня сигнала
  end if;

   if(r_count_hi_ena='1') then
        r_count_hi <= r_count_hi + 1;
	elsif(r_count_hi_ena='0') then
	    r_count_hi <= 0;
   end if;
	 
   if(r_count_lo_ena='1') then
        r_count_lo <= r_count_lo + 1;
	elsif(r_count_lo_ena='0') then
        r_count_lo <= 0;
   end if;
	
  end if;
end process len_pulse_counter;
end Behavioral;

 

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


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

Так не пойдёт. Это уже энная тема с одним и тем же вопросом.

Кидайте сюда то что нужно сделать целиком. Вам посоветуют как это сделать. А править вот эти чудо решения с двухтактовыми фронтдетекторами нет ни малейшего желания :(
Всё ТЗ со всеми времянками, входными частотами, скоростями реакции, ограничениями по ресурсам которые зачем то экономятся и пр... А ещё лучше с картинками.

 

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


Ссылка на сообщение
Поделиться на другие сайты
13 минут назад, MegaVolt сказал:

Так не пойдёт. Это уже энная тема с одним и тем же вопросом.

Кидайте сюда то что нужно сделать целиком. Вам посоветуют как это сделать. А править вот эти чудо решения с двухтактовыми фронтдетекторами нет ни малейшего желания :(
Всё ТЗ со всеми времянками, входными частотами, скоростями реакции, ограничениями по ресурсам которые зачем то экономятся и пр... А ещё лучше с картинками.

 

2х тактный фронтодетектор пришлось использовать потому, что 1 тактный как выяснилось ненадежно сбрасывает или записывает данные в регистр, потому что в симуляциях у меня почему то появлялись иногда удвоеные данные замера, как и в реальных тестах отлавливались такие же глюки.  Скорость реакции мне надо сделать на сколько это возможно самую минимальную, меньше чем указанная если это возможно вообще. 

Снимок экрана 2019-02-12 в 13.52.14.png

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


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

Не не понятно. И задача не понятна. И что такое как можно быстрее. 
Можно задачу изначальную? Параметры сигнала? Минимальные длительности сигнала. 

Проблемы в счёте который не успевает срабатывать за один такт нужно искать. Всё должно работать за один такт. 

Изначальна задача это проблема в реальном мире которую нужно решить.

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


Ссылка на сообщение
Поделиться на другие сайты
17 минут назад, MegaVolt сказал:

Не не понятно. И задача не понятна. И что такое как можно быстрее. 
Можно задачу изначальную? Параметры сигнала? Минимальные длительности сигнала. 

Проблемы в счёте который не успевает срабатывать за один такт нужно искать. Всё должно работать за один такт. 

Изначальна задача это проблема в реальном мире которую нужно решить.

Тактовая частота 48 МГц, Измеряемые сигналы от 80 кГц до 600 кГц.  Экономия ресурсов для возможного расширения функционала в плане выбора констант 4х битным селектором установки диапазонов срабатывания, а не перепрошивкой плис.

Тему тут я нашел всего одну про измеритель периода, но там так же edge детектор используется.

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


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

Мне вас пытать? Ну а дальше? При каких частотах должна быть замена? На что заменяем? Как быстро заменяем? Зачем?

Что за плис такая что в ней набор из 16 констант ощутимо жрёт ресурсы?

Сигнал проходит ПЛИС насквозь? Или ПЛИС его только мониторит?

 

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


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

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

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


Ссылка на сообщение
Поделиться на другие сайты
1 минуту назад, Nikolas72_91 сказал:

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

А почту не читаете принципиально?

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


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

Система такая, допустим автогенератор работает на частоте резонансной 265 кГц. Нужно пропустить сигнал от 210 кГц и до 290 кГц. По нижнему диапазону мы просто отключаем колебания генератора, а при превышении 290 кГц нужно переключить на генератор реализованный на делении частоты и переключается автогенератор на вынужденные колебания на делитель частоты который выдает 265 кГц, причем если возникла гармоника как на графике, то генератор досчитывает импульс т.е. продолжает импульс а потом уже совершает нормальные колебания 265 кГц, до сигнала выключения. 

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


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

Приветствую!

Начните кушать слона по кусочкам - для начала - измеряемый сигнал синхронен с тактовой или нет? Подозреваю что нет раз у вас фронт детектор глючит :mda:.  Значит первым делом  перевести его в тактовый домен через 2-3 триггера. Увы тут задержки не избежать.  Ну а потом все просто - так как счетчик у вас считает монотонно - то для экономии времени сравнивать его с константами можно  в процессе счета и по фронту защелкивать результат сравнения. Будет вам экономия 2-ры тактов :wink2: 

Удачи! Rob.

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


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

Тут какая то принципиальная не стыковка. Если при времени срабатывания 2 такта мы имеем неудобный глитч то при срабатывании быстрее мы будем иметь ещё более короткий глитч. Т.е. постановка задачи в корне неверная уже. 
 

Соответственно при такой задаче сами задержки в плис не играют никакой роли. А именно.

1. Пропускаем входной сигнал через синхронизатор.

2. Задерживаем его на несколько тактов например на 10 чтобы спать спокойно :)

3. Измеряем всё что нам нужно так медленно как нам это удобно (до 10 тактов)

4. если условия измерения не подошли запускаем альтернативный генератор.

5. Переключаем выход на альтернативный генератор ещё до того как ошибочный фронт вышел из плис.

Профит.

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


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

Синхронизатор на 2-битном сдвиговом регистре, с него детектор фронтов на "исключающее ИЛИ", по его сигналу синхронный сброс постоянно считающего счётчика и по нему же выгрузка насчитанного в выходной регистр — в общем, порядка трёх строк кода.

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


Ссылка на сообщение
Поделиться на другие сайты
3 часа назад, MegaVolt сказал:

Тут какая то принципиальная не стыковка. Если при времени срабатывания 2 такта мы имеем неудобный глитч то при срабатывании быстрее мы будем иметь ещё более короткий глитч. Т.е. постановка задачи в корне неверная уже. 
 

Соответственно при такой задаче сами задержки в плис не играют никакой роли. А именно.

1. Пропускаем входной сигнал через синхронизатор.

2. Задерживаем его на несколько тактов например на 10 чтобы спать спокойно :)

3. Измеряем всё что нам нужно так медленно как нам это удобно (до 10 тактов)

4. если условия измерения не подошли запускаем альтернативный генератор.

5. Переключаем выход на альтернативный генератор ещё до того как ошибочный фронт вышел из плис.

Профит.

Собственно задержка там получается больше чем 2 такта. При слишком коротком глитче есть вероятность, что глитч не успеет пролезти через трансформатор управления затвором транзисторов. Это 2 обмотки на ферритовом кольце вход и выход. Без ввода в клоковый домен никак? А то это же автогенератор и еще большие задержки в схеме это уже работа не на пике резонансной кривой а на ее уклоне. Ну или выходной сигнал обратной связи через  плис без синхронизации с клоковым доменом идет, чтобы его не сдвигать по фазе.На фотографии на данный момент вот такой глитч пролазит через трансформатор управления.

IMG_20190212_183730.jpg

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


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

Я ответил что нужно сделать чтобы их не было вовсе.

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


Ссылка на сообщение
Поделиться на другие сайты
6 часов назад, Nikolas72_91 сказал:

4 часа назад, Plain сказал:

Синхронизатор на 2-битном сдвиговом регистре, с него детектор фронтов на "исключающее ИЛИ", по его сигналу синхронный сброс постоянно считающего счётчика и по нему же выгрузка насчитанного в выходной регистр — в общем, порядка трёх строк кода.

после вывода результата надо еще сравнить результат с константами и отреагировать определенным событием

Тогда поправка — сравнивать с константами счётчик, а в регистр переписывать уже нужные события. Итого, задержка на всё — один такт, 20 нс.

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти