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

Обращение матриц на ПЛИС

Ну-у ребята, у Вас нечестный подход - 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) филигранной отстройки системы. Тут можно сказать что скорость подачи данных будет определять каким сложным может быть алгоритм, т.е. если скорость у нас высокая фин просто ничего не успеет сделать.

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

 

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

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

Ну, это вообще уже напоминает анек: :)

"Встречаются лисенок, волчонок и медвежонок. Лисенок:

- А мне мать джинсы привезла фирменные, на заклепках, с лейбаками! Во!!

Волченок:

- А мне батя магнитолу подарил, FM берет, лазерные диски, стерео, долби и все такое!

Медвежонок:

- А я... а мне... а у меня.... А я вам сейчас 3.14..дюлей дам!" :)

 

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

 

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

 

Да и со стоимостью все супер. Вобчем где-то оно понятно, как говорят на востоке - в засохшее дерево камней не кидают, это я про DSP ;)

Этой реплики не понял. Я хотел лишь сказать, что каждому зверю свой лес. И если есть задача, эффетивно решаемая, скажем, на MSP430 или AVR, то ставить туда ПЛИС или DSP по меньшей мере глупо. Кроме того, не одни ПЛИСы развиваются, но и процессоры тоже. И там прогресс весьма нехилый. И зацикливание на одном никогда не шло на пользу ни делу, ни квалификации специалиста.

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


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

Как по мне так RLE параллелится, это сильно зависит от способа передачи данных, например если использовать в фпга набортную память как src/dst.

 

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

 

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

 

 

С уважением des00.

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


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

Статей про распараллеливание рле полно в инете, вопрос в том как в систему поступают данные, для эффективного применения того или иного метода. Конкретно image processing я не занимаюсь, но могу, в свободное время, оценить [скорость/LCELL'ы] на возможность распараллеливания конкретный алгоритм, который должен быть представлен в виде функции.

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

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


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

Статей про распараллеливание рле полно в инете

 

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

 

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

 

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

В итоге может даже 100 го виртекса будет мало.

 

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

 

Хмм это что же за звук то такой ? :)

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


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

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

В итоге может даже 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 тоже стоят, чем занимаются не скажу ;) но звук, например, они просто не тянут по скорости.

Хмм это что же за звук то такой ? :)

телефония, будь она неладна ...

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


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

#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;

};

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


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

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

 

- 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.

Ваш ход, принц ;)

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


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

------------------------------------------------------------
-- Square Root Calculator   (FLEX10k)
-- < fpsqrt2.vhd >
-- 1998/11/11 (Wed) 
-- [email protected]
------------------------------------------------------------

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;

 

может поможет?

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


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

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

 

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

 

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

 

Самый главный для меня вопрос - как сделать функции

float y = sqrt(float) и float y = 1/sqrt(float x)

 

Думаю, что достаточно 1/sqrt(x), т.к. при составлении алгоритма не учитывалось, на чем он будет выполняться, просто минимизировали количество операций.

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


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

Вытащил из процессора таблицу начальных приближений 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).

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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