Forum: FPGA, VHDL & Co. Welche TimeQuest Constraints brauche ich noch?


von Stefan (Gast)


Lesenswert?

Hallo,

Ich habe ein Design in Quartus gemacht (streng synchron aufgebaut, 
~10000 LEs), welches leider manchmal nach dem Compilen korrekt 
funktioniert und manchmal nicht, was mich auf Timingprobleme schliessen 
lässt. Laut Timing analyzer müsste aber alles OK sein. Ich habe auch 
alle Clocks mit 'create_clock' und 'create_generated_clock' definiert. 
Weiss jemand welche zusätzlichen Constraints noch hilfreich sein 
könnten?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> streng synchron aufgebaut
Sieh mal deine Resets an.
Sind die asynchron?
Ist da evtl. sogar Kombinatorik drin?

von Stefan (Gast)


Lesenswert?

Meine state machines, FIFOs etc. haben zwar asynchrone resets, aber das 
Signal wird vorher gelatcht, also sollten glitches ausgeschlossen sein. 
Tja...

von Ras F. (rasfunk)


Lesenswert?

Ein wenig mehr Infos wären schon hilfreich, z.B. welcher Art der Fehler 
ist, ob er bei einem einzigen Build mal auftritt und mal nicht, oder ob 
es erst nach einer neuen Synthese wieder geht.

Zu den Constraints muss noch gesagt werden, dass neben den Clocks auch 
IOs constrained werden sollten - bei SOPC-Komponenten wie PCI oder 
DDR-Speicher wird das halbwegs automatisch per Skript gemacht.

von Mathi (Gast)


Lesenswert?

> Ich habe ein Design in Quartus gemacht (streng synchron aufgebaut,
> ...alle Clocks mit 'create_clock' und 'create_generated_clock' definiert.

Wie passt das zusammen?
Hast Du nun mehrere Clocks, dann muss das Design als asynchron behandelt 
werden, oder nicht?

von Stefan (Gast)


Lesenswert?

Also ob es funktioniert scheint reine glückssache zu sein und hängt von 
minimalen Änderungen ab (z.B. hinzufügen eines monitoring Pins). 
Ausschlag gebend scheint mir zu sein, dass das Zeug neu gefittet wird...
Was die IOs angeht, kann ich das mit dem Oszilloskop verifizieren.

Ein Beispiel eines sporadisch auftretenden Problems:
Ich weiss z.B. dass meien Ethernet-Schnittstelle funktioniert, da 1 mal 
pro Sekunde ein Watchdog-Packet übermittelt wird und das Paket korrekt 
ankommt. Wenn ich nun per Befehl eine Funktion im Design aktiviere, die 
Daten eines ADCs zum PC schicken soll kriege ich zum Beispiel nur Nullen 
en masse und das Paket wird falsch "verpackt", d.h. die Datenübertragung 
ist fehlerhaft, weil ein datenbyte als Paketgrösse interpretiert wird. 
Das könnte z.B. heissen dass die Paketgrösse am anfang des Pakets falsch 
geschrieben wird, oder dass das Paket zu lang oder zu kurz ist. 
Irgendwie ist das Problem logisch nicht erklärbar, oder ich bin zu blöd.
Hier mal ein Ausschnitt aus dem Code, der ein Paket macht und vom einen 
FIFO in den anderen schaufelt. Man muss dazu sagen, dass das Ziel-FIFO 
einen 16 Bit Eingang hat und einen 8 Bit Ausgang:
1
--  Get scope data
2
      
3
    when s_get_scope_data0 =>
4
      if scope_fifo_usedw[] >= 16 and w5100_tx_fifo_free_space[] >= 19 then 
5
        state = s_get_scope_data1;
6
      else
7
        state = s_get_meas_data0;
8
      end if;
9
      
10
    when s_get_scope_data1 =>
11
      -- Write packet size
12
      w5100_tx_fifo_din[] = 36;
13
      w5100_tx_fifo_write = vcc;
14
      
15
      state = s_get_scope_data2;
16
        
17
    when s_get_scope_data2 =>
18
      -- Write packet type
19
      w5100_tx_fifo_din[] = DATA_SCOPE;
20
      w5100_tx_fifo_write = vcc;
21
      
22
      state = s_get_scope_data3;
23
    
24
    when s_get_scope_data3 =>
25
      -- Write packet flags
26
      if scope_packet_counter[].q == 0 then
27
        w5100_tx_fifo_din[] = PACKET_FLAG_IS_FIRST;
28
        scope_packet_counter[].d = scope_packet_counter[].q + 1;
29
      elsif scope_packet_counter[].q == 15 then
30
        w5100_tx_fifo_din[] = PACKET_FLAG_IS_LAST;
31
        scope_packet_counter[].d = 0;
32
      else
33
        w5100_tx_fifo_din[] = 0;
34
        scope_packet_counter[].d = scope_packet_counter[].q + 1;
35
      end if;
36
      
37
      scope_packet_counter[].ena = vcc;
38
      w5100_tx_fifo_write = vcc;
39
      
40
      reg_a[].d = 16;
41
      reg_a[].ena = vcc;
42
      
43
      state = s_get_scope_data4;
44
      
45
    when s_get_scope_data4 =>
46
      if reg_a[].q != 0 then
47
        -- Write curve point
48
        scope_fifo_read = vcc;
49
        w5100_tx_fifo_din[] = scope_fifo_dout[];
50
        w5100_tx_fifo_write = vcc;
51
        
52
        reg_a[].d = reg_a[].q - 1;
53
        reg_a[].ena = vcc;
54
        
55
        state = s_get_scope_data4;
56
      else
57
        state = s_get_scope_data5;
58
      end if;
59
    
60
    when s_get_scope_data5 =>
61
      state = s_get_scope_data6;
62
    
63
    when s_get_scope_data6 =>
64
      state = s_get_scope_data7;
65
    
66
    when s_get_scope_data7 =>
67
      state = s_get_scope_data0;

von Stefan (Gast)


Lesenswert?

>> Ich habe ein Design in Quartus gemacht (streng synchron aufgebaut,
>> ...alle Clocks mit 'create_clock' und 'create_generated_clock' definiert.

>Wie passt das zusammen?
>Hast Du nun mehrere Clocks, dann muss das Design als asynchron behandelt
>werden, oder nicht?

Die anderen Clocks werden per Divider aus dem master clock generiert.

von Mathi (Gast)


Lesenswert?

Also ist das Design asynchron... Hast Du die Taktdomänen-Übergänge 
abgesichert?

von Stefan (Gast)


Lesenswert?

>Also ist das Design asynchron... Hast Du die Taktdomänen-Übergänge
>abgesichert?

Wo nötig setze ich DCFIFOs ein... aber das Design ist trotzdem synchron.

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.