/// Notes and Demos for LSU EE 4702-1 Spring 2001 // Material from LRM 4.1 /// Contents // Operator Overview // Handling of x and z by Logic Operators (Missing but should be here.) // Reduction Operators // Equality Operators // Concatenation (Not started.) // Conditional Operator // Operator Precedence and Association /// Operator Overview // LRM 4.1 // Many are identical to C counterparts. // Some C operators not present. // Some new ones specific to Verilog. // Precedence similar to C. /// Reduction Operators // A Reduction Operation is one that converts many operands to one. // In Verilog, the operands are the bits of a vector, the result // is a single bit. // Verilog Reduction Operators // & and // | or // ^ exclusive or // ~& not and // ~| not or // ~^ xnor (not exclusive or) /// WARNING: Table 4-19 in the "Experimental" LRM 4.1 is wrong (or mislabeled). /// Correct Tables: (Generated by test_reduction_xnor module, below.) // Reduction Exclusive Or // ^zz = x ^zx = x ^z1 = x ^z0 = x // ^xz = x ^xx = x ^x1 = x ^x0 = x // ^1z = x ^1x = x ^11 = 0 ^10 = 1 // ^0z = x ^0x = x ^01 = 1 ^00 = 0 // Reduction Exclusive Nor // ~^zz = x ~^zx = x ~^z1 = x ~^z0 = x // ~^xz = x ~^xx = x ~^x1 = x ~^x0 = x // ~^1z = x ~^1x = x ~^11 = 1 ~^10 = 0 // ~^0z = x ~^0x = x ~^01 = 0 ~^00 = 1 module reduction_examples(); reg [3:0] a, b, a_xor_b; integer rand1, rand2, rnand1, rnand2, ror1, ror2, rxor1, rxor2; initial begin a = 8'b0110; /// Reduction And // The two lines below do the same thing. rand1 = & a; rand2 = a[0] & a[1] & a[2] & a[3]; if( rand1 ) $display("Reg a is 15."); /// Reduction Nand // The two lines below do the same thing. rnand1 = ~& a; rnand2 = ! ( a[0] & a[1] & a[2] & a[3] ); if( rnand1 ) $display("Reg a is not 15."); /// Reduction Or // The two lines below do the same thing. ror1 = | a; ror2 = a[0] | a[1] | a[2] | a[3]; if( ror1 ) $display("Reg a is not zero."); /// Reduction Xor // The two lines below do the same thing. rxor1 = ^ a; rxor2 = a[0] ^ a[1] ^ a[2] ^ a[3]; if( rxor1 ) $display("Reg a's binary representation has an odd number of 1s."); /// Testing for Equality Using Reduction Xor b = 8'b0111; a_xor_b = a ^ b; // Bitwise xor. if( & a_xor_b ) $display("The contents of a and b are the same."); // The same thing without the temporary variable, a_xor_b. if( & ( a ^ b ) ) $display("The contents of a and b are the same."); end endmodule // reduction_examples module text_reduction_xnor(); // Print the result of the reduction xnor (~^) on all possible // two-bit values. reg [3:0] vals; // Used as a constant, holds the four logic values. integer a, b; reg [1:0] ab; initial begin vals = 4'b01xz; for(a=0; a<4; a=a+1) for(b=0; b<4; b=b+1) begin ab = { vals[a], vals[b] }; $display("~^%b = %b", ab, ~^ab); end end endmodule /// Equality Operators // Special handling needed for x's and z's. // == Logical equality. Result unknown if operand has x or z. // != Logical inequality. Result unknown if operand has x or z. // === Case equality. Compares x's and z's. // !== Case inequality. Compares x's and z's. // LHS == RHS // Evaluates to x if there is an x or z in LHS or RHS // Evaluates to 1 if LHS and RHS are the same numbers. // Evaluates to 0 if LHS and RHS are different numbers. // LHS === RHS // Evaluates to 1 if LHS and RHS are bitwise identical (0's, 1's, x's, and z's). // Otherwise evaluates to 0. // Operands are made the same size by padding the left-hand side // of the smaller operand with zeros. (Signs are NOT extended.) // N.B. neither x nor z act as a wildcard (don't care). module equality_examples(); reg [3:0] four_bit_register; reg [7:0] eight_bit_register; integer an_integer; initial begin /// Some obvious examples. // Since numbers below do not contain x's or z's logical and // case equivalence do the same thing. if( 3 == 4 ) $display("Something is VERY wrong."); if( 3 === 4 ) $display("Something is VERY wrong."); if( 3 != 4 ) $display("For this I need Verilog?"); if( 3 !== 4 ) $display("For this I need Verilog?"); // Four-bit number is extended to 8 bits. if( 8'd3 == 4'd3 ) $display("They're equal."); if( 8'd3 === 4'd3 ) $display("They're equal."); four_bit_register = 3; eight_bit_register = 3; if( four_bit_register == eight_bit_register ) $display("Still equal."); if( four_bit_register === eight_bit_register ) $display("Still equal."); /// Example of Zero Padding and Negative Number Handling // Regs and wires are treated as unsigned values. The assignment // of a negative value works correctly. However if it's converted // to a longer form (as with the equality operators) the lhs will // be padded with zeros, rather than sign extended and so the // result will no longer be a negative integer. four_bit_register = -3; // Value in register: 4'b1101 eight_bit_register = -3; // Value in register: 8'b11111101 $display("Four-bit reg: %d", four_bit_register); if( four_bit_register != eight_bit_register ) $display("They are not equal because the sign was not extended."); if( four_bit_register == eight_bit_register[3:0] ) $display("The low four bits are equal."); /// Examples Using x and z if( 4'b100x == 4'b100x ) $display("This won't print because of x's, they may not be equal."); if( 4'b100x != 4'b100x ) $display("This won't print because of x's, they may be equal."); if( 4'b10zx === 4'b10zx ) $display("The two constants are bitwise identical."); if( 4'b10zx !== 4'b10zx ) $display("This won't print because they are bitwise identical."); if( 4'b100x === 4'b1000 ) $display("This won't print, x is not the same as 0."); end endmodule /// Concatenation // {foo,bar,foobar} /// Conditional // CONDITION ? IFTRUE : IFFALSE // The conditional operator (?:) takes three (yes, three) operands. // If CONDITION is zero evaluates to IFFALSE. // If CONDITION is non-zero and does not contain x or z bits, evaluates // to IFTRUE. // If CONDITION contains an x or z evaluates to a bitwise combination of // IFTRUE and IFFALSE: // Combined bit is 0 iff corresponding bits are 0 in IFTRUE and IFFALSE. // Combined bit is 1 iff corresponding bits are 1 in IFTRUE and IFFALSE. // Otherwise combined bit is x. module conditional_example(x,y,a,b); input a,b; output x,y; wire [3:0] a,b; // Suppose b = 4'b1100; // If a = 4'd5 then x = 4'b1100; // If a = 4'd10 then x = 4'b1010; // If a = 4'b01xz then x = 4'b1xx0; wire [15:0] x = a < 10 ? b : 4'b1010; // If a < 10 then y = 10 // else if a < 20 then y = 20 // else if a < 30 then y = 30 // else y = 40; wire [15:0] y = a < 10 ? 10 : a < 20 ? 20 : a < 30 ? 30 : 40; endmodule // conditional_example /// Operator Precedence and Association // LRM 4.1 Table 4-4. // Operator Precedence // + - ! ~ (unary) highest precedence (Strongest Binding) // * / % // + - (binary) // << >> // < <= > >= // == != === !== // & ~& // ^ ^~ // | ~| // && // || // ?: (conditional operator) lowest precedence (Weakest Binding) // Association is from left to right except conditional (?:). module precedence_and_association_examples(); integer x, a, b, c, d, temp; initial begin /// Precedence Examples // Multiplication has higher precedence than addition so multiply first. x = a + b * c; // Multiply then add. x = ( a + b ) * c; // Add then multiply. // Comparison (<,>) has higher precedence than logical or (||), // so compare first, then or the results. if( a < b || c > d ) $display("Condition true."); // Logical equality (==) has higher precedence than bitwise xor (^). if( a ^ b == c ) $display("This is probably an error."); if( ( a ^ b ) == c ) $display("This is probably okay."); // Unary negation (!) has higher precedence than logical or (||). if( !a || b ) $display("(Not a) or b."); if( !(a || b) ) $display("Not (a or b)"); // The conditional operator has the lowest precedence, lower than addition. // if ( a < 10 ) x = b; else x = c + 1; x = a < 10 ? b : c + 1; // if ( a < 10 ) x = b + 1; else x = c + 1; x = ( a < 10 ? b : c ) + 1; /// Association Examples // Addition and subtraction have the same precedence, so the // leftmost operation is performed first. x = a + b - c; // Add then subtract. x = a - b + c; // Subtract then add. // The conditional operator has right-to-left association. (All // other operators associate left to right.) // The three lines below do the same things. x = a < 10 ? 10 : a < 20 ? 20 : 30; x = a < 10 ? 10 : ( a < 20 ? 20 : 30 ); if( a < 10 ) x = 10; else begin if ( a < 20 ) x = 20; else x = 30; end // The first line below and the next two lines do the same // probably-not-too-useful thing. (Which is why conditionals associate // right to left.) x = ( a < 10 ? 10 : a < 20 ) ? 20 : 30; if( a < 10 ) temp = 10; else temp = a < 20; if ( temp ) x = 20; else x = 30; end endmodule // precedence_examples