Ich verwende einen 2:16 Multiplexer mit 4 Xilinx FPGAs um digitale Daten
aus zwei Quellen auf 16 Verbraucher zu lenken. Die Busbreite sind 16 Bit
und die Datenrate 100 MHz SDR. (ursprünglich 100 MHz DDR auf 8 Bit).
Theoretisch kann jeder Verbraucher jede der beiden Quellen nutzen. Die
Auswahl geschieht über eine Logik, die die Quellen analysiert und die
jeweils richtige weiterschaltet. So sehen die ersten 1-4 Verbraucher
z.B. die Quelle 1 und die anderen die 2 oder auch umgekehrt.
Die Takte der Quellen müssen aber erhalten bleiben und mit auf den
Ausgang, damit die exakte Frequenz mitgeliefert wird. Retiming geht
nicht, weil mit dem Originaltakt ein ADC getrieben wird.
Dazu synchronisiere ich jede Quelle mit ihrem Takt ein, (PLL ist erlaubt
und vorteilhaft, wegen der clock skew Thematik) und geben sie an einen
MUX weiter. Jeder der jeweils 4 MUX bekommt ein Steuersignal, welche
Daten er weitergeben soll. Parallel dazu wird ein CLock-MUX benutzt, der
genau so funktioniert.
Die Steuerlogik läuft mit der System Clock des FPGAs und synched die
Quellen ein, um sie stabil analysieren zu können.
Die Schaltung funktioniert eigentlich, allerdings bekomme ich neuerdings
physikalische timing Probleme. Diese liegen ausschließlich im
Vorwärtspfad. Das Analysieren der Daten klappt und das statische
Umschalten funktioniert und ist stabil. (die dabei entstehenden
Aussetzer sind unbedeutend).
Das Timing, soweit spezifiziert, wird 100% getroffen.
Ich gehe davon aus, dass das Design noch nicht komplett constrained ist.
Ich habe eine Weile damit herumexperimentiert und gefunden, dass sich
XST wohl teilweise mit den Signalen zu vertun scheint. Daher habe ich
jedes einzelne Signal einzeln benannt. Im Umfeld der PLL war das ohnehin
nötig, weil 14.7 aus irgendeinem Grund keine vernüftige PLL-Instanz
hinbekam.
Bislang mache ich dies:
1) Periode auf den Eingang ganz vorne, also so, wie das Signal am PAD
heisst und auch im Editor angeboten wird?
NET "CLK_X_IN" TNM_NET = "CLK_X_IN";
TIMESPEC TS_CLK_X_IN = PERIOD "CLK_X_IN" 10 ns HIGH 50 % INPUT_JITTER 50
ps;
2) dasselbe für den Y-Pfad:
NET "CLK_Y_IN" TNM_NET = "CLK_Y_IN";
TIMESPEC TS_CLK_Y_IN = PERIOD "CLK_Y_IN" 10 ns HIGH 50 % INPUT_JITTER 50
ps;
3) und die Systemdomain:
4) Dazu Ignores zwischen den Domainen, damit die Synthese entspannt wird
und er nicht probiert, da was zu timen:
TIMESPEC "TS_IGNORE_X_TO_Y" = FROM CLK_X_IN TO CLK_Y_IN TIG;
TIMESPEC "TS_IGNORE_Y_TO_X" = FROM CLK_Y_IN TO CLK_X_IN TIG;
TIMESPEC "TS_IGNORE_X_TO_S" = FROM CLK_X_IN TO SYS_CLK_IN TIG;
TIMESPEC "TS_IGNORE_S_TO_X" = FROM SYS_CLK_IN TO CLK_X_IN TIG;
TIMESPEC "TS_IGNORE_S_TO_Y" = FROM SYS_CLK_IN TO CLK_Y_IN TIG;
TIMESPEC "TS_IGNORE_Y_TO_S" = FROM CLK_Y_IN TO SYS_CLK_IN TIG;
Tatbestand:
Etliche der TIGs werden ignoriert, was auch plausibel ist, weil es je
nach Designausführung solche Pfade nicht gibt. Was mich aber irriert ist
das Folgende:
WARNING:ConstraintSystem - TNM : CLK_Y_IN was distributed to a DCM but
new
TNM constraints were not derived. The requirement for derived TNM
constraints
is that the distributed TNM is referenced by no more than a single
PERIOD
constraint. Non-PERIOD referencers are also not allowed. This TNM is
used in
the following user groups or specifications:
<TIMESPEC TS_CLK_Y_IN = PERIOD "CLK_Y_IN" 5 ns HIGH 50 %
INPUT_JITTER 50 ps;> [C:/Matrix Control
Unit/FPGA/xst/matcon.ucf(168)]
<TIMESPEC "TS_IGNORE_S_TO_Y" = FROM SYS_CLK_IN TO CLK_Y_IN TIG;>
[C:/Matrix Control Unit/FPGA/xst/matcon.ucf(172)]
<TIMESPEC "TS_IGNORE_Y_TO_S" = FROM CLK_Y_IN TO SYS_CLK_IN TIG;>
Heisst das, dass das Constrained weggefallen ist wegen Doppelrefrenz?
Wie liesse sich das prüfen oder umgehen?
Weitere Frage, was brauche ich noch?
Global Offset constraints?
Probiert habe ich auch das Zusammenfassen der Eingänge und Ausgänge zu
Gruppen und ein Constrained zu setzen:
Eingangsgruppe z.B.
INST "MAT_X_D<0>" TNM = MATRIX_IN_X;
INST "MAT_X_D<1>" TNM = MATRIX_IN_X;
...
INST "MAT_X_D<15>" TNM = MATRIX_IN_X;
TIMEGRP "MATRIX_IN_X" OFFSET = IN 0 ns VALID 5 ns BEFORE "CLK_X_IN"
RISING;
TIMEGRP "MATRIX_IN_Y" OFFSET = IN 0 ns VALID 5 ns BEFORE "CLK_Y_IN"
RISING;
Was ich sehe ist, dass im Constraint Editor diese Eingänge noch als
unconstrained gelten, wohl aber hinten in der Gruppe gezeigt werden.
Wieder ein Xilinx Problem - gfs mit Grossschrift und Anführungszeichen?
Die disbezüglichen Ausgangsconstraineds scheinen nicht zu funktionieren
- er findet alle Signale als nicht im Timing zu treffen.
Soweit mir bekannt, verträgt die Xilinx Sysnthese, also XST kein
Doppel-Constraint und blockiert. Habe es auf die Schnelle mal
ausprobiert: Wenn Du die zusätzliche Anweisung mit den multiplen TIG
weglässt, nimmt er auch die Periodensettings und die daraus folgenden
Taktreserven werden ermittelt ("derived).
Schau mal in Deinen Systhesis Report und übermittle das mal.
Mal ein anderer Ansatz:
Ich sehe hier die Timing Probleme durch das Routing und den Clock-Mux.
Wie wäre es, wenn du beide Eingangsdatenströme in je ein kleines
Asynchrones Fifo schreibst. Der gemuxte Clock ließt dann wieder daraus.
Damit hast du den Vorteil, dass die Latenz/Phasenversatz vor dem
Clock-Mux keine Rolle mehr für das Timing danach spielt.
In diesem Fall kannst du alle zwei Pfade asynchron zueinander auf die
maximale Frequenz stellen bzw. das Contraint am Ausgang vom Clock-Mux
neu setzen. Das Timing sollte damit entspannt sein.
Das wäre dann nötig, wenn es grundsätzliche Timingprobleme gäbe, was
wohl nicht der Fall ist und ich auch eher nicht glaube, weil die
ClockMUX nicht langsamer sind, als die BUFGs selber, die allenthalben
verwendet werden, um die Logik zu treiben und die langen Routingpfade
viel mehr Delay produzieren. Ich meine, Xilinx gibt für die Buffer
irgendwas um die x00ps an.
Grundsätzlich ist das aber ein richtiger Einwand.
FPGA Pongo schrieb im Beitrag #4116139:
> weil die> ClockMUX nicht langsamer sind, als die BUFGs selber, die allenthalben> verwendet werden
BUFG, BUFGCE und BUFGMUX ist alles die selbe Hardware, nur mit
unterschiedlicher Beschaltung.
Duke
Ich komme zurück auf dieses design. Das FiFo hatte ich eingebaut - aber
er hängt sich noch immer an den constraints auf.
Es gibt 2 Dinge:
1) Wenn ich ein Timing ignore von der linken Seite des FiFos zur rechten
mache, findet er den rechten Takt, also den BUFGMUX-Ausgang nicht.
2) Die Umschaltung des BUFGMUX selber kommt aus eine dritten Domain, die
mit den Micocontroller läuft. Dessen Takt wird als Systemtakt des FPGa
verwendet. Ich habe daher ein weiteres TIG zwischen diesem Tatk und den
eigentlichen Datentakten liegen. Dies führt dann zu folgendem Fehler:
1
ConstraintSystem - TNM : OSC_100 was distributed to a DCM but new TNM constraints were not derived. The requirement for derived TNM constraints is that the distributed TNM is referenced by no more than a single PERIOD constraint. Non-PERIOD referencers are also not allowed. This TNM is used in the following user groups or specifications:
2
<TIMESPEC TS_OSC_100 = PERIOD "OSC_100" 10.000 ns HIGH 50 %;>
3
4
<TIMESPEC "TS_MUC_TO_DATA" = FROM OSC_100 TO DATA_1_CL TIG;>
5
<TIMESPEC "TS_DATA_TO_MUC" = FROM DATA_1_CL TO OSC_100 TIG;>
Offenbar stört er sich an der doppelten Verwendung des Mastertaktnamens.
Wie muss man das constaint formulieren, um ein TIG zu setzen, dass ihn
aber nicht bei den Berechungen der entstehenden Takte im DCM stört?
Ist das TIG überhaupt so richtig?
Habe schon den kompletten constraint guide durchgewühlt, komme aber zu
keinem schlüssigen Ergebnis.