//LSU EE 3755 � Fall
2005 �Computer Organization
//
/// Verilog Notes 2 -- Expressions
///
Contents
//
Continuous Assignment
//
Operators:� Bitwise Logical
//
Vectors, Bit Selects, and Part Select
//
Sized Numbers and Constants (Parameters)
//
Operators: Bitwise with Vectors
//
Operators: Arithmetic
//
Operators: Logical AND, etc
///
References
//
:P:�� Palnitkar, "Verilog HDL"
//
:Q:�� Qualis, "Verilog HDL Quick
Reference Card Revision 1.0"
//
:PH:� Patterson & Hennessy,
"Computer Organization & Design"
////////////////////////////////////////////////////////////////////////////////
///
Continuous Assignment
//
:P: 6.1����
//
Continuous assignment specifies a value for a wire using an
//
expression.
//
//
//
Continuous assignments can be made using the /assign/ keyword and in a
//
wire [or other net] declaration.
//
:Keyword: assign
//
//
:Sample:� assign a = b;
//
//
Here "b" is the expression.
//
The left hand side of an assignment always should be a wire[net].
//
:Example:
//
//
A simple use of the assign keyword.�
Output x is given
//
the value of "a".� Whenever
"a" changes "x" also changes.
//
Don't forget that: Whenever "a" changes "x" also changes.
//
//
The module below passes the signal through unchanged.
module
really_simple(x,a);
�� input a;
�� output x;
�� assign x = a;
endmodule
//
:Example:
//
//
The module below is functionally equivalent to the one above.
module
really_simple_with_a_gate(x,a);
�� input a;
�� output x;
�� and a1(x,a);
��
endmodule
//
:Example:
//
//
The module below also passes a signal through the module unchanged,
//
but this time it goes through an extra wire, w.� Whenever "a"
//
changes, w will change and that will change x.
module
something_similar(x,a);
�� input a;
�� output x;
�� wire��
w;
�� assign w = a;
�� assign x = w;
endmodule
//
:Example:
//
//
The module below is like the one above except that
//
continuous assignment to w is done in the wire declaration
//
rather than with a separate assign statement.
module
something_else_similar(x,a);
�� input a;
�� output x;
�� wire��
w = a;
�� assign x = w;
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operators:� Bitwise Logical
//
:P: 6.3,6.4
//
:P: 6.4.5��
//
Operators for performing bitwise logical operations.
//
//
(The meaning of bitwise and logical will be explained in the Vector
//
section below.)
//
//
//
Operators:
//� &�
bitwise and
//� |�
bitwise or
//� ~�
bitwise not
//� ^�
bitwise exclusive or
//
:Example:
//
//
A module implementing: x = ab + c;
module
my_abc_module(x,a,b,c);
�� input a, b, c;
�� output x;
�� assign x = a & b | c;
endmodule
//
:Example:
//
//
The module below is functionally equivalent but less readable than
//
the one above.
module
my_abc_module_gates(x,a,b,c);
�� input a, b, c;
�� output x;
�� wire��
ab;
��
�� and a1(ab,a,b);
�� or o1(x,ab,c);
endmodule
//
:Example:
//
//
Simple uses of the &, |, and ~ operators along with truth tables.
module
operator_demo(x1,x2,x3,x4,a,b);
�� input a, b;
�� output x1, x2, x3, x4;
�� // Bitwise AND.� (There is also a logical AND, discussed later.)
�� //
�� assign x1 = a & b;
�� //
�� // a�
b� |� a & b
�� //
""""""""""""""
�� // 0�
0� |��� 0
�� // 0�
1� |��� 0
�� // 1�
0� |��� 0
�� // 1�
1� |��� 1
�� // Bitwise OR.� (There is also a logical OR, discussed later.)
�� //
�� assign x2 = a | b;
�� //
�� // a�
b� |� a | b
�� //
""""""""""""""
�� // 0�
0� |��� 0
� �//
0� 1�
|��� 1
�� // 1�
0� |��� 1
�� // 1�
1� |��� 1
�� // Bitwise XOR.
�� //
�� assign x3 = a ^ b;
�� //
�� // a�
b� |� a ^ b
�� //
""""""""""""""
�� // 0�
0� |��� 0
�� // 0�
1� |��� 1
�� // 1�
0� |��� 1
�� // 1�
1� |��� 0
�� // Bitwise NOT;
�� //
�� assign x4 = ~a;
�� //
�� // a��
|� ~a
�� //
""""""""""""
�� // 0��
|�� 1
�� // 1��
|�� 0
endmodule
//
:Example:
//
//
A binary-full adder using operators.�
Some consider this more
//
readable than the earlier version.� Note
how spaces and returns
//
(whitespace) are used to make the assignment to sum readable.
module
bfa_implicit(sum,cout,a,b,cin);
�� input a,b,cin;
�� output sum,cout;
�� assign sum =
��������� ~a & ~b &� cin |
��������� ~a &� b & ~cin |
���������� a & ~b & ~cin |
���������� a &� b &� cin;
�� assign cout = a & b | b & cin | a
& cin;
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Vectors, Bit Selects, and Part Select
//
:P: 3.2.4��
///
Vectors
//
//
So far only 1-bit wires have been shown.
//
//
A /vector/ is a wire [or reg] that is more than one bit.
//
//
The size and the bit numbering are specified in the declaration.
//
(See examples.)
//
:Sample:� wire [10:0] a;
//
:Sample:� output [10:0] b;
//
//
Declares wire a and output b with least-significant bit 0 and
//
most-significant bit 10 (for a total of 11 bits).
�/// Bit and Part Selects
//
//
A bit select is used to extract a single bit from a wire [or reg].
//
:Sample:� assign x = a[1]; // Extract
bit 1.
//
//
A part select is used to extract several consecutive bits from a
//
wire [or reg].
//
:Sample:� assign y = a[5:3]; // Set y to
3 bits of a, bits 5 to 3.
//
:Example:
//
This example does not use vectors. The author, who knew nothing
//
about vectors, wanted a 4-bit input "a" and a 4-bit output x,
//
plus a one-bit output msb.
module
without_vectors(msb,x3,x2,x1,x0,a3,a2,a1,a0);
�� output msb;
�� output x3, x2, x1, x0;
�� input�
a3, a2, a1, a0;
�� assign msb = a3;
�� assign x3 = a3;
�� assign x2 = a2;
�� assign x1 = a1;
�� assign x0 = a0;
endmodule
//
:Example:
//
//
This is the way the module above should be done.� Here input "a"
//
and output "x" are declared as 4-bit vectors.� A bit select
//
is used in the assignment to msb.
module
with_vectors(msb,x,a);
�� output msb;
�� // Declare x as a 4-bit input, bit 3 is the
most-significant bit (MSB).
�� output [3:0] x;
�� input�
[3:0] a;
�� assign������ msb = a[3];� //
Extract bit 3 from a, which is the MSB.
�� assign������ x = a;
endmodule
//
:Example:
//
//
This module does the same thing as the one above.� It is written
//
differently: 0 is used to indicate the MSB (rather than 3).� Some
//
prefer that the MSB be the highest-numbered bit, some like it to be
//
the lowest-numbered bit.
module
more_vectors(msb,x,a);
�� output msb;
�� output [0:3] x; // Here MSB is 0 and LSB is
3.
�� input�
[0:3] a;
�� assign������ msb = a[0];
�� assign������ x = a;
endmodule
//
:Example:
//
//
Here the vector declaration is used in a wire, rather than
//
a port (input or output).
module
and_more_vectors(x,a);
�� input [15:0] a;
�� output [15:0] x;
�� wire [15:0]�� w;
�� assign������� w = a;
�� assign������� x = w;
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Sized Numbers and Constants (Parameters)
//
:P: 3.1.4, 3.2.8�
�/// Sized Numbers
//
//
In Verilog numbers can be written with a specific size and using
//
one of four radices (bases).
//
The number consists of a size (in bits) followed by an apostrophe,
//
followed by a b,o,d, or h (for binary, octal, decimal,
//
hexadecimal), followed by the number.
//
//
:Sample: 16'd5
//
//
The number five using 16 bits written in decimal.
//
//
:Sample: 16'b101
//
//
The number five represented using 16 bits written in binary.
�/// Constants
//
//
Constants are specified using the /parameter/ keyword.
//
//
:Sample:� parameter limit = 5;
//
//
This specifies a parameter named limit with a value of 5.
//
Identifier limit can be used in expressions but cannot be
//
assigned.� For more information see
parameter_examples module
//
below.
//
:Keyword:
//
parameter
//
:Example:
//
//
The number one and the number ten are specified in a variety of
//
ways.� Note the size of the wires and
that each wire is assigned
//
multiple times. (In this class, one should not assign the same wire
//
multiple times. [Elsewhere, it might be done if the wire is a bus
//
and is driven by tri-state devices.])
module
fixed(one,ten);
�� output [7:0] one;
�� output [15:0] ten;
�� // All assignments below do the same
thing.�
�� //
�� // Use the one that's easiest to read.
�� //
�� assign������� one = 1;���� // No
size specified.
�� assign������� one = 8'b1;� // One
specified in binary.
�� assign������� one = 8'b00000001;�
// One specified in binary.
�� assign������� one = 4'b1;� //
Sloppy, but works: Specified wrong size.
�� assign������� one = 8'd1;� // One
specified in decimal.
�� assign������� one = 8'h1;� // One
specified in hexadecimal;
�� // All assignments below do the same thing.
�� //
�� // Use the one that's easiest to read.
�� //
�� assign������� ten = 10;
�� assign������� ten = 16'b1010;
�� assign������� ten = 16'b0000000000001010;
�� assign������� ten = 16'd10;
�� assign������� ten = 16'ha;
�� assign������� ten = 16'h000a;
endmodule
//
:Example:
//
//
A sized number is used to specify the carry in of one of the bfa's
//
in a two-bit ripple adder.� It's
important to use a sized number
//
(rather than a regular number) for connections to modules.
module
ripple_2(sum,cout,a,b);
�� input [1:0] a, b;
�� output [1:0] sum;
�� output������ cout;
�� wire�������� c0;
�� bfa_implicit
bfa0(sum[0],c0,a[0],b[0],1'b0);
�� bfa_implicit bfa1(sum[1],cout,a[1],b[1],c0);
endmodule
//
:Example:
//
//
A module illustrating the use of parameters (as constants).
module
parameter_examples(an_input);
�� input [7:0] an_input;
�� parameter one = 1;
�� // Parameters can be sized numbers.
�� parameter two = 10'd2;
�� // The value of seconds_per_day is computed
once, at analysis
�� // (usually compile) time.
�� parameter seconds_per_day = 60 * 60 * 24;
�� parameter width = 12;
�� parameter height = 21;
�� // The value of area is computed once, at
analysis
�� // (usually compile) time.
�� parameter area = width * height;
�� // The line below is an error because
"an_input" is not a constant.
�� // parameter double_input = an_input * two;
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operators:� Bitwise with Vectors
//
The same references as the earlier bitwise logical section.
//
//
:P: 6.3,6.4
//
:P: 6.4.5��
//
Operators &, |, ~, ^ are called /bitwise/ because when
//
the operands are vectors the operation is done on each
//
bit of the vector.
//
:Example:
//
//
An appropriate use of a bitwise operator, followed by
//
code that does the same thing the hard way.
module
and_again(x1,a,b);
�� input [2:0] a, b;�� // Both a and b are 3 bits.
�� output [2:0] x1;
�� // An appropriate use.
�� //
�� // Bitwise AND, but this time operands are
3-bit vectors.
�� //
�� assign x1 = a & b;� // ANDs three pairs of bits.
�� // The same thing the hard way:
�� //
�� assign x1[0] = a[0] & b[0];
�� assign x1[1] = a[1] & b[1];
�� assign x1[2] = a[2] & b[2];
�� //
�� // Examples:
�� //
�� // a���
b��� |� a & b
�� //
""""""""""""""
�� // 000�
000� |� 000
�� // 000�
001� |� 000
�� // 010�
111� |� 010
�� // 100�
110� |� 100
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operators: Arithmetic
//
:P: 6.4.1
//
//
The arithmetic operators are:
//�� + (addition), - (subtraction), *
(multiplication), / (division),
//�� and % (remainder).
//
They operate on wires and data types to be covered later.
//
:Example:
//
//
A simple demonstration of arithmetic operators.
module
arith_op(sum,diff,prod,quot,rem,a,b);
�� input [15:0] a, b;
�� output [15:0] sum, diff, prod, quot, rem;
�� // For these operators vectors are
interpreted as integers.
�� // Addition
�� assign sum = a + b;
�� // Subtraction
�� assign diff = a - b;
�� // Multiplication
�� assign prod = a * b;
�� // Division
�� assign quot = a / b;
�� // Remainder (Modulo)
�� assign rem = a % b;
�� //
�� // Examples:
�� //
�� // a���
b��� |� a % b
�� //
""""""""""""""""""
�� // 3���
5��� |� 3
�� // 5���
3��� |� 2
�� // 7���
7��� |� 0
endmodule
//
:Example:
//
//
The input to the module below is a complex number (specified
//
with a real and imaginary part); the output is the square
//
of that number.
module
complex_square(sr,si,ar,ai);
�� input [31:0] ar, ai;
�� output [31:0] sr, si;
�� assign������ sr = ar * ar - ai * ai;
�� assign������ si = 2 * ar * ai;
�� // Notes on code above:
�� //
�� // Multiplication has higher precedence
than subtraction and so
�� // subtraction done last.
�� //
�� // A constant is used in the si expression.
endmodule
////////////////////////////////////////////////////////////////////////////////
///
Operators: Logical AND, etc
//
:P: 6.4.2
//
There is a logical AND operator, &&, that is different than
//
the bitwise AND, &.
//
Likewise there is a logical OR, ||, and a logical NOT, !.
//
See the example.
//
:Example:
//
//
Illustration of logical operators, and how they are different than
//
the bitwise operators.
module
and_again_again(x1,x2,x3,x4,a,b);
�� input [2:0] a, b;�� // Both a and b are 3 bits.
�� output [2:0] x1;
�� output������ x2, x3, x4;
�� // Bitwise AND, but this time operands are
3-bit vectors.
�� //
�� assign x1 = a & b;� // ANDs three pairs of bits.
�� //
�� // The same thing the hard way:
�� //
�� assign x1[0] = a[0] & b[0];
�� assign x1[1] = a[1] & b[1];
�� assign x1[2] = a[2] & b[2];
�� //
�� // Examples:
�� //
�� // a���
b��� |� a & b
�� //
""""""""""""""""""
�� // 000�
000� |� 000
�� // 000�
001� |� 000
�� // 010�
111� |� 010
�� // 100�
110� |� 100
�� // Logical AND. (Not to be confused with
bitwise AND!)
�� //
�� assign x2 = a && b;
�� //
�� // Here both a and b are 3 bits, but x2 is
a single bit.
�� // Wire a is treated as logical true if any
bit is 1;
�� // it is treated as logical false if all
bits are 0.
�� //
�� // Therefore x2 is set to 1 if a and b are
true and to zero
�� // if a or b is false.
�� //
�� // Examples:
�� //
�� // a���
b��� |� a && b
�� //
""""""""""""""""""
�� // 000�
000� |� 0
�� // 000�
001� |� 0
�� // 010�
101� |� 1
�� // 100�
110� |� 1
�� // Logical OR. (Not to be confused with
bitwise OR.)
�� //
�� assign x3 = a || b;
�� //
�� // Operands are treated as logical values
as described for &&.
�� //
�� // Wire x3 is set to 1 if a or b is true
and to zero
�� // if a and b are false.
�� //
�� // Examples:
�� //
�� // a���
b��� |� a || b
�� //
""""""""""""""""""
�� // 000�
000� |� 0
�� // 000�
001� |� 1
�� // 010�
101� |� 1
�� // 100�
110� |� 1
�� // Logical NOT.
�� //
�� assign x4 = !a;
�� //
�� // Wire x4 is set to zero if any bit in a
is 1,
�� // x4 is set to one if all bits in a are
zero.
endmodule