IO constraints für asynchrone Inputs in Lattice Diamond

OP #7929771
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?
#7930066
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

(Firma: Starfleet) #7930127
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.

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.

Angehängte Dateien:
: Bearbeitet durch User
#7930144
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.

Angehängte Dateien:
OP #7932667
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?).

#7932881
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren