source: vis_dev/vis-2.1/examples/elevator/elevator.v @ 12

Last change on this file since 12 was 11, checked in by cecile, 13 years ago

Add vis

File size: 7.9 KB
Line 
1`define elev 2
2`define floor 3
3`define width 2
4typedef enum {UP,DOWN} dir;
5typedef enum {STOPPED,MOVING} mov;
6typedef enum {OPEN,OPENING,CLOSED,CLOSING} dr;
7typedef enum {ON,OFF} onoff;
8
9//*********************************************** 
10module main(clk);
11input clk;
12wire[1:`elev] stop_next;
13wire[1:`elev] inc;
14wire[1:`elev] dec;
15wire[1:`elev] continue;
16wire[0:`width-1] init1, init2, init11, init22;
17
18assign init11=$ND(0,1,2,3);
19assign init22=$ND(0,1,2,3);
20assign init1 = init11==3?2:init11;
21assign init2 = init22==3?2:init22;
22
23elevator e1(clk,stop_next[1],inc[1],dec[1],continue[1],init1);
24elevator e2(clk,stop_next[2],inc[2],dec[2],continue[2],init2);
25main_control main_control(clk,inc,dec,stop_next,continue,init1,init2);
26endmodule
27//*********************************************** 
28
29//************************************************
30module main_control(clk,inc,dec,stop_next,continue,init1,init2);
31input clk,inc,dec,init1,init2;
32output stop_next,continue;
33wire[1:`elev] inc;
34wire[1:`elev] continue;
35wire[1:`elev] dec;
36wire[1:`elev] stop_next;
37reg [0:`width-1] locations[1:`elev];
38onoff reg up_floor_buttons[0:`floor-1];
39onoff reg down_floor_buttons[0:`floor-1];
40wire[0:`floor-1] random_up;
41wire[0:`width-1] init1,init2;
42wire[0:`floor-1] random_down;
43wire[0:`floor-1] buttons;
44wire[1:`elev] button_above,button_below;
45dir reg direction[1:`elev];
46initial begin
47         locations[1]=init1;
48         locations[2]=init2;
49         up_floor_buttons[0]=OFF;
50         up_floor_buttons[1]=OFF;
51         up_floor_buttons[2]=OFF;
52         down_floor_buttons[0]=OFF;
53         down_floor_buttons[1]=OFF;
54         down_floor_buttons[2]=OFF;
55         direction[1]=UP;
56         direction[2]=UP;
57end
58
59//compute if elevator should continue in same direction. We skip the next floor assuming
60// that the stop_next computation will take care of this.
61assign buttons[0] = up_floor_buttons[0]==ON || down_floor_buttons[0]==ON;
62assign buttons[1] = up_floor_buttons[1]==ON || down_floor_buttons[1]==ON;
63assign buttons[2] = up_floor_buttons[2]==ON || down_floor_buttons[2]==ON;
64assign button_below[1] = 
65        ((locations[1]==2)&&(buttons[0]||buttons[1]))
66        || (locations[1]==1 && buttons[0]);
67assign button_above[1] = ((locations[1]==0)&&(buttons[2]||buttons[1]))
68        || ((locations[1]==1)&&(buttons[2]));
69assign button_below[2] = 
70        ((locations[2]==2)&&(buttons[0]||buttons[1]))
71        || (locations[2]==1 && buttons[0]);
72assign button_above[2] = ((locations[2]==0)&&(buttons[2]||buttons[1]))
73        || ((locations[2]==1)&&(buttons[2]));
74assign continue[1] = button_above[1] && direction[1]==UP || button_below[1] && direction[1]==DOWN;
75assign continue[2] = button_above[2] && direction[2]==UP || button_below[2] && direction[2]==DOWN;
76
77//schedule the next pickup
78        assign stop_next[1]=((locations[1] != `floor-1)&&(direction[1]==UP))?
79                ((up_floor_buttons[locations[1]+1]==ON)?1:0):
80                (((locations[1] != 0)&&(direction[1]==DOWN))?
81                ((down_floor_buttons[locations[1]-1]==ON)?1:0):0);
82        assign stop_next[2]=((locations[2] != `floor-1)&&(direction[2]==UP))?
83                ((up_floor_buttons[locations[2]+1]==ON)?1:0):
84                (((locations[2] != 0)&&(direction[2]==DOWN))?
85                ((down_floor_buttons[locations[2]-1]==ON)?1:0):0);
86        assign random_up[0] = $ND(0,1);
87        assign random_down[0] = $ND(0,1);
88        assign random_up[1] = $ND(0,1);
89        assign random_down[1] = $ND(0,1);
90        assign random_up[2] = $ND(0,1);
91        assign random_down[2] = $ND(0,1);
92
93
94always@(posedge clk) begin
95// randomly push floor buttons
96for (i=0;i<=`floor-1;i=i+1)begin
97        if (random_up[i]) up_floor_buttons[i]=ON;
98        if (random_down[i]) down_floor_buttons[i]=ON;
99end
100
101//turn off scheduled floor buttons.
102// it is important to turn these off after the random pushes, since we
103// want the scheduled buttons to be OFF even though they may have been
104// randomly pushed.
105for (i=1;i<=`elev;i=i+1) begin
106        if ((locations[i] != `floor-1)&& (direction[i] == UP)) begin
107        if (up_floor_buttons[locations[i]+1]==ON) begin
108                up_floor_buttons[locations[i]+1] = OFF;
109                end
110        end
111        if ((locations[i] != 0)&& (direction[i] == DOWN)) begin
112        if (down_floor_buttons[locations[i]-1]==ON) begin
113                down_floor_buttons[locations[i]-1] = OFF;
114                end
115        end
116end
117end
118
119//keep track of locations and directions
120always@(posedge clk) begin
121for (i=1;i<=`elev;i=i+1) begin
122        if (locations[i]==`floor-1) direction[i] = DOWN;
123        if (locations[i]==0) direction[i]=UP;
124        if(inc[i]) begin
125                locations[i]=locations[i]+1;
126                direction[i]=UP;
127                end
128        if(dec[i]) begin
129                locations[i]=locations[i]-1;
130                direction[i]=DOWN;
131                end
132end
133end
134
135endmodule
136//*********************************************** 
137
138//*********************************************** 
139module elevator(clk,stop_next,inc,dec,continue,init);
140input clk,stop_next,continue,init;
141output inc,dec;
142onoff reg buttons[0:`floor-1];
143wire [0:`width-1] init;
144reg[0:`width-1] location;
145dir reg direction;
146mov reg movement;
147dr reg door;
148reg open_next;
149wire button_above, button_below;
150
151//initial begin
152initial open_next = 0;
153initial location = init;
154initial direction = UP;
155initial door = OPEN;
156initial movement = STOPPED;
157initial buttons[0]=OFF;
158initial buttons[1]=OFF;
159initial buttons[2]=OFF;
160//end
161
162wire[0:`floor-1] random_push;
163wire button_above,button_below;
164assign random_push = $ND(0,1,2,3,4,5,6,7);
165assign button_below = 
166                ((location==2)&&(buttons[1]==ON||buttons[0]==ON)) ||
167                ((location==1)&&buttons[0]==ON);
168assign button_above = ((location==0)&&(buttons[2]==ON||
169                        buttons[1]==ON)) ||
170                        ((location==1)&&(buttons[2]==ON));
171
172//******************************
173always@(posedge clk) begin
174// randomly push buttons.
175// But when door is open turn button off for that floor.
176for (i=0;i<=`floor-1;i=i+1) begin
177        if (i == location) buttons[i]=OFF;
178        else if (random_push[i]) buttons[i]=ON;
179end
180
181// record a request to stop at the next floor
182// it is important that this happens last since we want to
183// insure that the stop_next request is always recorded by
184// pushing the button.
185if(stop_next) begin
186        if (direction==UP) buttons[location+1]=ON;
187        else buttons[location-1]=ON;
188        end
189end
190//*******************************
191
192//*******************************
193always@(posedge clk) begin
194//schedule the door to open at the next floor
195if(door != CLOSED) open_next=0;
196else if (movement==MOVING&&(stop_next||(direction == UP&&buttons[location+1]==ON)||
197                                (direction == DOWN&&buttons[location-1]==ON)))
198                open_next=1;
199end
200//*******************************
201
202wire random;
203assign random = $ND(0,1);
204
205//*******************************
206always@(posedge clk) begin
207//Door operation: open the door if button[location] is on.
208//Random pause between different states.
209        case (door)
210                CLOSED: if (open_next&&movement==STOPPED)
211                        door=OPENING;
212                OPENING: if (random) door = OPEN;
213                OPEN: if (random) door = CLOSING;
214                CLOSING: if (random) door = CLOSED;
215                endcase
216end
217//*******************************
218
219// Move to next floor. Increase or decrease location when arrived.
220// Signal to main control (through inc or dec) that have arrived at next floor.
221wire stop_moving;
222wire start_moving;
223wire r_stop;
224assign start_moving = (continue || button_above&&direction==UP) || 
225                        (button_below && direction == DOWN);
226assign r_stop = $ND(0,1);
227assign stop_moving = r_stop&&(movement == MOVING);
228assign inc = (stop_moving)&&(direction == UP);
229assign dec = (stop_moving)&&(direction == DOWN);
230//*******************************
231always@(posedge clk) begin
232if (door == CLOSED) begin
233        case (movement)
234                STOPPED: if (door==CLOSED&&start_moving&&!open_next) 
235                        movement=MOVING;
236                MOVING: if (stop_moving) begin
237                        movement=STOPPED;
238                        if (direction == UP) location = location+1;
239                        if (direction == DOWN) location = location-1;
240                        end
241                endcase
242        end
243end
244//*******************************
245               
246// Determine direction of movement
247
248//*******************************
249always@(posedge clk) begin
250        case (direction) 
251                UP: if((!button_above)&&!continue) 
252                        direction = DOWN;
253                DOWN: if((!button_below)&&!continue) 
254                        direction = UP;
255                endcase
256        if(location==`floor-1) direction=DOWN;
257        if(location==0) direction=UP;
258        end
259//*******************************
260
261endmodule
262//*********************************************** 
Note: See TracBrowser for help on using the repository browser.