Hallo,
ich habe folgendes Problem.
Ich habe serielle LVDS Daten (8bit), die ich mittels eines
Schieberegsiters parallelisiere. Das klappt so alleine wunderbar in der
Simulation (SR_solo.png). Also die erste '1' wird auf Bit 0 des SRs
eingelesen und geschiftet, alle weiteren Daten werden korrekt eingelesen
und bei Full = '1' können sie dann ausgelesen werden.
Nun möchte ich aber die Daten auf der steigenden und fallenden Flanke
des Taktes auslesen. Dazu verwende ich ein IDDR2, welches mittels eines
DCM getaktet ist. Die Ausgänge Q0 und Q1 gehen jeweils auf zwei
getrennte Schieberegister. Aber hier übernimmt das SR statt der '1' am
Anfang eine '0' und dadurch stimmt die Ausgabe nicht mehr.
Ich habe nun testweise den Datenzweig der fallenden Flanke deaktiviert
und will wie zuvor auch nur die Daten der steigenden Flanke auslesen.
Diese Daten stammen aber diesmal von einem IDDR2, Ausgang Q0.
In dieser Konstellation tritt der Fehler auch auf... statt einer '1'
wird eine '0' im ersten Takt auf Bit 0 des SRs gelesen. Auch folgende
Takte stimmen teilweise nicht überein mit dem, was ich erwarte beim
Dateneinlesen (SR_IDDR2.png).
Wo genau kann der Fehler liegen, wenn das Schieberegister wunderbar
funktioniert, aber sobald ein IDDR2 dazwischen geschaltet wird, die
Eingabe in das SR fehlerhaft ist? Muss ich in dem Zusammenhang noch
etwas beachten?
Ich habe meine Quellen incl. der beiden Testbenches mit angehängt,
vielleicht hilft es bei der Fehlersuche?!
TOPFILE.zip
|---TOPFILE.vhd => tb_TOPFILE_IDDR2.vhd
|--DIFF_CLOCK_IN.vhd
|--DIFF_DATA_IN.vhd
|--schiebereg.vhd => tb_schiebreg8bit.vhd
VIELEN DANK!!
Ich habe gerade gesehen, dass das zweite SR, was ich aktuell noch
auskommentiert hatte, funktioniert. Auch zusammen mit dem IDDR2.
Sie fallende Flanke funktioniert also, nur die steigende macht
Probleme...
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.STD_LOGIC_ARITH.ALL;
4
useIEEE.STD_LOGIC_UNSIGNED.ALL;
5
libraryUNISIM;
6
useUNISIM.VComponents.all;
7
8
9
entityS2P_1laneDATAis
10
Port(CLOCK_IN_P:inSTD_LOGIC;--LVDS Takt
11
CLOCK_IN_N:inSTD_LOGIC;--LVDS Takt
12
RESET:inSTD_LOGIC;--Schieberegister Reset
13
RESET_DCM:inSTD_LOGIC;--DCM Reset
14
FULL_ris:outstd_logic;--schieberegister mit 8bit geladen
15
FULL_fal:outstd_logic;--schieberegister mit 8bit geladen
Ich denke ich habe den Fehler gefunden.
Der IDDR2 erzeugt ein Delay im Datenzweig... der Takt ist laut
Simulation 100ps eher da als die Daten und daher kann auch keine '1'
übernommen werden.
Nun ist wieder die Frage: Wie kann ich die Daten synchron zum Takt
schalten?
Kann ich den Takt irgendwie künstlich durch ein paar Gatter schicken,
dass dieser die gleiche Laufzeit hat wie die Daten und beide wieder
synchron am Eingang des SRs ankommen?
DANKE!!!
Für genau diesen Anwendungsfall gibts doch den DCM. Da kannst du die
Phasenlage aller Ausgangstakte zum Eingangstakt nochmal ganz fein
einstellen, im ps-Stufen. Siehe Bild -> Phase Shift
In der Hardware kann das dann durchaus noch mehr als 100ps werden. Da
musst du dann bestimmt nochmal am Delay drehen.
Ach na klar... oh mann... die einfachsten Lösungen sieht man nicht...
Also stelle ich den Parameter CLKOUT_PHASE_SHIFT auf "FIXED", nur
welcher Parameter legt fest, wie groß das Delay ist?
Ich würde nur sehr ungern einen neuen IPCore einbinden. Den vorhandenen
editieren wäre mir fast lieber.
VIELEN DANK!!!
Na gut, du könntest auch das Datenblatt des DCM oder im User Guide
lesen, aber "PHASE_SHIFT = 5" wäre zum Beispiel eine Einstellung.
Ausrechnen, wieviel das ist, musst du aber selbst, die Formel steht im
Datenblatt.
Hallo,
Kann man dieses Delay denn auch simulieren?
Ich habe nun doch einen neuen IP Core erzeugt und den VDHL Code kopiert
und anschließend versucht zu simulieren. Egal ob Phaseshift => 0 oder =>
255, das Simulationsergebnis unterscheidet sich in keinster Weise. Auch
im Größten Zoom ist kein Delay des DCM0 zum Eingangstakt sichtbar.
Das hier ist der erzeigte Code, den Phaseshift Parameter habe ich dann
wahlweise verändert, nur leider ohne Ergebnis:
Ja kann man simulieren. Dazu muss die Simulations-Auflösung aber 1ps
oder kleiner sein. Ich konnte den DCM bisher immer in der Simulation
benutzen, allerdings instanziiere ich immer nur den Core, den der
Core-Generator ausspuckt. Das machts übersichtlicher.
Hab es jetz genauso gelöst, hab den Core direkt eingebunden. So kann man
ja auch recht einfach direkt über den Wizzard das Delay einstellen.
Nur leider kann ich kein Delay erzeugen. Der Versatz zwischen Daten und
Clock bleibt unverändert bei 100ps... keine Chance daran zu rütteln und
das Design zu ner vernünftigen Funktion zu bewegen.
Im Modelsim kann ich bis zu einem Abstand von 1ps zoomen, also an der
Auflösung sollte es nicht liegen. Zumal ich nun testweise das Delay auf
2ns gestellt habe. Leider keine Veränderung :(
In der .fdo Datei steht schon folgendes drin:
vsim -t 1ps -lib work tb_TOPFILE_DCM_DELAY
Reicht das aus, oder wie verwende ich den Befehl?
Hab ihn gerade versucht im mehreren Varianten einzugeben, leider
resultiert bisher jeder Versuch in einer Fehlermeldung.
Ich starte das Modelsim direkt aus dem ISE...
DANKE
vsim -t ps -lib work tb_TOPFILE_DCM_DELAY
damit macht er was, hatte ich vorhin schon einmal probiert.
Nur leider verschwinden dann meine Simulationsergebnisse (Kurven) und
ich habe ihm bis jetzt noch nicht beibringen können, wieder erneut zu
starten.
weder "restart" noch "run 100000" bewirken etwas.
Wenn ich erneut "do {tb_TOPFILE_DCM_DELAY.fdo}" eingebe, wie von ISE
ganz am Anfang einer jeden Simulation, wird scheinbar alles wieder
zurückgesetzt und die einstellungen von vsim -t gehen wieder verloren.
Zumindest unterscheidet sich das Simulationsergebniss nicht von dem
davor... sofern die Auflösung der Grund für das nicht wirkende Delay des
DCM ist...
VIELEN DANK!
Naja, die Voreinstellung bei Xilinx ist schon 1ps Auflösung beim Start
der Simulation. Aber um diesem allen aus dem Weg zu gehen, kommst du
eventuell besser, wenn du dir im ModelSim eigene Projekte anlegst dafür.
Das ist viel bequemer. Dann ein .do File, in dem die Befehle für die
Simulation stehen:
vsim ...
add wave *
run 10000 ns
usw.
Also das bedeutet so viel, wie es liegt nicht an der Auflösung, dass die
100ps Delay weiterhin bestehen und ich meinen Ausgangstakt vom DCM nicht
verzögern kann.
Das ist weniger gut. Ich hatte gehofft, dass es nur noch eine
Einstellungssache ist.
Auch wenn ich den DCM stand-alone simuliere und Eingangstakt und
Ausgangstakt vergleiche, sind diese identisch trotz eingestelltem
Delay... ich verstehs nicht :(
Aber ohne diese Verzögerung kann ich zwar schauen, dass mein Design was
auswirft, aber inwieweit sinnvoll das ist, kann ich dann nicht mehr
beurteilen, wenn meine Daten schon falsch eingelesen werden. Somit kann
ich nicht mal die logische Funktion nachweisen und muss mich dann dazu
in der realen Hardware noch mit Timingsachen rumschlagen... eine
schlechte Kombination. Ich hoffe ich finde noch eine Lösung. Ich werde
es mal mit einem komplett neuen Projekt versuchen, in dem ich einfach
nur den DCM simuliere, ohne irgendetwas drum herum.
MfG
Sind denn die Simulationsmodelle aktuell? Da gibts ja immer mal neue von
Xilinx. Es gab gerade beim DCM mal Probleme, da ging z.B. das LOCK nie
auf 1.
Edit: Ich habs eben mal getestet. Du hast einen Spartan 3e, stimmts? Da
scheint die Simulations-Lib einen Bug zu haben, da gehts tatsächlich
nicht (wohl aber in Hardware). Ich hatte das bisher am Virtex 4 benutzt,
und da klappts auch in der Simulation bestens. Ich weiß nicht, ob die
aktuellen Libs von Modelsim XE 6.4b zur ISE 11.3 das beheben, kann sein.
Ich arbeite noch mit 6.3c
Ich habe einen Spartan 3A DSP XC3SD1800A-4FGG676C... bzw. das Starterkit
dazu.
Ich teste den einfachen DCM einfach mal in der Hardware und versuche es
zu messen... ich hoffe, dass ich hier in einem anderen Labor ein
passendes Oszi auftreiben kann.
Also ich kann es leider nicht genau messen.
Das Oszi was ich gefunden habe kann zwar angeblich 500MHz bei 5GT/s,
aber naja... wenn ich die Messspitzen anders anfasse, sehen die Kurven
anders aus. MIt 160MHz ist eben nicht zu scherzen, wenn man dann noch
1-3ns auflösen will.
Könnte eine ChipScope Lizenz die ganze Sache bereinigen bzw. Licht ins
Dunkel bringen, was der DCM in der Hardware macht?
Die kostenlose Version von CS wird bei mir leider nicht fehlerfrei
installiert und somit habe ich auch nicht die Auswahl, unter New Source
einen CS Core zu implementieren.
ChipScope kann nur taktsynchron sampeln. Das bringt dir nix weiter.
Klappt denn der Receiver in der Hardware auch nicht? Eventuell kommst du
mit Constraints weiter, also mit "OFFSET IN BEFORE" dem ISE sagen, dass
die Daten da x ns vor dem Takt anliegen müssen.
Ok, also ist ChipScope der falsche Weg.
Der Reciever in der Hardware funktioniert. Also der DCM spuckt am
Ausgang einen Takt aus, nur leider kann ich nicht exakt nachmessen, ob
nun wirklich das parametrierte Delay eingehalten wird, da mir die
Lokalisierung der steigenden und fallenden Flanken schwer fällt. Die
Signale sind schon sehr verwaschen und alles andere als ein sauberes
Rechteck (ist ja auch nicht zu erwarten). Ich habe die LVDS Signale eher
stiefmütterlich an das Starterkit geführt, ohne Terminierung und alles.
Auf meiner eigenen Hardware habe ich es ordentlich gemacht. Impedanzen
von 100Ohm eingehalten und auch dementsprechend terminiert. Aber die ist
eben noch nicht fertig, so muss ich vorerst auf das Starterkit
zurückgreifen.
>Eventuell kommst du>mit Constraints weiter, also mit "OFFSET IN BEFORE" dem ISE sagen, dass>die Daten da x ns vor dem Takt anliegen müssen.
Das bedeutet, dass ich den Datenkanälen ein constraint zuweise, dass
diese Daten meinetwegen 1ns vor der Taktflanke anliegen müssen? Also
wird dann bei der Implementierung dem Clock automatisch ein Delay
verpasst?
Die Variante schaue ich mir mal an.
Nur könnte ich da dann nicht Probleme mit meinem IDDR2 bekommen?
Die Daten kommen ja auf der fallenden und auf der steigenden Flanke des
Taktes. Oder wird einfach eine komplette Phasenverschiebung des Taktes
zu den Daten implementiert?
Constraints werden doch aber erst in der realen Hardware aktiv, bei der
Simulation habe ich dadurch keinen Vorteil, richtig?
Vielen Dank!
Ich hab gerade das appnote wp237 gefunden. Ich denke da steht alles
drin, was es mit dem OFFSET IN BEFORE zu tun hat und es ist auch ein
Bsp. für DDR gegeben.
Ich werde mich mal mit diesen Befehlen versuchen:
1
NET "CLKIN_IN_N" TNM_NET = CLKIN_IN_N;
2
TIMESPEC TS_CLKIN_IN_N = PERIOD "CLKIN_IN_N" 6.25 ns HIGH 50%;
3
NET "CLKIN_IN_P" TNM_NET = CLKIN_IN_P;
4
TIMESPEC TS_CLKIN_IN_P = PERIOD "CLKIN_IN_P" 6.25 ns HIGH 50%;
5
6
OFFSET = IN 1ns BEFORE CLKIN_IN_P;
7
OFFSET = IN -1ns BEFORE CLKIN_IN_P TIMEGRP falling_ffs_grp;
Bei differentiellen Signalen sollte es ja ausreichen, auf den positiven
Zweig Bezug zu nehmen, oder?
MfG