Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Dataflow Modelling

Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

Dataflow modeling

• 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.
• 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 is very large, designers
can design more effectively if they concentrate on implementing the
function at a level of abstraction higher than gate level.
• Dataflow 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.
• Currently, automated tools are used to create a gate-level circuit from a
dataflow design description.
Continuous Assignments
• A continuous assignment is the most basic statement in dataflow
modeling
• Drive a value onto a net.
• This assignment replaces gates in the description of the circuit and
describes the circuit at a higher level of abstraction.
• The assignment statement starts with the keyword assign.
Continuous assignments 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 as soon as one of the right-hand-side
operands changes and the value is assigned to the left-hand-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.
• Delay values can be specified for assignments in terms of time units.
Delay values are used to control the time when a net is assigned the
evaluated value.
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;
VERILOG code for Half adder
module ha(a,b,s,c);
input a,b;
output s,c;
assign s = a^b;
assign c =a&b;

endmodule
VERILOG code for Half adder
module ha(a,b,s,c);
input a,b;
output s,c;
assign {c,s} = a+b;
endmodule
VERILOG code for Half adder
module ha(a,b,s,c);
input a,b;
output s,c;
assign #10 s = a^b;
assign #20 c = a&b;

endmodule
VERILOG code for mux (2to1)
module mux2to1(a, b, s, y);
input s,a,b;
output y;

assign y = (~s&a)|(s&b);

endmodule
VERILOG code for mux (2to1)
module mux2to1(a, b, s, y);
input s,a,b;
output y;
wire s1,s2,s3;

assign s1 = ~s;
assign s2 = s1&a;
assign s3 = s&b;
assign y = s2|s3;

endmodule
VERILOG code for mux (2to1)
module mux2to1(a, b, s, y);
input s,a,b;
output y;
wire s1,s2,s3;

assign s1 = ~s;
assign s2 = s1&a;
assign s3 = s&b;
assign #10 y = s2|s3;

endmodule
VERILOG code for mux (2to1)
module mux2to1(a, b, s, y);
input s,a,b;
output y;

assign y = s? b:a;
endmodule
Verilog code for binary to gray code
converter
module binarytogray(b,g);
input [2:0] b;
output [2:0] g;

assign g[2]= b[2];


assign g[1]= b[2] ^ b[1];
assign g[0]= b[1] ^ b[0];

endmodule
Verilog code for binary to gray code
converter module btogtb;
module binarytogray(b,g);
reg [2:0]b;
input [2:0] b; wire [2:0]g;
output [2:0] g; btog b1(b,g);

initial b=00;
assign g[2]= b[2]; always #5 b = b+1;
assign g[1:0]= b[2:1] ^ b[1:0]; initial
begin
$monitor ($time , " b=%b, g=%b", b,g);
endmodule #50 $finish;
end
endmodule
Stimulus
0 b=000, g=000
5 b=001, g=001
10 b=010, g=011
15 b=011, g=010
20 b=100, g=110
25 b=101, g=111
30 b=110, g=101
35 b=111, g=100
40 b=000, g=000
45 b=001, g=001
Verilog code for binary to gray code
converter
module binarytogray (b, g);
parameter n=2 ;

input [n:0] b;
output [n:0] g;

assign g[n]=b[n];
assign g[n-1:0]=b[n:1]^b[n-1:0];

endmodule
Verilog code for 4-bit Ripple carry adder
module rippleadder(a, b, cin, s, cout);
input [3:0] a;
input [3:0] b;
input cin;
output [3:0] s;
output cout;
wire [4:0]c;
assign c[0]=cin;
assign s[3:0]=a[3:0]^b[3:0]^c[3:0];
assign c[4:1]=(a[3:0]&b[3:0])|(c[3:0]&b[3:0])|(a[3:0]&c[3:0]);
assign cout=c[4];
endmodule
4-bit Ripple carry Adder
module fulladd4(sum, c_out, a, b, c_in);

output [3:0] sum;


output c_out;
input[3:0] a, b;
input c_in;

assign {c_out, sum} = a + b + c_in;


endmodule
Stimulus
module rcatb;
reg [3:0] a,b;
reg cin;
wire [3:0] s;
wire cout;
rca c1(a,b,cin,s,cout);
initial a=4'b0000;
always #5 a = a+1;
initial b=4'b1111;
always #5 b = b+1;
initial cin=0;
initial
begin
$monitor ($time , " a=%b, b=%b, cin = %b, s=%b, cout=%b ", a,b,cin,s,cout);
#100 $finish;
end
endmodule
0 a=0000, b=1111, cin = 0, s=1111, cout=0
5 a=0001, b=0000, cin = 0, s=0001, cout=0
10 a=0010, b=0001, cin = 0, s=0011, cout=0
15 a=0011, b=0010, cin = 0, s=0101, cout=0
20 a=0100, b=0011, cin = 0, s=0111, cout=0
25 a=0101, b=0100, cin = 0, s=1001, cout=0
30 a=0110, b=0101, cin = 0, s=1011, cout=0
35 a=0111, b=0110, cin = 0, s=1101, cout=0
40 a=1000, b=0111, cin = 0, s=1111, cout=0
45 a=1001, b=1000, cin = 0, s=0001, cout=1
50 a=1010, b=1001, cin = 0, s=0011, cout=1
55 a=1011, b=1010, cin = 0, s=0101, cout=1
60 a=1100, b=1011, cin = 0, s=0111, cout=1
65 a=1101, b=1100, cin = 0, s=1001, cout=1
70 a=1110, b=1101, cin = 0, s=1011, cout=1
75 a=1111, b=1110, cin = 0, s=1101, cout=1
80 a=0000, b=1111, cin = 0, s=1111, cout=0
module stimulus;
reg [3:0] A, B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
fulladd4 FA1_4(SUM, C_OUT, A, B, C_IN);
Initial
begin
$monitor($time," A= %b, B=%b, C_IN= %b, C_OUT= %b, SUM= %b\n," A, B, C_IN, C_OUT, SUM);
A = 4'd0; B = 4'd0; C_IN = 1'b0;
#5 A = 4'd3; B = 4'd4;
#5 A = 4'd2; B = 4'd5;
#5 A = 4'd9; B = 4'd9;
#5 A = 4'd10; B = 4'd15;
#5 A = 4'd10; B = 4'd5; C_IN = 1'b1;
end
endmodule
Verilog code for carrylookahead adder
module carrylookaheadadder(a, b, cin, s, cout);
input [3:0] a;
input [3:0] b;
input cin;
output [3:0] s;
output cout;
wire [3:0] p,g;
wire [4:0]c;
assign c[0]=cin;
assign p = a ^ b;
assign g = a &b;
assign s[3:0] = p[3:0]^c[3:0];
assign c[4:1]= (p[3:0]& c[3:0])|g[3:0];
assign cout=c[4];
endmodule
4-to-1 Multiplexer
Method 1: logic equation
module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);

output out;
input i0, i1, i2, i3;
input s1, s0;

assign out = (~s1 & ~s0 & i0)|


(~s1 & s0 & i1) |
(s1 & ~s0 & i2) |
(s1 & s0 & i3) ;
endmodule
Method 2: conditional operator
module multiplexer4_to_1 (out, i0, i1, i2, i3, s1, s0);

output out;
input i0, i1, i2, i3;
input s1, s0;

assign out = s1 ? ( s0 ? i3 : i2) : (s0 ? i1 : i0) ;


endmodule
full adder with carry lookahead
module fulladd4(sum, c_out, a, b, c_in);
output [3:0] sum;
output c_out;
input [3:0] a,b;
input c_in;
wire p0,g0, p1,g1, p2,g2, p3,g3;
wire c4, c3, c2, c1;
assign p0 = a[0] ^ b[0],
p1 = a[1] ^ b[1],
p2 = a[2] ^ b[2],
p3 = a[3] ^ b[3];
assign g0 = a[0] & b[0],
g1 = a[1] & b[1],
g2 = a[2] & b[2],
g3 = a[3] & b[3];
assign c1 = g0 | (p0 & c_in),
c2 = g1 | (p1 & g0) | (p1 & p0 & c_in),
c3 = g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c_in),
c4 = g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 & p2 & p1 & p0 & c_in);
assign sum[0] = p0 ^ c_in,
sum[1] = p1 ^ c1,
sum[2] = p2 ^ c2,
sum[3] = p3 ^ c3;
assign c_out = c4;
endmodule

You might also like