Verilog Modules For Common Digital Functions

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
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 g0(sum[0], c[1], a[0], b[0], ci) ;


fa g1(sum[1], c[2], a[1], b[1], c[1]) ;
fa g2(sum[2], c[3], a[2], b[2], c[2]) ;
fa g3(sum[3], co, a[3], b[3], c[3]) ;

endmodule
2-1 Multiplexer

// 2-1 MUX
// This is a dataflow description
// This is a behavioral description.
module mux2to1(out, sel, in) ;
module mux2to1(out, sel, in) ;
input sel ;
input sel ;
output out ;
output out ;
input [1:0] in ;
input [1:0] in ;
reg out ;
assign out = sel ? in[1] : in[0] ;
always @(sel or in) begin
endmodule
if (sel == 1) out = in[1] ;
else out = in[0] ;
end
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 [7:0] out ;


input [2:0] a ;
input 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 [2:0] a ;
reg en ;
reg [3:0] i ;
wire [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 q ;
reg 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 clk ;
input nclr ;
input nload ;
input ent ;
input enp ;
output rco ;
output [3:0] count ;
input [3:0] parallel_in ;

reg [3:0] count ;


reg 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 q;
input clk, reset ;
wire d;

d_ff dff0(q, d, clk, reset) ;


not 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 tff0(q[0], clk, reset) ;


t_ff tff1(q[1], q[0], reset) ;
t_ff tff2(q[2], q[1], reset) ;
t_ff tff3(q[3], q[2], reset) ;

endmodule
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
Next state
Registers
Q D

CLK
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 = s3 ;
ras = 1'b1 ;
cas = 1'b0 ;
ready = 1'b0 ;
end
else if (cs)
begin
next_state = s1 ;
ras = 1'b0 ;
cas = 1'b1 ;
ready = 1'b0 ;
end
else
begin
next_state = s0 ;
ras = 1'b1 ;
cas = 1'b1 ;
ready = 1'b1 ;
end
end
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 = s0 ;
ras = 1'b1 ;
cas = 1'b1 ;
ready = 1'b1 ;
end
else
begin
next_state = s2 ;
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
1-bit ALU Module
// 1-bit alu like the one in Mano text (ECE580)

module alui(aci, clk, control, acip1, acim1, dri) ;


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

reg 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 [7:0] mem[0:63] ;


reg [7:0] data_out ;

tri [7:0] data ;

wire 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 [3:0] bcd1 ;


output [3:0] bcd0 ;
input [4:0] bin ;

reg [3:0] bcd1 ;


reg [3:0] bcd0 ;
reg [7:0] bcd ;
integer 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