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 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
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?
