User Tools

Site Tools


lab_12

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

lab_12 [2019/04/08 20:11] (current)
Line 1: Line 1:
 +====== Lab 12: Bit-Level Floating Point Calculator ======
  
 +In this lab, you will build your own floating-point adder/​subtractor/​multiplier,​ implemented at the bit-level, based upon the IEEE standard.
 +
 +===== Overview =====
 +
 +The IEEE Floating Point Standard was developed in the 80s to achieve three basic purposes:
 +  - Arithmetic should be correctly rounded.
 +  - Floating point numbers should be consistently represented across machines.
 +  - Exception handling should be sensible and consistent.
 +
 +You will implement a simple floating-point add/​subtract/​multiply calculator using the 7-segment display, the keypad, the pushbuttons,​ two sliding switches, and the ZYNQ processor, of course. In this lab you will implement your own floating-point add/​subtract/​multiplication function that adds/​subtracts/​multiplies two floating-point numbers together using the IEEE format. ​
 +
 +
 +===== Specifications =====
 +
 +In this lab, you will implement a floating-point adder/​subtractor/​multiplier that accepts two floating-point numbers as input and outputs a floating-point result. All numbers will be computed and represented using single-precision (32-bit) IEEE floating point. You will write your own code for floating point operations using basic C-code, logical operations, integer math operations, and so forth. You are **not** allowed to use the floating-point library provided with the C-compiler in your final system. You may use the compiler-provided floating-point functionality to help debug your system but you must not rely on it for the final solution, other than to print the result to the terminal as explained below.
 +
 +Please see the following webpages for a short description of the IEEE standard and examples of how to perform arithmetic:
 +
 +  * [[http://​www.math.byu.edu/​~schow/​work/​IEEEFloatingPoint.htm]]
 +  * [[http://​kipirvine.com/​asm/​workbook/​floating_tut.htm]]
 +  * [[http://​stackoverflow.com/​questions/​5291732/​converting-from-binary-to-ieee-floating-point]]
 +  * [[http://​en.wikipedia.org/​wiki/​IEEE_floating_point]]
 +  * [[http://​www.h-schmidt.net/​FloatConverter/​]]
 +
 +The link below explains sscanf.
 +
 +  * [[http://​crasseux.com/​books/​ctutorial/​sscanf.html]]
 +
 +  - We have a limited number of displayable digits, so we will have to be clever about how we enter our numbers. We will use a combination of the keypad, push buttons and the LEDs to enter the numbers. First, here's is how the LEDs will be used:
 +      - LD0 = ON: You are ready to receive the significand for the first digit.
 +      - LD1 = ON: You are ready to receive the exponent for the first digit.
 +      - LD2 = ON: You are ready to receive the significand for the second digit.
 +      - LD3 = ON: You are ready to receive the exponent for the second digit.
 +      - LD4 = ON: You are displaying the result of the addition/​subtraction/​multiplication.
 +      - Note that the LEDs should only be on as described above. They should remain on while the number is being entered. Otherwise, they should be off.
 +  - The push-buttons will work as follows:
 +      - BTNC will serve as the enter key. You will press this after you have keyed in the values for your number.
 +      - BTNU will serve as the reset key. You can press this key at any time to force your system to its initial state.
 +      - BTNL will cause the first digit to be displayed on the 7-segment display. As long as you hold this button, the significand followed by the exponent for the first digit will slowly scan across the display. You will insert a space between the signficand and the exponent when displaying the number.
 +      - BTNR will cause the second digit to be displayed on the 7-segment display and will otherwise operate the same as BTNL.
 +  - You will also use two sliding switches.
 +    - SW0, that, when up, causes the system to perform subtraction,​ and that, when down, causes the system to perform addition.
 +    - SW1 that, when up, causes the system to perform multiplication,​ and that, when down, causes the system to perform addition/​subtraction,​ according to SW0. Note that SW1 takes priority over SW0.
 +  - The system will automatically display the result of the operation performed on the two floating-point numbers on the 7-segment display as soon as the second number (significand + exponent) has been entered.
 +  - Use the * key on the keypad to change the sign of either the significand or exponent. Each time you press the * key, the sign will switch for the value currently being entered. You must be able to push the * key to change the sign of a value at any time up until you hit the "​enter"​ button (see below).
 +
 +The system will operate as follows:
 +  - When the system starts up, it is ready to accept the significand for the first digit and the LD0 LED will illuminate. Key in the digits for the significand and hit the enter push-button.
 +  - LD1 illuminates and the system is ready to accept the exponent for the first digit. Key in the exponent and hit the enter button.
 +  - LD2 illuminates and the system is ready to accept the significand for the second digit. Key in the significand and hit the enter button.
 +  - LD3 illuminates and the system is ready to accept the exponent for the second digit. Key in the exponent and hit the enter button.
 +  - LD4 illuminates and displays either the result of the operation. Note that you must be able to slide SW0 or SW1 during this time and have the display update accordingly. ​
 +  - The result is also displayed on the console using a printf() with a floating-point specifier. This will check to see that you are abiding by the IEEE standard. Print the result to the terminal anytime the display changes its value. This means that you will also reprint the value to the terminal each time one of the slide switches changes value.
 +  - Input will assume normalized scientific notation. You won't need to input the decimal point as it will be assumed that there is only a single digit to the left of the decimal point. You must display the implicit decimal point as you enter the number and at any time you are displaying numbers.
 +
 +You don't need to handle any of the following:
 +  - Rounding modes (just truncate),
 +  - NAN,
 +  - Infinity,
 +  - Exception handling, etc.
 +
 +You do need to handle underflow/​overflow. If overflow occurs, make the display flash all "​O"​s. If underflow occurs, make the display flash all "​U"​s.
 +===== Notes =====
 +
 +  - It will be very important to design this lab in a modular fashion. A lot of your code can be reused if you are careful.
 +  - You must use the state-machine techniques that we studied throughout the semester.
 +  - You don't have to use the task scheduler, but it may be a good idea to use it.
 +
 +===== Hints and Helps =====
 +You will need to use a ''​union''​ in this lab. Modern compilers often try to keep us from looking under the hood to see what is going on. Moreover, they often try to keep you from messing with what is under the hood. This is usually desirable but in computer engineering,​ we want to know exactly what is going on. We, as computer engineers, also like messing with stuff under the hood. :-) A ''​union''​ helps with this.
 +
 +A ''​union''​ looks a lot like a struct but with a very important difference. All of the variables declared in a ''​union''​ occupy the **same** memory space. For example, in the ''​union''​ named ''​my_union''​ shown below two variables have been declared: ''​int bit_view''​ and ''​float float_view''​. The compiler will allocate enough memory to hold the largest of these variables and then ensure that reads and writes to these two variables are directed to a single memory location. So, why is this useful? It allows us to have two views of our floating point numbers, a low-level view of the bits (bit_view) and the floating-point view used by all of the floating-point routines.
 +
 +<​code>​
 +union{
 +  int bit_view;
 +  float float_view;
 +} my_union;
 +</​code>​
 +
 +This makes it easy to switch back and forth between the two views without annoying the compiler. The code below shows you how to use the union effectively for this lab. The code below also shows you how to use ''​sscanf()''​ and ''​ssprintf()''​ to convert an ASCII string of characters into a float, and, vice versa, to convert a float back into a string of ASCII characters. I suspect that you will find these functions extremely useful while working on Lab 12. Note that it is OK to use ssprintf and sscanf to convert back and forth between the ASCII and bit-level versions of the floating-point numbers. You must implement the ''​+'',​ ''​-''​ and ''​*''​ functions yourself.
 +
 +<​code>​
 +#include <​stdio.h>​
 +#include "​platform.h"​
 +// Lots of handy stuff for Lab 12.
 +// 1. How to convert from a string-based number to a float.
 +// 2. How to view the bits of the float.
 +// 3. How to convert the float back into a string-based number.
 +
 +int main()
 +{
 +   ​init_platform();​
 +   ​printf("​Hello World\n\r"​);​
 +   union {
 +     int bit_view;
 +     float float_view;
 +   } my_union;
 +   const char* number_string_1 = "​0.0075E2"; ​               // 0.75
 +   char number_string_2[256]; ​                              // Define a char buffer I will use later.
 +   ​sscanf(number_string_1,​ "​%e",​ &​(my_union.float_view)); ​  // Convert the string-based number into a real float.
 +   ​printf("​Sign-bit:​ %x\n", (my_union.bit_view & 0x80000000) >> 31);
 +   ​printf("​Exponent:​ %d\n", (my_union.bit_view & 0x7F800000) >> 23);
 +   ​printf("​Significand:​ %x\n", (my_union.bit_view & 0x007FFFFF));​
 +   // Add 1 to the exponent just for fun. exponent = 126 that has a 0 in the LSB of the exponent. ​
 +   // OR-ing '​1'​ to the LSB of the exponent adds 1 to the exponent.
 +   ​my_union.bit_view |= 0x00800000;
 +   ​printf("​Exponent:​ %d\n", (my_union.bit_view & 0x7F800000) >> 23); // Confirm that exponent increased by 1.
 +   // Floating point value should double. Do you see why?
 +   ​sprintf(number_string_2,​ "​%e",​ my_union.float_view); ​    // Take the float and convert it back to a string.
 +   ​printf("​%s\n",​ number_string_2); ​                        // Print out the converted string.
 +   ​return 0;
 +}
 +
 +</​code>​
 +
 +This code was tested on the ZED board and printed out the following when executed.
 +<​code>​
 +Hello World
 +Sign-bit: 0
 +Exponent: 126
 +Significand:​ 400000
 +Exponent: 127
 +1.500000e+00
 +</​code>​
 +
 +
 +===== Grading =====
 +
 +The best score for pass-off will be achieved by those lab implementations that work the most smoothly and predictably. Hand in a write-up as you have with the earlier labs.
lab_12.txt ยท Last modified: 2019/04/08 20:11 (external edit)