Inbäddade system för datainsamling ECG (11 / 14 steg)
Steg 11: Använda filter från HLS och/eller FIR kompilatorn
Eftersom jag hade tidigare erfarenhet av filter konstruktion i C/C++, valde jag Vivado HLS programmet att genomföra filtren.
Filterfunktionen bör ha ett huvud som följer:
Annullera funktion (< data_type > * ingång, < data_type > * utgång, < data_type > * coeffs)
Första låt oss ta en titt på funktionsargumenten. Vilken datatyp bör vi välja? Om detta skulle vara del av ett PC-program, då datatyper inte vore mycket av ett problem (vi kunde välja dubbla eller flyta), men vi vill att syntetisera till maskinvara, så databredd är ett problem. ADS1299 databladet anger den exakta datatypen: undertecknade 24b data (komplement till 2s), så det skulle vara ett slöseri att använda 64 eller 32b flytande punkt data.
Lyckligtvis HLS har ett huvud bara för det här jobbet - "ap_int.h" innehåller anpassad bredd heltal och fast punkt datatyper.
Nu till den sista delen, koefficienterna. Koefficienterna som genererades i Matlab och kommer att användas i HLS. Om koefficienterna som anges endast en gång, kan vi ange dem som konstanter i början av funktionen. Om vi vill ändra koefficienterna som vi kan lämna i argumenten, men lagring måste vara en med dubbla portar RAM/ROM typ eftersom optimering kräver det.
Det första digitala filtret kommer att vara en 65 punkt Gran filtrerar.
CONST int firlen = 65;
CONST int dWidth = 24.
TypeDef ap_fixed < dWidth + 4, 4 > fir_t; < br >
Vilken fir_t ska användas för fast punkt datatyp. Vi behöver ett lagring register för indata, en temporal registrera och lagring register för summan av produkter.
fir_t xStore [firlen];
ap_int < dWidth + 4 > tempX;
ap_fixed < dWidth * 2, dWidth-8 > summa; < br >
Summa registret måste ha en storlek som kan hantera 65 24b * 24b värden förmodad.
Vi måste definiera filter koefficienterna som (värdena kan kopieras från Matlab):
fir_t coeffB [firlen] = {...};
I en oändlig slinga vi lagra indatavärden, konvertera dem och gå vidare till MAC operation.
While(1) {
för (int jag = 0; jag < firlen - 1; ++ jag)
xStore [i] = xStore [jag + 1];
Temp = (ap_int < dwidth += "" 4 = "" >) *(x++); < br >< / dwidth > xStore [firlen-1](dWidth + 3,0) = temp (dWidth + 3,0);
summa = 0;
för (int jag = 0; jag < firlen; ++ jag)
summa += coeffB [i] * xStore [(firlen-1) -i];
}
Sist men inte minst måste vi konvertera värdet som fast punkt till heltal i slingan.
Temp = fir_t (summa) .range(dwidth-1,0);
*(y++) = (ap_int < dwidth >) temp; < / dwidth >
Nu är det dags för C syntes. Vi kan se (bild 1) bara en liten mängd användes med medel, som beräknade tidpunkten är 15.33ns. Vi kan optimera filtret av pipelining lagring och MAC slingor med
#pragma HLS PIPELINE II = 1
På samma sätt kan IIR-filter göras.
Denna gång processen är som följer:
- Skifta input registren och lagra nästa värde.
- Skrivåtgärder MAC (för ingång och utgång registren).
- flytta ut registret och lagra utdata.
- returnera utdata.
Den sista bilden visar den synthesiyed strukturen efter pipelining filtret.