DataFlow Modeling in Verilog
DataFlow Modeling in Verilog
DataFlow Modeling in Verilog
Dated:
22nd August, 2016 to 26th August, 2016
Semester:
Autumn 2016
Continuous assignments have the following characteristics: The left hand side of an assignment must always be a scalar or vector net or a
concatenation of scalar and vector nets. It cannot be a scalar or vector register.
Continuous assignments are always active. The assignment expression is evaluated a
soon as one of the right-hand-side operands changes and the value is assigned to the lefthand-side net.
The operands on the right-hand side can be registers or nets or function calls. Registers or
nets can be scalars or vectors.
Examples of continuous assignments are shown below. Operators such as &, ^, |, {, } and + used
in the examples will be explained a little later. At this point, concentrate on how the assign
statements are specified.
Examples of Continuous Assignment:// Continuous assign. out is a net. i1 and i2 are nets.
assign out = i1 & i2;
// Continuous assign for vector nets. addr is a 16-bit vector
net addr1 and addr2 are 16-bit //vector registers.
assign addr[15:0] = addr1_bits[15:0] ^ addr2_bits[15:0];
// Concatenation. Left-hand side is a concatenation of a scalar
net and a vector net.
assign {c_out, sum[3:0]} = a[3:0] + b[3:0] + c_in;
Implicit Continuous Assignment:Instead of declaring a net and then writing a continuous assignment on the net, Verilog provides
a shortcut by which a continuous assignment can be placed on a net when it is declared. There
can be only one implicit declaration assignment per net because a net is declared only once.
In the example below, an implicit continuous assignment is contrasted with a regular continuous
assignment.
//Regular continuous assignment
wire out;
assign out = in1 & in2;
//Same effect is achieved by an implicit continuous assignment
wire out = in1 & in2;
Digital Logic Design
Session:-2k15 Computer
Implicit Net Declaration:If a signal name is used to the left of the continuous assignment, an implicit net declaration will
be inferred for that signal name. If the net is connected to a module port, the width of the inferred
net is equal to the width of the module port.
// Continuous assign. out is a net.
wire i1, i2;
assign out = i1 & i2; //Note that out was not declared as a wire
but an implicit wire declaration for out is done by the
simulator.
Let us take a closer look at expressions, operators, and operands that are used inside continuous
assignments.
Expressions, Operators, and Operands:Dataflow modeling describes the design in terms of expressions instead of primitive gates.
Expressions, operators, and operands form the basis of dataflow modeling.
Expressions:Expressions are constructs that combine operators and operands to produce a result.
// Examples of expressions. Combines operands and operators
a ^ b
addr1[20:17] + addr2[20:17]
in1 | in2
Operands:Operands can be any one of the data types defined. Some constructs will take only certain types
of operands. Operands can be constants, integers, real numbers, nets, registers, times, bit-select
(one bit of vector net or a vector register), part-select (selected bits of the vector net or register
vector), and memories or function calls (functions are discussed later).
integer count, final_count;
final_count = count + 1;//count is an integer operand
real a, b, c;
c = a - b; //a and b are real operands
Digital Logic Design
Session:-2k15 Computer
Operator Symbol
Arithmetic
Logical
Operation
Performed
multiply
Number of
Operands
two
divide
two
add
two
subtract
two
modulus
two
**
!
power (exponent)
logical negation
two
one
&&
logical and
two
||
logical or
two
Lab Instructor:-Engr. Aamir Arsalan
Relational
Equality
Bitwise
Reduction
Shift
>
greater than
two
<
less than
two
>=
two
<=
==
two
two
!=
inequality
two
===
case equality
two
!==
~
case inequality
bitwise negation
two
one
&
bitwise and
two
bitwise or
two
bitwise xor
two
^~ or ~^
&
bitwise xnor
reduction and
two
one
~&
reduction nand
one
reduction or
one
~|
reduction nor
one
reduction xor
one
^~ or ~^
>>
reduction xnor
Right shift
one
Two
<<
Left shift
Two
>>>
Two
<<<
Two
Concatenation
Replication
Conditional
{}
{{}}
?:
Concatenation
Replication
Conditional
Any Number
Any Number
Three
If any operand bit has a value x, then the result of the entire expression is x. This seems intuitive
because if an operand value is not known precisely, the result should be an unknown.
in1 = 4'b101x;
in2 = 4'b1010;
sum = in1 + in2; // sum will be evaluated to the value 4'bx
Modulus operators produce the remainder from the division of two numbers. They operate
similarly to the modulus operator in the C programming language.
13 % 3
16 % 4
-7 % 2
7 % -2
//
//
//
//
Evaluates
Evaluates
Evaluates
Evaluates
to
to
to
to
1
0
-1, takes sign of the first operand
+1, takes sign of the first operand.
Unary operators:The operators + and - can also work as unary operators. They are used to specify the positive or
negative sign of the operand. Unary + or operators have higher precedence than the binary + or
operators.
-4 // Negative 4
+5 // Positive 5
Negative numbers are represented as 2's complement internally in Verilog. It is advisable to use
negative numbers only of the type integer or real in expressions. Designers should avoid negative
numbers of the type <sss> '<base> <nnn> in expressions because they are converted to unsigned
2's complement numbers and hence yield unexpected results.
//Advisable to use integer or real numbers
-10 / 5// Evaluates to -2
//Do not use numbers of type <sss> '<base> <nnn>
-'d10 / 5// is equivalent (2's complement of 10)/5 = (232 - 10)/5
// where 32 is the default machine word width.
// This evaluates to an incorrect and unexpected result.
Logical Operators:Logical operators are logical-and (&&), logical-or (||) and logical-not (!). Operators && and ||
are binary operators. Operator ! is a unary operator. Logical operators follow these conditions:
1. Logical operators always evaluate to a 1-bit value, 0 (false), 1 (true), or x (ambiguous).
2. If an operand is not equal to zero, it is equivalent to a logical 1 (true condition). If it is
01equal to zero, it is equivalent to a logical 0 (false condition). If any operand bit is x or
z, it is equivalent to x (ambiguous condition) and is normally treated by simulators as a
false condition.
3. Logical operators take variables or expressions as operands.
Use of parentheses to group logical operations is highly recommended to improve readability.
Also, the user does not have to remember the precedence of operators.
// Logical operations
A = 3; B = 0;
A && B // Evaluates to 0. Equivalent to (logical-1 && logical-0)
A || B // Evaluates to 1. Equivalent to (logical-1 || logical-0)
!A// Evaluates to 0. Equivalent to not(logical-1)
Digital Logic Design
Session:-2k15 Computer
Equality Operators:Equality operators are logical equality (==), logical inequality (!=), case equality (===), and case
inequality (!==). When used in an expression, equality operators return logical value 1 if true, 0
if false. These operators compare the two operands bit by bit, with zero filling if the operands are
of unequal length. Table below lists the operators.
It is important to note the difference between the logical equality operators (==, !=) and case
equality operators (===, !==). The logical equality operators (==, !=) will yield an x if either
operand has x or z in its bits. However, the case equality operators ( ===, !== ) compare both
operands bit by bit and compare all bits, including x and z. The result is 1 if the operands match
exactly, including x and z bits. The result is 0 if the operands do not match exactly. Case equality
operators never result in an x.
// A = 4, B = 3
// X = 4'b1010, Y = 4'b1101
// Z = 4'b1xxz, M = 4'b1xxz, N = 4'b1xxx
A == B // Results in logical 0
X != Y // Results in logical 1
X == Z // Results in x
Z === M // Results in logical 1 (all bits match, including x and
z)
Z === N // Results in logical 0 (least significant bit does not
match)
M !== N // Results in logical 1.
Bitwise Operators:Bitwise operators are negation (~), and(&), or (|), xor (^), xnor (^~, ~^). Bitwise operators
perform a bit-by-bit operation on two operands. They take each bit in one operand and perform
the operation with the corresponding bit in the other operand. If one operand is shorter than the
other, it will be bit-extended with zeros to match the length of the longer operand. Logic tables
for the bit-by-bit computation are shown in Table below. A z is treated as an x in a bitwise
operation. The exception is the unary negation operator (~), which takes only one operand and
operates on the bits of the single operand.
Examples of bitwise operators are shown below.
// X = 4'b1010, Y = 4'b1101
// Z = 4'b10x1
~X
X & Y
X | Y
X ^ Y
X ^~ Y
//
//
//
//
//
X & Z
// Result is 4'b10x0
It is important to distinguish bitwise operators ~, &, and | from logical operators !, &&, ||.
Logical operators always yield a logical value 0, 1, x, whereas bitwise operators yield a bit-by-bit
value. Logical operators perform a logical operation, not a bit-by-bit operation.
// X = 4'b1010, Y = 4'b0000
X | Y // bitwise operation. Result is 4'b1010
X || Y // logical operation. Equivalent to 1 || 0. Result is 1.
Reduction Operators:Reduction operators are and (&), nand (~&), or (|), nor (~|), xor (^), and xnor (~^, ^~). Reduction
operators take only one operand. Reduction operators perform a bitwise operation on a single
vector operand and yield a 1-bit result. The logic tables for the operators are the same as shown
Digital Logic Design
Session:-2k15 Computer
above. The difference is that bitwise operations are on bits from two different operands, whereas
reduction operations are on the bits of the same operand. Reduction operators work bit by bit
from right to left. Reduction nand, reduction nor, and reduction xnor are computed by inverting
the result of the reduction and, reduction or, and reduction xor, respectively.
// X = 4'b1010
&X //Equivalent to 1 & 0 & 1 & 0. Results in 1'b0
|X//Equivalent to 1 | 0 | 1 | 0. Results in 1'b1
^X//Equivalent to 1 ^ 0 ^ 1 ^ 0. Results in 1'b0
//A reduction xor or xnor can be used for even or odd parity
//generation of a vector.
The use of a similar set of symbols for logical (!, &&, ||), bitwise (~, &, |, ^), and reduction
operators (&, |, ^) is somewhat confusing initially. The difference lies in the number of operands
each operator takes and also the value of results computed.
Shift Operators:Shift operators are right shift ( >>), left shift (<<), arithmetic right shift (>>>), and arithmetic left
shift (<<<). Regular shift operators shift a vector operand to the right or the left by a specified
number of bits. The operands are the vector and the number of bits to shift. When the bits are
shifted, the vacant bit positions are filled with zeros. Shift operations do not wrap around.
Arithmetic shift operators use the context of the expression to determine the value with which to
fill the vacated bits.
// X = 4'b1100
Y = X >> 1; //Y is 4'b0110. Shift right 1 bit. 0 filled in MSB
position.
Y = X << 1; //Y is 4'b1000. Shift left 1 bit. 0 filled in LSB
position.
Y = X << 2; //Y is 4'b0000. Shift left 2 bits.
integer a, b, c; //Signed data types
a = 0;
b = -10; // 00111...10110 binary
c = a + (b >>> 3); //Results in -2 decimal, due to arithmetic
shift
Shift operators are useful because they allow the designer to model shift operations, shift-andadd algorithms for multiplication, and other useful operations.
Digital Logic Design
Session:-2k15 Computer
Concatenation Operator:The concatenation operator ( {, } ) provides a mechanism to append multiple operands. The
operands must be sized. Unsized operands are not allowed because the size of each operand must
be known for computation of the size of the result.
Concatenations are expressed as operands within braces, with commas separating the operands.
Operands can be scalar nets or registers, vector nets or registers, bit-select, part-select, or sized
constants.
// A = 1'b1, B = 2'b00, C = 2'b10, D = 3'b110
Y = {B , C} // Result Y is 4'b0010
Y = {A , B , C , D , 3'b001} // Result Y is 11'b10010110001
Y = {A , B[0], C[1]} // Result Y is 3'b101
Replication Operator:Repetitive concatenation of the same number can be expressed by using a replication constant. A
replication constant specifies how many times to replicate the number inside the brackets ( { } ).
reg
reg
reg
A =
A;
[1:0] B, C;
[2:0] D;
1'b1; B = 2'b00; C = 2'b10; D = 3'b110;
Examples:A design can be represented in terms of gates, data flow, or a behavioral description. In this
section, we consider the 4-to-1 multiplexer and 4-bit full adder using data flow modeling and
compare it to gate level modeling.
Logic Diagram of a multiplexer is given below:-
Verilog Description using Gate level Modeling:// Module 4-to-1 multiplexer. Port list is taken exactly from
// the I/O diagram.
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
// Internal wire declarations
wire s1n, s0n;
wire y0, y1, y2, y3;
// Gate instantiations
// Create s1n and s0n signals.
not (s1n, s1);
not (s0n, s0);
// 3-input and gates instantiated
and (y0, i0, s1n, s0n);
and (y1, i1, s1n, s0);
and (y2, i2, s1, s0n);
and (y3, i3, s1, s0);
// 4-input or gate instantiated
or (out, y0, y1, y2, y3);
endmodule
We describe the multiplexer, using dataflow statements. Compare it with the gate-level
description. We show two methods to model the multiplexer by using dataflow statements.
Verilog Description using Dataflow level Modeling:Method 1: Logic Equation:-
We can use assignment statements instead of gates to model the logic equations of the
multiplexer. Notice that everything is same as the gate-level Verilog description except that
computation of out is done by specifying one logic equation by using operators instead of
individual gate instantiations. I/O ports remain the same. This is important so that the interface
with the environment does not change. Only the internals of the module change. Notice how
concise the description is compared to the gate-level description.
// Module 4-to-1 multiplexer using data flow using logic equation:// Compare to gate-level model
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
//Logic equation for out
assign out =
(~s1 & ~s0 & i0)|
(~s1 & s0 & i1) |
(s1 & ~s0 & i2) |
(s1 & s0 & i3) ;
endmodule
Method 2: Conditional Operator:There is a more concise way to specify the 4-to-1 multiplexers. In Conditional Operator section,
we described how a conditional statement corresponds to a multiplexer operation. We will use
this operator to write a 4-to-1 multiplexer.
4-to-1 Multiplexer, Using Conditional Operators:// Module 4-to-1 multiplexer using data flow. Conditional
operator.
// Compare to gate-level model
module multiplexer4_to_1 (out, i0, i1, i2, i3, s1, s0);
// Port declarations from the I/O diagram
output out;
input i0, i1, i2, i3;
input s1, s0;
// Use nested conditional operator
assign out = s1 ? ( s0 ? i3 : i2) : (s0 ? i1 : i0) ;
Digital Logic Design
Session:-2k15 Computer
endmodule
4-bit Full Adder:The logic diagrams of one bit and 4 bit full adder is shown below.
endmodule
Verilog Description for 4-bit Ripple Carry Full Adder:// Define a 4-bit full adder
module fulladd4(sum, c_out, a, b, c_in);
// I/O port declarations
output [3:0] sum;
output c_out;
input[3:0] a, b;
input c_in;
// Internal nets
wire c1, c2, c3;
// Instantiate four
fulladd fa0(sum[0],
fulladd fa1(sum[1],
fulladd fa2(sum[2],
fulladd fa3(sum[3],
endmodule
4-bit Full Adder, Using Dataflow Operators:module fulladd4(sum, c_out, a, b, c_in);
// Inputs and outputs
output [3:0] sum;
output c_out;
input [3:0] a,b;
input c_in;
// Internal wires
wire p0,g0, p1,g1, p2,g2, p3,g3;
wire c4, c3, c2, c1;
Digital Logic Design
Session:-2k15 Computer
// compute the p
assign p0 = a[0]
p1 = a[1]
p2 = a[2]
p3 = a[3]
// compute the g
assign g0 = a[0]
g1 = a[1]
g2 = a[2]
g3 = a[3]
& c_in),
& g0) | (p2 & p1 & p0 &
& g1) | (p3 & p2 & p1 &
p2 & p1 & p0 & c_in);
description
of
the
module