-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEE445_HW1_2030393.v
198 lines (186 loc) · 5.23 KB
/
EE445_HW1_2030393.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
module EE445_HW1_2030393(RST,CLK,PASSWD,PADOUT,DAV,OK,LOCKED,G,R,Y);
input RST;
input CLK;
input PASSWD;
input [3:0]PADOUT; //Output of the keypad
input DAV;
input OK;
reg[15:0]INPUT; //Register to store the input
reg[15:0]CURRENT; //Current password
reg[2:0]SHIFTC; //Counter to keep track of shifts
reg[2:0]INNUM; //Number of inputs after last OK
output reg LOCKED;
reg[15:0]PREV1;
reg[15:0]PREV2;
reg[15:0]PREV3;
reg[31:0]LEDC; //Counter to keep track of LED toggle times
output reg G;
output reg R;
output reg Y;
reg [2:0]STATE;
reg B_DAV; //Buffer for DAV
parameter S_PassEnter= 3'd0;
parameter S_Unlocked = 3'd1;
parameter S_Wrong = 3'd2;
parameter S_Shift = 3'd3;
parameter S_NewPass = 3'd4;
parameter S_Shift2 = 3'd5;
always @(negedge RST or posedge CLK) begin
if (!RST) begin //Asynchronous reset
STATE <= S_PassEnter;
INPUT <= 0;
INNUM <= 0;
SHIFTC <= 0;
CURRENT <= 16'h1234;
G <= 0;
R <= 0;
Y <= 1;
LEDC <= 0;
LOCKED <= 0;
PREV1 <= 16'h1234;
PREV2 <= 16'h1234;
PREV3 <= 16'h1234;
STATE <= S_PassEnter;
B_DAV <= 0;
end else begin
B_DAV <= DAV; //Buffer DAV to be able to check for changes
case (STATE)
S_PassEnter: begin
if(OK) begin
if(INNUM == 3'd4) begin
if(!PASSWD) begin //Pasword is assumed to be active low
if(INPUT==CURRENT) begin
Y <= 0;
INNUM <= 0;
INPUT <= 0;
STATE <= S_NewPass; //If OK is pressed while PASSWD is on and the password is correct go to new password state
end else begin
LEDC <= 0;
INNUM <= 0;
INPUT <= 0;
STATE <= S_PassEnter; //If the password is incorrect go back to pass enter to try again
end
end else begin
if(INPUT==CURRENT) begin //If PASSWD is off and password is correct go to unlocked state and light green LED
LOCKED <= 1;
G <= 1;
Y <= 0;
STATE <= S_Unlocked;
end else begin //If the pasword is incorrect go to wrong state and light red LED
R <= 1;
Y <= 0;
STATE <= S_Wrong;
end
end
end else begin //If less than 4 inputs are taken ignore them and clear.
INNUM <= 0;
INPUT <= 0;
STATE <= S_PassEnter;
end
end else begin
if ((B_DAV != DAV) && (DAV == 1)) begin //If OK is not pressed wait until DAV goes from 0 to 1
if(INNUM == 3'd4) begin //Ignore inputs after 4th
STATE <= S_PassEnter;
end else begin //Store the input if less than 4 inputs are taken then increment INNUM
INPUT[3:0] <= PADOUT;
STATE <= S_Shift;
INNUM <= INNUM + 1'b1;
end
end else begin
STATE <= S_PassEnter;
end
end
end
S_Unlocked: begin
if (LEDC >= 32'd5000000) begin //Light the green led 5s and then turn it off when returning back to PassEnter.
LOCKED<= 0; //Lock the door again after 5 seconds
STATE <= S_PassEnter;
INNUM <= 0;
INPUT <= 0;
G <= 0;
Y <= 1;
end else begin
LEDC <= LEDC + 1 ;
STATE <= S_Unlocked;
end
end
S_Wrong: begin
if (LEDC >= 32'd3000000) begin //Light the green led 5s and then turn it off when returning back to PassEnter.
STATE <= S_PassEnter;
INNUM <= 0;
INPUT <= 0;
R <= 0;
Y <= 1;
end else begin
LEDC <= LEDC + 1 ;
STATE <= S_Wrong;
end
end
S_Shift: begin
if ((SHIFTC==4) || (INNUM == 4)) begin//Shift the INPUT 4 times to make space for the next input. If 4th input came don't shift since it is in place
SHIFTC<= 0;
STATE <= S_PassEnter;
end else begin
INPUT = INPUT << 1;
SHIFTC<= SHIFTC + 1'b1;
STATE <= S_Shift;
end
end
S_NewPass: begin
if (LEDC >= 32'd500000) begin //Turn the lod on and of every 0.5 seconds
Y <= ~Y;
LEDC <= 0;
end else begin
LEDC <= LEDC + 1 ;
if (OK) begin //If OK is pressed and there are 4 inputs store the new passwords and shift the old ones.
if(INNUM == 3'd4) begin
if ((INPUT==PREV1)||(INPUT==PREV2)||(INPUT==PREV3)) begin
STATE <= S_NewPass;
INNUM <= 0;
end else begin
CURRENT <= INPUT;
PREV1 <= CURRENT;
PREV2 <= PREV1;
PREV3 <= PREV2;
INNUM <= 0;
INPUT <= 0;
STATE <= S_PassEnter;
LEDC <= 0;
Y <= 1;
end
end else begin
INNUM <= 0;
STATE <= S_NewPass;
end
end else begin
if ((B_DAV != DAV) && (DAV == 1)) begin //This part is the same as PassEnter state. It recieves the new password input
if(INNUM == 3'd4) begin
STATE <= S_NewPass;
end else begin
INPUT[3:0] <= PADOUT;
STATE <= S_Shift2;
INNUM <= INNUM + 1'b1;
end
end else begin
STATE <= S_NewPass;
end
end
end
end
S_Shift2: begin
if ((SHIFTC==4) || (INNUM == 4)) begin //Works the same as Shift but goes to different states.
SHIFTC<= 0;
STATE <= S_NewPass;
end else begin
INPUT = INPUT << 1;
SHIFTC<= SHIFTC + 1'b1;
STATE <= S_Shift2;
end
end
default : begin
STATE <= S_PassEnter;
end
endcase
end
end
endmodule