///
LSU EE 3755 -- -- Computer Organization
//
///
Verilog Notes 3 -- Spring 2009-- 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