Project 6: Stack-based Calculator
Due 31 October 2017
The purpose of this project is to make use of RAM to implement a stack-based four function calculator. The concepts of stacks and the use of memory will lead into the next project where you design a complete CPU.
A stack-based calculator uses a stack to hold the operands of an operation. The user first enters and pushes the operands, then selects an operation to execute that makes use of the top two operands on the stack.
If you imagine a calculator and its display, we're going to use a register [MBR] to represent the display, which is also the currently active number. We'll also use the MBR as the top of the stack for the purpose of operations.
To control our calculator, we're going to use three buttons to execute actions, two switches to select the mathematical operation (+, -, *, /), and eight switches to specify values. Button 2 will be the Capture button and will write the current value from the switches to the MBR. Button 3 will be the Enter button and will push the MBR onto the stack. Button 4 will be the Action button and will execute the operation specified by the two operation switches, using the MBR and the first value on the stack, putting the result back in the MBR.
As an example, consider that we want to add 4 plus 5. We would do this in the following steps.
- Set the value switches to the binary value for 4.
- Click the Capture button to move 4 into the MBR. A 4 should now show up on the 7-segment display.
- Click the Enter button to push 4 onto the stack.
- Set the value switches to the binary value for 5.
- Click the Capture button to move 5 into the MBR. A 5 should now show up on the 7-segment display.
- Set the operation switches to 00 for ADD.
- Click the Action button to add the MBR to the top value of the stack. The result, 9, should end up in the MBR and on the display.
The value of the MBR will always be echoed in the two seven segment displays.
- Make a new project for lab 6 in a new folder. If you are going to use a 7-segment display to show the contents of memory, then copy over your VHDL 7-segment display driver in to the new folder. I'll refer to the project and top-level circuit as calculator.
- Using the Tools:MegaWizard Plug0in Manager, create a RAM that has 16 words of 8 bits each. Therefore, it should have 4 address bits and 8 data bits. I'll refer to this circuit as memram in the file memram.vhd, This step will create a VHDL file that you will include in your project.
Create a top-level VHDL file with an entity that has the same name as
the project (e.g. calculator). You will need the following input and output
signals for the entity's port statement.
clock: in std_logic clock signal reset: in std_logic reset signal b2: in std_logic button 2, capture input b3: in std_logic button 3, Enter b4: in std_logic button 4, Action op: in std_logic_vector(1 downto 0) Action switches (2) data: in std_logic_vector(7 downto 0) Input data switches (8) digit0: out std_logic_vector(6 downto 0) Output values for 7-segment display digit1: out std_logic_vector(6 downto 0) Output values for 7-segment display stackview: out std_logic_vector(3 downto 0) Stack debugging
- Create a component statement for the RAM in the architecture header. Be sure to include the VHDL memram file created by the Wizard in your project.
- Create the internal signals you will need to build the state machine and access the RAM. You will need signals for the RAM input, RAM write enable, RAM output, stack pointer, memory buffer register, and state. You will also likely need a temporary register for holding an operand removed from the stack.
Plan out a state machine that will implement the calculator. You
can use the lab circuit as a model. Include your state machine
diagram as part of your wiki report.
Note: multiplication requires a destination that has twice as many bits as the operands. When executing multiplication you can either assign the result to a 16-bit temporary register and then truncate it to 8-bits or you can limit multiplication to the low four bits of the two operands.
Implement your state machine.
Port map the RAM and the seven-segment displays. The seven-segment
circuits should take in the low 4 and high 4 bits of the MBR, and
their outputs should connect to the digit0 and digit1 output signals.
Connect the stack pointer to the stackview output signal of your
If you built your 7-segment display as a BDF diagram, use the "create/update" option and create the VHDL file for your 7-segement display circuit, which you can then port map into your main circuit.
- Assign pins and test your circuit on the board. Take some videos of it in action for all of the different operations.
- Get your stacker lab circuit running on the board. Take a video of it in action.
- Expand the number of arithmetic operations.
- Write a test bench program in VHDL that you can use to test your circuit with GHDL.
- Put in checks so your stack will never go over or under value.
- Try fixed-point math.
- Expand the size of the data to 12-bit registers. If you go to 16 bits, it will require more care when entering data.
Create a wiki page with your report. For each task, write a short description of the task, in your own words.
- Demonstrate that you got your stacker working by including the GHDL output in your report.
- Provide a description of your top-level design. This should include your state machine diagram.
- Show your circuit in action for each of the four operations.
- Describe other testing you did to ensure the circuit is working properly.
- Include a description, and pictures or videos, of any extensions.
Give your wiki page the label cs232s17project6.
Put your VHDL files in a project6 folder in your Private subdirectory on the handin server.