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

 
 
 
Reply to this topicStart new topic
> Как сделать быстрый Priority encoder, Проблема множества прерываний.
count_enable
сообщение Jun 8 2017, 13:18
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 28-01-13
Из: Испания
Пользователь №: 75 384



Дано: от 10 до 100 блоков могущих сгенерировать прерывание. Требуется: подтвердить приём прерывания и записать номер блока в память.

Моя логика: Блоки остаются в высоком состоянии пока не получат подтверждения. Приоритетным энкодером выбирать по одному блоку за такт. Желательно чтобы энкодер работал быстрее чем тактовая блоков, чтобы максимально быстро их обслужить.

Написал приоритетный энкодер типа:
Код
entity spikebuffer is
generic( NUMINPUTS: integer:=1000;
            OUT_WIDTH:integer :=10);
    Port ( REQ : in  STD_LOGIC_VECTOR (NUMINPUTS-1 downto 0);
              ACK : out  STD_LOGIC_VECTOR (NUMINPUTS-1 downto 0);
           CLK : in  STD_LOGIC;
           AEROUT : out  STD_LOGIC_VECTOR (OUT_WIDTH-1 downto 0);  --отсюда вылетает номер прерывания 1 за такт
              DVALID:out STD_LOGIC);
end spikebuffer;

architecture Behavioral of spikebuffer is


begin

shifting : PROCESS(clk)
   VARIABLE highest_switch : integer range 0 to NUMINPUTS := NUMINPUTS;
begin
if rising_edge(CLK) then
ACK<=(others=>'0');
DVALID<='0';
highest_switch := NUMINPUTS;
   for i in 0 to NUMINPUTS-1  loop
      if REQ((i)) = '1' then                       -- ищем прерывания
         highest_switch := (i);                -- последнее найдённое запоминаем
            DVALID<='1';
      end if;
   end loop;
    if (highest_switch<NUMINPUTS) then   -- если были прерывания
        AEROUT<=std_logic_vector(to_unsigned(highest_switch,AEROUT'length));
        ACK(highest_switch)<='1';       -- то подтверждаем приём и тогда блок отпустит REQ
    else
        DVALID<='0';
        ACK<=(others=>'0');
    end if;
end if;
end process;


К сожалению для 7 виртекса синтезируется на ~140 Mhz. Возможно ли написать требуемый блок быстрее? Как за мин. количество клоков прочитать и запомнить от 0 до 100 прерываний?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 8 2017, 13:20
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 189
Регистрация: 17-02-06
Пользователь №: 14 454



почему нельзя выбирать за такт из нескольких блоков?
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jun 8 2017, 13:32
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 28-01-13
Из: Испания
Пользователь №: 75 384



А как записать в память? Держать память на каждый блок я не потяну (важна последовательность прерываний а не просто их наличие). Сейчас все номера блоков сливаются в одно долгое FIFO. Надо получить запись типа "1,2,3,0(нет),0,0,3,32,6,3,0,2,4".

Вот упрощённая логика разгоняется аж до 157 МГц, а хотелось бы минимум вдвое больше. Причём как я выяснил, тормозом является именно подтверждение ACK(highest_switch)<='1'; Без него скорость увеличивается в разы.
Код
shifting : PROCESS(clk)
   VARIABLE highest_switch : integer range 0 to NUMINPUTS := NUMINPUTS;
begin
if rising_edge(CLK) then
ACK<=(others=>'0');
DVALID<='0';
highest_switch := NUMINPUTS;
   for i in 0 to NUMINPUTS-1  loop
      if REQ((i)) = '1' then
         highest_switch := (i);
            DVALID<='1';
      end if;
   end loop;
    ACK(highest_switch)<='1';
end if;
end process;

end Behavioral;
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 8 2017, 13:35
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 3 572
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(count_enable @ Jun 8 2017, 16:18) *
Дано: от 10 до 100 блоков могущих сгенерировать прерывание. Требуется: подтвердить приём прерывания и записать номер блока в память.

...
К сожалению для 7 виртекса синтезируется на ~140 Mhz. Возможно ли написать требуемый блок быстрее? Как за мин. количество клоков прочитать и запомнить от 0 до 100 прерываний?

Если будете делать параллельный контроллер, как у Интел, то придется задействовать много ресурсов.
Сделайте блок по системе DEC, т.е. последовательный. По всем блокам последовательно проходит сигнал разрешения запроса. В каждом блоке - триггер и "И". Если этот блок требует прерывания, то он не пропустит сигнал дальше. И можно дать обратный сигнал, который скажет "младшему" о том, что "старший" хочет прерывание...
Ну и дальше дается сигнал "чтения вектора" и тот блок, который "старший", выставит свой вектор, а "младшим" это будет запрещено...
Все в один такт при чтении и один такт - для защелкивания запроса каждом в блоке..


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jun 8 2017, 13:42
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 28-01-13
Из: Испания
Пользователь №: 75 384



Извините, но я не cовсем понял sad.gif

Т.е. у нас есть N блоков каждый со входом IRQEN которые соединены в цепочку типа daisy-chain, и первый в этой цепочке перехватывает сигнал и выставляет на общюю шину свой IRQID?
Я не совсем понял "последовательно проходит сигнал запроса" - не получится ли это обычный опрос по одному клоку на блок?
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 8 2017, 13:51
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 3 572
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(count_enable @ Jun 8 2017, 16:42) *
Извините, но я не cовсем понял sad.gif

Т.е. у нас есть N блоков каждый со входом IRQEN которые соединены в цепочку типа daisy-chain, и первый в этой цепочке перехватывает сигнал и выставляет на общюю шину свой IRQID?
Я не совсем понял "последовательно проходит сигнал запроса" - не получится ли это обычный опрос по одному клоку на блок?

Ну да, это daisy-chain... Разрешения проходят через блоки, как бусы на нитке. Блок либо пропускает разрешение, либо не пропускает разрешение к следующему блоку.
И далее есть обратный сигнал от "верхних" блоков к "нижним", который блокирует нижним выставление вектора при чтении...
Если хотите подробнее, то могу по скайпу голосом...


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jun 8 2017, 13:53
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 28-01-13
Из: Испания
Пользователь №: 75 384



Большое вам спасибо! Думаю понял как оно. А зачем сигнал блокады? Мы ведь можем по дефолту запретить блокам выставлять что-либо кроме Hi-Z без разрешения?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 8 2017, 13:58
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 189
Регистрация: 17-02-06
Пользователь №: 14 454



ну да с наиболее приоритетного конца соединить их через мультиплексор. Если прерывание горит, то выход вбок, если нет, то выход на следующий блок. Подать единичку, она "добежит" до самого первого прерывания, и выйдет в бок. Дальше на все прерывания подать АСК объединенный по & с вышедшей единичкой. Ну и общий 1 хот дешифратор в адрес.
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jun 8 2017, 14:00
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 3 572
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(count_enable @ Jun 8 2017, 16:53) *
Большое вам спасибо! Думаю понял как оно. А зачем сигнал блокады? Мы ведь можем по дефолту запретить блокам выставлять что-либо кроме Hi-Z без разрешения?

Внутри ПЛИС Hi-Z не действуют...
И без обратного сигнала при подаче "чтения вектора" все блоки, хотящие прерывания выставят 1, а не хотящие - 0. Получите слово из 100 бит. Которое потом надо будет "свернуть" в "адрес вектора". А при использовании запрета для "нижних", самый "верхний" выставит уже готовый "адрес вектора", который может быть в него намертво зашит, или загружен ему в регистр...


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 8 2017, 14:28
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 189
Регистрация: 17-02-06
Пользователь №: 14 454



можно чтобы блок выставлял адрес если 1 вбок или 0, если нет единички и адреса все по ИЛИ соединить.

то есть снизу единичка, если прерывание есть, то на выход адрес и 1, и вверх 0, если прерывания нет, то на выход адрес 0 и 0, и вверх 1. И все модули соединяем друг за другом. Адреса по ИЛИ. АСК по И со вторым выходом.


Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jun 8 2017, 14:46
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 912
Регистрация: 23-12-04
Пользователь №: 1 643



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

Поиск решения без понимания задачи.

Цитата(count_enable @ Jun 8 2017, 16:32) *
Моя логика: Блоки остаются в высоком состоянии пока не получат подтверждения. Приоритетным энкодером выбирать по одному блоку за такт. Желательно чтобы энкодер работал быстрее чем тактовая блоков, чтобы максимально быстро их обслужить.

Первое не стыкуется со вторым

Цитата(count_enable @ Jun 8 2017, 16:32) *
А как записать в память? Держать память на каждый блок я не потяну (важна последовательность прерываний а не просто их наличие). Сейчас все номера блоков сливаются в одно долгое FIFO. Надо получить запись типа "1,2,3,0(нет),0,0,3,32,6,3,0,2,4".
...


Сохранение порядок генерации прерываний Ваша схема не гарантирует (вернее он будет только если за цикл опроса сигналов будет только одно прерывание). А если несколько?

При daisy-chain будут большие latency при реакции на прерывания. Опят же Ваши требования тут универсальные но уж слишком общие "... чтобы работал быстрее ...". sm.gif

Думаю что тут можно делать каскадную схему - делить вектор на группы и обрабатывать их независимыми арбитрами которые потом также арбитрировать. Будет Вам и скорость и latency.

Удачи! Rob.

Go to the top of the page
 
+Quote Post
count_enable
сообщение Jun 9 2017, 14:16
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 293
Регистрация: 28-01-13
Из: Испания
Пользователь №: 75 384



Цитата
Внутри ПЛИС Hi-Z не действуют...
ЕМНИП синтезатор заменяет их на wire OR вполне успешно, иначе я не совсем понял как "запретить" блоку выставлять что-то на общую шину. Все блоки сидят на одной "IRQNUM" и должны какое-то состояние выставить. Разве нет?

Написал согласно Вашим рецептам, но с hi-z, синтезировалось и симулируется. Показывает 446 МГц для 100 блоков - вполне неплохо, хотя на большие "гирлянды" конечно масштабировать не стоит.

Теперь о каскадировании. Уважаемый RobFPGA, это была моя начальная идея, но я так и не придумал как потом объединять несколько выходных потоков в реальном времени.
Я немного неправильно описал систему, слишком упрощённо. Не хочу перегружать деталями. Точный порядок прерываний не нужен, они квантуются каждые несколько десятков клоков - т.е. внутри этого окна они могут быть перемешаны, но обрабатывать их после этого окна нежелательно. Окна формируются прерыванием от Глобального Оконного Таймера (ГОТ). Т.е. между двумя событиями ГОТ порядок остальных прерываний роли не играет.

Общая логика такова: каждый блок может заявить прервание каждые Х клоков. Если Х>N то задача тривиальна но обычный случай это N=100..200 X=20, частота ок.300 МГц. Т.е. в критичном случае у нас будет 200 прерываний и 20 циклов (300 МГц) на обработку. Если прерывание не было обслужено на протяжении 20 циклов то поднимается флаг "ПРОСРОЧЕН" который тормозит конвеер пока все прерывания не обработают.
Обработка прерывания - запись его в большую очередь.
Соответственно задача стоит обработать макс. число прерываний за мин. время. Подход двоякий: во-первый второй тактовый сигнал большей частоты, во-вторых минимальное число клоков на обработку.

Если поделить все блоки на группы меньше 20 то задача банально решается опросом. Но после этого у нас есть N/20 независимых очередей которые надо склеить в одну сохранив порядок окон ГОТ. Мои неуклюжие попытки (поллинг мастеров и поочередная выгрузка очередей "до следующего ГОТа") к сожалению получались неудобными и медленными.

Я подозреваю надо обьеденить подходы, или сделав daisy-chain из локальных мастеров, или наоборот, сделать дерево где локальные мастера будут короткими daisy-chain цепочками (10 блоков синтезируются на ок.800 Мгц).
Я продолжаю экспериментировать, и буду благодарен за новые идеи.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 9 2017, 14:53
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 189
Регистрация: 17-02-06
Пользователь №: 14 454



так если у вас не 1 такт, то лучше обрабатывать маленькими порциями.
100 за 1 такт - долго,
10 за 1 такт быстрее, причем значительно, а за следующий вам из 10 ответов опять надо будет выбрать 1. То есть 1 по 100 меняем на 2 по 10, и получаем сильный прирост.

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

Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jun 9 2017, 16:26
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 912
Регистрация: 23-12-04
Пользователь №: 1 643



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

Цитата(count_enable @ Jun 9 2017, 17:16) *
порядок прерываний не нужен, они квантуются каждые несколько десятков клоков - т.е. внутри этого окна они могут быть перемешаны, но обрабатывать их после этого окна нежелательно. Окна формируются прерыванием от Глобального Оконного Таймера (ГОТ). Т.е. между двумя событиями ГОТ порядок остальных прерываний роли не играет.

Ну так это значительно упрощает задачу.
Раз есть глобальный таймер значит можно иметь и НОМЕР окна в котором появились прерывании.

Цитата(count_enable @ Jun 9 2017, 17:16) *
Если поделить все блоки на группы меньше 20 то задача банально решается опросом. Но после этого у нас есть N/20 независимых очередей которые надо склеить в одну сохранив порядок окон ГОТ.
Мои неуклюжие попытки (поллинг мастеров и поочередная выгрузка очередей "до следующего ГОТа") к сожалению получались неудобными и медленными.

В очередь пишем и номер окна а при чтении из текущей очереди читаем с отслеживанием номера.
Или еще проще - в каждую очередь ВСЕГДА пишем бит окончания окна, а на выходе читаем из каждой очереди пока не увидим это бит а затем переходим к чтению следующей по кольцу.

Удачи! Rob.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd August 2017 - 20:47
Рейтинг@Mail.ru


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