设计一个10层楼的电梯控制器模块,要求:(1) 以按键的时间先后优先级进行设计;(2) 以楼层最短位置先后优先级进行设计。
电梯运行规则:
当电梯处在上升模式时,只响应比电梯所在位置高的上楼请求,由下向上逐个执行,直到最后一个上楼请求执行完毕。如果高层有下楼请求,直接升到有下楼请求的最高楼层,然后进入下降模式。下降模式类似。
定义每层楼的状态,可扩展至任意楼层。
UP(IN):XXXXXXXXXX(10~1楼;1有效,0无效),上楼请求
DOWN(IN):XXXXXXXXXX(10~1楼;1有效,0无效),下楼请求
其中1层只能有上楼请求,10层只能有下楼请求,同一层不能既有上楼请求又有下楼请求。上楼或下楼请求被响应后对应位清零。
BUTTON(IN):XXXXXXXXXX(10~1楼;1有效,0无效),要去往的楼层
到达要去往的楼层后对应位清零。
POSITION(OUT):XXXX(当前楼层)
FLOOR:XXXXXXXXXX(10~1楼;1有效,0无效),电梯需要停下并开关门的楼层
电梯处在上升模式时,FLOOR=UP|BUTTON;电梯处在下降模式时,FLOOR=DOWN|BUTTON。
UP_DOWN:X(0上升模式,1下降模式)
状态图
仿真流程图
Design Block:
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230module elevator (CLK,RESET,UP,DOWN,BUTTON,POSITION); input CLK,RESET; input [10:1] UP,DOWN,BUTTON; output reg [3:0] POSITION; reg [3:0] P; reg [10:1] FLOOR; reg UP_DOWN; reg tmp,flag; integer temp; reg [8:0] CurrentState,NextState; parameter S0=9'b000000001,S1=9'b000000010,S2=9'b000000100,S3=9'b000001000,S4=9'b000010000,S5=9'b000100000,S6=9'b001000000,S7=9'b010000000,S8=9'b100000000; always @ (posedge CLK or negedge RESET) begin if(~RESET) CurrentState<=S0; else CurrentState<=NextState; end always @ (RESET or CurrentState or UP_DOWN or UP or DOWN or BUTTON or P or flag) begin if(~RESET) begin UP_DOWN=0; FLOOR=10'b0; P=4'b0001; flag=0; end else begin if(flag==0) FLOOR=UP_DOWN?DOWN|BUTTON:UP|BUTTON; case(CurrentState) S0: begin POSITION=P; if(FLOOR==10'b0) NextState=S0; else begin if(UP_DOWN==0) begin if(P==4'b1010) UP_DOWN=1; else begin case(P) 4'b0001: tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0010: tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0011: tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0100: tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0101: tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0110: tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0111: tmp=FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b1000: tmp=FLOOR[9] | FLOOR[10]; 4'b1001: tmp=FLOOR[10]; endcase if(tmp==0) begin FLOOR=DOWN|BUTTON; case(P) 4'b0001: tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0010: tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0011: tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0100: tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0101: tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0110: tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b0111: tmp=FLOOR[8] | FLOOR[9] | FLOOR[10]; 4'b1000: tmp=FLOOR[9] | FLOOR[10]; 4'b1001: tmp=FLOOR[10]; endcase if(tmp==0) UP_DOWN=1; else begin flag=1; UP_DOWN=0; end end end end else begin if(P==4'b0001) UP_DOWN=0; else begin case(P) 4'b1010: tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b1001: tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b1000: tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0111: tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0110: tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0101: tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0100: tmp=FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0011: tmp=FLOOR[2] | FLOOR[1]; 4'b0010: tmp=FLOOR[1]; endcase if(tmp==0) begin FLOOR=UP|BUTTON; case(P) 4'b1010: tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b1001: tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b1000: tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0111: tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0110: tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0101: tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0100: tmp=FLOOR[3] | FLOOR[2] | FLOOR[1]; 4'b0011: tmp=FLOOR[2] | FLOOR[1]; 4'b0010: tmp=FLOOR[1]; endcase if(tmp==0) UP_DOWN=0; else begin flag=1; UP_DOWN=1; end end end end NextState=S1; end end S1: NextState=S2; S2: NextState=S3; S3: NextState=S4; S4: begin if(UP_DOWN==0) NextState=S5; else NextState=S6; end S5: begin if(FLOOR==10'b0) NextState=S0; else begin P=P+1'b1; if(flag==1) begin: B1 integer i; temp=0; for(i=10;i>0 && temp==0;i=i-1) if(FLOOR[i]==1) temp=i; if(P==temp) begin flag=0; UP_DOWN=1; NextState=S0; end else NextState=S7; end else begin if(FLOOR[P]) NextState=S0; else NextState=S7; end end end S6: begin if(FLOOR==10'b0) NextState=S0; else begin P=P-1'b1; if(flag==1) begin: B2 integer i; temp=0; for(i=1;i<11 && temp==0;i=i+1) if(FLOOR[i]==1) temp=i; if(P==temp) begin flag=0; UP_DOWN=0; NextState=S0; end else NextState=S8; end else begin if(FLOOR[P]) NextState=S0; else NextState=S8; end end end S7: NextState=S5; S8: NextState=S6; endcase end end endmodule
Test Bench:
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`timescale 1ns/1ns module Test_elevator; reg CLK,RESET; reg [10:1] UP,DOWN,BUTTON; wire [3:0] POSITION; elevator U0(CLK,RESET,UP,DOWN,BUTTON,POSITION); always begin CLK=1'b0; #5 CLK=1'b1; #5; end initial begin RESET=1'b0; #10 RESET=1'b1; #790 $stop; end initial begin UP=10'b0; #10 UP=10'b0000010001; #40 UP=10'b0000010000; #160 UP=10'b0; end initial begin DOWN=10'b0; #210 DOWN=10'b1100000000; #180 DOWN=10'b0100000000; #60 DOWN=10'b0; #120 DOWN=10'b0000100000; #40 DOWN=10'b0; end initial begin BUTTON=10'b0; #10 BUTTON=10'b0000001000; #140 BUTTON=10'b0; #20 BUTTON=10'b0010000000; #140 BUTTON=10'b0; #40 BUTTON=10'b0000100000; #200 BUTTON=10'b0; #20 BUTTON=10'b0000000001; #180 BUTTON=10'b0; end endmodule
仿真波形图:
总结
这个题目去年做过,今年回过头来看有了一些新的思考。相比之前在每层楼增加了上下楼请求按钮(UP、DOWN),在电梯里增加了要去往的楼层按键(BUTTON),将FLOOR变成中间变量,表示电梯需要停下并开关门的楼层。整个系统功能完善了许多,也更具备实用性。
最后
以上就是靓丽康乃馨最近收集整理的关于Verilog HDL设计——电梯控制器模块的全部内容,更多相关Verilog内容请搜索靠谱客的其他文章。
发表评论 取消回复