/// LSU EE 3755 -- -- Computer Organization
//
/// Verilog Notes 3 -- Fall 2005-- Expressions
/// Contents
//
Operators: Equality, Comparison
//
Operator: Conditional
//
Operators: Shift, Cat
//
Operator Precedence and Association
//
ALU Example
///
References
//
:P: Palnitkar, "Verilog HDL"
//
:Q: Qualis, "Verilog HDL Quick
Reference Card Revision 1.0"
//
:PH: Patterson & Hennessy,
"Computer Organization & Design"
////////////////////////////////////////////////////////////////////////////////
///
Operators: Equality, Comparison
//
:P: 6.4.3, 6.4.4
//
There are two equality operators, == and ===, and two inequality
//
operators, != and !==.
//
//
There are also comparison operators.
//
//
See the example.
//
:Example:
//
//
Examples and description of the equality operators.
module
equality(x1,x2,x3,x4,a,b);
input [2:0] a, b; // Both a and b are 3 bits.
output x1, x2, x3, x4;
// Logical Equality
//
assign x1 = a == b;
//
// If a and b consist only of 0's and 1's:
//
If a and b are identical, x1 is set to 1,
//
if a and b differ, x1 is set to 0.
// If a or b has an x or z, x1 is set to x.
//
// Examples:
//
// a
b | a == b
//
""""""""""""""""""
// 000
000 | 1
// 000
001 | 0
// 001
001 | 1
// x01
001 | x
// x01
x01 | x // Note: x is not
a don't care.
// Logical Inequality
//
assign x2 = a != b;
//
// Analogous to logical equality.
//
// Examples:
//
// a
b | a != b
//
""""""""""""""""""
// 000
000 | 0
// 000
001 | 1
// 001
001 | 0
// x01
001 | x
// x01
x01 | x
// Case Equality
//
assign x3 = a === b;
//
// If a and b are identical (including x's
and z's) x3 is 1 otherwise
// x3 is set to zero.
//
// Examples:
//
// a
b | a === b
//
""""""""""""""""""""
// 000
000 | 1
// 000
001 | 0
// 001
001 | 1
// x01
001 | 0
// x01
x01 | 1
// Case Inequality
//
assign x4 = a !== b;
//
// If a and b are identical (including x's
and z's) x4 is set to 0 otherwise
// x4 is set to one.
//
// Examples:
//
// a
b | a !== b
//
""""""""""""""""""""
// 000
000 | 0
// 000
001 | 1
// 001
001 | 0
// x01
001 | 1
// x01
x01 | 0
endmodule
//
:Example:
//
//
Illustration and explanation of the comparison operators.
module
compare(x1,x2,x3,x4,a,b);
input [7:0] a, b; // Both a and b are 8 bits.
output x1, x2, x3, x4;
// Take note: Comparison (and other)
operators interpret contents of a
// vector (e.g., a and b) as unsigned.
// Greater Than
//
assign x1 = a > b;
//
//
// Examples:
//
// a
b | a > b
//
""""""""""""""""""
// 3
1 | 1
// 1
3 | 0
// 4
4 | 0
// x
4 | x
// -1
3 | 1 See note below.
//
// The 8-bit 2's complement representation
of -1 is 8'b11111111
// which is identical to the 8-bit
representation of 255, 8'b11111111.
// The comparison operand will always
interpret contents of a vector
// as an unsigned integer.
// Greater Than or Equal To
//
assign x2 = a >= b;
//
//
// Examples:
//
// a
b | a >= b
//
""""""""""""""""""
// 3
1 | 1
// 1
3 | 0
// 4
4 | 1
// x
4 | x
// -1
3 | 1 See note above.
// Less Than
//
assign x3 = a < b;
//
//
// Examples:
//
// a
b | a < b
//
""""""""""""""""""
// 3
1 | 0
// 1
3 | 1
// 4
4 | 0
// x
4 | x
// -1
3 | 0 See note above
// Less Than or Equal To
//
assign x4 = a <= b;
//
//
// Examples:
//
// a
b | a <= b
//
""""""""""""""""""
// 3
1 | 0
// 1
3 | 1
// 4
4 | 1
// x
4 | x
// -1
3 | 0 See note above.
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operator: Conditional
//
:P: 6.4.10
//
//
:Sample: assign v = x ? y : z
//
// If x is 1 assign y to v, if x is 0 assign z
to v.
//
//
:Sample: assign v = x < 3 ? y + 1 :
z - x;
//
// If x < 3 assign y+1 to v; if x >= 3
assign z-x to v.
//
:Example:
//
//
A simple illustration of the conditional operator.
module
conditional(x,a,b,s);
input [31:0] a, b;
input s;
output [31:0] x;
// The Conditional Operator
//
//
assign x = s ? a : b;
//
// Examples:
//
// a
b s | s ? a : b
//
""""""""""""""""""""
// 11 22 0
| 22 (b selected if s == 0)
// 11 22 1
| 11 (b selected if s != 0 and
not unknown)
// 11 22 x
| x
endmodule
//
:Example:
//
//
Use of the conditional operator to implement a four-input
//
multiplexor.
//
//
With procedural code, to be covered later, there are many
//
ways to code multiplexors.
module
mux4(x,a,b,c,d,select);
input [31:0] a, b, c, d;
input [1:0] select;
output [31:0] x;
assign x =
select == 0 ? a :
select == 1 ? b :
select == 2 ? c : d;
// Notes on example above:
//
// "select == 0" evaluates to
Logic 0 (if select isn't value 0)
//
or to Logic 1 (if select is value 0).
//
//
endmodule
//
:Example:
//
//
Another use of the conditional operator.
In this one parenthesis
//
are necessary.
module
more_conditional(x,a,b,adjust_a,adjust_b);
output [15:0] x;
input [15:0] a, b;
input adjust_b, adjust_a;
assign x = ( adjust_a ? a + 5 : a ) + ( adjust_b ? b + 5 : b );
// In example above parentheses are needed,
otherwise the middle "+"
// would grab the "a" away from
the first conditional.
//
x = adjust_a ? a + 5 :
//
a + adjust_b ? b + 5 : b ;
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operators: Shift, Concatenate
//
:P: 6.4.7, 6.4.8
//
The shift operators, << and >>, perform left and right shifts.
//
// Zeros are shifted in to the vacated
positions.
//
//
The concatenation operator, {}, makes a large vector out of
//
its arguments.
//
//
See examples for further description.
//
:Example:
//
//
Illustration and description of shift operators.
module
shifts(x1,x2,a,s);
input [15:0] a;
input [2:0] s;
output [15:0] x1, x2;
// The Left Shift Operator
//
assign x1 = a << s;
//
// Examples:
//
// a
s | a << s
//
"""""""""""""""""""
// 01011 0 | 01011 // Note: shown
in binary
// 01011 1 | 10110
// 01011 2 | 01100
// 01011 7 | 00000
// The Right Shift Operator
//
assign x2 = a >> s;
//
// Examples:
//
// a
s | a >> s
//
"""""""""""""""""""
// 11011 0 | 11011 // Note: shown
in binary
// 11011 1 | 01101
// 01011 2 | 00010
// 01011 7 | 00000
endmodule
//
:Example:
//
//
Use of the shift operator to multiply by four.
module
a_times_4_plus_b(x,a,b);
input [7:0] a, b;
output [10:0] x;
assign x = ( a << 2 ) + b;
endmodule
//
:Example:
//
//
Illustration and description of the concatenate operator.
module
cat(x,y,a,b);
input [3:0] a, b;
output [7:0] x;
output [7:0] y;
// The Concatenation Operator
//
assign
x = { a, b };
//
// Examples:
//
// a
b | { a, b }
//
"""""""""""""""""""
// 0000 1111 | 00001111
// 1010 1111 | 10101111
// Note: Constants within the concatenation
operator must be sized,
// for example, 3'd5 is okay but 5 is not.
assign
y = { a, 3'd5, b };
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operator Precedence and Association
//
:P: 6.4.11
//
Precedence and association specify for which operator an operand is used.
//
See Examples.
///
Operator Precedence
// + - ! ~ (unary) highest precedence
// *
/ %
// + -
(binary)
// <<
>>
// <
<= > >=
// ==
!= === !==
// &
~&
// ^ ^~
// | ~|
// &&
// ||
// ?: (conditional operator) lowest precedence
// Association is from left to right except
conditional (?:).
//
:Example:
//
//
Examples illustrating precedence and association. This example
//
uses behavioral code which has not been covered yet but should
//
be easy enough to figure out.
module
precedence_and_association_examples();
integer x, a, b, c, d, e, temp;
integer
i_am_a_condition_for_operator_to_the_right;
integer
i_am_the_else_part_of_the_operator_to_the_left;
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
// All operators associate left-to-right
except ?:.
// 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.)
x
= a ? b :
i_am_a_condition_for_operator_to_the_right ? d : e;
// x=
a ? b :
//
i_am_a_condition_for_operator_to_the_right ? d : e;
x = ( a ? b : i_am_the_else_part_of_the_operator_to_the_left
) ? d : e;
// x will be
assigned with d or e.
//
if a is true, the condition for next
statement will be “b”.
//
which looks like x= b ? d : e;
//
//
if a is false, the condition for next
statement will be
//”
i_am_the_else_part_of_the_operator_to_the_left “
//
which looks like x= i_am_the_else_part_of_the_operator_to_the_left ? d :e ;
// The three lines below do the same
things.
x = a < 10 ? 10 : a < 20 ? 20 :
30;
//
When a = 9, 19, 29:
// a
=9:
// x = 9 < 10 ? 10 : 9 < 20 ? 20 : 30;
// x = 10;
// a =
19:
// x = 19 < 10 ? 10 : 19 < 20 ? 20 : 30;
// x = 19 < 20 ? 20 : 30;
// x = 20;
// a =
29:
// x =
29 < 10 ? 10 : 29 < 20 ? 20 : 30;
// x =
29 < 20 ? 20 : 30;
// x =
30;
//With
parentheses
x
= a < 10 ? 10 : ( a < 20 ? 20 : 30 );
//
When a = 9, 19, 29:
// a =9 .
// x = a < 10 ? 10 : ( 9 < 20 ? 20 : 30
);
// x = 9 < 10 ? 10 : 20;
// x = 10;
//
// a = 19 .
// x = a < 10 ? 10 : ( 19 < 20 ? 20 : 30
);
// x = 19 < 10 ? 10 : 20;
// x = 20;
//
// a = 29 .
// x = a < 10 ? 10 : ( 29 < 20 ? 20 : 30
);
// x = 29 < 10 ? 10 : 30;
// x = 30;
if( a < 10 ) x = 10; else begin if (
a < 20 ) x = 20; else x = 30; end
x = ( a < 10 ? 10 : a < 20 ) ? 20
: 30;
// When a = 9 , 19, 29..
//
a = 9.
// x = ( 9 < 10 ? 10 : 9 < 20 ) ? 20 :
30 ;
// x =
10 ? 20 : 30 ;
// Since 10 means true,
// x =
10 ? 20 : 30 ;
// x =
20;
//
a = 19.
// x = ( 19 < 10 ? 10 : 19 < 20 ) ? 20 :
30 ;
// x = 19 < 20 ? 20 : 30 ;
// x = 20;
//
a = 29.
// x = ( 29 < 10 ? 10 : 29 < 20 ) ? 20 :
30 ;
// x = 29 < 20 ? 20 : 30 ;
// x = 30;
end
endmodule
// precedence_examples
/// Note on Style
//
//
Avoid unnecessary parenthesis for common operators.
//
For example use:
// x = a + b * c;
//
Do not use:
// x = a + ( b * c );
//
The second assignment does exactly the same thing as the first but
//
the parenthesis add clutter which can become cumbersome in complex
//
expressions.
//
//
Note that the Palnitkar text specifies the opposite style,
//
and so would prefer the second assignment.
////////////////////////////////////////////////////////////////////////////////
///
ALU Example
//
:PH: 4.5 An example of a different
ALU.
//
An example of a CPU arithmetic and logical unit (ALU).
//
An ALU typically has two operand inputs (a and b below),
//
a control input (op below), and a result output. It
//
can perform several arithmetic and logical operations,
//
the operation to perform is specified by the op input.
//
There are two ALU modules below, one uses the conditional
//
operator, the other uses a multiplexor module, which
//
is also defined.
//
:Example:
//
//
ALU using the conditional operator.
module
alu(result,a,b,op);
input [31:0] a, b;
input [3:0] op;
output [31:0] result;
parameter op_add = 0;
parameter op_sub = 1;
parameter op_or = 2;
parameter op_a = 3; // Result is a (unmodified).
parameter op_b = 4; // Result is b (unmodified).
parameter op_srl = 5; // Shift a
right logical (no sign extension).
parameter op_sra = 6; // Shift a
right arithmetic (sign extension).
parameter op_rr = 7; // Rotate a right.
assign result =
op == op_add ? a + b :
op == op_sub ? a - b :
op == op_or ? a | b :
op == op_a ? a :
op == op_b ? b :
op == op_srl ? a >> 1 :
op == op_sra ? {a[31], a[31:1] }:
op == op_rr ? {a[0],
a[31:1] } : 0;
endmodule
//
:Example:
//
//
A multiplexor with eight 32-bit inputs.
To be used in the
//
ALU below.
module
mux8x32(o,s,i0,i1,i2,i3,i4,i5,i6,i7);
input [31:0] i0,i1,i2,i3,i4,i5,i6,i7;
input [2:0] s;
output [31:0] o;
assign o =
s == 0 ? i0 :
s == 1 ? i1 :
s == 2 ? i2 :
s == 3 ? i3 :
s == 4 ? i4 :
s == 5 ? i5 :
s == 6 ? i6 : i7;
endmodule
//
:Example:
//
//
An ALU using the multiplexor. Note that
the constants are not used
//
and that it is much harder to tell if a particular operation is in
//
the correct multiplexor input.
module
alu2(result,a,b,op);
input [31:0] a, b;
input [2:0] op;
output [31:0] result;
// Parameters not used here.
parameter op_add = 0;
parameter op_sub = 1;
parameter op_or = 2;
parameter op_a = 3; // Result is a (unmodified).
parameter op_b = 4; // Result is b (unmodified).
parameter op_srl = 5; // Shift a
right logical (no sign extension).
parameter op_sra = 6; // Shift a
right arithmetic (sign extension).
parameter op_rr = 7; // Rotate a right.
mux8x32 m1(result, op,
a + b,
a - b,
a | b,
a,
b,
a >> 1,
{a[31], a[31:1] },
{a[0], a[31:1] }
);
endmodule