0% found this document useful (0 votes)
55 views17 pages

Lock

This document describes a Verilog implementation of an electronic combination lock. It includes modules for a keyboard scanner (kb_scan) that detects key presses and encodes the key value, and a validator (validate) that checks if the entered combination is correct. The kb_scan module uses a finite state machine to sequentially scan the rows and columns of a keyboard matrix to detect pressed keys. The validate module uses counters, comparators and state machine to check the entered combination against the correct code and drive a 7-segment display. A testbench is provided to simulate entering a sample key combination.

Uploaded by

Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views17 pages

Lock

This document describes a Verilog implementation of an electronic combination lock. It includes modules for a keyboard scanner (kb_scan) that detects key presses and encodes the key value, and a validator (validate) that checks if the entered combination is correct. The kb_scan module uses a finite state machine to sequentially scan the rows and columns of a keyboard matrix to detect pressed keys. The validate module uses counters, comparators and state machine to check the entered combination against the correct code and drive a 7-segment display. A testbench is provided to simulate entering a sample key combination.

Uploaded by

Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 17

Verilog

Descriptions of
Digital Systems

Electronic Lock
//
// Electronic combinational lock
//
module lock(seg7,key, valid_key, col, row, mclk, resetL) ;
output
[0:6] seg7;
output
[0:3] col ;
output
[3:0] key ;
output
valid_key ;
input
resetL ,mclk ;
input
[0:3] row ;
wire

clk ;

// Divide master clock down to 100 Hz


// clock_divider u0(clk, mclk, resetL) ;
assign clk = mclk ;
// Keyboard scan
// When valid_key goes active, the key register contains last key entered
kb_scan

u1(key, valid_key, col, row, clk, resetL) ;

// Has someone entered a valid combination?


// User interface is a seven segment display
validate
endmodule

u2(seg7, key, valid_key, clk, resetL) ;

Keyboard Scanner Module

Kb_scan
//
// Module to scan matrix keyboard
// FSM to scan the keyboard
//
module kb_scan(key, valid_key, col, row, clk, resetL) ;
output
output
output
input
input

[3:0] key ;
valid_key ;
[0:3] col ;
[0:3] row ;
clk, resetL ;

reg
reg
reg
reg
reg

[0:3] row_reg;
[2:0] nstate, pstate ;
valid, valid_key ;
[3:0] key, key_code ;
[0:3] col ;

wire

kd ;

parameter

st_0 = 3'd0, st_1 = 3'd1, st_2 = 3'd2,


st_3 = 3'd3, st_4 = 3'd4, st_5 = 3'd5,
st_6 = 3'd6 ;

// synchronize row info with the clock


always @(negedge clk or negedge resetL) begin
if (~resetL) row_reg <= 4'b0000 ;
else row_reg <= row ;
end

Kb_scan (Continued)
// if any key is down, the kd signal will be high
assign

kd = | row_reg ;

// state register process for FSM


always @(negedge clk or negedge resetL) begin
if (~resetL) pstate <= st_0 ;
else pstate <= nstate ;
end
// state transition and output process
always @(kd or pstate) begin
valid = 0 ;
col = 4'b1111 ;
case (pstate)
st_0: if (~kd) nstate = st_0 ;
else begin
nstate = st_1 ;
col = 4'b1000 ;
end
st_1:

if (~kd) begin
nstate = st_2
col = 4'b0100
end
else begin
nstate = st_5
col = 4'b1000
valid = 1 ;
end

;
;
;
;

Kb_scan (Continued, more)


st_2:

st_3:

if (~kd) begin
nstate = st_3
col = 4'b0010
end
else begin
nstate = st_5
col = 4'b0100
valid = 1 ;
end
if (~kd) begin
nstate = st_4
col = 4'b0001
end
else begin
nstate = st_5
col = 4'b0010
valid = 1 ;
end

;
;

;
;
;
;

st_4:

if (~kd) nstate = st_0 ;


else begin
nstate = st_5 ;
col = 4'b0001 ;
valid = 1 ;
end

st_5:

if (kd) nstate = st_5 ;


else nstate = st_0 ;

default: nstate = st_0 ;


endcase
end

;
;

Kb_scan (Continued, even more)


// Encode key using row and col info
always @(row_reg or col) begin
casex ({row_reg, col})
8'b1xxx_1000 : key_code = 4'b0001
8'b1xxx_0100 : key_code = 4'b0010
8'b1xxx_0010 : key_code = 4'b0011
8'b1xxx_0001 : key_code = 4'b1010
8'b01xx_1000 : key_code = 4'b0100
8'b01xx_0100 : key_code = 4'b0101
8'b01xx_0010 : key_code = 4'b0110
8'b01xx_0001 : key_code = 4'b1011
8'b001x_1000 : key_code = 4'b0111
8'b001x_0100 : key_code = 4'b1000
8'b001x_0010 : key_code = 4'b1001
8'b001x_0001 : key_code = 4'b1100
8'b0001_1000 : key_code = 4'b1110
8'b0001_0100 : key_code = 4'b0000
8'b0001_0010 : key_code = 4'b1111
8'b0001_0001 : key_code = 4'b1101
default: key_code = 4'd0 ;
endcase
end

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

// Register the key_code


always @(posedge clk or negedge resetL) begin
if (~resetL) key <= 4'b0000;
else if (valid) key <= key_code ;
end
// Delay valid_key signal
always @(negedge clk or negedge resetL) begin
if (~resetL) valid_key <= 0 ;
else valid_key <= valid ;
end

Validate Module

Validate
//
// Module to validate entry code being entered
//
module validate(seg7, key, valid_key, clk, resetL) ;
output
[0:6] seg7 ;
input
valid_key, resetL, clk ;
input
[3:0] key ;
wire

pound_sign, Z, AeqB, EQ ;

reg
reg
reg
reg
reg
reg
reg

eqQ ;
[1:0]
[0:6]
[1:0]
[2:0]
[3:0]
[0:6]

pstate, nstate ;
seg7 ;
digit_sel ;
cnt ;
B ;
display_reg_inp ;

// control signals for data path


reg
reg

init, dec_cnt, ld_eq, ld_display ;


[1:0] display_sel ;

// some useful constants


parameter

st_0 = 2'b00, st_1 = 2'b01,


st_2 = 2'b10, st_3 = 2'b11 ;

Validate (Continued)
parameter

two = 4'b0010, zero = 4'b0000,


eight = 4'b1000, one = 4'b0001 ;

parameter

blank = 7'b0000000 ,
open = 7'b1110111 ,
error = 7'b1101101 ;

// generate pound_sign present signal


assign

pound_sign = (key == 4'b1111) ;

// mux stored digits in combination to be checked


always @(digit_sel) begin
case (digit_sel)
2'b00 : B = one ;
2'b01 : B = eight ;
2'b10 : B = zero ;
2'b11 : B = two ;
endcase
end
// Magnitude comparator
assign

AeqB = (key == B) ;

Validate (Continued, more)


// Equality checker
assign

EQ = AeqB & eqQ ;

always @(posedge clk or negedge resetL) begin


if (~resetL) eqQ <= 1 ;
else if (init) eqQ <= 1 ;
else if (ld_eq) eqQ <= EQ ;
end
// seven segment display MUX and register
always @(display_sel) begin
case (display_sel)
2'b00 : display_reg_inp
2'b01 : display_reg_inp
2'b10 : display_reg_inp
default: display_reg_inp
endcase
end

=
=
=
=

blank ;
open ;
error ;
blank ;

always @(posedge clk or negedge resetL) begin


if (~resetL) seg7 <= blank ;
else if (ld_display) seg7 <= display_reg_inp ;
end
// 3-bit counter and terminal count output
always @(negedge resetL or posedge clk) begin
if (~resetL) cnt <= 4 ;
else if (dec_cnt) cnt <= cnt - 1 ;
else if (init) cnt <= 4 ;
end
assign

Z = (cnt == 3'b000) ;

Validate (Continued, even more)


// Create digit select from cnt output
always @(cnt) begin
case (cnt)
4 : digit_sel = 2'b00 ;
3 : digit_sel = 2'b01 ;
2 : digit_sel = 2'b10 ;
1 : digit_sel = 2'b11 ;
default: digit_sel = 2'b00 ;
endcase
end
// state register process for FSM
always @(negedge clk or negedge resetL) begin
if (~resetL) pstate <= st_0 ;
else pstate <= nstate ;
end
// state transition process for FSM
always @(pstate or valid_key) begin
init = 0 ;
ld_eq = 0 ;
dec_cnt = 0 ;
ld_display = 0 ;
display_sel = 0 ;
case (pstate)
st_0 : begin
nstate = st_1 ;
ld_display = 1 ;
init = 1 ;
end

Validate (Continued, one more)


st_1 :

begin
if (Z) begin
nstate = st_3 ;
ld_display = 1 ;
if (eqQ) display_sel = 1 ;
else display_sel = 2 ;
end
else begin
if (valid_key) begin
ld_eq = 1 ;
nstate = st_2 ;
end
else nstate = st_1 ;
end
end

st_2 :

begin
nstate = st_1 ;
dec_cnt = 1 ;
end

st_3 :

if (pound_sign) nstate = st_0 ;


else nstate = st_3 ;
default: nstate = st_0 ;
endcase
end
endmodule

Lock Testbench
//
// Testbench for electronic combinational lock
//
`timescale
1 ms / 1 us
module lock_tb ;
wire
wire
wire

[0:6] seg7 ;
[0:3] col ;
[3:0] key ;

reg
reg
reg

[0:3] row ;
mclk ;
resetL ;

// Instantiate the lock


lock

uut(seg7, key, valid_key, col, row, mclk, resetL) ;

// Clock generator
// Clock period is 10 msec
initial begin
mclk = 1 ;
forever #10 mclk = ~mclk ;
end

Lock Testbench (Continued)


// Apply test vectors
initial begin
#0
begin
resetL = 0 ;
row = 4'b0000 ;
end
#10

resetL = 1 ;

// key stroke is (row #, col #)


// 1st key stroke (1,1) = "1"
#200
wait(col == 4'b1111) row = 4'b1000 ;
wait(col == 4'b1000) row = 4'b1000 ;

#200

row = 4'b0000 ;

// 2nd key stroke (3,2) = "8"


#200
wait(col == 4'b1111) row = 4'b0010 ;
wait(col == 4'b1000) row = 4'b0000 ;
wait(col == 4'b0100) row = 4'b0010 ;
#200

row = 4'b0000 ;

Lock Testbench (Continued, more)


// 3rd key stroke (4,2) = "0"
#200
wait(col == 4'b1111) row = 4'b0001 ;
wait(col == 4'b1000) row = 4'b0000 ;
wait(col == 4'b0100) row = 4'b0001 ;
#200

row = 4'b0000 ;

// 4th key stroke (1,2) = "2"


#200
wait(col == 4'b1111) row = 4'b1000 ;
wait(col == 4'b1000) row = 4'b0000 ;
wait(col == 4'b0100) row = 4'b1000 ;
#200

row = 4'b0000 ;

// 5th key stroke (4,3) = "#"


#200
wait(col
wait(col
wait(col
wait(col
#200

==
==
==
==

row = 4'b0000 ;

4'b1111)
4'b1000)
4'b0100)
4'b0010)

row
row
row
row

=
=
=
=

4'b0001
4'b0000
4'b0000
4'b0001

;
;
;
;

Lock Testbench (Continued, even more)


// Log signal info
//
//
//
//
//

initial begin
$dumpfile("./lock.dmp") ;
$dumpflush ;
$dumpvars(3, lock_tb) ;
end

// Print out key code whenver valid_key goes active


always @(posedge valid_key) begin
$strobe("Key is %b and seg7 is %b", key, seg7) ;
end
endmodule

You might also like