2016-04-15 16 views
1

Ich suchte auf SO, und im Web, nirgendwo gefunden die ans. Ich habe folgenden Code, wo es erfolgreich geparst `define und generieren Sie die erwarteten Ergebnisse, aber wenn die Anzahl der Aufrufe von Makro ist dann groß, Können wir Looping Construct?.For loop in `define Makro

`define myreg(name) \ 
    addr_``name  

`define para(i) \ 
    parameter `myreg(i) = i 

module register; 

`para(1); 
`para(2); 
`para(3); 
`para(4); 

initial 
begin 
    $display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2); 
    $display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4); 
    #100 $finish; 
end 
endmodule 

Simulation Ergebnis:

// # Loading work.register(fast) 
// # run -all 
// # ADDR1 =   1, ADDR2 =   2 
// # ADDR3 =   3, ADDR4 =   4 
// # ** Note: $finish : reg.v(18) 

Nun, wenn ich for-Schleife verwenden, wie in folgenden Code,

`define myreg(name) \ 
    addr_``name  

`define para(i) \ 
    parameter `myreg(i) = i 

module register; 

genvar i; 
generate 
    for (i = 1; i<=4; i=i+1) 
    begin 
    `para(i); 
    end 
endgenerate 

initial 
begin 
    $display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2); 
    $display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4); 
    #100 $finish; 
end 
endmodule 

In diesem Fall ist es zeigt einen Fehler beim Anzeige oder Verwendung, Simulationsergebnis:

// # vsim -lib work register -c -do "run -all; quit -f" -appendlog -l qverilog.log -vopt 
// # ** Note: (vsim-3813) Design is being optimized due to module recompilation... 
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_1' in hierarchical name '/addr_1'. 
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_2' in hierarchical name '/addr_2'. 
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_3' in hierarchical name '/addr_3'. 
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_4' in hierarchical name '/addr_4'. 
// # Optimization failed 
// # Error loading design 

Es wird mehrmals gefragt, aber die richtige Lösung wird von niemandem gegeben, jede Hilfe wird sehr geschätzt.

Antwort

1

Das Problem ist eigentlich viel einfacher als sharvil111 erklärt.

Die Richtlinien `define s, `ifdef s und `include s alle von einem Präprozessor behandelt bekommen, die einen Strom von Text erzeugt und in einen Compiler zugeführt. Der Präprozessor weiß nichts über die Verilog-Syntax, und der Compiler sieht keine dieser Anweisungen, weil sie verarbeitet wurden.

Sie können tatsächlich durch Hinzufügen der vlog -E <filename> Option, um diesen Zwischenstrom Text sehen, die den Ausgang des Vorprozessors zu

Es gibt keine Looping-Richtlinie in Verilog/SystemVerilog schreibt. Einige Optionen für Sie sind:

  • schreiben Sie die Makros von Hand. Vielleicht können Sie eine Funktion in Ihrem Texteditor finden, um Ihnen dabei zu helfen, dies zu tun
  • Verwenden Sie einen anderen Makro-Präprozessor, um Ihren Code zu generieren. Dies kann das Debuggen erschweren, da Sie zwei Sätze von Quellcodedateien verwalten müssen.
  • Restructure Code ein Array statt mit separat benannte Parameter
+0

"Verwenden Sie einen anderen Makro-Präprozessor, um Ihren Code zu generieren. Dies kann das Debuggen erschweren, da Sie zwei Gruppen von Quellcodedateien verwalten müssen." Können Sie ein Beispiel oder einen Code angeben? –

+0

http://en.nothingisreal.com/wiki/GPP –

+0

Können Sie mir bitte sagen, wie kann ich das verwenden * vlog -E *? –

3

Für jede Simulation von Ereignissen folgende Reihenfolge statt:

Compilation Phase ==> Ausarbeitungsphase ==> Run Phase (Simulation Phase)

Bei Kompilierung, die Syntax Fehlerprüfung und Makros Textsubstitution durchgeführt wird. Speicher für alle Variablen berechnet und eine ausführbare Datei erstellt. Während der Kompilierungszeit, die der Quellcode eines Programms ist übersetzt in ausführbaren Code.

Bei Ausarbeitung Zeit, die Instanzen und Verbindung zwischen Instanzen gebildet. Durch die Konnektivität, ich meine Überprüfung Portbreiten und Häfen Existenz etc. Da sind die eigentlichen Instanzen erstellt, Parameter sind auch bei Ausarbeitung ausgewertet.

Bei Laufzeit, natürlich, die eigentliche Simulation beginnt auf den Stationen von Null Zeit.

Makros werden bei Kompilierung (daher bekannt als Compiler Richtlinien) bewertet, während generate Block bei Ausarbeitung Zeit auswertet.

Mit Bezug auf IEEE 1800-2012, Abschnitt 27.3:

generieren Systeme während Ausarbeitung des Entwurfs ausgewertet werden. ... Sie werden zum Zeitpunkt der Ausarbeitung ausgewertet und das Ergebnis wird vor Beginn der Simulation bestimmt. Daher sollten alle Ausdrücke in generierten Schemata konstante Ausdrücke sein, deterministisch zum Zeitpunkt der Ausarbeitung.

Das erste Beispiel wird ausgeführt, weil alles zur Kompilierzeit erledigt ist. Alle Variablen werden zur Kompilierzeit selbst deklariert. Daher funktioniert der Code gut.

Im zweiten Beispiel, Sie versuchen zu declare Variablen bei Ausarbeitung Zeit, die nicht erlaubt ist. No more Speicher zu den Variablen wird zur Herstellungszeit zugeteilt.

Weitere Informationen zur Kompilierungs- und Verarbeitungszeit finden Sie in Abschnitt 3.12 unter IEEE 1800-2012.

+1

Ihre Erklärung ist perfekt nutzen zu können! Ich habe das Konzept verstanden. Was soll ich für den zweiten Code tun? Ist es möglich, in der Kompilierzeit Wiederholungen oder "for" Schleifen zu machen? Oder es ist nicht möglich? –

+1

Sie haben nur eine begrenzte Anzahl von Compiler-Direktiven, die 'generate' Schleife ist keine Lösung. Ich würde es vorziehen, ein ** Array ** von Variablen zu verwenden, die durch Parameter gesteuert werden, wie 'Parameter SIZE = 5; reg [7: 0] ADDR [GRÖSSE]; '. Oder Sie können ein Makro-gesteuertes Array wie 'ifdef SIZE reg [7: 0] ADDR [SIZE]; sonst definiere SIZE 5 ADDR [SIZE]; endif '. Und stellen Sie "SIZE" als Simulationsschalter wie '+ define + SIZE = 5' bereit. Dies überschreibt die SIZE wie beim Simulationsschalter. – sharvil111

+0

Eher in den Kommentaren, können Sie es bitte hinzufügen, um zu antworten? –