2012-06-21 2 views
7

Die allgemeine Faustregel in allen Büchern, die ich bisher gelesen habe, ist, dass Sie nicht blockierende Zuweisungen in immer Blöcken verwenden müssen, die von der steigenden oder fallenden Flanke der Uhr gesteuert werden. Im Gegensatz dazu müssen blockierende Zuweisungen für die kombinatorische Logikbeschreibung verwendet werden. Diese Regel macht für mich Sinn und Autoren von Beispielen folgen ihr gründlich.immer @ * blockieren mit einer einzigen nicht-blockierenden Zuordnung - gut, schlecht oder irrelevant?

Jedoch entdeckte ich das folgende Stück Verilog in einer der Produktionscode:

always @* begin 
    in_ready <= out_ready || ~out_valid; 
end 

Man beachte, daß nicht-blockierende Zuordnung <= verwendet wird. Ich denke nicht, dass es in diesem Fall einen Unterschied macht, da es keine Mehrfachaufgaben gibt. Ich kann jedoch keine Erklärung dafür finden. Die Frage ist also - macht es keinen Unterschied, sowohl im Rahmen eines gegebenen immer Block und als Teil des größeren Designs?

Antwort

4

Nicht relevant, aber schlechte Praxis.

I bezweifeln, dass die Einzelzuweisung Nebenwirkungen verursacht. Der always Block wird für jede Änderung auf der rechten Seite ausgelöst, wobei in_ready aktualisiert wird. Es gibt nichts zu blockieren, so dass Nicht-Blockieren keine Probleme verursacht.

Falls eine größere Design hatte:

always @* begin 
    in_ready <= out_ready || ~out_valid ; 
    other_ready <= in_ready || other_ready ; 
end 

Ich bin nicht sicher, wie es kombi ist es könnte ein zusätzliches Delta Schritt nehmen zu lösen.

+0

kommen wird es Ihnen danken. Ja, dein Codebeispiel zeigt definitiv nicht nur eine schlechte Übung, sondern wird auch nicht so funktionieren, wie es beabsichtigt war, es sei denn, es war wirklich beabsichtigt, so zu sein, was wenig Sinn macht. Ich frage mich, was die Meinung der Downvoter zu diesem Thema war. Du hast eigentlich recht. Ich habe dasselbe als Teil einer größeren Frage von mir auf dem EE-Stapelaustausch bestätigt (electronics.stackexchange.com/questions/34287/flip-flop-vs-combinatorial-description-what-exactly-is-the-difference/). Danke für Ihre Hilfe! –

+0

Vielen Dank für das Feedback, bekam 2 downvotes aber keine Kommentare zu sagen, warum. – Morgan

7

Natürlich verstößt dies gegen meine Codierungsrichtlinie # 3: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf) aber es wird funktionieren.

Der Grund, die Verwendung nichtblockierender Zuweisungen zum Codieren von kombinatorischer Logik zu vermeiden, ist die Simulationsleistung. In Munkymorgys Beispiel wird nach den Staustufen-Triggern die rechte Seite (RHS) aller Gleichungen ausgewertet, zurück zum Anfang des Always-Blocks, die LHS der Gleichungen aktualisiert, was wiederum die blockiere immer, was wiederum den Simulator dazu zwingt, die RHS der Gleichungen auszuwerten, an die Spitze des Always-Blocks zu gehen und dann die LHS der Gleichungen zu aktualisieren. Bei größeren Blöcken könnte dies zu mehreren Iterationen durch den Block always mit der entsprechenden Simulation führen.

In Ihrem einfachen 1-zeiligen Beispiel gibt es keine interne Simulationsstrafe, aber an anderen Stellen kann es zu Überschneidungen kommen.

Gute Programmierer verwenden durchweg gute Codierung Gewohnheiten. Ich würde den Code ändern. Wenn das Ändern des Codes die Simulationsergebnisse unterbricht, gibt es zusätzliche schlechte Codierungsgewohnheiten, die an anderer Stelle im Code vergraben sind. Der Code sollte nicht so fragil sein.

Grüße - Cliff Cummings - Verilog & SystemVerilog Guru

1

seine nicht schlecht Sie haben die Wahl, ob Sie die Art und Weise die Schaltung verstehen seine sehr feine so zum Beispiel

immer @ * beginnen b verhalten < = a + c; a = b; Ende

  1. so in diesem Codebeispiel die komplette Schaltung innerhalb des immer Block entwickelt wird, wenn etwas in der Empfindlichkeit Liste, die alle Eingänge entweder ansteigen wird, ist erhalten aktiviert oder fallen sie ihren aktuellen Zustand b <
  2. jetzt ändern = a + c jetzt wird hier ein Volladdierer mit 'a' und 'c' als Eingabe erzeugt aber
  3. jetzt ist der Entwurf gemacht oder der Compiler synthetisiert die Schaltung so, dass die nächste Anweisung a = b hier ist Draht wird aus dem alten Wert und nicht aus dem aktualisierten b herausgenommen und wird an einen übergeben; so einfach
  4. wenn Sie wollen die gleiche Sie willkommen sind, passieren kein Problem zu tun in synthetisierbaren