Forum: FPGA, VHDL & Co. FPGA Datenakquisition


von Joge (Gast)


Lesenswert?

Hallo,

ich arbeite momentan an einem PC-Oszilloskop.
Hier ist mein Hardware:
-  Flaschy Board
-  Xylo-L USB Board
Der ADC läuft mit 125Mhz und der FIFO (FX2) mit 50Mhz.
Ich werde für das Zwischenspeichern einen Block-RAM verwenden.

Meine Vermutung  ist, der RAM wird sehr schnell gefüllt als gelesen was 
zu Daten Verluste führen kann.
Liege ich hier Falsh? Wenn ja, gibt es eine andere Möglichkeit die Daten 
fast Verlustfrei zu senden?

Gruß
Ming Lee

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Joge schrieb:
> Meine Vermutung  ist, der RAM wird sehr schnell gefüllt als gelesen was
> zu Daten Verluste führen kann. Liege ich hier Falsh?
Nein.
> Wenn ja, gibt es eine andere Möglichkeit die Daten
> fast Verlustfrei zu senden?
Der einzige Weg: du mußt die Daten schneller zum PC senden als sie 
eingelesen werden. Wenn du das nicht kannst, wird dein Puffer irgendwann 
gefüllt sein und du hast einen Datenverlust.

In der Praxis wird das dann ganz einfach so gemacht, dass ein Speicher 
ab einem Triggerzeitpunkt gefüllt wird. Und wenn er dann voll ist, wird 
das weitere Einlesen von Daten angehalten.

von Joge (Gast)


Lesenswert?

Danke für die Antwort^^

> In der Praxis wird das dann ganz einfach so gemacht, dass ein Speicher
> ab einem Triggerzeitpunkt gefüllt wird. Und wenn er dann voll ist, wird
> das weitere Einlesen von Daten angehalten.

Das Einlesen der Daten soll nicht eingehalten werden. Deswegen habe ich 
mir gedacht, wenn die RAM voll ist, sollen die hinkommenden Daten 
irgendwie zwischengespeichert. Aber ich weiß nicht wie ich das 
bewerkstelligen kann?

von Christian R. (supachris)


Lesenswert?

Joge schrieb:
> Das Einlesen der Daten soll nicht eingehalten werden.

Wenn du "angehalten" meinst, geht das nur, wenn die Datenverbindung zum 
PC incl. Abspeichern oder was der PC sonst noch damit anstellen soll, 
immer und garantiert im Mittel schneller ist als die Aufnahme. 
Kurzzeitige Einbrüche lassen sich durch große FIFOs umgehen, aber wenn 
die Datenverbindung im Mittel langsamer ist als die Aufnahme kannst du 
nichts machen. Wenn ich da allerdings 125MS/s lese und dann den Cypress 
FX2. Tja, dann passt das nicht zusammen. Der FX2 schafft maximal 40MB/s, 
und das nur bei guter Pufferung und nur im Mittel. Damit kannst du 
niemals die Daten in Echtzeit zum PC streamen. Dafür bräuchte es schon 
PCIe, damit könnte es klappen, wenn die Puffer groß genug sind und du 
einen schnellen PC mit schnellen Festplatten hast. Denn irgendwo müssen 
die Daten ja hin. Außerdem wirst du mit dem S3E500 auf dem Board keinen 
Blumentopf gewinnen, der hat kaum BRAM.

von Joge (Gast)


Lesenswert?

Danke für die Antwort ^^

Lothar Miller schrieb:
> In der Praxis wird das dann ganz einfach so gemacht, dass ein Speicher
> ab einem Triggerzeitpunkt gefüllt wird. Und wenn er dann voll ist, wird
> das weitere Einlesen von Daten angehalten.

Ich habe versucht deinen Ansatz zu implementieren, aber bin leider 
gescheitert.Bei mir war das USB (CyAPI) Empfang einen Problem.
Kannst du mir dienen Ansatz detaillierter erklären?
Für Vorschläge und Tutorials-Links bin ich sehr dankbar.

Gruß
Lee

von Joge (Gast)


Lesenswert?

Das ist hier den USB C++ Code für matlab:
1
#include <stdio.h>
2
#include <windows.h>
3
#include "math.h"
4
#include "mex.h"
5
#include "CyAPI.h"
6
7
static GUID GUID_KNJN_FX2 = {0x0EFA2C93, 0x0C7B, 0x454F, 0x94, 0x03, 0xD6, 0x38, 0xF6, 0xC3, 0x7E, 0x65};
8
9
#define BulkOutPipe0 USBDevice->EndPoints[1]
10
#define BulkInPipe1  USBDevice->EndPoints[2]
11
#define BulkOutPipe2 USBDevice->EndPoints[3]
12
#define BulkOutPipe3 USBDevice->EndPoints[4]
13
#define BulkInPipe4  USBDevice->EndPoints[5]
14
#define BulkInPipe5  USBDevice->EndPoints[6]
15
16
//using namespace std;
17
void mexFunction(int nlhs, mxArray *phls[], int nrhs, const mxArray *prhs[])
18
{
19
  CCyUSBDevice *USBDevice = new CCyUSBDevice(NULL, GUID_KNJN_FX2);
20
    mxArray *xData;
21
    double *xValues;
22
  double *dataOut;
23
    unsigned char bufin[512]; 
24
    //xData = (mxArray*)prhs[0];
25
          
26
    /* get pointers to data */
27
    //xValues = mxGetPr(xData);
28
  //int command = mxGetN(xData);
29
    //printf("--------command: %d ------\n", command);
30
  
31
  
32
  LONG len = 512;
33
  int i=0, j=0;
34
  double max=1000;
35
  
36
  phls[0] = mxCreateDoubleMatrix(1, max, mxREAL);
37
  dataOut = mxGetPr(phls[0]);
38
39
    for(i=0;i<max;i++)
40
  {  
41
    BulkInPipe4->XferData(bufin, len);
42
    dataOut[i]= bufin[j];
43
    //printf("Received %d bytes: %d %d\n", len, bufin[0]-'0', bufin[1]-'0');
44
    j++;
45
    if(i==511)j=0;
46
  }
47
  
48
    
49
     
50
  delete USBDevice;
51
}

von Joge (Gast)


Lesenswert?

Sorry falscher Code!!

Richtig ist:
1
for(i=0;i<max;i++)
2
  {  
3
    if(j==0)BulkInPipe4->XferData(bufin, len);
4
    dataOut[(int)i]= bufin[j];
5
    j++;
6
    if(j==512)j=0;
7
  }

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.