hdl3 - faculty.cs.tamu.edu

Verilog
CPSC 321 Computer Architecture
Andreas Klappenecker
Demux Example
2-to-4 demultiplexer with active low
enable
a
b
z[3] z[2] z[1] z[0]
0
x
x
1
1
1
1
1
0
0
1
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
1
1
1
0
1
1
1
Demux: Structural Model
// 2-to-4 demultiplexer
module demux1(z,a,b,enable);
input a,b,enable;
output [3:0] z;
wire abar,bbar;
enable
a
b
0
x
x
1
1
1
1
1
0
0
1
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
1
1
1
0
1
1
1
not v0(abar,a), v1(bbar,b);
nand (z[0],enable,abar,bbar);
nand (z[1],enable,a,bbar);
nand (z[2],enable,abar,b);
nand (z[3],enable,a,b);
endmodule
z[3] z[2]
z[1] z[0]
Demux: Dataflow model
enable
a
b
0
x
x
z[3] z[2]
// 2-to-4 demux
1
0
0
// dataflow model module
1
1
0
1
0
1
demux2(z,a,b,enable);
1
1
1
input a,b,enable;
output [3:0] z;
assign z[0] = | {~enable,a,b};
assign z[1] = ~(enable & a & ~b);
assign z[2] = ~(enable & ~a & b);
assign z[3] = enable ? ~(a & b) : 1'b1;
endmodule
z[1] z[0]
1
1
1
1
1
1
1
0
1
1
0
1
1
0
1
1
0
1
1
1
Demux: Behavioral Model
// 2-to-4 demultiplexer with active-low outputs
module demux3(z,a,b,enable);
input a,b,enable;
output [3:0] z;
reg z; // not really a register!
always @(a or b or enable)
case ({enable,a,b})
enable
a
b
z[3] z[2] z[1] z[0]
default: z = 4'b1111;
0
x
x
1
1
1
1
3'b100: z = 4'b1110;
1
0
0
1
1
1
0
3'b110: z = 4'b1101;
1
1
0
1
1
0
1
3'b101: z = 4'b1011;
1
0
1
1
0
1
1
3'b111: z = 4'b0111;
1
1
1
0
1
1
1
endcase
endmodule
Always Blocks

The sensitivity list @( … ) contains the
events triggering an evaluation of the
block




@(a or b or c)
@(posedge a)
@(negedge b)
A Verilog compiler evaluates the
statements in the always block in the
order in which they are written
Assignments

If a variable is assigned a value in a
blocking assignment
a = b & c;
then subsequent references to a contain
the new value of a
 Non-blocking assignments <=
assigns the value that the variables had
while entering the always block
D Flip-flop
module D_FF(Q,D,clock);
output Q;
input D, clock;
reg Q;
D
D
C
C
always @(negedge clock)
D
Q <= D;
C
endmodule
Q
D
latch
Q
D
Q
D
latch _
C
Q
Q
_
Q
Clock

A sequential circuit will need a clock


supplied by the testbed
Clock code fragment
reg clock;
parameter period = 100;
initial clock 0;
always @(period/2)
clock = ~clock;
D-Flipflop with Synchronous Reset
module flipflop(D, Clock, Resetn, Q);
input D, Clock, Resetn;
output Q;
reg Q;
always @(posedge Clock)
if (!Resetn)
Q <= 0;
else
Q <= D;
endmodule // 7.46 in [BV]
Gated D-Latch
module latch(D, clk, Q)
input D, clk;
output Q;
reg Q;
C
Q
_
Q
D
always @(D or clk)
if (clk)
Q <= D;
endmodule
Missing else clause => a latch will be
synthesized to keep value of Q when clk=0
D
C
Q
Shift register
D
Clock
D Q
Q
Q1
D Q
Q
Positive edge triggered
D flip-flops
Q2
time
t0
t1
t2
t3
t4
t5
t6
t7
D
1
0
0
1
1
1
0
0
Q1
0
1
0
0
1
1
1
0
Q2
0
0
1
0
0
1
1
1
What is wrong here?
module example(D,Clock, Q1, Q2)
input D, Clock;
output Q1, Q2;
reg Q1, Q2;
always @(posedge Clock)
begin
Q1 = D;
Q2 = Q1; // D=Q1=Q2
end
endmodule
Shift register: Correct Version
module example(D,Clock, Q1, Q2)
input D, Clock;
output Q1, Q2;
reg Q1, Q2;
always @(posedge Clock)
begin
Q1 <= D;
Q2 <= Q1;
end
endmodule
Rule of Thumb


Blocking assignments are used to
describe combinatorial circuits
Non-blocking assignments are used in
sequential circuits
n-bit Ripple Carry Adder
module ripple(cin, X, Y,
S, cout);
parameter n = 4;
input cin;
input [n-1:0] X, Y;
output [n-1:0] S;
output cout;
reg [n-1:0] S;
reg [n:0] C;
reg cout;
integer k;
always @(X or Y or cin)
begin
C[0] = cin;
for(k = 0; k <= n-1; k=k+1)
begin
S[k] = X[k]^Y[k]^C[k];
C[k+1] = (X[k] & Y[k])
|(C[k]&X[k])|(C[k]&Y[k]);
end
cout = C[n];
end
endmodule
Loops and Integers



The for loop is used to instantiate
hardware modules
The integer k simply keeps track of
instantiated hardware
Do not confuse integers with reg
variables
Bit-Counter



Count the number of bits having value 1
in register X
Again an example for parameters
Another example of a for loop
Bit Counter
module bit_cnt(X,Count);
parameter n = 4;
parameter logn = 2;
input [n-1:0] X;
output [logn:0] Count;
reg [logn:0] Count;
integer k;
always @(X)
begin
Count = 0;
for(k=0;k<n;k= k+1)
Count=Count+X[k];
end
endmodule