Stap 11: Met behulp van de filters van de HLS en/of de FIR-Compiler
Aangezien ik had voorafgaande ervaring met filter bouw in C/C++, koos ik het Vivado HLS-programma uit te voeren van de filters.
De filter-functie moet als volgt een koptekst:
void function (<data_type>* input, <data_type> *output, <data_type> *coeffs)
Eerste laten we eens een kijkje op de functieargumenten. Welk gegevenstype moet we kiezen? Als onderdeel van een PC-programma, zou dit dan gegevenstypen zou niet veel van een zorg (we konden kiezen dubbele of zweven), maar we synthetiseren aan hardware willen, dus Gegevensbreedte een bron van zorg is. Het gegevensblad van de ADS1299 geeft de exacte gegevenstype: ondertekende 24b gegevens (2s aanvullen), dus het zou een verspilling te gebruiken 64 of 32b zwevend punt gegevens.
Gelukkig HLS heeft een header alleen voor deze job - "ap_int.h" bevat aangepaste breedte integer en vaste punt gegevenstypen.
Nu aan het laatste deel, de coëfficiënten. De coëfficiënten in Matlab werden gegenereerd, en zal worden gebruikt in HLS. Als u de coëfficiënten zijn slechts eenmaal opgeeft, kunnen we hen als constanten aan het begin van de functie aangeven. Als we willen veranderen de coëfficiënten kunnen we laten in de argumenten, maar de opslag moet een dubbele poort type RAM/ROM omdat de optimalisatie vereist.
De eerste digitale filter zullen een 65 punt FIR filter.
const int firlen = 65; const int dWidth = 24; typedef ap_fixed<dWidth + 4, 4> fir_t;<br>
Het type van de fir_t zal worden gebruikt voor dekpunt gegevenstype. We moeten een register van de opslag voor de invoergegevens, een tijdelijke register en een register van de opslag voor de som van de producten.
fir_t xStore[firlen]; ap_int<dWidth + 4>tempX; ap_fixed<dWidth*2,dWidth-8> sum;<br>
Het register van de som moet een grootte die kan omgaan met 65 24b * 24b waarden sumed.
We moeten definiëren de coëfficiënten van de filter als (de waarden kunnen worden gekopieerd vanuit Matlab):
fir_t coeffB[firlen] = {...};
In een oneindige lus we slaan de invoerwaarden, omzetten, en gaat u verder met de MAC-bewerking.
while(1){ for(int i = 0; i < firlen - 1; ++i) xStore[i] = xStore[i+1]; temp = (ap_int<dwidth +="" 4="">) *(x++);<br></dwidth> xStore[firlen-1](dWidth + 3,0) = temp(dWidth + 3,0); sum = 0; for(int i=0; i < firlen; ++i) sum += coeffB[i]*xStore[(firlen - 1) -i]; }
Laatste maar niet minste moet we de vaste puntenwaarde converteren naar integer met teken in de lus.
temp = fir_t(sum).range(dWidth -1,0); *(y++) = (ap_int<dwidth>) temp;</dwidth>
Nu is het tijd voor C-synthese. Wij zien (figuur 1), dat slechts een kleine hoeveelheid van de middelen werd gebruikt, en de geschatte timing 15.33ns is. We kunnen het filter optimaliseren door de opslag en de MAC loops met pipelining
#pragma HLS PIPELINE II=1
Ook kan de IIR filter worden gemaakt.
Ditmaal het proces is als volgt:
- Verschuif de invoer registers en de volgende waarde opslaan.
- De MAC-schrijfbewerkingen (voor de input en output registers).
- verschuiven van het uitvoer-register en sla de uitvoer op.
- de uitvoer retourneren
De laatste foto toont de structuur van de synthesiyed na het filter pipelining.