User Tools

Site Tools


2014:floating_point_unit

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
2014:floating_point_unit [2014/12/17 14:05]
kyflores
2014:floating_point_unit [2014/12/17 17:59] (current)
kyflores [Complete FPU]
Line 21: Line 21:
 All modules are designed, simulated, and tested in Modelsim PE and are written in Verilog. All modules are designed, simulated, and tested in Modelsim PE and are written in Verilog.
 ==== Complete FPU ==== ==== Complete FPU ====
- +This is the top level module. It just hooks up the adder/​subtractor and multiplier, plus deals with bus size discrepancies and flow control. 
 +{{:​2014:​top_level.png|}}
 ==== Addition/​Subtraction ==== ==== Addition/​Subtraction ====
 Addition would be as simple as it sounds if there was no exponent to deal with. Before operands enter our adder, they must first be normalized to the larger of the two exponents. We do this by finding the difference of exponents, and shifting the smaller operand by the difference. This process is vulnerable to losing precision, especially if one exponent is much larger than the other. The larger exponent is passed out to the result, and the shifted operands are then added as usual. Subtraction is identical as negatives are dealt with nicely in two's complement notation. Normalizing to the exponent in subtraction is the same as in addition.{{ :​2014:​scan01.png |}} Addition would be as simple as it sounds if there was no exponent to deal with. Before operands enter our adder, they must first be normalized to the larger of the two exponents. We do this by finding the difference of exponents, and shifting the smaller operand by the difference. This process is vulnerable to losing precision, especially if one exponent is much larger than the other. The larger exponent is passed out to the result, and the shifted operands are then added as usual. Subtraction is identical as negatives are dealt with nicely in two's complement notation. Normalizing to the exponent in subtraction is the same as in addition.{{ :​2014:​scan01.png |}}
Line 28: Line 28:
  
 ==== Multiplication ==== ==== Multiplication ====
-Multiplication starts with making sure both operands are positive and the reset flag is pulsed. If they'​re negative, they aren't anymore! The two's complement representation of a negative number was troublesome to deal with, so we removed it and dealt with it at the end by looking at the signs of the inputs. That said, multiplication with a computer is surprisingly human, behaving similarly to long multiplication from 3rd grade. To try this method yourself, write down operand A and operand B. If the rightmost place of B is 1, add the value of A to an accumulator. Then, shift A to the left 1 place, filling in the empty place with a zero, and shift B right one place, again filling in the empty with a zero. Repeat the cycle of adding A is the rightmost place of B is 1 until all places of B are zero. After this shift and accumulate process is done, we change the sign of the output to match the inputs. The multiplier will display its result as soon as it is ready (it sees that B is all 0). To find the correct exponent in a multiplication operation, just add the input exponents. If the exponents cause an exception by having a carryout or overflow, an output flag will indicate that the exponent displayed is not valid. The res_ok flag in multiplier'​s internals becomes true when the B operand is entirely shifted out, signalling that the operation is finished. This flag allows the result to be displayed early if B is short!{{ :​2014:​scan02-2.png ​|{{ :​2014:​scan02-2.png?​300 ​|}}}}+Multiplication starts with making sure both operands are positive and the reset flag is pulsed. If they'​re negative, they aren't anymore! The two's complement representation of a negative number was troublesome to deal with, so we removed it and dealt with it at the end by looking at the signs of the inputs. That said, multiplication with a computer is surprisingly human, behaving similarly to long multiplication from 3rd grade. To try this method yourself, write down operand A and operand B. If the rightmost place of B is 1, add the value of A to an accumulator. Then, shift A to the left 1 place, filling in the empty place with a zero, and shift B right one place, again filling in the empty with a zero. Repeat the cycle of adding A is the rightmost place of B is 1 until all places of B are zero. After this shift and accumulate process is done, we change the sign of the output to match the inputs. The multiplier will display its result as soon as it is ready (it sees that B is all 0). To find the correct exponent in a multiplication operation, just add the input exponents. If the exponents cause an exception by having a carryout or overflow, an output flag will indicate that the exponent displayed is not valid. The res_ok flag in multiplier'​s internals becomes true when the B operand is entirely shifted out, signalling that the operation is finished. This flag allows the result to be displayed early if B is short! {{:​2014:​scan02-2.png|}}
  
  
Line 53: Line 53:
 To run or build on this project, only some knowledge of Verilog is required. The HDL simulator Modelsim was used for developing the system, but any Verilog simulator should do, pending modification of our do files. We assume the user has some Verilog simulator installed and thus do not provide installation instructions. There are no build instructions because there is no hardware. To run or build on this project, only some knowledge of Verilog is required. The HDL simulator Modelsim was used for developing the system, but any Verilog simulator should do, pending modification of our do files. We assume the user has some Verilog simulator installed and thus do not provide installation instructions. There are no build instructions because there is no hardware.
 ===== Module Organization Scheme & Run Directions===== ===== Module Organization Scheme & Run Directions=====
-  ​Blah+Module table index. 
 +===== adder.v ===== 
 +  ​f_adder(out,​ carryout, a, b, carryin); 
 +  * workgroup8(output[7:​0] out, output carryout, input[7:0] opA, input[7:0] opB, input carryin, output overflow);​ 
 +  * csa64(output[63:​0] out, output carryout, input[63:0] opA, input[63:0] opB, input carryin); 
 +  * csa24(output[23:​0] out, output carryout, input[23:0] opA, input[23:0] opB, input carryin); 
 +  * csa32(output[31:​0] out, output carryout, input[31:0] opA, input[31:0] opB, input carryin, output overflow);​ 
 + 
 +===== complete_add.v ===== 
 +  * bitshift_right(input[23:​0] opA, input[7:0] shift, output[23:​0] shifted_opA);​ 
 +  * bitshift_left(input[23:​0] opA, input[7:0] shift, output[23:​0] shifted_opA);​ 
 +  * sign_extend_8_to_32(input[7:​0] operand, output[31:​0] res); 
 +  * sign_extend_24_to_32(input[23:​0] operand, output[31:​0] res); 
 +  * sign_extend_32_to_56(input[31:​0] operand, output[55:​0] res); 
 +  * complete_add(input[31:​0] opA, input[31:0] opB, input carryin, output[31:​0] res, output final_carryout,​ output final_overflow);​ 
 + 
 + 
 +===== multiply.v ===== 
 +  * negate_32(input negate, input[31:0] operand, output[31:​0] res); 
 +  * negate_64(input negate, input[63:0] operand, output[63:​0] res); 
 +  * multiplier(input clk, input reset, input[31:0] opA, input[31:0] opB, output[63:​0] res, output res_ok); 
 +  * complete_multiplier(input clk, input[31:0] opA, input[31:0] opB, input reset, output exp_ok, output[55:​0] result); 
 + 
 +===== SLT.v ===== 
 +  * SLT_behavioral(input[31:​0] input1, input[31:0] input2, output res); 
 +  * SLT_structural(input[31:​0] opA, input[31:0] opB, output res); 
 +  * inverter_32(input[31:​0] operand, output[31:​0] res); 
 + 
 +===== support_modules.v ===== 
 +  * barrel_shifter32(input[4:​0] shamt, input dir, input[31:0] dataIn, output[31:​0] dataOut); 
 +  * barrel_shifter64(input[4:​0] shamt, input dir, input[63:0] dataIn, output[63:​0] dataOut); 
 +  * sign_extend_u(input[31:​0] operand, output[63:​0] out); 
 +  * sign_extend_s(input[31:​0] operand, output[63:​0] out); 
 +  * upcounter(input clk, input reset, output reg[4:0] cval); 
 +  * adder64(input[63:​0] opA, input [63:0] opB, output[63:​0] res); 
 +  * reg64(input clk, input[63:0] dataIn, output reg[63:0] dataOut, input reset); 
 +  * and64(input[63:​0] dataIn, input compare, output[63:​0] dataOut); 
 +  * mux2_1_1(input in0,input in1,input sel,output out); 
 +  * mux2_1_1s(input in0,input in1,input sel,output out); 
 +  * mux2_1_32(input[31:​0] in0,​input[31:​0] in1,input sel,​output[31:​0] out); 
 +  * mux2_1_64(input[63:​0] in0,​input[63:​0] in1,input sel,​output[63:​0] out); 
 +  * mux3_1_1(input in0, input in1, input in2, input sel, output out); 
 +  * mux3_1_56(input[55:​0] in0, input[55:0] in1, input[55:0] in2, input[1:0] sel, output[55:​0] out); 
 +  * mux3_1_2(input[1:​0] in0, input[1:0] in1, input[1:0] in2, input[1:0] sel, output[1:0] out); 
 + 
 +===== Run Pre-built Test ===== 
 +  * test_fpu.do - Runs tests that involve the entire unit. Test cases are fed in manually as this unit has no flow control of its own. 
 + 
 +Download the things here.{{:​2014:​fpu.zip|}}
  
 +===== Work Plan =====
 +Our original work schedule was very functional and we had an adequate amount of time to finish the modules that we hoped to finish. Specifically,​ we had spent about 8 hours per week working on the project. We only spent a bit more time when we were merging the modules together and creating the top-level module.
 ===== The Unexpected ===== ===== The Unexpected =====
 Here's a list and description of problems, tradeoffs, or frustrations that weren'​t immediately obvious when we made our initial design. Here's a list and description of problems, tradeoffs, or frustrations that weren'​t immediately obvious when we made our initial design.
2014/floating_point_unit.1418843147.txt.gz · Last modified: 2014/12/17 14:05 by kyflores