Project 5: Elevator Control
B441/E315, Fall 2018 Version 2018.5
In this lab you will practice using state machines by designing and implementing a simulator of a 4-floor elevator system. You will also learn to use 7-segment displays.
An array of 7 LEDs is used to display decimal digits (0, 1, ... , 9) and alphabetical characters (A, b, C, d, E, F, g, etc. ). The display works by illuminating appropriate segments to create the letter or number. The combinations of segments which are illuminated to display decimal digits are shown below.
For example the digit 1 can be displayed by illuminating segments B and C. The digit 5 requires segments A, F, G, C, and D.
You can also use the 7-Segment display for non-ascii characters by simply setting the appropriate segments. For this project, you will get to create an elevator with an open door by setting segments C, D, E, and F. You can create a elevator with a closed door by setting segments C, D, E, and G.
A word of caution: the 7-segment drivers are active low logic, which means they interpret 0’s as “True” and 1’s as “False”. Please code your driver accordingly. Additionally, A-G are encoded from right to left, ie A is the LSB and G is the MSB. More information about the 7-segment display can be found in the Basys3 documentation found under the “Resource” folder of the Google Drive.
You will find Verilog’s localparam (local parameter) useful for building state machines. These allow you to encode a state’s value into a convenient name, without having to worry about how many bits will require.
We suggest you encode your state machine’s states as names, and then use them to drive your state machine. One quick example is listed below:
// These can be called whatever you want.
localparam STATE_IDLE = 0;
localparam STATE_ONE = 1;
localparam STATE_TWO = 2;
//STATE_SIZE tracks how many bits is necessary to store
// the last (or biggest) state. Replace STATE_TWO with the highest
// numbered state from above
localparam STATE_SIZE = $clog2(STATE_TWO + 1);
//register to hold the current, next state
//auto-resized to hold the biggest state value
reg [STATE_SIZE-1:0] state;
reg [STATE_SIZE-1:0] nextState;
//sequential block, using Flip Flops
always @(posedge clk)
state <= nextState; //non-blocking
//combinational block, using &,|,~
always @(*) begin
nextState = STATE_IDLE; //default
STATE_IDLE: nextState = STATE_ONE; //blocking
STATE_ONE: nextState = STATE_TWO; //blocking
STATE_TWO: nextState = STATE_IDLE; //blocking
When constructing testbenches for sequential logic, you may find the @(negedge clk) formulation helpful. This will execute the simulation until the next falling edge of the clock signal. At this point, all the output signals should be stable, allowing you to test them without having to know the exact #delay values necessary. With this you can skip forward a considerable time in the simulation. An example is given below:
btnC = 1; // set reset
@(negedge slowClk)//wait until the falling edge of slowClk
btnC = 0; //clear reset
@(negedge slowClk) //wait for falling edge
btnU = 0; //call elevator
Additional testbench details will be posted to Piazza.
Suppose that a building with four floors has a freight elevator which is used to distribute containers of, well let’s just say ‘beverages’. The elevator is initially loaded with enough beverages for the day. A person calls the elevator to a floor by pressing a pushbutton which is located next to the elevator door on that floor. When the elevator car arrives, the door opens and someone takes out a container of beverages and leaves the elevator. The elevator stays at the floor with door open until another pushbutton is pressed on some other floor.
When the elevator is called from another floor, the door closes and the elevator leaves for the floor from which it was called.
Door openings and closings take 1-3 seconds, and the elevator travelling between the floors also takes 1 - 3 seconds.
You will simulate this freight elevator system by using the 7-segment displays on the Basys board to visually represent the elevator car. Four 7-segment displays represent four floors, and if the car is at floor i (i = 1, 2, 3, 4), then the segments C, D and E of the i’th 7-segment display are illuminated. In addition segment G is illuminated if the door is closed, and segment F is illuminated if the door is open.
For example, the following diagram represents the four 7-segment displays which indicate that the elevator is on floor 3 and the door is open.
The next diagram shows the door closed but still on floor 3.
To illustrate the operation of the simulator, suppose that the elevator is on the third floor with the door open, and it is called to the first floor. The following diagram shows snapshots of the displays in time, each step takes about 1- 3 seconds.
Initially the elevator is on floor 3 with the door open (top figure). 1-3 seconds after being called, the door closes (figure 2nd from the top), then the elevator travels down to floor 2 (figure 3rd from the top). It arrives at floor 1 (figure 2nd from the bottom), and finally the doop opens (bottom figure).
Your assignment is to create the following Verilog modules and testbenches as specified below.
Create a Verilog file named ElevCtrl.v which defines a module as follows:
input clk, //clock
input rst, //reset
input [3:0] floorBtn,
output [1:0] floorSel,
This module is responsible for creating the state machine necessary to control the elevator. It takes in a clock and a reset generate from a higher-level module. It also takes in the raw floor request buttons. You will need to design a state machine to drive both the next state and two outputs. floorSel is an encoding of the floor value, 2’h0 is the 1’st floor, 2’h1 is the 2nd floor, etc. door is an boolean signal which should be 1’h1 to indicate the elevator door is currently open.
When rst (reset) is asserted, your controller should assume the elevator auto-magically teleports to floor 1 (bottom floor) with the door open. A button press should be remembered until your elevator arrives at that floor and opens the door. Your state machine should respond to whichever floor button pressed first, and ignore all additional button presses until the elevator has opened its door. You do not need to worry about multiple buttons being pressed simultaneously.
Create a Verilog file named SevSegDisplay.v which defines a module as follows:
input [1:0] floorSel,
output [6:0] segments,
output [3:0] select
This module is responsible for correctly mapping the current floor and door position to the 7-segment display. floorSel is an encoding of the floor value, 2’h0 is the 1’st floor, 2’h1 is the 2nd floor, etc. door is an boolean signal which should be 1’h1 to indicate the elevator door is currently open. segments and select are the raw outputs that should be used to drive the 7-segment display. For example, segment drives LED segment A. select activates the rightmost LED.
For information regarding the display: https://reference.digilentinc.com/basys3/refmanual
This module is given for you to use. It is used to create a low-frequency clock, ie the 1-3 seconds clock. You will not be tested on this module, nor do you need to write a testbench for it. The autograder will automatically add this module in a file named SlowClk.v to your project for evaluation. While necessary for correct timing in the Demo phase, it is un-usefully slow to simulate. If you wish to simulate this module, we suggest you change slowClk = q to slowClk = q.
reg [25:0] q;
//positive-edge triggered, synchronous reset flip flop
always @(posedge clk)
if (rst) q <= 25’h0;
else q <= q + 1;
assign slowClk = q; //slow for simulations
Your next task is to create a Verilog file named top.v defined as follows:
input btnC, // aka reset
output [15:0] led, //this is optional
output [6:0] seg,
output [3:0] an
// DO NOT MODIFY!
//generate a slow clock
//the slow clock shouldn’t reset in this project, so tie rst to 0
SlowClk sc0( .clk(CLK100MHz), .rst(1’h0), .slowClk(slowClk) );
// your code here
This module should instantiate both submodules and route the appropriate signals into/out of it as follows:
Elevator Controller Name
7-Segment Display Name
The led output is optional. It can be included or omitted as desired. It will not be tested.
For this project, you only need to create two testbenches. One testbench for SevSegDisplay and one for ElevCtrl. We do not require a testbench for top or slowClk. Testbenches that simulate with an unmodified slowClk are un-usefully slow.
Remember to select “System Verilog” from the “File Type” drop-down menu.
You will also need to reconfigure your constraints file to align with the top-level module declaration. The names should line up properly by default. A reference file is available in the Google Drive folder.
The evaluation will have two steps, first submission of your source code and testbench to the autograder. Second, you will need to synthesize your design, download it to the FPGA and do a demonstration for the TA.
Log on to https://autograder.sice.indiana.edu and submit your code as per Project 1.
Program your FPGA with your demultiplexer and demonstrate your working system to the TA. You will not receive full points until the TA has approved your demonstration.