Title: Verilog Descriptions of Digital Systems
1Verilog Descriptions of Digital Systems
2Electronic Lock
// // Electronic combinational lock // module
lock(seg7,key, valid_key, col, row, mclk, resetL)
output 06 seg7 output 03 col
output 30 key output valid_key
input resetL ,mclk input 03
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
u2(seg7, key, valid_key, clk, resetL)
endmodule
3Keyboard Scanner Module
4Kb_scan
// // Module to scan matrix keyboard // FSM to
scan the keyboard // module kb_scan(key,
valid_key, col, row, clk, resetL) output
30 key output valid_key
output 03 col input 03 row
input clk, resetL reg
03 row_reg reg 20 nstate,
pstate reg valid, valid_key reg
30 key, key_code reg
03 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 _at_(negedge clk or
negedge resetL) begin if (resetL) row_reg
lt 4'b0000 else row_reg lt row end
5Kb_scan (Continued)
// if any key is down, the kd signal will be high
assign kd row_reg // state register
process for FSM always _at_(negedge clk or
negedge resetL) begin if (resetL) pstate
lt st_0 else pstate lt nstate
end // state transition and output process
always _at_(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
6Kb_scan (Continued, more)
st_2 if (kd) begin
nstate st_3 col
4'b0010 end
else begin nstate st_5
col 4'b0100
valid 1 end
st_3 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
7Kb_scan (Continued, even more)
// Encode key using row and col info always
_at_(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
_at_(posedge clk or negedge resetL) begin if
(resetL) key lt 4'b0000 else if (valid)
key lt key_code end // Delay valid_key
signal always _at_(negedge clk or negedge
resetL) begin if (resetL) valid_key lt 0
else valid_key lt valid end
8Validate Module
9Validate
// // Module to validate entry code being
entered // module validate(seg7, key, valid_key,
clk, resetL) output 06 seg7 input
valid_key, resetL, clk input 30
key wire pound_sign, Z, AeqB, EQ
reg eqQ reg 10 pstate, nstate
reg 06 seg7 reg 10
digit_sel reg 20 cnt reg
30 B reg 06 display_reg_inp
// control signals for data path reg
init, dec_cnt, ld_eq, ld_display reg
10 display_sel // some useful constants
parameter st_0 2'b00, st_1 2'b01,
st_2 2'b10, st_3 2'b11
10Validate (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 _at_(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)
11Validate (Continued, more)
// Equality checker assign EQ AeqB
eqQ always _at_(posedge clk or negedge resetL)
begin if (resetL) eqQ lt 1 else if
(init) eqQ lt 1 else if (ld_eq) eqQ lt EQ
end // seven segment display MUX and
register always _at_(display_sel) begin
case (display_sel) 2'b00
display_reg_inp blank 2'b01
display_reg_inp open 2'b10
display_reg_inp error default
display_reg_inp blank endcase end
always _at_(posedge clk or negedge resetL) begin
if (resetL) seg7 lt blank else if
(ld_display) seg7 lt display_reg_inp end
// 3-bit counter and terminal count output
always _at_(negedge resetL or posedge clk) begin
if (resetL) cnt lt 4 else if
(dec_cnt) cnt lt cnt - 1 else if (init)
cnt lt 4 end assign Z (cnt 3'b000)
12Validate (Continued, even more)
// Create digit select from cnt output
always _at_(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
_at_(negedge clk or negedge resetL) begin if
(resetL) pstate lt st_0 else pstate lt
nstate end // state transition process for
FSM always _at_(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
13Validate (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
14Lock Testbench
// // Testbench for electronic combinational
lock // timescale 1 ms / 1 us module lock_tb
wire 06 seg7 wire 03 col
wire 30 key reg 03 row
reg mclk reg 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
15Lock 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
16Lock 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 4'b1111) row 4'b0001
wait(col 4'b1000) row 4'b0000
wait(col 4'b0100) row
4'b0000 wait(col 4'b0010)
row 4'b0001 200
row 4'b0000
17Lock 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 _at_(posedge valid_key) begin
strobe("Key is b and seg7 is b", key, seg7)
end endmodule