Wie gesagt, sind nicht immer alle Blöcke synthetisierbar. Es gibt auch einige Blöcke, die von den Synthesewerkzeugen akzeptiert werden, die jedoch Ergebnisse liefern, die sich von denen eines Simulators unterscheiden.
Zuerst die Empfindlichkeitsliste. Die übliche Regel ist, dass es entweder nur Kantenerkennungskonstrukte enthalten darf (und es gibt normalerweise eine begrenzte Auswahl möglicher Kombinationen) oder dass es (möglicherweise durch Verwendung von * oder systemverilogs always_comb) jedes Signal enthalten muss, das als Eingabe für den Block verwendet wird. Wir nennen den ersteren einen kombinatorischen Block und den letzteren einen sequentiellen oder Block. Wenn Sie nur eine Teilmenge von Eingaben in ein kombinatorisches Blocksynthesewerkzeug aufnehmen, werden Sie normalerweise einfach ignoriert und so getan, als ob die vollständige Liste angegeben worden wäre (Erstellen von Simulations- / Synthesekonflikten).
Zweite Blockierung gegen Noblocking-Aufgaben. In einem kombinatorischen Block spielt der Unterschied keine große Rolle, aber in einem sequentiellen Block spielt er eine große Rolle.
In einem sequentiellen Block, der nicht blockierende Zuweisungen modelliert, wird ein Register ziemlich direkt modelliert, während Zuweisungsmodellvariablen blockiert werden (was abhängig von der Reihenfolge des Einstellens und Lesens Register implizieren kann oder nicht). In der Regel sollte ein "reg" -Satz, der blockierende Zuweisungen in einem sequentiellen Block verwendet, nur in demselben Block gelesen werden, und blockierende und nicht blockierende Zuweisungen sollten nicht in demselben "reg" gemischt werden.
Das Mischen von blockierenden und nicht blockierenden Zuweisungen zu demselben Element führt wahrscheinlich zu Synthesefehlern. Das Erstellen einer Blockierungszuordnung in einem Block und das Lesen in einem anderen Block führt wahrscheinlich zu Fehlanpassungen bei der Simulation / Synthese (und möglicherweise sogar zu Fehlanpassungen zwischen verschiedenen Simulationsläufen).
Jetzt haben wir die Grundregeln aus dem Weg, um zu überlegen, wie der Compiler Code in Logik umwandelt.
Der erste Schritt besteht darin, alle Schleifen abzuwickeln. Dies bedeutet, dass Schleifen eine maximale Iterationszahl haben müssen, die zum Zeitpunkt der Synthese bestimmt werden kann, da sonst ein Synthesefehler auftritt.
Anschließend kann das Tool den Kontrollfluss des Blocks analysieren und in einen Datenfluss umwandeln. Jede Variable wird zu einem oder mehreren Signalen. Jede if-Anweisung oder ein ähnliches Konstrukt wird zu einem oder mehreren Multiplexern, die auswählen, welche Ergebnismenge tatsächlich verwendet wird.
Das Tool wird dann wahrscheinlich versuchen, einige Optimierungen anzuwenden.
In Quartus können Sie die Ergebnisse dieses Prozesses nach dem Erstellen Ihres Projekts sehen, indem Sie auf "tools-> netlist views-> rtl viewer" gehen.
Nachdem diese strukturelle Darstellung in Bezug auf abstrakte Logikelemente erzeugt wurde, fährt das Werkzeug fort, diese abstrakten Elemente auf die Ressourcen abzubilden, über die der Chip tatsächlich verfügt.
block of code
ist ..