0% found this document useful (0 votes)
46 views

Dataflow Modelling

Dataflow modeling provides a powerful way to design circuits by describing the data flow between registers rather than instantiating individual gates. Continuous assignments are the basic statements in dataflow modeling and are used to drive values onto nets. This replaces gates and describes the circuit at a higher level of abstraction. Continuous assignments always evaluate as soon as an operand changes value and assign the result to the left-hand side net. Examples show continuous assignments for half adders, muxes, and binary to gray code converters in Verilog. Testbenches provide stimulus and monitor outputs to verify the designs.

Uploaded by

Mayur Nayaka
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views

Dataflow Modelling

Dataflow modeling provides a powerful way to design circuits by describing the data flow between registers rather than instantiating individual gates. Continuous assignments are the basic statements in dataflow modeling and are used to drive values onto nets. This replaces gates and describes the circuit at a higher level of abstraction. Continuous assignments always evaluate as soon as an operand changes value and assign the result to the left-hand side net. Examples show continuous assignments for half adders, muxes, and binary to gray code converters in Verilog. Testbenches provide stimulus and monitor outputs to verify the designs.

Uploaded by

Mayur Nayaka
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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