Hallo zusammen, ich habe einen seriellen Datenstrom mit Double Data Rate (DDR). Dieser wird in einem IDDR2 Baustein in zwei SDR Datenströme zerlegt und damit werden dann zwei Schieberegister gefüllt, um sie zu parallelisieren. Nun habe ich das Problem, dass der IDDR2 und die Schieberegister mit dem gleichen Takt getaktet sind. Daraus ergibt sich das Problem, dass das Schieberegister schon den ersten Wert speichert, obwohl erst einen Takt später verlässliche Daten am Ausgang des IDDR2 anliegen. Dadurch ergeben sich falsche Werte im Schieberegister. Nun möchte ich erreichen, dass die Schieberegister erst mit dem zweiten Takt anfangen zu arbeiten, nämlich genau dann, wenn verlässliche Daten am Ausgang des IDDR2 anliegen. Dabei ist es nicht nötig, dass die Schieberegister jeweils einen Takt länger warten, sondern nur der erste Takt stört, da nur hier falsche Daten ausgelesen werden können. Wie genau kann ich eine solche Verzögerung um genau eine Periodendauer realisieren? Ein Delay im DCM des Eingangstaktes bringt keinen Sinn, weil sowohl IDDR2 und Schiebereg. an dessen Ausgang hängen. Ich wäre für Hinweise sehr dankbar :) MfG Andi
Bastle dir eine FSM. Diese setzt beim zweiten Mal ein ready Signal. Dieses kannst du dann Abfragen und nur auslesen, wenn es gesetzt ist.
Wenn ich das richitg verstehe hast Du ein DataReady Signal (DDR) und Daten. Jetzt willst Du mit dem Data Ready Signal mit jeweils der ansteigenden und fallenden Flanke die Daten einlesen. --> Dies hast Du mit einem IDDR gemacht. Jetzt stellst Du fest das die Daten nicht immer richtig sind. Dies liegt einfach daran das die Daten während der ansteigenden und fallenden Flanke noch nicht stabiel anliegen. Was Du jetzt machen must ist die DataReady Leitung ein wenig zu verzögern. Somit liegen die Daten bereits stabiel an. Die Verzögerung des DataReady-Ready Signals kann man über zwei Möglichkeiten erreichen. 1. Du machst auf Deiner Platine die DataReady-Leitung etwas länger als die Datenleitung --> somit hat die DataReady Leitung eine höhere Laufzeit 2. Du verzögers die DataReady Leitung im FPGA mit einem IDELAY-Element. Hier bin ich auch gerade dabei und lese gerade das Datenblatt.
Hallo, Danke für die Antworten: - die Sache mit dem ready-Signal werde ich mal verfolgen. Es wartet einfach den ersten Takt ab und setzt sich dann auf High und das Schieberegister bekommt dann nur werte zugeschrieben, wenn dieses Signal 1 ist... Werde ich mir mal Gedanken machen, wie ich das realisieren kann... vielleicht mit einer Art Zähler? Der Zählt von 0 bis 2 und bei Zählerstand = 1 setze ich ein Signal auf 1 und da bleibt es dann auch. Oder hat jemand bessere Ideen bzw. Vorschläge wie ich so etwas realisieren könnte? - eine Änderung auf der Platine, sprich Leitungslängen, kann ich nicht mehr verändern - IDELAY sieht interessant aus, leider gibt es nur zwei Probleme. Scheinbar kann es nur direkt hinter einen IOB geschaltet werden, somit kann ich keine internen Signale verzögern. Zweites Problem ist, dass es nur für Virtex PFGAs geht... ich nutze aber einen Spartan 3A DSP DANKE :)
> IDELAY sieht interessant aus, leider gibt es nur zwei Probleme. > Scheinbar kann es nur direkt hinter einen IOB geschaltet werden, Ja klar, nur im IO-Block ist es physikalisch vorhanden...
Genau, und deswegen kommt es für mich nicht in Frage, weil ich ja den Eingangstakt aufsplitte und nur einen Teilzweig verzögern möchte. Ich habe gerade mit dem IBUFDS_DLY_ADJ herumprobiert, aber auch hier nutzt es mir nix, weil die Daten vorm IDDR2 verzögert werden. Das Problem besteht aber hinter dem IDDR2. Ideal wäre also eine Möglichkeit, ein Zwischensignal zu verzögern, ohne dazu einen IOB verwenden zu müssen. DANKE!!
Ich glaube so macht es keinen Sinn. Du solltest vielleicht noch mal erzählen was Du genau machen willst. Hast Du nun einen AD-Wandler oder andere Geräte?
Hallo, ja genau, ich habe einen 16bit ADC, der seine Daten aber seriell via LVDS ausgibt. Deswegen muss ich diese Daten erst parallelisieren. Hinzu kommt, dass die Daten an der steigenden und der fallenden Flanke des Taktes anliegen (DDR). Also muss ich die LVDS Daten und den LVDS Takt mittels IBUFDS bzw. diff. DCM in binäre Signale wandeln. Danach gehen die Daten direkt an einen IDDR2, aus dem zwei Datenströme kommen (einmal steigende und einmal fallende Flanke). Diese beiden Datenströme gehen dann in zwei Schieberegister, um sie zu parallelisieren und zu sortieren. Das Problem war nun, dass der Takt direkt nach dem DCM an die Schieberegister geht, die Daten aber den Umweg über den IDDR2 Baustein nehmen. Daraus ergeben sich Verzögerungen, so dass die Daten später anlagen als der Takt und sich daraus Widersprüche in den gespeicherten Daten ergeben haben. Also habe ich nun den Takt zum Schieberegister mit einem weiteren DCM_DELAY (blau) verzögert und nun liegen die Daten korrekt im Schieberegister. Im Anhang habe ich versucht, das noch ein wenig zu veranschaulichen. In der Simulation funktioniert es nun, nun muss es nur noch in der Hardware funktionieren. Kann man das so machen, oder ist das eine schlechte Designpraxis? Werden denn in der Simulation in ISim Laufzeiten schon berücksichtigt? Ich syntetisiere das Projekt und mache dann eine Simulation. Die Delay vom DCM werden 1zu1 umgesetzt. Auch waren Laufzeitunterschiede durch den IDDR2 messbar, nur deswegen mußte ich diesen Aufwand ja betreiben. Bildet die Simulation (behavioral) ungefähr die realität wieder? Oder muss ich dazu eine post-route Simulation machen? Vielen Dank, MfG Andi
Leider lassen sich zwei DMCs in Reihe nicht implementieren... oh mann :( Aber vielleicht ist jetzt klar, was genau ich machen will und vielleicht gibt es weitere Hinweise dazu? Hat jemand ein Bsp, wie ein process die erste steigende Flanke eines Taktes ignoriert und dann erst ein Signal auf 1 setzt? So etwa, nur dass eben die erste Flanke ignoriert wird: prozess: process (PClk)
1 | begin
|
2 | if rising_edge(Takt) then |
3 | signal = '1'; |
4 | end if; |
5 | end process; |
DANKE!
Das Prinzip ist zwar klar, aber die Methode nicht. Der IDDR2 Baustein taktet Dir die Signale ein, diese treten am Ausgang natürlich verzögert zur Taktflanke auf. Am Schieberegister kannst Du die Daten doch mit dem selben Takt weiterverarbeiten, diese werden dann sauber 1 Takt später eingetaktet. Warum sollte das stören? Ich hoffe, Dir ist schon klar, dass Clk-in ein kontinuierlicher Takt sein muss, der dauernd läuft, ansonsten funktioniert die DCM nicht. Das erkennen des 1. Bit muß deshalb aus dem Datenstrom erfolgen, eine 1. Flanke des Takts gibt es nicht!
@Andreas B.: Vielleicht suchst Du den OPPOSITE_EDGE bzw. SAME_EDGE -Mode vom IDDR? Duke
1.Mit welcher GEschwindigkeit wird dann Dein ADC betrieben und was für einen FPGA verwendest Du? 2. Ich würde es etwas einfacher gestalten. Du hast Deine Daten (DDR) diese würde ich in einem normalen IDDR geben und den Modus (Pipeline..) verwenden. Somit kommen liegt beim IDDR immer mit der ansteigenden Clock-Flanke beide Daten (Q1 und Q2 ) an. Wenn Du die Rohdaten nur an den PC senden willst kannst Du die Sortierung auch am PC vornehmen wenn Du jedoch die Daten im FPGA weiter verarbeiten willst, must Du diese natürlich richtig zusammensetzen. Ich denke mal mit einem Schiebregister bist Du da auf dem falschen Weg. Weil Du müstet 2 Werte auf einmal mit einem Takt schieben. Dies würde ich nicht machen. Ich würde eher etwas anderes probieren: Stell Dir vor Du hast eine Speicher der 16 Bits enthalten kann. Du nimmst einen Zähler. Zu Beginn ist der Zähler 0. Jetzt bekommst Du die ersten beiden Werte vom AD-Wandler. Nun ersetzt Du die 0. und 1. Speicherzelle von Deinem 16Bit Speicher. Anschließend zählst Du den Zähler um 1 hoch. Jetzt kommen die nächsten 2 AD-Wandlerwerte. Nun ersetzt Du die 2. und 3. Speicherzelle und so weiter. Diese geht so 1. immer den Counter mit der ansteigen Clock Flanke um 1 erhöhen if(CLK'event and CLK = '1') then if(Reset = '1')then S_COUNTER <= "000"; else S_COUNTER <= S_COUNTER +1; end if; end if; if(Reset = '1')then DATA<= "0000000000000000"; elsif(CLK'event and CLK = '1')then case S_REGZ is when "0000" => DATA(0)<= Q1; DATA(1)<= Q2; when "0001" => DATA(2)<= Q1; DATA(3)<= Q2; when "0010" => DATA(2)<= Q1; DATA(3)<= Q2; when "0011" => DATA(4)<= Q1; DATA(5)<= Q2; when "0100" => DATA(6)<= Q1; DATA(7)<= Q2; . . . when others => NULL; end case; end if; Q1 und Q2 sind die beiden Ausgänge vom IDDR Das schöne dabei ist das der Counter einen Überlauf hat und somit wieder bei 0 anfängt. Dies ist sicherlich nicht die beste Lösung jedoch würde die sicherlich funktionieren.
Es gibt auch schon fertige IP´s die LVDS verstehen. Ich weiß dass bei Altera welche dabei sind. Bei Xilinx bin ich mir nicht so sicher aber ich denke mal schon. Der Nachteil ist natürlich du musst dich erstmal mit denen auseinander setzen.
Um ein LVDS-Signal in ein "normales" umzuwandeln benötigt man keinen IP-Core sondern man nimmt muß die Eingangsbuffer nur richtig konfigurieren
So wie ich es verstanden habe kann man dank der differentiellen Übertragung die Daten schneller übertragen und dadurch Leitungen sparen. Das "normale" ist z.B. 16 bit breit. Der LVDS IP Core macht daraus vier LVDS Leitungen. Es wird also teilweise seriell übertragen. Dafür aber vier mal schneller, damit das Signal rechtzeitig ankommt. Auf der anderen Seite wird es dann wieder parallelisiert. Das machen die LVDS IP-Cores. Und vielleicht könnte man den hier auch verwenden, so sparrt man sich den eigenen Code.
@mki LVDS bedeutet erst einmal nix anderes als Low Voltage Differential Signal und hat nix mit einem auf den entsprechenden Pins betriebenen Protokoll zu tun... Die Unart daraus gleich eine serialisierte Übertragung ableiten zu wollen findet sich allerdings immer häufiger, unter anderem auch bei Xilinx, ist aber falsch. Das was Du meinst, kommt unter zahlreichen Beschreibungen daher: FlatLink(TM) TI Flat Panel Display Link Flat Panel Link FPD-Link dann gibt es noch HDMI und DVI welche auf dem gleichen Prinzip beruhen. Bei Xilinx auf der Homepage findet man dazu auch gute Erklärungen und fertigen HDL-Code zum Verstehen. (XAPP485 & XAPP486). Eine umfassende Dokumentation findet man bei Xilinx (inkl. dem Einsatz der Spartan3 IO Primitives), wenn man nach: "Spartan-3E Display Development Kit" sucht und dann das ZIP mit dem LVDS Reference Design runterlädt. Das auf der gleichen Seite verlinkte PDF direkt wird vom Server nicht gefunden... Gruß Andreas
VIELEN DANK für die ausführliche Hilfe und die vielen Hinweise. Ich werde erst einmal bei der Methode mit den Schieberegistern bleiben. Dort habe ich einfach mehr Freiheiten, später noch Steuersignale einzuarbeiten. Ich habe die Sache mit der Taktverzögerung im SR jetzt so gelöst. Ich habe ganz am Anfang oder nach dem Reset einen Counterwert 4, der rückwärts zählt. Ist 0 erreicht, wird er aber nur auf 3 zurückgesetzt. Damit ist der erste Durchlauf einen Takt länger. Ein Steuersignal, welches mir anzeigt, wann jetzt genau gültige Daten kommen, lasse ich mir vom ADC erzeugen und hält die SR im Reset, wenn keine gültigen Daten anliegen. Wenn das Signal auf 1 gesetzt wird, bedeutet gültige Daten, laufen die SR los und somit habe ich eine definierte Anfangsbedingung. Die LVDS Daten kommen mit dem 160MHZ Takt, verwenden tue ich einen Spartan 3A DSP... Ich habe noch ein paar Probleme mit meinem FiFo am Ausgang, mit dessen Hilfe ich auch asynchron mit dem PC lesen kann, weil Schreib- und Lesetakt ja nicht abhängig voneinander sind. Ich denke, ich werde der Übersicht halber dafür einen neuen Thread eröffnen. DANKE!!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.