Fixed-point Calculator

This laboratory assignment accompanies the book, Embedded Microcomputer Systems: Real Time Interfacing,
Second edition, by Jonathan W. Valvano, published by Thomson, copyright © 2006.

Goals
• Design and build a calculator,
• Develop routines for fixed- point arithmetic .
Review
• Valvano Section 1.5.5 on fixed-point numbers.
Starter files
• None

Background

You are not required to follow the specific syntax described in this background section. The two examples
are included to illustrate the approximate level of complexity required of your calculator. In these examples, an
ASCII string is input from the keyboard. During this input stage, a clear or backspace key allows the operator to
correct typing mistakes. During the time the operator is entering a new command, the entire LCD display shows the
command as it is being typed. There will be a specific key or keys (e.g., = ! or <ENTER>) that terminates the string
and causes the string to be interpreted.

A literal is defined a sequence of characters that represent a specific value (e.g., 0 1.3 3.14). Operators
are characters (or sequences of characters) that cause actions to occur (e.g., + - * / = ! A). There may be delimiting
characters, like spaces , which the calculator uses to define its syntax. There are two basic approaches to building a
calculator. The algebraic approach uses a syntax based on the rules of algebra . To execute binary operations
(requiring two inputs), we would type the operator between the two inputs

1.3-2.4= (sets the temporary register to -1.10)
30*0.11= (sets the temporary register to 3.30)

Binary operators (+ - * /) can be used in a unary syntax with the first parameter implied as the temporary register.
For example,

1+2= (sets the temporary register to 3.00)
+3= (sets the temporary register to 6.00)
/8= (sets the temporary register to 0.75)

To execute a unary operation (requiring one input), we would type the operator before the input

(sets the temporary register to 0.50)

To implement a save register, two functions are needed (for example, let ! mean store and let A mean recall). The
store function copies the temporary register into the save register, and the recall function can be used in place of a
literal inside a calculation. For example

1.3+1.7= (sets the temporary register to 3.00)
! (sets the save register to 3.00)
10/A= (sets the temporary register to 3.33)

In this syntax, the = and ! keys cause the line to be executed . Algebraic calculators use parentheses and operator
precedence to create complex calculations (parentheses and precedence are not required for this lab). Algebraic
calculators do not need a delimiter, like space, to separate operands. After the operator hits the = or ! key, your
calculator executes the line and shows both the temporary register and the save register.

A second approach to implementing a calculator uses Reverse Polish Notation (RPN), like an HP
calculator. An advantage of RPN is that complex calculations can be performed without parentheses or operator
precedence rules. The storage elements for a RPN calculator form a LIFO stack. In this syntax we use the <ENTER>
key to cause a line to be executed. When a literal is executed its value is pushed on the stack. For example, typing
cause a line to be executed. When a literal is executed its value is pushed on the stack. For example, typing
1.3 2.4 <ENTER> (pushes 1.30 and 2.40 on the stack, with 2.40 on top)
To execute binary operations (requiring two input), we would type the operator after the inputs
1.3 2.4 - <ENTER> (pushes a 1.30, pushes a 2.40, pops the 1.30 2.40 and pushes a -1.10)
To execute a unary operation (requiring one input), we would type the operator after the input
0.25 <ENTER> (pushes a 0.25, pops the 0.25, then pushes a 0.50 on top of the stack)
 

RPN calculators will need a delimiter, like space, to separate operands. Again, two functions are needed to
implement a save register (let ! mean store and let A mean recall). The store function pops the top element off the
LIFO stack storing it into the save register, and the recall function pushes the contents of the save register onto the
LIFO stack. For example

1.3 1.7 + ! <ENTER> (sets the save register to 3.00, with no net change to stack )
10 A / <ENTER> (pushes a 3.33 onto the stack, the save register still contains 3.0)

After the operator hits the <ENTER> key, your calculator executes the line and shows the top of the LIFO stack and
the save register. Because each token in a RPN calculator always does the same thing, it will be easy to implement a
calculator that supports multiple operations in one command line. E.g.,
1 2 + 3 + 8 / <ENTER> (pushes a 0.75 on top of the stack)
The RPN interpreter simply scans the string, dividing into tokens (separated by spaces + - * / )
If the token is a literal, push its value on the stack.
If the token is a binary operator, pop two elements off stack, operate, push result on the stack.
If the token is a unary operator, pop one element off stack, operate, push result on the stack.

Preparation

Write the main program that implements a five-function 16-bit signed fixed -point calculator. Your calculator
will have at least two storage variables (e.g., a temporary register and a save register or a LIFO stack and a save
register). All numbers will be stored using the fixed-point format developed back in Lab 1. The matrix keyboard
will include the numbers ‘0’-‘9’, and the letters ‘+’, ‘-’, ‘*’, ‘/’, ‘=’ ‘!’ ‘A’ ‘’ and ‘.’. (The RPN calculator will also
need a space). You will need either a clear or a backspace character to let the operator correct typing errors. You are
free to design the calculator functionality in any way you wish, but you must be able to: 1) observe the save value
and the temporary; 2) type numbers in using the matrix keyboard; 3) add, subtract, multiply, divide and square root ;
4) display the results on the HD44780 LCD display. No SCI input/output is allowed in the calculator program.
Figure 10.1 shows a possible data flow graph of the calculator.

Figure 10.1. Data flows from the keyboard to the LCD.

Figure 10.2 shows a possible call graph of the system. Dividing the system into modules allows for concurrent
development and eases the reuse of code.

Figure 10.2. A call graph showing the four modules used by the calculator.

Procedure

Test the calculator software in small pieces. You should stress test the system by purposely attempting illegal or
nonsensical commands. An appropriate response to illegal inputs or improper syntax is to display an error.
Similarly, the calculator should give a descriptive error after a numerical overflow, a divide by zero, or a square root
of a negative number . Record the list of test cases and the responses of your calculator. You could manually type in
the test cases and manually record the responses. Alternatively, you could create an automated test program, like
Lab 1, that feeds input strings to your calculator and records the output strings.

Deliverables (exact components of the lab report)
A) Objectives (1/2 page maximum)
B) Hardware Design
Show any changes you made since the previous lab
C) Software Design (a hardcopy software printout is due at the time of demonstration)
Describe the algorithm you used to calculate square root
Explain any data structures used to implement the calculator
If you organized the system different than Figure 10.1 and 10.2, then draw its data flow and call graphs
D) Measurement Data
Test log showing input test cases and output responses
E) Analysis and Discussion (1 page maximum)

Checkout
First, the TA will attempt to use your calculator without any verbal instructions from you at all. You will then
demonstrate any additional functions the TA couldn’t figure out. Be ready to discuss issues such as range,
resolution, precision, overflow, truncation, roundoff, and dropout.
A hardcopy printout of your software will be given to your TA, and graded for style at a later time.

Hints

1) Here is a Newton’s Method for finding square root as defined in floating-point. You can convert this algorithm
into fixed-point. Overflow and dropout should be considered when implementing fixed-point calculations. Be
careful to make sure the square root function completes, and doesn’t get caught in an infinite loop. s is the input and
t is the output, such that t will become sqrt(s)
make an initial guess, e.g., t =2.0
do this calculation a small number of times depending on the precision, and the initial guess (e.g., 8)
t = ((t*t+s)/t)/2

2) Create a half-page instruction sheet, including a key code layout. This allows you to label the keys without
permanently damaging the keyboard. A good implementation allows the TA, with just this instruction sheet, to be
able to figure out and use most features of your calculator

Prev Next