Forum: FPGA, VHDL & Co. IO constraints für asynchrone Inputs in Lattice Diamond


von Diode E. (c2h5oh)


Lesenswert?

Ich arbeite mit verschiedenen Chips von Lattice mit Lattice Diamond und 
hätte gerne etwas Orientierung, welche Constraints für asynchrone Inputs 
notwendig sind. Mir geht es weniger um einen spezifischen Fall als eher 
um ein "how to it right".
Leider ist die Dokumentation von Lattice spärlich bis nicht vorhanden 
bzw. das was ich gefunden habe enthält nicht wirklich praktische 
Beispiele.

Eine gute Quelle diesbezüglich, die auch auf Lattice spezifische Details 
eingeht, wäre wirklich hilfreich.

Für asynchrone Eingänge verwende ich typischerweise einen zweistufigen 
Synchronizer (asynchrones Eingangssignal: input, synchronisiertes 
Ausgangssignal: output(1)):
1
process(clk, rst)
2
begin
3
if rst='0' then
4
output <= (others => '0');
5
elsif rising_edge(clk) then
6
output <= output(0) & input;
7
end if;
8
end process;

Die Eingangssignale sind sehr unterschiedlich und reichen von 
mechanischen Inputs (weniger als 1 Flanke pro Sekunde) zu read/write 
Handshake Signalen eines parallelen Memory Bus, die nur einige Sample 
Clock Cycles lang sind.

Die Fragen die ich mir Stelle sind:
- Muss ich hier keep Attribute im Code verwenden damit die Toolchain die 
Flipflops nicht wegoptimiert? Falls ja, wie würden diese aussehen?
- Wie verhindere ich, dass bei hohem Fanout die Flipflops dupliziert 
werden, insbesondere das erste Flipflop output(0)? Gibt es dafür 
überhaupt eine Möglichkeit?
- Welche Timing Constraints benötige ich bzw. benötige ich überhaupt 
welche? Muss ich den Einfang als false path definieren?
Was passiert mit Eingängen, die im Constraint File weder als false path 
definiert sind, noch setup/hold constraints haben? Werden die einfach 
als asynchron angenommen und in der STA ignoriert?
- Habe ich irgendwelche Constraints übersehen die notwendig wären?

von Jens W. (jensw)


Lesenswert?

Hi,

warum willst du an das asynchrone Signal ein Constraint machen? Das 
Signal bleibt doch asynchron, heißt es hat keinen Bezug zum Clock. Das 
kannst du dir sparen.

Deinen Prozess für das Einsynchronisieren würde ich anders machen:
1
process()
2
begin 
3
  wait until rising_edge(clk);
4
  if rst='0' then
5
    output <= (others => '0');
6
  else
7
    output <= output(0) & input;
8
  end if;
9
end process;

Bei deiner Version bleibt der Reset asynchron. Das macht bei der 
Synthese Probleme und bringt dir die tollsten Effekte, die du 
stundenlang suchst.

Grüße, Jene

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Angehängte Dateien:

Lesenswert?

Ist halt die Frage, was du mit constraints erreichen kannst, in der 
Regel halt nur das Placement der FF und das ist hier eher egal.
Es gibt je nach Hersteller spezielle Constraints für IO's, wie 
IO-Standard oder Pull/UP/Down da sollte man mal reinschauen, ob man was 
braucht.

Und mancher timing analyse muss man extra sagen, das dieser Eingangspfad 
asynchron ist - mit einem "false_path" constraint.

Für synchronizer wird manchmal empfohlen, das timing constraint zwischen 
diesen (bei dir (0) und (1) eng zu machen) das reduziert nochmals die 
Wahrscheinlichkeit des reinwanderns eines Metastabilen Zustandes. Die 
ist aber schon bei einem einfachen Snchronizer sehr gering.

Wichtiger ist die funktionale Beschreibung, also der VHDL/Verilog-Code, 
also nicht das nachgeschaltete debouncing vergessen.

https://nandland.com/project-4-debounce-a-switch/

Was den reset betrifft, hier vielleicht komplett weglassen ?! Oder 
weningtens für den aller ersten (bei dir output( 0))?!. Das ist ja eine 
Input-line, da kann und soll sowieso alles mögliche reinkommen. Und 
schau dir mal die Schaltung des IO-Pads an (Anhang) gibt es da eine 
reste-line?! Ohne Reset kann das synthesetool für den synchronizer auch 
Shiftregister verwenden. Wichtig ist, das die nachfolgende Schaltung 
nicht ausser Tritt kommt.



* https://www.fdi.ucm.es/profesor/mendias/DAS-ise-spartan/docs/wp272.pdf
* https://docs.amd.com/v/u/en-US/wp275



Und es kann je nach Herstelelr/fpga-typ einen Unterschied aus machen, ob 
man asynchronen oder synchronen Reset verwendet.

IO-PAD -FF ist auch so ein  Thema, möglicherweise auch bei Lattice. Man 
sollte versuchen, das physisch erste FF zu benutzen, also das im Pad, Da 
gibt es manchmal constraints um das zu erzwingen, da muss man mal zur 
Kontrolle im Routing/Report nachschauen.

: Bearbeitet durch User
von Rick D. (rickdangerus)


Angehängte Dateien:

Lesenswert?

Diode E. schrieb:
> - Muss ich hier keep Attribute im Code verwenden damit die Toolchain die
> Flipflops nicht wegoptimiert?
Nein.

> - Wie verhindere ich, dass bei hohem Fanout die Flipflops dupliziert
> werden, insbesondere das erste Flipflop output(0)?
Man kann schauen ob das Signal auf ein 'global net' geführt wird. Das 
steht im Synthesereport unter 'Global Clocks', auch wenn es kein 
Taktsignal ist.
Oder man macht die FF-Kette bewußt länger und läßt 
Registervervielfachung zu (Remove Duplicate Registers = FALSE).

> - Welche Timing Constraints benötige ich bzw. benötige ich überhaupt
> welche?
Solange das externe Signal keinen Bezug zum Takt hat, braucht es kein 
Constraint:
https://www.latticesemi.com/en/Blog/2021/06/07/18/52/ImportanceofTimingConstraints


> Eine gute Quelle diesbezüglich, die auch auf Lattice spezifische Details
> eingeht, wäre wirklich hilfreich.
Das angehängt Dokument hatte ich mal aus dem Netz gefischt. Vielleicht 
hilft es Dir ja.

von Diode E. (c2h5oh)


Lesenswert?

Danke für die Antworten. Um die Reset Problematik werde ich mich separat 
kümmern, vieles davon habe ich zumindest schon mal gehört.

Rick D. schrieb:
> Diode E. schrieb:
>> Muss ich hier keep Attribute im Code verwenden damit die Toolchain die
>> Flipflops nicht wegoptimiert?
>
> Nein.

Ich glaube dir das, aber findet man diese Information irgendwo? Das 
Dokument von Lattice kenne ich und habe ich durch, den Link auf die 
Lattice Page auch. Da steht in meinen Augen nichts explizit zu 
asynchronen Eingängen drin, oder übersehe ich das? Die grundlegenden 
Befehle für synchrone Inputs kenne ich, es scheitert dann oft an den 
Details (vor allem: wo finde ich die Namen der benötigten Netze auf die 
ich Constraints anwenden soll?).

von Rick D. (rickdangerus)


Lesenswert?

Ich verwende solche 'Spezial'-Constraints verhältnismäßig sparsam.
Wichtig ist der Takt und logischerweise die Pinzuordnung.
Außerdem will Lattice immer wissen mit welcher Spannung ich die IOs 
betreibe.
Ab- und zu kommt noch DRIVE/PULLMODE/SLEWRATE hinzu.

Ich kann mich nicht erinnern, daß mir der Synthesizer schon mal Logik 
wegoptimiert hat, die gebraucht wurde.

Diode E. schrieb:
> Da steht in meinen Augen nichts explizit zu
> asynchronen Eingängen drin, oder übersehe ich das?
Richtig. Für asynchrone Signale gibt es einfach keine Constraints, nur 
für synchrone.

> (vor allem: wo finde ich die Namen der benötigten Netze auf die
> ich Constraints anwenden soll?)
Öhm, die Namen für die IO-Ports legst Du doch selbst fest.
Ansonsten schaut man aufmerksam durch die verschiedenen Synthesereports 
oder öffnet das Design im 'Netlist Analyzer' oder im 'Netlist Viewer'. 
Wenn das alles nicht hilft, suchst Du Dein Netz im 'Physical View'.

Hier als Beispiel ein Ausschnitt aus einem Map-Report:
1
   Number of clocks:  1
2
     Net clk_c: 317 loads, 317 rising, 0 falling (Driver: PIO clk )
3
   Number of Clock Enables:  6
4
     Net N_53: 32 loads, 0 LSLICEs
5
     Net un1_state_15_0_i: 75 loads, 59 LSLICEs
6
     Net un1_state_9_0_i: 7 loads, 7 LSLICEs
7
     Net state_22_d: 79 loads, 79 LSLICEs
8
     Net un1_state_14_0_i: 91 loads, 75 LSLICEs
9
     Net state_21_d: 9 loads, 9 LSLICEs
10
   Number of LSRs:  4
11
     Net state_d[13]: 19 loads, 19 LSLICEs
12
     Net state[0]: 1 loads, 0 LSLICEs
13
     Net quadrant_0_sqmuxa: 1 loads, 1 LSLICEs
14
     Net quadrant_0_.fb: 1 loads, 1 LSLICEs
15
   Number of nets driven by tri-state buffers:  0
16
   Top 10 highest fanout non-clock nets:
17
     Net x_pipe_2: 114 loads
18
     Net state_22_d: 97 loads
19
     Net un1_state_14_0_i: 91 loads
20
     Net state[0]: 84 loads
21
     Net un1_state_15_0_i: 75 loads
22
     Net N_1039: 67 loads
23
     Net state[1]: 59 loads
24
     Net gain[1]: 57 loads
25
     Net re_cf[15]: 51 loads
26
     Net gain[7]: 48 loads


Falls Du wirklich ein Problem mit wegoptimierten Netzen bzw. Logik hast, 
liegt es vermutlich schlicht und ergreifend daran, daß die Ausgänge aus 
dieser Logik nicht verwendet werden oder einen konstanten Wert 
darstellen.

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.