2013-05-07 53 views
10

Es endete also, dass der Fehler, der mich tagelang gehalten hatte, ein Codeabschnitt war, der zu "False" ausgewertet werden und "True" auswerten sollte. Mein anfänglicher Code ging so etwas wie:Was ist der Unterschied zwischen Verilog! und ~?

if(~x && ~y) begin 
    //do stuff 
end 

d Wenn x nicht ein und y ist nicht einer dann Sachen zu tun. Beim Durchlaufen des Debuggers stellte ich fest, dass, obwohl x 1 war, der Ausdruck in der if-Anweisung immer noch in TRUE resultierte und der nachfolgende Code ausgeführt wurde.

Allerdings, wenn ich die Aussage geändert:

if(x == 0 && y == 0) begin 
//do stuff 
end 

und auch versucht:

if(!x && !y) begin 
//do stuff 
end 

der Code innerhalb der if-Anweisung wurde nicht bewertet, die das erwartete Verhalten ist. Ich verstehe, dass ~ eine bitweise Negation ist und! eine logische Verneinung, aber sollte nicht (~ x & & ~ y) und (! x & &! y) zur gleichen Sache bewerten? Ich fürchte, die Codebasis ist zu groß, daher kann ich sie hier nicht einfügen, aber dies war die einzige Änderung, die ich vorgenommen habe, damit der Code so funktioniert, wie ich es beabsichtigt hatte. Vielen Dank.


Als Antwort auf eine der nachstehenden Bemerkungen: Ich habe einen Testfall erstellt, dieses Verhalten zu testen:

`Zeitplan 10ns/1ns

Modul test_negation();

integer x, y; 

initial begin 
    x = 1; y = 0; 

    if(~x && ~y) begin 
     $display("%s", "First case executed"); 
    end 

    if(!x && !y) begin 
     $display("%s", "Second case executed"); 
    end 

    if(x == 0 && y == 0) begin 
     $display("%s", "Third case executed"); 
    end 
end endmodule 

Und seltsam genug, „Erster Fall ausgeführt“ wird das ursprüngliche Verhalten ich beobachtet, um zu bestätigen gedruckt.

+0

raten, aber wäre nicht bitweise Verneinung etwas wie ~ ~ 0xAA = 0x55', vs. '! 0xAA' ist das Äquivalent von" 0xAA ist nicht Null, also werte ". –

+0

@Marc B Ja, das ist ein wichtiger Unterschied. In diesem Fall sind jedoch sowohl x als auch y 1 Bit lang. Wenn x "1" ist, würde ich eine bitweise Negation ~ x als "0" erwarten. – iab

+0

Ein Bit lang? Wie seltsam. Können Sie ein Testprojekt machen, um die Werte von 'x','! X', '~ x',' y', '! Y',' ~ y' und '(~ x && ~ y)' und anzuzeigen '(! x &&! y)'? –

Antwort

13

Das ! Symbol steht für boolesche oder logische Negation. Für jeden Wert von x, der nicht Null ist, !x wird zu Null oder Falsch ausgewertet, und wenn x Null ist, wird !x zu eins ausgewertet, oder wahr.

Das Symbol ~ steht für eine bitweise Negation. Jedes Bit in dem Wert wird umgeschaltet, so dass für ein 16-Bit x == 0xA5A5, ~x zu 0x5A5A ausgewertet werden würde.

Die Bedingung if() erwartet einen Ausdruck, der als wahr oder falsch ausgewertet wird, wobei alles ungleich null (positiv oder negativ) wahr ist und null falsch ist.

Die && ist eine logische UND. Es benötigt zwei Ausdrücke, die zu eins oder wahr ausgewertet werden, wenn und nur wenn beide Ausdrücke wahr sind. Auch hier bedeutet "wahr" nicht null, positiv oder negativ.

alles gegeben, können wir die einzige Zeit ~x und !x auf den gleichen Wert sehen, dass zu bewerten ist, wenn x == -1 oder, wenn x nicht signiert ist, wenn x == MAX_UNSIGNED.

+0

Ich habe dem ursprünglichen Beitrag ein Testprojekt hinzugefügt. Das gleiche Verhalten wird beobachtet! – iab

+0

Wie viele Bits breit ist die Standard-Ganzzahl? ~ 1 == 0xFFFE und ~ 0 == 0xFFFF, damit das Beispiel sinnvoll ist. –

+1

Es ist leider viel komplizierter als das (ich sehe, jemand hat gerade Ihre Antwort angeklickt). Ihre Erklärung von '!' Ist falsch - das Ergebnis ist 3-stufig ('1',' 0', 'x'), und'! X' ist auch 'x'. In Abs. 2 ist es oft schwierig zu entscheiden, wie groß eine Variable ist, was zu Überraschungen führen kann. Für Abs 3 müssen Sie "x" berücksichtigen. Für Abs 4 ist Ihre Definition von "wahr" falsch - sie muss nicht null und bekannt sein. Und so weiter. – EML

2

~ ist ein bitweiser Operator und gibt das Invert des Arguments zurück.

! ist ein logischer Operator und gibt ein einzelnes Bit zurück.

Beispiel:

reg [7:0] bit_wise, logic_op; 
initial begin 
    bit_wise = ~8'hA1; // bit_wise == 8'h6E 
    logic_op = !8'hA1; // logic_op == 8'b00 
    $display("bit_wise:%h logic_op:%h", bit_wise, logic_op); // bit_wise:5e logic_op:00 
end 

Für Ihr Beispiel:

if(~x && ~y) begin 
    //do stuff 
end 

Ist das Gleiche wie:

if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s 
    //do stuff 
end 

Im Allgemeinen ist die beste Art der Programmierung logische Operatoren innerhalb if-Anweisungen zu verwenden ist . Verwenden Sie nur bitweise Operatoren mit Datenzuordnungsmanipulationen.

+0

FYI - Die '' 1'-Syntax ist nicht gültig Verilog-Syntax. Dieses Konstrukt wurde in SystemVerilog eingeführt. – dwikle

+0

Da ich die Breite von 'x' und' y' nicht kannte, entschied ich mich, die SystemVeilog-Syntax zu verwenden und eine Notiz zu setzen, um zu erklären, wofür "1" gedacht ist. Seit der Veröffentlichung von IEEE Std 1800-2009 sind Verilog und SystemVerilog ein und dasselbe . (In der Zusammenfassung erwähnt, vielleicht kann jemand anderes ein besseres Zitat finden.) – Greg

+0

Die Verwendung von ~ in der if-Anweisung ist nicht sehr klar. Ich würde immer ~ mit einem Vergleich verwenden. Auch mein Simulator glaubt nicht, dass Verilog und SystemVerilog dasselbe sind. Verilog wird oft verwendet, um sich auf die Spezifikationen von 1995 oder 2001 zu beziehen, bevor SystemVerilog für ältere Tools einen großen Unterschied macht. – Morgan

4

Ich sehe. Die Variable "x" in dem obigen Code war eine Verilog-Ganzzahl (integer x;). Eine Ganzzahl Variable wird jedoch durch Verilog als eine 32-Bit-Ganzzahl dargestellt. Also, obwohl x "1" war, wie ich beobachtet hatte, wird ~ x nicht zu "0" sondern "1111111111111111111111111111111110" führen! Und so ist es nicht verwunderlich, dass der Erste Fall ausgeführt wurde. Mein Fehler. Danke für alle Antworten.

+0

Gute Frage, und Sie haben es geschafft, die richtige Antwort selbst zu bekommen. – EML

+0

Froh, dass Sie es ausgearbeitet haben. Die Lektion besteht darin, die "reg" - und "wire" -Typen im klassischen Verilog oder die "bit" - und "logic" -Typen im modernen Verilog zu verwenden und Ihre Signale entsprechend zu dimensionieren. (Achtung, diese Typen sind nicht gleichwertig) –

Verwandte Themen