Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обращение матриц на ПЛИС
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
jojo
Обращение матриц на ПЛИС

Тут надо комплексную матрицу 16x16 обратить (эрмитову). Формат исходных данных int32, результат - не хуже float, лучше - double. Есть ли готовые мегафункции, не обязательно нелицензионные?

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

В нынешней реализации обращения на DSP используются квадратный корень и деление (вещественные), сложение, вычитание и умножение (комплексные).

Хочу уменьшить нагрузку на DSP и разместить обращение матрицы в относитильно защищенной от взлома ПЛИС.
cdg
ИМХО если не за 1 такт надо, то с ПЛИС и не стоит заморачиваться - дороже выйдет.
jojo
Да, я все больше убеждаюсь, что ПЛИС "дороже выйдет", в т.ч. при обращении матриц. Отсутствие похожих функций в Synplify DSP и Altera DSP Builder на ту же мысль наводит.

В Tiger Sharc получилось порядка 2*10^3 тактов для матрицы 16*16.

Тут теоретики обещают подсказать способ обращения, пригодный для ПЛИС, возможно, с завершающим этапом в процессоре. Отпишу сюда о результатах.
cdg
В пору аспирантской юности, помнится сталкивался с решением задачи обращения матриц очень большого размера, так там для обращеня использовали модифицированный алгоритм Гаусса с приведением матрицы к виду Вандермонда (давно это было могу и попутать, но точно в киевском политехе ребята над этой задачей бились smile.gif )
Harbour
На плис проект будет работать все равно быстрее чем на любом супер-пупер DSP, вот только стоить он будет действительно дороже (затраты на HDL-программер 'а). Навскидку пару вариантов :

- можно из готового проекта на DSP наиболее муторные места сделать в железе (следует грамотно встроить все это дело в конвейер)
- использовать C-based FPGA design, возможно с последующей оптимизацией
des00
Цитата(Harbour @ Feb 8 2006, 02:35) *
На плис проект будет работать все равно быстрее чем на любом супер-пупер DSP


Не факт, если алгоритм сугубо последовательный и не допускает параллелизма объектов или ветвей,
решение на ДСП будет более быстрое, т.к. тактовая частота дсп больше раза в 2-3 раза чем на ФПГА.
тут от алгоритма все зависит.
Harbour
Это правда если сравнивать современные DSP с доисторическими FPGA - сейчас получить >200Mhz/такт на каком-то cyc2 не проблема. Даже в случае отсутствия параллелизма, в FPGA pipeline более эффективный получится, так как нет лишних накладных расходов, которые присутствуют в заточенном под универсальные задачи DSP конвейере.
dxp
Цитата(Harbour @ Feb 9 2006, 15:34) *
Это правда если сравнивать современные DSP с доисторическими FPGA - сейчас получить >200Mhz/такт на каком-то cyc2 не проблема.

В плане быстродействия cyc2 от cyc не особенно отличается, даже кое-где проигрывает. И на обоих можно и на 300 МГц разогнать. Только вот сложность логики, работающей на такой частоте, будет очень малой - не более одного уровня. Если же логику усложнить, то или тактовая сильно упадет, или конвейер придется городить, оптимизировать его. Тоже задача еще та.

Цитата(Harbour @ Feb 9 2006, 15:34) *
Даже в случае отсутствия параллелизма, в FPGA pipeline более эффективный получится, так как нет лишних накладных расходов, которые присутствуют в заточенном под универсальные задачи DSP конвейере.

Какие такие универсальные задачи? Там заточенность под пересылку данных и арифметические операции - именно то, что и нужно. Что-то я очень сомневаюсь, что без параллелизма любой Cyclone обгонит тот же Blackfin@600MHz.
jojo
Думаю, по меньшей мере последние этапы обращения можно в ПЛИС разместить, где используется комплексная арифметика. Как я убедился, сумматоры и умножители (float, а лучше double) занимают сравнительно мало места.

Все это ради того, чтобы осложнить копирование устройства, не ради ускорения вычислений. У процессора медленная (100 МГц) внешняя шина, это портит картину.


Что делать с квадратным корнем и делением на него - мне пока непонятно. Их можно тоже реализовать в ПЛИС (Методом Ньютона-Рафсона, как в процессора). Собственно, если эти деление и корень сделать - останется только конечный автомат реализовать.

А деление и sqrt() (float/double)никто не делал? сколько места заняло?


Добавление: тут надо обогнать не Blackfin, а TigerSharc. В целых числах или с фиксированной точкой динамический диапазон мал будет. Несколько напрягает длина конвейера (5-7) мегафункций с плавающей точкой. Но и так сойдет.
Harbour
Цитата(dxp @ Feb 9 2006, 12:57) *
Цитата(Harbour @ Feb 9 2006, 15:34) *

Это правда если сравнивать современные DSP с доисторическими FPGA - сейчас получить >200Mhz/такт на каком-то cyc2 не проблема.

В плане быстродействия cyc2 от cyc не особенно отличается, даже кое-где проигрывает. И на обоих можно и на 300 МГц разогнать. Только вот сложность логики, работающей на такой частоте, будет очень малой - не более одного уровня. Если же логику усложнить, то или тактовая сильно упадет, или конвейер придется городить, оптимизировать его. Тоже задача еще та.

Цитата(Harbour @ Feb 9 2006, 15:34) *
Даже в случае отсутствия параллелизма, в FPGA pipeline более эффективный получится, так как нет лишних накладных расходов, которые присутствуют в заточенном под универсальные задачи DSP конвейере.

Какие такие универсальные задачи? Там заточенность под пересылку данных и арифметические операции - именно то, что и нужно. Что-то я очень сомневаюсь, что без параллелизма любой Cyclone обгонит тот же Blackfin@600MHz.

Ну-ну ... хотите contest ? Алгоритм в студию (исходник на С например), я делаю на FPGA , Вы на фине. Учтите что данные еще в CPU ввести надо и вывести - а это в пересчете на наны - уйма времени, а FPGA не нуждается в прерываниях и ping-pong буферах, можно и через HPI, но что тогда с пайплайном будет ?
Универсальность, то бишь окаменелость, DSP конвейера в том что данные движутся кажный такт в строго определенных направлениях со строго определенной пропускной способностью, т.е. имеем например в каком-нить DSP 2 datapath'а по 256 бит да конвейер на 8 инструкций и кирдык - и вот берем мы наш несчастный алгоритм и под эту arch точим и кромсаем., т.е. негде развернутся в нашем DSP, не до конца он, так сказать, программируемый. В FGPA же совсем другое дело, может чуть помуторней, но это дело привычки.

TIA
des00
Ну в качестве примера, RLE кодирование большого масива данных из памяти.
Задача сугубо последовательная и практически не обладающая параллелилизмом.
Harbour
Как по мне так RLE параллелится, это сильно зависит от способа передачи данных, например если использовать в фпга набортную память как src/dst.
Ну давайте Ваш конкретный исходничек, посмотрим что можно сделать, что-то типа :

int rle_encode(uchar *src, uchar *dst, uint src_len)
{
uint dst_len = 0;
// your algo comes here
//
return dst_len;
}

P.S. Что-то далеко от темы про матрицы уехали wink.gif
dxp
Цитата(Harbour @ Feb 9 2006, 20:48) *
Ну-ну ... хотите contest ? Алгоритм в студию (исходник на С например), я делаю на FPGA , Вы на фине. Учтите что данные еще в CPU ввести надо и вывести - а это в пересчете на наны - уйма времени, а FPGA не нуждается в прерываниях и ping-pong буферах, можно и через HPI, но что тогда с пайплайном будет ?
Универсальность, то бишь окаменелость, DSP конвейера в том что данные движутся кажный такт в строго определенных направлениях со строго определенной пропускной способностью, т.е. имеем например в каком-нить DSP 2 datapath'а по 256 бит да конвейер на 8 инструкций и кирдык - и вот берем мы наш несчастный алгоритм и под эту arch точим и кромсаем., т.е. негде развернутся в нашем DSP, не до конца он, так сказать, программируемый. В FGPA же совсем другое дело, может чуть помуторней, но это дело привычки.

Знаете, пиписками мериться что-то неохота, да и времени нет. А если хочеться убедиться, то возьмите например простой КИХ фильтр тапа скажем на 32 и сравните. На блекфине это будет два тапа на такт, т.е. при 600 МГц 1200 мегатапов. Да, конечно, еще есть накладные расходы на настройку хардваре луп и дата адрес генератора, но это порядка 5-10 тактов. Такт 1.67 нс, таким образом вычисление очередного отсчета сигнала займет порядка (считаем по наихудшему случаю 10 тактов на инициализацию + 5 тактов на вызов функции и столько же на возврат): (10 + 5 + 5 + 32/2)*1.67нс = 36*1.67нс = 60 нс. И что?! Какая ПЛИС без параллелизма сможет такое?

Что касается пересылки данных, то сведения об аппаратной поддержке этого процесса, в частности, у черного фина у Вас несколько неверные. Там есть 12-канальный DMA, который позволяет делать пересылки на максимальной скорости совершенно без участия CPU. Хоть с последовательного порта наливайте, хоть с PPI, хоть из внешней памяти во внутреннюю и обратно. Типично, скорость обмена с внешней SDRAM 133 МГц. Т.е. отнимем примерно 1% накладных на рефреш и получим (133-1.33)*16 или порядка 260 мегабайт в секунду (если непрерывно лить, а там все можно так организовать - DMA можно настроить один раз и он будет лить по дескрипторам по кругу).

И если учесть что младший BF-531 стОит меньше $10 в розницу, то тут множно и подумать, на чем выгоднее делать. Особенно, если учесть, что сложность реализации подобных фильтров на процессоре на порядок (как минимум) меньше, чем на ПЛИС.

Резюмируя. Никто не оспаривает того тезиса, что на ПЛИС, при возможности распараллелить и не ограничиваясь по стоимости, всегда можно сделать быстрее. Сказно было лишь то, что последовательлно на проце штатные операции выходят быстрее. И это логично - ведь там тоже железа нехило навернуто - умножитель-аккумулятор, толстые и быстрые шины, быстрое АЛУ и т.д., все это аппаратно на кристале, а не разведено на универсальной логике в ПЛИС. Никакой узел в ПЛИС не может работать быстрее аналогичного узла в аппаратном процессоре, это естественно. Поэтому у ПЛИС преимущества только возможности параллелить и на нестандартных операциях - типа, развернуть слово (чтобы младшие биты стали старшими, а старшие младшими), если проц не поддерживает это на уровне инструкций.
des00
Цитата(dxp @ Feb 10 2006, 00:25) *
И если учесть что младший BF-531 стОит меньше $10 в розницу, то тут множно и подумать, на чем выгоднее делать. Особенно, если учесть, что сложность реализации подобных фильтров на процессоре на порядок (как минимум) меньше, чем на ПЛИС.

Резюмируя. Никто не оспаривает того тезиса, что на ПЛИС, при возможности распараллелить и не ограничиваясь по стоимости, всегда можно сделать быстрее. Сказно было лишь то, что последовательлно на проце штатные операции выходят быстрее. И это логично - ведь там тоже железа нехило навернуто - умножитель-аккумулятор, толстые и быстрые шины, быстрое АЛУ и т.д., все это аппаратно на кристале, а не разведено на универсальной логике в ПЛИС. Никакой узел в ПЛИС не может работать быстрее аналогичного узла в аппаратном процессоре, это естественно. Поэтому у ПЛИС преимущества только возможности параллелить и на нестандартных операциях - типа, развернуть слово (чтобы младшие биты стали старшими, а старшие младшими), если проц не поддерживает это на уровне инструкций.


Или нужно большое кол-во битовых операций

А по сабжу Полностью согласен с уважаемым dxp, есть определенный круг задач, решение которых на FPGA по соотношению цена/качество целесообразно,
а городить из ФПГА процессор и ждать от него чуда ничего хорошего не получиться.
Harbour
Цитата(dxp @ Feb 10 2006, 07:25) *
Цитата(Harbour @ Feb 9 2006, 20:48) *

Ну-ну ... хотите contest ? Алгоритм в студию (исходник на С например), я делаю на FPGA , Вы на фине. Учтите что данные еще в CPU ввести надо и вывести - а это в пересчете на наны - уйма времени, а FPGA не нуждается в прерываниях и ping-pong буферах, можно и через HPI, но что тогда с пайплайном будет ?
Универсальность, то бишь окаменелость, DSP конвейера в том что данные движутся кажный такт в строго определенных направлениях со строго определенной пропускной способностью, т.е. имеем например в каком-нить DSP 2 datapath'а по 256 бит да конвейер на 8 инструкций и кирдык - и вот берем мы наш несчастный алгоритм и под эту arch точим и кромсаем., т.е. негде развернутся в нашем DSP, не до конца он, так сказать, программируемый. В FGPA же совсем другое дело, может чуть помуторней, но это дело привычки.

Знаете, пиписками мериться что-то неохота, да и времени нет. А если хочеться убедиться, то возьмите например простой КИХ фильтр тапа скажем на 32 и сравните. На блекфине это будет два тапа на такт, т.е. при 600 МГц 1200 мегатапов. Да, конечно, еще есть накладные расходы на настройку хардваре луп и дата адрес генератора, но это порядка 5-10 тактов. Такт 1.67 нс, таким образом вычисление очередного отсчета сигнала займет порядка (считаем по наихудшему случаю 10 тактов на инициализацию + 5 тактов на вызов функции и столько же на возврат): (10 + 5 + 5 + 32/2)*1.67нс = 36*1.67нс = 60 нс. И что?! Какая ПЛИС без параллелизма сможет такое?

Ну-у ребята, у Вас нечестный подход - FPGA давай без параллелизьму, а мы тут DSP бум юзать по полной. Напоминаю, так сказать, нить рассуждений - des00 говорил об определенном плохо распараллелливающемся алгоритме, который, типа, на DSP будет быстрее чем на FPGA. А меряться с Вами мне неинтересно - я где-то за это время речь жму (ITU compliant G726) на первом циклоне.
Цитата
Что касается пересылки данных, то сведения об аппаратной поддержке этого процесса, в частности, у черного фина у Вас несколько неверные. Там есть 12-канальный DMA, который позволяет делать пересылки на максимальной скорости совершенно без участия CPU. Хоть с последовательного порта наливайте, хоть с PPI, хоть из внешней памяти во внутреннюю и обратно. Типично, скорость обмена с внешней SDRAM 133 МГц. Т.е. отнимем примерно 1% накладных на рефреш и получим (133-1.33)*16 или порядка 260 мегабайт в секунду (если непрерывно лить, а там все можно так организовать - DMA можно настроить один раз и он будет лить по дескрипторам по кругу).

Да ну ! И Вы в состоянии заливающиеся данные по DMA тут же обрабатывать, так сказать в процессе пересылки DMA -> ОЗУ ? Тут одно из двух - или память должна быть 2-портовой в DSP (в фине внутренняя - однопортовая) или нужно обрабатывать данные по времени сразу за DMA, что требует (1) быстрого алгоритма, (2) филигранной отстройки системы. Тут можно сказать что скорость подачи данных будет определять каким сложным может быть алгоритм, т.е. если скорость у нас высокая фин просто ничего не успеет сделать.
Цитата
И если учесть что младший BF-531 стОит меньше $10 в розницу, то тут множно и подумать, на чем выгоднее делать. Особенно, если учесть, что сложность реализации подобных фильтров на процессоре на порядок (как минимум) меньше, чем на ПЛИС.

Да хоть даром пусть его отдают - фирма AD славится своими "достижениями" в области камней и софта, глядя на толщину errata их чипов и уникальность visualdsp как-то становится не по себе.
Цитата
Резюмируя. Никто не оспаривает того тезиса, что на ПЛИС, при возможности распараллелить и не ограничиваясь по стоимости, всегда можно сделать быстрее. Сказно было лишь то, что последовательлно на проце штатные операции выходят быстрее. И это логично - ведь там тоже железа нехило навернуто - умножитель-аккумулятор, толстые и быстрые шины, быстрое АЛУ и т.д., все это аппаратно на кристале, а не разведено на универсальной логике в ПЛИС. Никакой узел в ПЛИС не может работать быстрее аналогичного узла в аппаратном процессоре, это естественно. Поэтому у ПЛИС преимущества только возможности параллелить и на нестандартных операциях - типа, развернуть слово (чтобы младшие биты стали старшими, а старшие младшими), если проц не поддерживает это на уровне инструкций.

Да и со стоимостью все супер. Вобчем где-то оно понятно, как говорят на востоке - в засохшее дерево камней не кидают, это я про DSP wink.gif
dxp
Цитата(Harbour @ Feb 10 2006, 12:53) *
Ну-у ребята, у Вас нечестный подход - FPGA давай без параллелизьму, а мы тут DSP бум юзать по полной. Напоминаю, так сказать, нить рассуждений - des00 говорил об определенном плохо распараллелливающемся алгоритме, который, типа, на DSP будет быстрее чем на FPGA. А меряться с Вами мне неинтересно - я где-то за это время речь жму (ITU compliant G726) на первом циклоне.

А причем тут это. Я про Фому (про фильтр, т.е.), а Вы про Ерему. В общем, сдаетесь!? smile.gif smile.gif

Цитата(Harbour @ Feb 10 2006, 12:53) *
Цитата

Что касается пересылки данных, то сведения об аппаратной поддержке этого процесса, в частности, у черного фина у Вас несколько неверные. Там есть 12-канальный DMA, который позволяет делать пересылки на максимальной скорости совершенно без участия CPU. Хоть с последовательного порта наливайте, хоть с PPI, хоть из внешней памяти во внутреннюю и обратно. Типично, скорость обмена с внешней SDRAM 133 МГц. Т.е. отнимем примерно 1% накладных на рефреш и получим (133-1.33)*16 или порядка 260 мегабайт в секунду (если непрерывно лить, а там все можно так организовать - DMA можно настроить один раз и он будет лить по дескрипторам по кругу).

Да ну ! И Вы в состоянии заливающиеся данные по DMA тут же обрабатывать, так сказать в процессе пересылки DMA -> ОЗУ ? Тут одно из двух - или память должна быть 2-портовой в DSP (в фине внутренняя - однопортовая) или нужно обрабатывать данные по времени сразу за DMA, что требует (1) быстрого алгоритма, (2) филигранной отстройки системы. Тут можно сказать что скорость подачи данных будет определять каким сложным может быть алгоритм, т.е. если скорость у нас высокая фин просто ничего не успеет сделать.

Как у Вас все сложно. Память в фине побита на блоки (afair, размером 4Кбайт) и можно спокойно одновременно обращатсья в разные блоки. Пока DMA льет данные в один блок, мы спокойненько лабаем другой, потом меняем местами. Там же тоже не дураки сидят, и фин - это не первый их процессор, прошлые ошибки учтены, новые возможности введены.

Цитата(Harbour @ Feb 10 2006, 12:53) *
Цитата

И если учесть что младший BF-531 стОит меньше $10 в розницу, то тут множно и подумать, на чем выгоднее делать. Особенно, если учесть, что сложность реализации подобных фильтров на процессоре на порядок (как минимум) меньше, чем на ПЛИС.

Да хоть даром пусть его отдают - фирма AD славится своими "достижениями" в области камней и софта, глядя на толщину errata их чипов и уникальность visualdsp как-то становится не по себе.

Ну, это вообще уже напоминает анек: smile.gif
"Встречаются лисенок, волчонок и медвежонок. Лисенок:
- А мне мать джинсы привезла фирменные, на заклепках, с лейбаками! Во!!
Волченок:
- А мне батя магнитолу подарил, FM берет, лазерные диски, стерео, долби и все такое!
Медвежонок:
- А я... а мне... а у меня.... А я вам сейчас 3.14..дюлей дам!"
smile.gif

А если серьезно, то не ошибается тот, кто ничего не делает. Фин - реально сложный проц, в нем помимо CPU еще наворочено ой-ой-ой сколько всякого. И чтобы это все заработало - надо поработать и напрягаться. Сегодня ревизия 0.4 уже вполне юзабельная. Да и в ките, где 0.3 стоит, я на грабли в интересующем меня спектре задач пока не наступал.

По поводу уникальности. А не пугает уникальность Quartus'а или ISE? А под фин есть еще гринхиллс и даже, вроде (не проверял), гнутый компилер. С уникальностью тулзов в мире ПЛИС все значительно хуже, нежели в мире процессоров.

Цитата(Harbour @ Feb 10 2006, 12:53) *
Да и со стоимостью все супер. Вобчем где-то оно понятно, как говорят на востоке - в засохшее дерево камней не кидают, это я про DSP wink.gif

Этой реплики не понял. Я хотел лишь сказать, что каждому зверю свой лес. И если есть задача, эффетивно решаемая, скажем, на MSP430 или AVR, то ставить туда ПЛИС или DSP по меньшей мере глупо. Кроме того, не одни ПЛИСы развиваются, но и процессоры тоже. И там прогресс весьма нехилый. И зацикливание на одном никогда не шло на пользу ни делу, ни квалификации специалиста.
des00
Цитата(Harbour @ Feb 10 2006, 01:53) *
Как по мне так RLE параллелится, это сильно зависит от способа передачи данных, например если использовать в фпга набортную память как src/dst.


Если не сложно распишите подробнее, как можно распаралелить РЛЕ(ширина данных 32 бита, ), и при этом остаться в РАЗУМНЫХ пределах по объему в фпга, и при этом уложить все это дело хотя бы на 266МГц ?

Т.е. избежать сверх широких шин данных (> 4 32 битных слов), избежать большого кол-ва регистров, большого кол-ва блоков памяти, сложных перемуксирований потока и тд.


С уважением des00.
Harbour
Статей про распараллеливание рле полно в инете, вопрос в том как в систему поступают данные, для эффективного применения того или иного метода. Конкретно image processing я не занимаюсь, но могу, в свободное время, оценить [скорость/LCELL'ы] на возможность распараллеливания конкретный алгоритм, который должен быть представлен в виде функции.
Избегать сложностей не нужно - нужно грамотно разделить задачи между DSP и FPGA, о чем и была речь в исходном посте. У меня на платах DSP тоже стоят, чем занимаются не скажу wink.gif но звук, например, они просто не тянут по скорости.
des00
Цитата
Статей про распараллеливание рле полно в инете


Спасибо, попробую поискать. Меня интересует именно алгоритмическое распараллеливание.

Цитата
вопрос в том как в систему поступают данные, для эффективного применения того или иного метода.


Тут сложно не согласиться, но вот способ поступления данных в систему, опять же будет зависить от доступного в фпга объема. (данные нужно хранить и мультиплексировать, а это сильно ест ресурс) .
В итоге может даже 100 го виртекса будет мало.

Цитата
Избегать сложностей не нужно - нужно грамотно разделить задачи между DSP и FPGA, о чем и была речь в исходном посте. У меня на платах DSP тоже стоят, чем занимаются не скажу wink.gif но звук, например, они просто не тянут по скорости.


Хмм это что же за звук то такой ? smile.gif
Harbour
Цитата(des00 @ Feb 10 2006, 13:49) *
Тут сложно не согласиться, но вот способ поступления данных в систему, опять же будет зависить от доступного в фпга объема. (данные нужно хранить и мультиплексировать, а это сильно ест ресурс) .
В итоге может даже 100 го виртекса будет мало.


Я бы данные загонял в FPGA embedded ram blocks - там за счет доступности есть много путей для дальнейшей оптимизации в плане параллельности. При проектировании высокоскоростных систем должно быть обязательно создано и промеряно на стендах 2-3 рабочих варианта с целью выявить особенности и недостатки конкретного алгоритма, например можно применить вот такой последовательный подход :

1) C-алгоритм на PC с готовой системой тест-векторов
2) DSP реализация с целью выявить узкие места, подсистема тест-векторов должна быть замкнута прямо на DSP
3) в случае если нехватает скорости - выносим узкие места из DSP в FPGA
4) если совсем плохо - делаем все на FPGA

Для такого подхода обычно применяется стендик с 1-2 DSP и 1-2 FPGA <=> ether <=> host прога на PC. Только по результатам такой вот предварительной оценки имеет смысл закладывать тот или иной чип.

Цитата
Избегать сложностей не нужно - нужно грамотно разделить задачи между DSP и FPGA, о чем и была речь в исходном посте. У меня на платах DSP тоже стоят, чем занимаются не скажу wink.gif но звук, например, они просто не тянут по скорости.

Цитата
Хмм это что же за звук то такой ? smile.gif

телефония, будь она неладна ...
jojo
#include <math.h>

Обращение выполняется за 4 этапа. С двумя последними мне все понятно, там "* + -" с плавающей точкой. И с регуляризацией понятно. Но во что обойдется реализация этапа 2 в ПЛИС. Как я понимаю, придется сделать значительный кусок АЛУ DSP, который делает sqrt и 1/x во флоате.


Вообще сколько стоит денег в Москве такое реализовать? Может, руководство согласится и вместо TS203 мы поставим ПЛИС и простенький DSP..

Но не люблю я эти Плисы. Тут есть много проектов, которые накрылись из-за того, что аффторы не справились из-за Плис.

A - массив 16x16 структур {float Re, float Im}.
d - число для регуляризации матрицы
N - 16, N2 - 32 (так автор алгоритма захотел)
S и K - временные массивы 16x16 структур {float Re, float Im}.

void inv(float *A, int N, int N2, float *S, float *K, float d)
{
int p,q,k,pr,pi,qr,qi,kr,ki;
float a,ar,ai;

//(Этап 0 приведен полностью) регуляризация
q=0;
for (p=0;p<N;p++)
{
A[p*N2+q]+=d;
q+=2;
}

//(Этап 1 приведен полностью) вычисление S
//p=1
a=A[0];
S[0]=sqrt(a);
S[1]=0.;
K[0]=1./S[0];
K[1]=0.;
//re и im
for (p=0;p<N2;p++)
{
S[p]=A[p]*K[0];
}

//p>1
pr=0;
pi=1;
for (p=1;p<N;p++)
{
pr+=2;
pi+=2;
a=A[p*N2+pr];
for (q=0;q<=p-1;q++)
{
a-=(S[q*N2+pr]*S[q*N2+pr]+S[q*N2+pi]*S[q*N2+pi]);
}


S[p*N2+pr]=(float)sqrt(a);
S[p*N2+pi]=0.;
K[p*N2+pr]=1./S[p*N2+pr];
K[p*N2+pi]=0.;


qr=pr;
qi=pi;
for (q=p+1;q<N;q++)
{
qr+=2;
qi+=2;
ar=A[p*N2+qr];
ai=A[p*N2+qi];
for (k=0;k<=p-1;k++)
{
ar-=(S[k*N2+pr]*S[k*N2+qr]+S[k*N2+pi]*S[k*N2+qi]);
ai-=(S[k*N2+pr]*S[k*N2+qi]-S[k*N2+pi]*S[k*N2+qr]);
}
S[p*N2+qr]=ar*K[p*N2+pr];
S[p*N2+qi]=ai*K[p*N2+pr];
}
} //(Этап 1 завершен)


//Этап 2 пропущен. Это перемножение матриц S и K
ar-=(S[p*N2+kr]*K[k*N2+qr]-S[p*N2+ki]*K[k*N2+qi]);
ai-=(S[p*N2+kr]*K[k*N2+qi]+S[p*N2+ki]*K[k*N2+qr]);
K[p*N2+qr]=ar*K[p*N2+pr];
K[p*N2+qi]=ai*K[p*N2+pr];

//Этап 3 пропущен. Это перемножение матриц K и транспонированной K
ar+=(K[p*N2+kr]*K[q*N2+kr]+K[p*N2+ki]*K[q*N2+ki]);
ai+=(K[p*N2+ki]*K[q*N2+kr]-K[p*N2+kr]*K[q*N2+ki]);
A[]=ar;
A[]=ai;
A[]=ar;
A[]=-ai;

return;
};
Harbour
Прикинул на пальцах Ваши матрицы, вот чего вышло :

- float был переделан в fixed point 32 бита (16/16)
- sqrt был заменен заглушкой [ float sqrt(float v) { return v; } ] - под рукой
не оказалось подходящей реализации
- интерфейс к массивам был оставлен single-port async ram и выведен на пины (изврат конечно, никто не спорит)
- для оценки взят камень EP1C20F400C6, так как пинов получилось в районе 256 :

- clk
- reset
- start_processing
- processing_inv_is_done
- float d[32] out - просто регистр
- float A[32] out
- float A[32] in
- A_addr[8]
- A_we
- float S[32] out
- float S[32] in
- S_addr[8]
- S_we
- float K[32] out
- float K[32] in
- K_addr[8]
- K_we
- async_ram_en - обчая линия

- замечания по f() :

- переменные kr и ki используются с неопределенным значением
- опущены последние 4 строки f()

Без какой либо особой оптимизации по скорости - for ex. 1 цикл остался тупо линейным, у меня вышло
2911 тактов на оценочной частоте 50Mhz. Предварительная оценка (т.е. максимум) данной f() по ресурсам такова :

Device Utilization for EP1C20F400C:

Resource Used Avail Utilization
-----------------------------------------------
IOs 258 301 85.71%
LCs 14216 20060 70.87%

в квартусе :

+--------------------------------------------------------------------------------+
; Fitter Resource Usage Summary ;
+---------------------------------------------+----------------------------------+
; Resource ; Usage ;
+---------------------------------------------+----------------------------------+
; Total logic elements ; 13,909 / 20,060 ( 69 % ) ;
; -- Combinational with no register ; 13443 ;
; -- Register only ; 8;
; -- Combinational with a register ; 458;
; ;;
; Logic element usage by number of LUT inputs ;;
; -- 4 input functions ; 2577;
; -- 3 input functions ; 7711;
; -- 2 input functions ; 3472 ;
; -- 1 input functions ; 148 ;
; -- 0 input functions ; 1 ;
; ; ;
; Logic elements by mode ; ;
; -- normal mode ; 7024 ;
; -- arithmetic mode ; 6885 ;
; -- qfbk mode ; 102 ;
; -- register cascade mode ; 0 ;
; -- synchronous clear/load mode ; 466 ;
; -- asynchronous clear/load mode ; 0 ;
; ; ;
; Total LABs ; 1,528 / 2,006 ( 76 % ) ;
; Logic elements in carry chains ; 7119 ;
; User inserted logic elements ; 0 ;
; Virtual pins ; 0 ;
; I/O pins ; 258 / 301 ( 86 % ) ;
; -- Clock pins ; 2 / 2 ( 100 % ) ;
; Global signals ; 1 ;
; M4Ks ; 0 / 64 ( 0 % ) ;
; Total memory bits ; 0 / 294,912 ( 0 % ) ;
; Total RAM block bits ; 0 / 294,912 ( 0 % ) ;
; PLLs ; 0 / 2 ( 0 % ) ;
; Global clocks ; 1 / 8 ( 13 % ) ;
+---------------------------------------------+----------------------------------+

Заводится эта фигня, если верить precision'у, а оснований не верить у нас
нет, где-то на 65.062MHz, min period - 15.370 ns, квартус как всегда более консервативен :

; Worst-case tsu ; N/A ; None ; 26.537 ns S_rsc_singleport_data_out[3] ; inv_inv_proc_1|slc_i32_l90_cse_24_ ; -- ; clk ; 0 ;
; Worst-case tco ; N/A ; None ; 164.411 ns ; inv_inv_proc_1|div_div_b_17_ ; K_rsc_singleport_data_in[0] ; clk ; -- ; 0 ;
; Worst-case tpd ; N/A ; None ; 35.901 ns ; K_rsc_singleport_data_out[0] ; S_rsc_singleport_data_in[17] ; -- ; -- ; 0 ;
; Worst-case th ; N/A ; None ; -2.489 ns ; d[5] ; inv_inv_proc_1|inv_d_5_ ; -- ; clk ; 0 ;
; Clock Setup: 'clk' ; 0.256 ns ; 50.00 MHz ( period = 20.000 ns ) ; 50.65 MHz ( period = 19.744 ns ) ; inv_inv_proc_1|slc_i32_l90_cse_18_ ; inv_inv_proc_1|inv_ai_1_26_ ; clk ; clk ; 0 ;
; Clock Hold: 'clk' ; 0.633 ns ; 50.00 MHz ( period = 20.000 ns ) ; N/A ; inv_inv_proc_1|inv_q_1__4_1_0_ ; inv_inv_proc_1|inv_q_1__4_1_0_ ; clk ; clk ; 0 ;
; Total number of failed paths ; ; ; ; ; ; ; ; 0

Если взять cyclone-2 (так как в проекте заюзаны mul и div), данные засунуть в internal dual-port ram, да еще потратить время на оптимизацию, то результат по ресурсам обычно можно сократить вдвое, а скорость поднять в 4 - 10 раз.
Также приделывается нормальный интерфейс к данным и т.д. и т.п., короче шлифовать можно до опупения.
Итого получаем грубо 2911 * 19.75ns = ~57.5 мкс (без учета sqrt) на _всю_ операцию в FGPA.
Ваш ход, принц wink.gif
psL
Код
------------------------------------------------------------
-- Square Root Calculator   (FLEX10k)
-- < fpsqrt2.vhd >
-- 1998/11/11 (Wed)
-- yamaoka@tube.ee.uec.ac.jp
------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

library metamor;
use metamor.attributes.all;

entity fpsqrt2 is
  port ( CLK  : in std_logic;                    
         A    : inout std_logic_vector(15 downto 0);
         BL   : in std_logic_vector(7 downto 0);  
         BH   : out std_logic_vector(7 downto 0);    
         OBF  : in std_logic_vector(1 downto 0);
         ACK  : out std_logic_vector(1 downto 0);
         STB  : out std_logic_vector(1 downto 0);
         IBF  : in std_logic_vector(1 downto 0);
         CL   : in std_logic_vector(5 downto 0)
      );

attribute pinnum of A   : signal is  "BC23,BB24,BC25,BB26,BC27,BB28,BC29,BB30,BC31,BB32,BC33,BB34,BC35,BB36,BC37,B
B38";
attribute pinnum of BL  : signal is  "BC13,BB14,BC15,BB16,BC17,BB18,BC19,BB20";
attribute pinnum of BH  : signal is  "BC5,BB6,BC7,BB8,BC9,BB10,BC11,BB12";
attribute pinnum of CLK : signal is  "D22";
attribute pinnum of OBF : signal is  "AV18,AV28";
attribute pinnum of ACK : signal is  "AU19,AU29";
attribute pinnum of STB : signal is  "AU21,AU31";
attribute pinnum of IBF : signal is  "AV20,AV30";
attribute pinnum of CL  : signal is  "AU23,AV24,AU25,AU33,AV34,AU35";

end fpsqrt2;

architecture RTL of fpsqrt2 is

signal A_REG : std_logic_vector(15 downto 0);    
signal ACK_BUF : std_logic_vector(1 downto 0);        
signal IN_CNT : std_logic;    
signal OUT_CNT : std_logic;                   

signal FA, FB : std_logic_vector(31 downto 0);        
signal SQ : std_logic;
signal EQ : std_logic_vector(7 downto 0);        
signal MQ : std_logic_vector(22 downto 0);        
signal QL, QH : std_logic_vector(15 downto 0);

begin

ACK_BUF <= OBF;
ACK <= ACK_BUF;

A <= "ZZZZZZZZZZZZZZZZ" when ACK_BUF = "00" else A_REG;

------------< Input Data from PC >--------------
process ( BL(0), OBF ) begin
if BL(0) = '1' then
    FA <= "00000000000000000000000000000000";
    IN_CNT <= '0';
elsif OBF'event and OBF = "11" then
    if IN_CNT = '0' then
        FA(15 downto 0) <= A;
        IN_CNT <= '1';
    else
        FA(31 downto 16) <= A;
        IN_CNT <= '0';        
    end if;
end if;
end process;

------------< Output Data to PC >--------
process ( BL(0), BL(1), IBF ) begin
if BL(0) = '1' then
    OUT_CNT <= '0';
    A_REG <= "0000000000000000";
    STB <= "11";
elsif rising_edge( BL(1) ) then    
    STB <= "00";
    if OUT_CNT = '0' then
        A_REG <= QL;
        OUT_CNT <= '1';
    else
        A_REG <= QH;
        OUT_CNT <= '0';        
    end if;
end if;
if IBF = "11" then
    STB <= "11";
end if;
end process;

process
    variable MA : std_logic_vector(25 downto 0);
    variable TEQ : std_logic_vector(7 downto 0);
    variable TMQ : std_logic_vector(24 downto 0);
    variable TMP1, TMP2, REMAIN : std_logic_vector(27 downto 0);
begin
wait until rising_edge( CLK );

TEQ := FA(30 downto 23) - "01111111";
EQ <= ( TEQ(7) & TEQ(7 downto 1) ) + "01111111";

if FA(23) = '1' then
    MA := "01" & FA(22 downto 0) & '0';
else
    MA := '1' & FA(22 downto 0) & "00";
end if;

TMP1 := "00000000000000000000000000" & MA( 25 downto 24 );
TMP2 := "0000000000000000000000000001";

for I in 0 to 24 loop
    REMAIN := TMP1 - TMP2;
    if REMAIN(27) = '0' then
        TMQ(24-I) := '1';
        if I <= 11 then
            TMP1( (I+3) downto 0 ) := REMAIN( (I+1) downto 0 ) & MA( (23-(2*I)) downto (22-(2*I)));
        else
            TMP1( (I+3) downto 0 ) := REMAIN( (I+1) downto 0 ) & "00";
        end if;
        TMP2( (I+3) downto 0 ) := TMP2( (I+2) downto 1 ) & "01";
        TMP2(2) := '1';
    else
        TMQ(24-I) := '0';
        if I <= 11 then
            TMP1( (I+3) downto 0 ) := TMP1( (I+1) downto 0 ) & MA( (23-(2*I)) downto (22-(2*I)));
        else
            TMP1( (I+3) downto 0 ) := TMP1( (I+1) downto 0 ) & "00";
        end if;    
        TMP2( (I+3) downto 0 ) := TMP2( ( I+2 ) downto 1) & "01";
    end if;
end loop;
SQ <= '0';

TMQ := TMQ + "0000000000000000000000001";
MQ <= TMQ(23 downto 1);

end process;

QL <= MQ(15 downto 0);
QH <= SQ & EQ & MQ(22 downto 16);

end RTL;


может поможет?
jojo
В процессоре этап 1 выполняется за 14.3 мкс (7128 такта ядра) вместе с корнем, программа пока еще на Си. Циклы оптимизировались хорошо, заметного выигрыша при переписывании на ассемблере не ожидается.

Такт 20 нс, конечно, великоват. Количество тактов мне нравится. Но все же я бы остановился на floate или double, т.к. не знаю, что будет с обработкой при переходе на фиксированную точку.

Видимо, все же Stratix 2 более подходит. Я безопасности проекта хочу, помимо скорости вычислений.

Самый главный для меня вопрос - как сделать функции
float y = sqrt(float) и float y = 1/sqrt(float x)

Думаю, что достаточно 1/sqrt(x), т.к. при составлении алгоритма не учитывалось, на чем он будет выполняться, просто минимизировали количество операций.
jojo
Вытащил из процессора таблицу начальных приближений rsqrt (1/sqrt x), для получения каждых 32 бит точности нужна итерация y_new = y_old * (1.5 - y_old*y_old*x*0.5). y_old - начальное приближение. Т.е. Rsqrt вычисляется за несколько тактов.

Для себя я решил, что в ПЛИС можно полностью вычислить обратную матрицу в форматах float и double.

Кстати, в каком синтезаторе есть float и double? Или в библиотеках к нему? Нашел в Квартусе плавающие сумматор и умножитель, но смущает длина их конвейеров (5-8).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.