Hallo,
ich habe zwei interessante Fragen zu Quartus 2 (11.1 SP2) und der
Cyclone 4-Family:
Frage Nr. 1:
Gibt es eine Möglichkeit per Constrait ein Signal um mehrere ns zu
verzögern. Ganz konkret:
1
libraryieee;
2
useieee.std_logic_1164.all;
3
4
entityTestis
5
6
port(
7
iData:instd_logic;
8
oData0ns:outstd_logic;
9
oData4ns:outstd_logic;
10
oData8ns:outstd_logic;
11
oData12ns:outstd_logic);
12
13
endTest;
14
15
architectureRtlofTestis
16
17
begin-- Rtl
18
19
oData0ns<=iData;
20
oData4ns<=iData;
21
oData8ns<=iData;
22
oData12ns<=iData;
23
24
endRtl;
Das Eingangssignal wird auf 4 FPGA-Ausgangs-Pins 1:1 geschrieben. Jedoch
möchte ich einen Delay von 4, 8 bzw. 12 ns zu oData0ns erreichen. Ist
das überhaupt mit Quartus 2 Assignments oder SDC Constraints möglich?
Frage Nr. 2:
Ich habe ein sehr großes FPGA-Design, bei dem viele Register und alle
M9K-Blöcke gebraucht werden. Dementsprechend ist der Fitter auch
eingeschränkt und kann die Logikblöcke nicht mehr ganz so frei wählen,
da ja die Interconnects zu den M9K-Blöcken passen müssen. In dem Design
habe ich 4 externe ADCs, die von 4 separaten, synchronen
Trigger-Leitungen (LVDS @ 250 Mhz) gesteuert werden. Siehe folgenden
Code:
1
oTrigger1<=TriggerSignal;
2
oTrigger2<=TriggerSignal;
3
oTrigger3<=TriggerSignal;
4
oTrigger4<=TriggerSignal;
Die 4 Ausgangssignale werden also von dem gleichen, intern erzeugten
Signal getrieben. Die Output-Pins liegen aber nicht nebeneinandern,
sondern sind über den Chip verteilt. Nach dem Fitter und TimeQuest
stelle ich nun fest, dass sich die Clock-To-Output-Times für die 4
oTrigger-Signale von 4 bis 8 ns unterscheiden (sowohl rise als auch
fall). Da die externen ADCs von einer 250MHz-Clock-Domain angesteuert
werden, wirken sich die Laufzeitunterschiede negativ aus (Periodendauer
4ns). Gibt es eine Möglichkeit mit Quartus2 ein Constraint zu setzen,
sodass alle Outputs tatsächlich zur selben Zeit (Toleranz 0,5ns)
erfolgen?
Vielen Dank,
Johnsn
Hi,
1. Synchron lösen. Ein kurzes Schieberegister mit 250MHz Takt müsste der
Cy4 schaffen, das kannst du dann mit dem entsprechenden Delay abgreifen.
2. gleich mal vorneweg, ich bin was Timinganalyse angeht eher einäugig.
Also bitte mit Vorbehalt und gesundem Menschenverstand weiterlesen :-)
Ich würde es so versuchen: Alles über Timequest (SDC) mit den
entsprechenden Optionen in Quartus (timing-driven synthesis glaube ich)
- Virtuellen 250MHz Clock erzeugen
create_clock -name "VCLK250" -period 4.000ns
- Clock von den anderen lösen (Wenn ich dich richtig verstanden habe,
ist die absolute Zeit nicht wichtig, nur der zeitunterschied der
Signale)
set_clock_groups -asynchronous -group [get_clocks {VCLK100}]
- Output delays für die Pins angeben
#set_output_delay -max -clock { VCLK250 } x.x [get_ports {oTrigger1
oTrigger...}]
#set_output_delay -min -clock { VCLK250 } y.y [get_ports {oTrigger1
oTrigger...}]
Hi Marius,
danke für den Tipp. Laut User-Guide der Megafunction sieht es für mich
so aus, als ob man nur einen Input-Delay angeben kann. Dies wird durch
den SDC-Befehl "set_input_delay" erreicht. Allerdings handelt es sich
bei der 1. Frage nicht um LVDS Signale sondern 3,3V-TTL.
ad Frage 2: auch hier werden keine ALTLVDS Megafunctions eingesetzt,
sondern die Erzeugung des Differenzsignals mittel Pin-Assignment.
Aber wenn du den SERDES mit dem 4-fachen Grundtakt betreibst, dann hast
du was du wollst. Geht allerdings, wenn dein Eingangssignal von extern
kommt.
Gruß
Marius
Delays in den IOs der Altera-FPGAs lassen sich auf mehrere
Arten bestimmen:
1. wie schon beschrieben per TimeQuest/SDC-Constraints
2. Im QSF-File, z.B.
set_instance_assignment -name PAD_TO_INPUT_REGISTER_DELAY 3 -to di
set_instance_assignment -name CLOCK_TO_OUTPUT_DELAY 1 -to do
3. Im VHDL-File per Attribute, z.B.
attribute altera_attribute of di : signal is
"-name PAD_TO_INPUT_REGISTER_DELAY 3";
attribute altera_attribute of do : signal is
"-name CLOCK_TO_OUTPUT_DELAY 1";
(entspricht den QSF-Einträgen aus 2.)
4. Im Assignment-Editor die Constraints aus 2. bzw. 3. eingeben
(2. bis 4. sind wesentlich genauer als 1.)
Marius Wensing schrieb:> Aber wenn du den SERDES mit dem 4-fachen Grundtakt betreibst, dann hast> du was du wollst. Geht allerdings, wenn dein Eingangssignal von extern> kommt.>> Gruß> Marius
Die Verzögerungen von 0,4,8,12ns waren nur sinngemäß gewählt. Könnten
genausogut auch 0,3,7,12 ns sein, deshalb lässt es sich nicht so schön
mit Schieberegistern wählen.
Die Vorschläge von 1234 und Sigi hab ich versucht, haben aber nicht
wirklich eine Auswirkung gezeigt. Wenn ich einen virtual clock einführe
und die set_output_delay option verwende, dann verschwinden die
betroffenen Signale sogar aus dem "Clock to Output Times" Report von
TimeQuest. Mit Oszi gemessen, hat die Option auch keine Auswirkung
gezeigt.
Der QSF-Parameter CLOCK_TO_OUTPUT_DELAY lässt sich nicht anwenden:
Warning (176437): Can't set option TCO Chain to 1 -- option is not used
in pin oTrigger8ns -- changed to 0. Ich schätze mal, dass diese Funktion
nur für gewisse Pin möglich ist.
Bei meinen Beispielen zu 2,3,4 habe ich Register-Constraints
vergessen, also z.B.
attribute altera_attribute : string;
-- register = ON/OFF
attribute altera_attribute of di_reg : signal is
"-name FAST_INPUT_REGISTER ON";
attribute altera_attribute of do_reg : signal is
"-name FAST_OUTPUT_REGISTER ON";
DI_REG und DO_REG müssen in diesem Fall Register-Ausgänge
sein (ohne Register lassen sich für Ausgänge die Delay-Stufen
nicht verwenden!).
Es muss zu diesem Ansatz noch gesagt werden, dass sich maximal
kleinere NS-Bereiche an Verzögerungen erreichen lassen (beim
Cyclone-1: 1 Delay entspr. 0.7ns, max 3 Delays möglich).
Wenn du also mehrere NS (2..12ns) erreichen möchtest, dann musst
du auf Schieberegister für gröbere Delays ausweichen und dann
über die Constraints verfeinern. (und: 0ns als Delay ist nicht
möglich)
Zu deinem 2. Problem: Auch das lässt sich über Constraints lösen.
Einfach die M9K-Blöcke bestimmen und für diese im Assignment-Editor
so setzen, dass sie möglichst dicht an den entspr. Pins liegen.
Ich habe kein Beispiel für M9k-Blöcke, aber als Orientierung hilft
vieleicht ein Constraint für eine LE-Zelle:
set_location_assignment LC_X1_Y13_N0 -to "\\le_gen:0:le_inst"
(wurde vom Assignment-Editor ins QSF-File geschrieben!)
Hi Sigi,
danke für deine Antwort. Ich hab's eh vermutet, dass eine Verzögerung
von mehreren ns per Constraint nicht zu lösen ist. Aber ich finde es ist
ein gutes Beispiel, um sich mit SDC und Timing-Optimierung generell
auseinanderzusetzen.
Beim 2. Problem, habe ich mir so geholfen, dass ich im SDC-File mit
set_output_delay (und virtual clock) einen min- und max-Wert vergeben
habe. Zusätzlich arbeite ich mit einer LogicLock-Region und erzwinge die
Platzierung der betroffenen LEs ca in der Mitte der wo die Output-Pins
sind. Da das interne Trigger-Signal von einem Register kommt,
funktioniert das ganz gut und ich kann die Clock-To-Output-Times in den
Bereich von 4,3 bis 5,1 ns trimmen. Bei 250Mhz ist das zwar auch noch
nicht ideal, aber es funktioniert brauchbar.