Dataflow Modeling
Dataflow Modeling
Introduction
For small circuits, the gate level modeling approach works very well because the
number of gates is limited and the designer can instantiate and connect every gate
individually. Also gate level modeling is very intuitive to a designer with a basic
knowledge of digital logic design. However, in complex designs the number of gates
id very large. Thus designers can design more effectively if they concentrate on
implementing the function at a level 0f abstraction higher than gate level. Data flow
modeling provides a powerful way to implement a design.
Verilog allows a circuit to be designed in-terms of the data flow between registers and
how a design processes data rather than instantiation of individual gates.
Continuous Assignments
A continuous assignment is the most basic statement in dataflow
modeling, used to drive a value onto a net. A continuous assignment
replaces gates in the description of the circuit and descrbes the circuit at a
higher leel of abstraction.
A continuous assignment statement starts with the keyword assign. The
syntax of an assign statement is as follows.
// syntax of assign statement in the simplest form
<continuous_assign>
::= assign <drive_strength>?<delay>? <list_of_assignments>;
Notice that drive strength is optional and can be specified in terms of
strength levels. Value set. We will not discuss drive strength specification
here, we will discuss later. The default value for drive strength is strong1
and strong0. The delay value is also optional and can be used to specify
delay on the assign statement.
Continuous assignments have the following characteristics.
1. 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.
2. Continuous assignments are always active the assignment
expression is evaluated as soon as one of the right hand side
operands changes and the value is assigned to the left hand side
net.
3. The operands on the right hand side can be register or nets or
function calls. Registers or nets can be scalars or vectors.
4. Delay values can be specified for assignments I terms of time units.
Delay values are used to control the time when a net is assigned the
evaluated value. This feature is similar to specifying dealys for
gates. It is very useful in modeling timing behavior in real circuits.
Examples:
In the above example out is undeclared, but verilog makes an implicit net declaration
for out.
wire out;
assign out = in0 ^ in1;
Delays
Delay values control the time between the change in a right side operand and when
the new value is assigned to the left hand side. Three ways of specifying delays in
continuous statements are regular assignment delay, implicit continuous assignment
delay, and net declaration delay.
If there is any change in the operands in the RHS, then RHS expression will be
evaluated after 10 units of time. Lets say that at time t, if there is change in one of the
operands in the above example, then the expression is calculated at t+10 units of time.
The value of RHS operands present at time t+10 is used to evaluate the expression.
is same as
wire out;
assign 10 out = in0 ^ in1;
is same as
wire out;
assign #10 out = in;
Examples
output out[0:3];
input in0, in1;
endmodule
output out;
input in0, in1, in2, in3;
input s0, s1;
assign out = (~s0 & ~s1 & in0)|(s0 & ~s1 & in1)|
(~s0 & s1 & in2)|(s0 & s1 & in0);
endmodule
output out;
input [7:0] in;
input [2:0] sel;
endmodule
endmodule
Modeling//NOT gate
module notgate(a,y);
input a;
output y;
assign y= ~a;
endmodule
//OR gate
module orgate(a,b,y);
inpput a,b;
output y;
assign y=(a|b)
;endmodule
//AND gate
module andgate(a,b,y);
input a,b;
output y;
assign y=(a&b);
endmodule
//NOR gate
module norgate(a,b,y);
inpput a,b;
output y;
assign y=~(a|b);
endmodule
//NAND gate
module nandgate(a,b,y);
input a,b;
output y;
assign y=~(a&b);
endmodule
//XOR gate
module xorgate(a,b,y);
input a,b;
output y;
assign y=(a^b);
endmodule
Operands
Some constructs will take only certain types of operands. Operands can be
constants, integers, real numbers, nets, registers, times, biit-select.
Verilog operators
* multiply arithmetic
/ divide arithmetic
% modulus arithmetic
+ binary plus arithmetic
- binary minus arithmetic
<< shift left shift
>> shift right shift
> greater than relational
>= greater than or equal relational
< to relational
<= less than relational
less than or equal to
== case equality equality
!= case inequality equality
& bit-wise AND bit-wise
^ bit-wise XOR bit-wise
| bit-wise OR bit-wise
&& logical AND logical
|| logical OR logical
?: Conditional Conditional
1. Arithmetic
input [2:0] A, B;
output [3:0] Y1;
output [4:0] Y3;
output [2:0] Y2, Y4, Y5;
reg [3:0] Y1;
reg [4:0] Y3;
reg [2:0] Y2, Y4, Y5;
always @(A or B)
begin
Y1=A+B;//addition
Y2=A-B;//subtraction
Y3=A*B;//multiplication
Y4=A/B;//division
Y5=A%B;//modulus of A divided by B
end
endmodule
2. Sign
input [2:0] A, B;
output [3:0] Y1, Y2, Y3;
reg [3:0] Y1, Y2, Y3;
always @(A or B)
begin
Y1=+A/-B;
Y2=-A+-B;
Y3=A*-B;
end
endmodule
3. Relational
always @(A or B)
begin
Y1=A<B;//less than
Y2=A<=B;//less than or equal to
Y3=A>B;//greater than
if (A>B)
Y4=1;
else
Y4=0;
end
endmodule
4. Equality and inequality
Equality and inequality operators are used in exactly the same way
as relational operators and return a true or false indication depending on
whether any two operands are equivalent or not.
5. Logical
input [6:0] A;
input [5:0] B;
output [6:0] Y;
reg [6:0] Y;
always @(A or B)
begin
Y(0)=A(0)&B(0); //binary AND
Y(1)=A(1)|B(1); //binary OR
Y(2)=!(A(2)&B(2)); //negated AND
Y(3)=!(A(3)|B(3)); //negated OR
Y(4)=A(4)^B(4); //binary XOR
Y(5)=A(5)~^B(5); //binary XNOR
Y(6)=!A(6); //unary negation
end
endmodule
7. Shift
Shift operators require two operands. The operand before the operator
contains data to be shifted and the operand after the operator contains the
number of single bit shift operations to be performed. 0 is being used to
fill the blank positions.
module Shift (A, Y1, Y2);
input [7:0] A;
output [7:0] Y1, Y2;
parameter B=3; reg [7:0] Y1, Y2;
always @(A)
begin
Y1=A<<B; //logical shift left
Y2=A>>B; //logical shift right
end
endmodule
8. Concatenation and Replication
input [2:0] A, B;
output [14:0] Y;
parameter C=3'b011;
reg [14:0] Y;
always @(A or B)
begin
Y={A, B, (2{C}}, 3'b110};
end
endmodule
9. Reduction
input [3:0] A;
output Y1, Y2, Y3, Y4, Y5, Y6;
reg Y1, Y2, Y3, Y4, Y5, Y6;
always @(A)
begin
Y1=&A; //reduction AND
Y2=|A; //reduction OR
Y3=~&A; //reduction NAND
Y4=~|A; //reduction NOR
Y5=^A; //reduction XOR
Y6=~^A; //reduction XNOR
end
endmodule
10. Conditional
always @(Time)
begin
Y=(Time!=TimeOut) ? Time +1 : Zero;
end
endmodule
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.
Y = {B , C} // Result Y is 4'b0010
Y = {A , B , C , D , 3'b001} // Result Y is 11'b10010110001
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 A;
reg [1:0] B, C;
reg [2:0] D;