Forum: FPGA, VHDL & Co. Signal Delay Altera Cyclone 4


von Johannes T. (johnsn)


Lesenswert?

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
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity Test is
5
  
6
  port (
7
    iData     : in  std_logic;
8
    oData0ns  : out std_logic;
9
    oData4ns  : out std_logic;
10
    oData8ns  : out std_logic;
11
    oData12ns : out std_logic);
12
13
end Test;
14
15
architecture Rtl of Test is
16
17
begin  -- Rtl
18
19
  oData0ns  <= iData;
20
  oData4ns  <= iData;
21
  oData8ns  <= iData;
22
  oData12ns <= iData;
23
24
end Rtl;

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

von Marius W. (mw1987)


Lesenswert?

Zu Frage 1:
Schau dir mal im MegaWizard die ALTLVDS_TX Megafunction an. Da ist ein 
SERDES drin.

Gruß
Marius

von 1234 (Gast)


Lesenswert?

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...}]

von Johannes T. (johnsn)


Lesenswert?

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.

von Marius W. (mw1987)


Lesenswert?

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

von Sigi (Gast)


Lesenswert?

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.)

von Johannes T. (johnsn)


Lesenswert?

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.

von Sigi (Gast)


Lesenswert?

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!)

von Johannes T. (johnsn)


Lesenswert?

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.

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.