Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Jeszcze raz VHDL - problem ze zwięzłym zapisem

73 views
Skip to first unread message

stch...@gmail.com

unread,
May 23, 2015, 8:37:08 PM5/23/15
to
Problem jest w zasadzie rozwinięciem poprzedniego wątkaDo rzeczy, układ ma obliczać coś takiego: C=|R(0)+...+R(15)-R(16)-....-R(31)|, gdzie C,R(i)-liczby 11 bitowe bez znaku. R(i) są to kolejne sekcje rejestru posuwnego, w którym na pierwszą sekcję jest podawana 11 bitowa liczba "A" (bez znaku). Układ działa poprawnie zarówno na symulatorze jak i na żywym organiźmie. Wszystkie operacje +/- zrobiłem krok po kroku. A co gdybym miał pierdyljon sekcji rejestru posuwnego?
Jak to zwięźlej zapisać? Kod wygląda tak:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity amod is

Port ( A : in STD_LOGIC_VECTOR (10 downto 0);
CLK : in STD_LOGIC;
C : out STD_LOGIC_VECTOR (10 downto 0));
end amod;

architecture Behavioral of amod is
type Shift_Register_Type is array (31 downto 0) of std_logic_vector(10 downto 0);
signal Cs:std_logic_vector(14 downto 0):="000000000000000";
signal Rejestr:Shift_Register_Type;
begin



process(CLK)
begin
if rising_edge(CLK) then
Rejestr<=Rejestr(30 downto 0)&A;
Cs<=std_logic_vector(to_unsigned(abs(to_integer(signed('0'&Rejestr(0)))+
to_integer(signed('0'&Rejestr(1)))+
to_integer(signed('0'&Rejestr(2)))+
to_integer(signed('0'&Rejestr(3)))+
to_integer(signed('0'&Rejestr(4)))+
to_integer(signed('0'&Rejestr(5)))+
to_integer(signed('0'&Rejestr(6)))+
to_integer(signed('0'&Rejestr(7)))+
to_integer(signed('0'&Rejestr(8)))+
to_integer(signed('0'&Rejestr(9)))+
to_integer(signed('0'&Rejestr(10)))+
to_integer(signed('0'&Rejestr(11)))+
to_integer(signed('0'&Rejestr(12)))+
to_integer(signed('0'&Rejestr(13)))+
to_integer(signed('0'&Rejestr(14)))+
to_integer(signed('0'&Rejestr(15)))-
to_integer(signed('0'&Rejestr(16)))-
to_integer(signed('0'&Rejestr(17)))-
to_integer(signed('0'&Rejestr(18)))-
to_integer(signed('0'&Rejestr(19)))-
to_integer(signed('0'&Rejestr(20)))-
to_integer(signed('0'&Rejestr(21)))-
to_integer(signed('0'&Rejestr(22)))-
to_integer(signed('0'&Rejestr(23)))-
to_integer(signed('0'&Rejestr(24)))-
to_integer(signed('0'&Rejestr(25)))-
to_integer(signed('0'&Rejestr(26)))-
to_integer(signed('0'&Rejestr(27)))-
to_integer(signed('0'&Rejestr(28)))-
to_integer(signed('0'&Rejestr(29)))-
to_integer(signed('0'&Rejestr(30)))-
to_integer(signed('0'&Rejestr(31)))),15));

end if;
end process;
C<=Cs(14 downto 4);
end Behavioral;

Jakub Rakus

unread,
May 24, 2015, 4:38:20 PM5/24/15
to
On 24.05.2015 02:37, stch...@gmail.com wrote:
> Problem jest w zasadzie rozwinięciem poprzedniego wątkaDo rzeczy, układ ma obliczać coś takiego: C=|R(0)+...+R(15)-R(16)-....-R(31)|, gdzie C,R(i)-liczby 11 bitowe bez znaku. R(i) są to kolejne sekcje rejestru posuwnego, w którym na pierwszą sekcję jest podawana 11 bitowa liczba "A" (bez znaku). Układ działa poprawnie zarówno na symulatorze jak i na żywym organiźmie. Wszystkie operacje +/- zrobiłem krok po kroku. A co gdybym miał pierdyljon sekcji rejestru posuwnego?
> Jak to zwięźlej zapisać? Kod wygląda tak:
<ciach>

Można użyć funkcji, która wygeneruje taką sumę dla zadanej liczby
sygnałów, w funkcji trzeba by wykorzystać for ... loop. Można też
bezpośrednio w procesie użyć for ... loop.

--
Pozdrawiam
Jakub Rakus

stch...@gmail.com

unread,
May 24, 2015, 5:34:24 PM5/24/15
to
No więc właśnie tak kombinowałem.
Pseudokod:

for i in 0 to 15 loop
Cs<=Cs+R(i)-R(i+16)
end loop;

I wyszedł z tego akumulator :((

Jakub Rakus

unread,
May 25, 2015, 3:52:12 PM5/25/15
to
On 24.05.2015 23:34, stch...@gmail.com wrote:

>
> No więc właśnie tak kombinowałem.
> Pseudokod:
>
> for i in 0 to 15 loop
> Cs<=Cs+R(i)-R(i+16)
> end loop;
>
> I wyszedł z tego akumulator :((
>

Bo to nie można tego zrobić na sygnałach tylko na variable wewnątrz
procesu. I wtedy nie <= tylko :=.

--
Pozdrawiam
Jakub Rakus

stch...@gmail.com

unread,
May 25, 2015, 5:27:36 PM5/25/15
to
OK, dzięki! Teraz działa.

J.F.

unread,
May 26, 2015, 4:36:42 AM5/26/15
to
Użytkownik napisał w wiadomości grup
>Problem jest w zasadzie rozwinięciem poprzedniego wątkaDo rzeczy,
> układ ma obliczać coś takiego: C=|R(0)+...+R(15)-R(16)-....-R(31)|,
> gdzie C,R(i)-liczby 11 bitowe bez znaku.
> R(i) są to kolejne sekcje rejestru posuwnego, w którym na pierwszą
> sekcję jest podawana 11 bitowa liczba "A" (bez znaku).
>Układ działa poprawnie zarówno na symulatorze jak i na żywym
>organiźmie.
> Wszystkie operacje +/- zrobiłem krok po kroku. A co gdybym miał
> pierdyljon sekcji rejestru posuwnego?
>Jak to zwięźlej zapisać? Kod wygląda tak:

Czy ja dobrze rozumiem ze mamy rejestr przesuwny o 32 slowach 11
bitowych,
co takt zegara slowa wprowadzamy nowa wartosc, reszte przesuwamy, i
wyliczamy sume pierwszych 16 slow minus suma drugich 16 slow ?

Pomijajac trudnosci jak to zwiezle w VHDL zapisac ... pomysleliscie
jak to powinno byc zrealizowane ? Czy zdajecie sie na optymalizator ?
:-)

Bo sumator 32 liczb jest dosc kosztowny, ciekawe - kompilatorowi
pamieci zabraknie przy optymalizacji funkcji, czy zrealizuje
kaskadowo.
A im wiecej slow w tym rejestrze, tym ciezsze zadanie.

To sie w krzemie realizuje inaczej ...

J.

stch...@gmail.com

unread,
May 27, 2015, 2:48:12 AM5/27/15
to
W dniu wtorek, 26 maja 2015 10:36:42 UTC+2 użytkownik J.F. napisał:
> Użytkownik napisał w wiadomości grup
> >Problem jest w zasadzie rozwinięciem poprzedniego wątkaDo rzeczy,
> > układ ma obliczać coś takiego: C=|R(0)+...+R(15)-R(16)-....-R(31)|,
> > gdzie C,R(i)-liczby 11 bitowe bez znaku.
> > R(i) są to kolejne sekcje rejestru posuwnego, w którym na pierwszą
> > sekcję jest podawana 11 bitowa liczba "A" (bez znaku).
> >Układ działa poprawnie zarówno na symulatorze jak i na żywym
> >organiźmie.
> > Wszystkie operacje +/- zrobiłem krok po kroku. A co gdybym miał
> > pierdyljon sekcji rejestru posuwnego?
> >Jak to zwięźlej zapisać? Kod wygląda tak:
>
> Czy ja dobrze rozumiem ze mamy rejestr przesuwny o 32 slowach 11
> bitowych,
> co takt zegara slowa wprowadzamy nowa wartosc, reszte przesuwamy, i
> wyliczamy sume pierwszych 16 slow minus suma drugich 16 slow ?

Dobrze rozumiesz.

>
> Pomijajac trudnosci jak to zwiezle w VHDL zapisac ... pomysleliscie
> jak to powinno byc zrealizowane ? Czy zdajecie sie na optymalizator ?
> :-)
>
> Bo sumator 32 liczb jest dosc kosztowny, ciekawe - kompilatorowi
> pamieci zabraknie przy optymalizacji funkcji, czy zrealizuje
> kaskadowo.
> A im wiecej slow w tym rejestrze, tym ciezsze zadanie.

Robię to na spartanie6 (XCS6LX45) i nie ma żadnego problemu z implementacją.

>
> To sie w krzemie realizuje inaczej ...
>
Jak?

J.F.

unread,
May 27, 2015, 4:40:37 AM5/27/15
to
Użytkownik napisał w wiadomości grup
dyskusyjnych:b145b622-569c-4b81...@googlegroups.com...
A jest jakas szansa zobaczyc jak to kompilator zrobil ?
Ewentualnie - ile makrocell mu to zajelo, jakie opoznienia wyszly ?

>> To sie w krzemie realizuje inaczej ...
>Jak?

Pomysl pierwszy - rysunek by sie przydal, ale moze sie uda slowami:
32 rejestry w szeregu, tylko ze na wejsciu kazdego (z wyjatkiem
pierwszego) z nich umieszczasz sumator A i wyjscia poprzednego
rejestru.

Tym sposobem drugi rejestr widzi R1= A+A(-1), [A(-n) - A opoznione
o n cykli)
R2 = A+R1 = A+ A(-1) + A(-2) [bo w miedzyczasie sie o cykl opoznilo]
itd.
Gdzies w polowie musisz wstawic roznice A-R(15)


Pomysl drugi - jesli jest zwykla suma, to ona co cykl zmienia sie
tylko o nowy wyraz, ktory wchodzi do sumy, i ostatni, ktory wypada.
Czyli wystarczy jeden akumulator S, w ktorym co cykl liczymy
S = S +A - A(-31)
Oczywiscie na poczatku trzeba wyzerowac i S i wszystkie rejestry R,
aby byla zgodnosc :-).

Ty masz roznice dwoch sum, to sie wyrazenie nieznacznie skomplikuje.

J.

stch...@gmail.com

unread,
May 27, 2015, 5:55:21 AM5/27/15
to
W dniu środa, 27 maja 2015 10:40:37 UTC+2 użytkownik J.F. napisał:

>
> A jest jakas szansa zobaczyc jak to kompilator zrobil ?
> Ewentualnie - ile makrocell mu to zajelo, jakie opoznienia wyszly ?

Można to zobaczyć na edytorze wyroutowanego układu, ale analizę tego pozostawiam raczej mnichom z Shaolin, albo tym co mają czasu w nadmiarze.
Makrocele to masz w CPLD. Ja robię na FPGA raczej dosyć małym, ale i tak ilość zasobów logicznych jest taka, że ten konkretny problem zajmuje kompletnie nieistotny procent. W ogóle o tym nawet nie myślę. Opóźnienia jak najbardziej możesz monitorować, ewentualnie narzucić swoje constraintsy. Ja tego nawet nie robię, zostawiam to kompilatorowi "as is", układ działa poprawnie na 20MHz.

>
> >> To sie w krzemie realizuje inaczej ...
> >Jak?
>
> Pomysl pierwszy - rysunek by sie przydal, ale moze sie uda slowami:
> 32 rejestry w szeregu, tylko ze na wejsciu kazdego (z wyjatkiem
> pierwszego) z nich umieszczasz sumator A i wyjscia poprzednego
> rejestru.
>
> Tym sposobem drugi rejestr widzi R1= A+A(-1), [A(-n) - A opoznione
> o n cykli)
> R2 = A+R1 = A+ A(-1) + A(-2) [bo w miedzyczasie sie o cykl opoznilo]
> itd.
> Gdzies w polowie musisz wstawic roznice A-R(15)
>

Rozumiem, że coś w tym stylu:

http://www.fotoszok.pl/show.php/2420352_sumator.jpg.html

>
> Pomysl drugi - jesli jest zwykla suma, to ona co cykl zmienia sie
> tylko o nowy wyraz, ktory wchodzi do sumy, i ostatni, ktory wypada.
> Czyli wystarczy jeden akumulator S, w ktorym co cykl liczymy
> S = S +A - A(-31)
> Oczywiscie na poczatku trzeba wyzerowac i S i wszystkie rejestry R,
> aby byla zgodnosc :-).


>
> Ty masz roznice dwoch sum, to sie wyrazenie nieznacznie skomplikuje.
>

Jasne, można i tak i owak, niemniej jednak nie dostrzegam żadnych zalet w stosunku do przyjętego rozwiązania.

Pzdr.

J.F.

unread,
May 27, 2015, 6:09:27 AM5/27/15
to
Użytkownik napisał w wiadomości grup
dyskusyjnych:7ba3c1df-aa38-42e9...@googlegroups.com...
W dniu środa, 27 maja 2015 10:40:37 UTC+2 użytkownik J.F. napisał:
>> A jest jakas szansa zobaczyc jak to kompilator zrobil ?
>> Ewentualnie - ile makrocell mu to zajelo, jakie opoznienia wyszly ?

>Można to zobaczyć na edytorze wyroutowanego układu, ale analizę tego
>pozostawiam raczej mnichom z Shaolin, albo tym co mają czasu w
>nadmiarze.
>Makrocele to masz w CPLD. Ja robię na FPGA raczej dosyć małym, ale i
>tak ilość zasobów logicznych jest taka, że ten konkretny problem
>zajmuje kompletnie nieistotny procent. W ogóle o tym nawet nie myślę.
>Opóźnienia jak najbardziej możesz monitorować, >ewentualnie narzucić
>swoje constraintsy. Ja tego nawet nie robię, zostawiam to
>kompilatorowi "as is", układ działa poprawnie na 20MHz.

>> Pomysl pierwszy - rysunek by sie przydal, ale moze sie uda slowami:
>> 32 rejestry w szeregu, tylko ze na wejsciu kazdego (z wyjatkiem
>> pierwszego) z nich umieszczasz sumator A i wyjscia poprzednego
>> rejestru.
Dokladnie.

>> Pomysl drugi - jesli jest zwykla suma, to ona co cykl zmienia sie
>> tylko o nowy wyraz, ktory wchodzi do sumy, i ostatni, ktory wypada.
>> Czyli wystarczy jeden akumulator S, w ktorym co cykl liczymy
>> S = S +A - A(-31)

>Jasne, można i tak i owak, niemniej jednak nie dostrzegam żadnych
>zalet w stosunku do przyjętego rozwiązania.

Funkcja logiczna wydaje znacznie prosztsza.
Ale moze nie doceniam kompilatora.

Jesli masz wszystko przygotowane ... moze bys zrobil drugi projekt w
alternatywnej wersji, tylko jak to ocenic - % zajetosci zasobow,
wyliczona maksymalna czestotliwosc pracy, czas pracy kompilatora ?
To ostatnie najmniej istotne :-)


J.

stch...@gmail.com

unread,
May 27, 2015, 11:26:11 AM5/27/15
to
W dniu środa, 27 maja 2015 12:09:27 UTC+2 użytkownik J.F. napisał:

>
> Funkcja logiczna wydaje znacznie prosztsza.
> Ale moze nie doceniam kompilatora.
>
> Jesli masz wszystko przygotowane ... moze bys zrobil drugi projekt w
> alternatywnej wersji, tylko jak to ocenic - % zajetosci zasobow,
> wyliczona maksymalna czestotliwosc pracy, czas pracy kompilatora ?
> To ostatnie najmniej istotne :-)
>
>
Jako jedeny moduł w FPGA, Twoja wersja zajmuje minimalnie mniej zasobów czysto logicznych (LUT's), ale tyle samo Flip-Flopów, co jest akurat oczywiste (rejestr posuwny). Natomiast w całości mojego projektu zastosowanie modułu w/g Twojego pomysłu - na odwrót. Dzieje się tak zapewne dlatego, że mapowanie w przypadku wykorzystania większej liczby zasobów zaczyna być bardziej "agresywne". Algorytmów nie znamy, więc są to czyste spekulacje z mojej strony. Prędkość praktycznie ta sama, można to popychać ~140MHz.

J.F.

unread,
May 27, 2015, 11:40:54 AM5/27/15
to
Użytkownik napisał w wiadomości grup
No, to ciekaw jestem jak to kompilator zrealizowal.

Dodawanie 32 liczb 11-bit- wydaje mi sie, ze to bardzo wredna funkcja.
Oczywiscie mozna zrealizowac zwyklymi sumatorami dwoch liczb, nawet
tyle samo ich trzeba, ale czas propagacji powinien wzrosnac.
Jak zrobil "liniowo" a nie "drzewem binarnym", to nawet sporo wzrosnac
...

Chyba, ze nawet nie zblizyles sie do granicy szybkosci ...

J.








stch...@gmail.com

unread,
May 27, 2015, 1:29:59 PM5/27/15
to
W dniu środa, 27 maja 2015 17:40:54 UTC+2 użytkownik J.F. napisał:

>
> No, to ciekaw jestem jak to kompilator zrealizowal.
>
> Dodawanie 32 liczb 11-bit- wydaje mi sie, ze to bardzo wredna funkcja.
> Oczywiscie mozna zrealizowac zwyklymi sumatorami dwoch liczb, nawet
> tyle samo ich trzeba, ale czas propagacji powinien wzrosnac.
> Jak zrobil "liniowo" a nie "drzewem binarnym", to nawet sporo wzrosnac
> ...

W FPGA jest trochę inaczej i nie należy, wręcz NIE WOLNO myśleć w kategoriach bramek logicznych i połączeń między nimi i wydawałoby się wynikających z tego czasów propagacji. Tutaj masz generatory funkcji, które w obrębie pojedyńczego CLB są niczym innym jak pamięcią statyczną i realizują dowolną funkcję logiczną n-zmiennych (n-zależne od typu FPGA). Jest to właściwie LUT(look up table), w którym wartości zmiennych wejściowych stanowią adres do gotowego wyniku. Oczywiście taka kobyła jak sumator 32 liczb 11-bitowych nie wlezie w pojedyńczy LUT, więc czasy propagacji są pomiędzy poszczególnymi CLB, ale jest to mocno zniwelowane..

>
> Chyba, ze nawet nie zblizyles sie do granicy szybkosci ...
>

Na próbę pocisnąłem to na 80MHz, co akurat w moim projekcie nie ma sensu. Też działa!!

stch...@gmail.com

unread,
May 29, 2015, 6:48:39 AM5/29/15
to
W dniu środa, 27 maja 2015 17:40:54 UTC+2 użytkownik J.F. napisał:
A jednak Twój pomysł jest lepszy!! Postanowiłem rozszerzyć zagadnienie do 64 liczb. No i od tego momentu zaczęły się chece. Zasoby i czas propagacji poszły ostro w górę, podczas gdy w/g Twojej porady nadal wszystko jest cacy.

J.F.

unread,
May 29, 2015, 7:39:46 AM5/29/15
to
Użytkownik napisał w wiadomości grup
W dniu środa, 27 maja 2015 17:40:54 UTC+2 użytkownik J.F. napisał:
>> No, to ciekaw jestem jak to kompilator zrealizowal.
>
>> Dodawanie 32 liczb 11-bit- wydaje mi sie, ze to bardzo wredna
>> funkcja.
>> Oczywiscie mozna zrealizowac zwyklymi sumatorami dwoch liczb, nawet
>> tyle samo ich trzeba, ale czas propagacji powinien wzrosnac.
>> Jak zrobil "liniowo" a nie "drzewem binarnym", to nawet sporo
>> wzrosnac

>A jednak Twój pomysł jest lepszy!! Postanowiłem rozszerzyć
>zagadnienie do 64 liczb. No i od tego momentu zaczęły się chece.
>Zasoby i czas propagacji poszły ostro w górę, podczas gdy w/g Twojej
>porady nadal wszystko jest cacy.

Ciesze sie, ze choc raz teoria zgadza sie z praktyka :-)

Ale nadal jestem ciekaw jak on to zrobil z 32 liczbami, ze tak dobrze
bylo :-)

J.

stch...@gmail.com

unread,
May 29, 2015, 4:23:58 PM5/29/15
to
W dniu piątek, 29 maja 2015 13:39:46 UTC+2 użytkownik J.F. napisał:

>
> Ciesze sie, ze choc raz teoria zgadza sie z praktyka :-)

Jeżeli teoria nie zgadza się z praktyką, to tym gorzej dla praktyki :)))
Eeee tam.., jeżeli w cyfrówie wymiśli się coś BANALNIE prostego, to nie ma bata we wsi, coby to nie działało.. Podałeś też pomysł z wykorzystaniem akumulatora..
Toż to pierwsze o czym pomyślałem, ale doszedłem do wniosku, że to lipa.. No bo po n+1 mlasknięciach zegara akumulator się "przekręci". Resetowanie co n-mlasknięć jest też beż sensu, bo tracę dane R(n downto 0)!!

Ale..., Twój pomysł z akumulatorem + mój pomysł z rejestrem posuwnym ma sens.

Robimy taki akumulator : Acc:=Acc+A(n)-A(0). A(n) - aktualna próbka z ADC, A(0) - n-mlasknięć starsza próbka z FIFO. Owym FIFO może być właśnie rejestr posuwny. Innymi słowy A(i) leci równolegle na akumulator i rejestr posuwny. Wyjście z rejestru (na końcu), to A(0). Minimalne zużycie zasobów FPGA dla dowolnego 'n', powinno śmigać na ciężkich MHz. Jutro sprawdzę na 'żywym organiźmie'. Dzięki za pomysły, sensownie się z Tobą gada !!
0 new messages