You are on page 1of 30

Verilog Modules

for Common
Digital Functions

Full Adder (Dataflow Description)


//
// Here is a data flow description of a full_adder
//
module fa(sum, co, a, b, ci) ;
output sum, co ;
input a, b, ci ;
assign sum = a ^ b ^ ci ;
assign co = (a & b) | ((a | b) & ci) ;
endmodule

Full Adder (Behvioral Description)

// 1-bit full-adder (behavioral)


module fa(sum, co, a, b, ci) ;
input a, b, ci ;
output co, sum ;
assign {co, sum} = a + b + ci ;
endmodule

Full Adder Testbench


// testbench for fa cell

module fa_tb ;
reg a, b, ci ;
reg [3:0] i ;
wire sum, co ;
fa

u0(sum, co, a, b, ci) ;

initial begin
$monitor($time, " a is %b, b is %b, ci is %b, sum is %b, co is %b\n",
a, b, ci, sum , co) ;
for (i=0; i < 8; i=i+1) #10 {a, b, ci} = i ;
end
endmodule

Adder (4-bit) Structural Description


// Module to implement a 4-bit adder
// Structural description using fa module
module

adder4(sum, co, a, b, ci) ;


output
[3:0] sum ;
output
co ;
input
[3:0] a ;
input
[3:0] b ;
input
ci ;
wire
[3:1] c ;
fa
fa
fa
fa

endmodule

g0(sum[0],
g1(sum[1],
g2(sum[2],
g3(sum[3],

c[1], a[0], b[0], ci) ;


c[2], a[1], b[1], c[1]) ;
c[3], a[2], b[2], c[2]) ;
co, a[3], b[3], c[3]) ;

2-1 Multiplexer
// 2-1 MUX
// This is a behavioral description.
module mux2to1(out, sel, in) ;
input sel ;
output out ;
input [1:0] in ;
reg out ;
always @(sel or in) begin
if (sel == 1) out = in[1] ;
else out = in[0] ;
end
endmodule

// This is a dataflow description


module mux2to1(out, sel, in) ;
input sel ;
output out ;
input [1:0] in ;

assign out = sel ? in[1] : in[0] ;


endmodule

2-1 Multiplexer (Case Statement)


// 2-1 MUX
// This is a behavioral description.
module mux2to1(out, sel, in) ;
input sel ;
output out ;
input [1:0] in ;
reg out ;
always @(sel or in) begin
case (sel)
0: out = in[0] ;
1: out = in[1] ;
endcase
end
endmodule

//
//
//
//

3-8 Decoder
3-8 decoder with an enable input
This is a behavioral description.

module decoder(out, en, a) ;


output
input
input

[7:0] out ;
[2:0] a ;
en ;

reg

[7:0] out ;

always @(a or en) begin


out = 8'd0 ;
case(a)
3'd0 : out = 8'd1 ;
3'd1 : out = 8'd2 ;
3'd2 : out = 8'd4 ;
3'd3 : out = 8'd8 ;
3'd4 : out = 8'd16 ;
3'd5 : out = 8'd32 ;
3'd6 : out = 8'd64 ;
3'd7 : out = 8'd128 ;
default: $display("The unthinkable has happened.\n") ;
endcase
if (!en) out = 8'd0 ;
end
endmodule

3-8 Decoder Testbench


// Test bench for 3-8 decoder
module decoder_tb ;
reg
reg
reg
wire

[2:0] a ;
en ;
[3:0] i ;
[7:0] out ;

// Instantiate the 3-8 decoder


decoder

uut(out, en, a);

// Exhaustively test it
initial begin
$monitor($time, " en is %b, a is %b, out is %b\n",en, a, out) ;
#10 begin
en = 0 ;
for (i=0; i < 8; i=i+1) #10
a = i ;
end
#10 begin
en = 1 ;
for (i=0; i < 8; i=i+1) begin #10
a = i ;
end
end
endmodule

Digital Magnitude Comparator


// 4-bit magnitude comparator
// This is a behavioral description.
module magcomp(AltB, AgtB, AeqB, A, B) ;
input [3:0] A, B ;
output AltB, AgtB, AeqB ;
assign AltB = (A < B) ;
assign AgtB = (A > B) ;
assign AeqB = (A = B) ;

endmodule

D-Latch
/*
Verilog description of a negative-level senstive D latch
with preset (active low)
*/
module dlatch(q, clock, preset, d) ;
output q ;
input clock, d, preset ;
reg
q;
always @(clock or d or preset) begin
if (!preset) q = 1 ;
else if (!clock) q = d ;
end
endmodule

D Flip Flop
// Negative edge-triggered D FF with sync clear
module D_FF(q, d, clr, clk) ;
output q ;
input d, clr, clk ;
reg
q;
always @ (negedge clk) begin
if (clr)
q <= 1'b0 ;
else
q <= d ;
end
endmodule

D Flip Flop Testbench


// Testbench for D flip flop
module test_dff ;
wire
reg

q ;
d, clr, clk ;

D_FF

u0(q, d, clr, clk) ;

initial begin
clk = 1'b1 ;
forever #5 clk = ~clk ;
end
initial fork
#0 begin
clr = 1'b1 ;
d = 1'b0 ;
end
#20 begin
d = 1'b0 ;
clr=1'b0 ;
end
#30 d = 1'b1 ;

#50 d = 1'b0 ;
join
initial begin
$monitor($time, "clr=%b, d=%b,q=%b", clr, d, q) ;
end
endmodule

4-bit D Register with Parallel Load


//
// 4-bit D register with parallel load
//
module dreg_pld(Dout, Din, ld, clk) ;
input [3:0] Din ;
input ld, clk ;
output [3:0] Dout ;
reg
[3:0] Dout ;
always @(posedge clk) begin
if (ld) Dout <= Din ;
else Dout <= Dout ;
end

endmodule

1-Bit Counter Cell


// 1 bit counter module
module cnt1bit(q, tout, tin, clr, clk) ;
output q ;
output tout ;
input tin ;
input clr ;
input clk ;
reg
q;
assign tout = tin & q ;
always @ (posedge clk) begin
if (clr == 1'b1)
q <= 0 ;
else if (tin == 1'b1)
q <= ~q ;
end
endmodule

2-Bit Counter
// 2-bit counter
module cnt2bit(cnt, tout, encnt, clr, clk) ;
output [1:0] cnt ;
output tout ;
input encnt ;
input clr ;
input clk ;
wire ttemp ;
cnt1bit u0(cnt[0], ttemp, encnt, clr, clk) ;
cnt1bit u1(cnt[1], tout, ttemp, clr, clk) ;
endmodule

74161 Operation

4-bit Synchronous Counter (74LS161)


// 4-bit counter
module counter_4bit(clk, nclr, nload, ent, enp, rco, count, parallel_in) ;
input
input
input
input
input
output
output
input

clk ;
nclr ;
nload ;
ent ;
enp ;
rco ;
[3:0] count ;
[3:0] parallel_in ;

reg
reg

[3:0] count ;
rco ;

always @ (count or ent)


if ((count == 15) && (ent == 1'b1))
rco = 1'b1 ;
else
rco = 1'b0 ;
always @ (posedge clk or negedge nclr)
begin
if (nclr == 1'b0)
count <= 4'd0 ;
else if (nload == 1'b0)
count <= parallel_in ;
else if ((ent == 1'b1) && (enp == 1'b1))
count <= (count + 1) % 16 ;
end
endmodule

T Flip-flops
// T type flip-flop built from D flip-flop and inverter
module t_ff(q, clk, reset) ;
output
input
wire
d_ff
not

q;
clk, reset ;
d;

dff0(q, d, clk, reset) ;


not0(d, q) ;

endmodule

Ripple Counter
/*
*/

This is an asynchronout ripple carry counter.


It is 4-bits wide.

module ripple_carry_counter(q, clk, reset) ;


output [3:0] q ;
input clk, reset ;
t_ff
t_ff
t_ff
t_ff

tff0(q[0],
tff1(q[1],
tff2(q[2],
tff3(q[3],

endmodule

clk, reset) ;
q[0], reset) ;
q[1], reset) ;
q[2], reset) ;

Up/Down Counter
// 4-bit up/down counter
module up_dwn(cnt, up, clk, nclr) ;
output [3:0] cnt ;
input up, clk, nclr ;
reg
[3:0] cnt ;

always @(posedge clk) begin


if (~nclr) cnt <= 0 ;
else if (up) cnt <= cnt + 1 ;
else cnt <= cnt - 1 ;
end
endmodule

Shift Register
// 4 bit shift register
`define WID 3
module serial_shift_reg(sout, pout, sin, clk) ;
output sout ;
output [`WID:0] pout ;
input sin, clk ;
reg
[`WID:0] pout ;
always @(posedge clk) begin
pout <= {sin, pout[`WID:1]} ;
end

assign sout = pout[0] ;


endmodule

Universal Shift Register


// 4 bit universal shift register
module universal(pout, pin, sinr, sinl, s1, s0, clk) ;
output [3:0] pout ;
input sinl, sinr, clk, s1, s0 ;
input [3:0] pin ;
reg
[3:0] pout ;
always @(posedge clk) begin
case ({s1,s0})
0: pout <= pout ;
1: pout <= {pout[2:0], sinl} ;
2: pout <= {sinr, pout[3:1]} ;
3: pout <= pin ;
endcase
end
endmodule

Mealy FSM

Inputs

Outputs
COMBINATIONAL
LOGIC

Current State
Registers
Q

CLK

Next state

DRAM Controller
// Example of a Mealy machine for a DRAM controller
module mealy(clk, cs, refresh, ras, cas, ready) ;
input
clk, cs, refresh ;
output
ras, cas, ready ;
parameter

s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4 ;

reg [2:0] present_state, next_state ;


reg
ras, cas, ready ;
// state register process
always @ (posedge clk)
begin
present_state <= next_state ;
end

DRAM Controller (part 2)


// state transition process
always @ (present_state or refresh or cs)
begin
case (present_state)
next_state = s0 ;
ras = 1'bX ;
cas = 1'bX ;
ready = 1'bX ;
s0 : begin
if (refresh)
begin
next_state =
ras = 1'b1 ;
cas = 1'b0 ;
ready = 1'b0
end
else if (cs)
begin
next_state =
ras = 1'b0 ;
cas = 1'b1 ;
ready = 1'b0
end
else
begin
next_state =
ras = 1'b1 ;
cas = 1'b1 ;
ready = 1'b1
end
end

s3 ;

s1 ;

s0 ;

DRAM Controller (part 3)


s1 : begin
next_state = s2 ;
ras = 1'b0 ;
cas = 1'b0 ;
ready = 1'b0 ;
end
s2 : begin
if (~cs)
begin
next_state =
ras = 1'b1 ;
cas = 1'b1 ;
ready = 1'b1
end
else
begin
next_state =
ras = 1'b0 ;
cas = 1'b0 ;
ready = 1'b0
end
end
s3 : begin
next_state = s4 ;
ras = 1'b1 ;
cas = 1'b0 ;
ready = 1'b0 ;
end
s4 : begin
next_state = s0 ;
ras = 1'b0 ;
cas = 1'b0 ;
ready = 1'b0 ;
end
endcase
end
endmodule

s0 ;

s2 ;

1-bit ALU Module


// 1-bit alu like the one in Mano text (ECE580)
module alui(aci,
output
input
input
input
reg

clk, control, acip1, acim1, dri) ;


aci ;
clk ;
[2:0] control ;
acip1, acim1, dri ;
aci ;

parameter nop = 3'b000, com = 3'b001, shr = 3'b010,


shl = 3'b011, dr = 3'b100, clr = 3'b101,
and_it = 3'b110 ;
always @ (posedge clk) begin
case (control)
nop: aci <= aci ;
com: aci <= ~aci ;
shr: aci <= acip1 ;
shl: aci <= acim1 ;
dr:
aci <= dri ;
clr: aci <= 0 ;
and_it: aci <= aci & dri ;
default: aci <= aci ;
endcase
end
endmodule

Modeling Memory
// memory model, bidir data bus
module memory(data, addr, ce, rw) ;
inout [7:0] data ;
input ce, rw ;
input [5:0] addr ;
reg
reg
tri
wire

[7:0] mem[0:63] ;
[7:0] data_out ;
[7:0] data ;
tri_en ;

always @(ce or addr or rw or data) begin


if (~ce)
if (rw)
data_out = mem[addr] ;
else
mem[addr] = data ;
end
assign tri_en = ~ce & rw ;
assign data = tri_en ? data_out : 8'bz ;
endmodule

Binary to BCD
//
// We need to convert a 5-bit binary number
// to 2 BCD digits
//
module bin2bcd(bcd1, bcd0, bin) ;

output
output
input

[3:0] bcd1 ;
[3:0] bcd0 ;
[4:0] bin ;

reg
reg
reg
integer

[3:0] bcd1 ;
[3:0] bcd0 ;
[7:0] bcd ;
i ;

always @ (bin) begin


bcd1 = 4'd0 ;
bcd0 = 4'd0 ;
for (i=0; i < 5; i= i + 1) begin
if (bcd0 >= 4'd5) bcd0 = bcd0 + 4'd3 ;
if (bcd1 >= 4'd5) bcd1 = bcd1 + 4'd3 ;
bcd = {bcd1, bcd0} ;
bcd = bcd << 1 ;
bcd[0] = bin[4-i] ;
bcd1 = bcd[7:4] ;
bcd0 = bcd[3:0] ;
end
end
endmodule

You might also like