Fpadd 2
Fpadd 2
1
Table of Contents
Section page
Simulation Results 7
1) Verilog waveforms 8-13
2) IRSim simulation 14-16
Verification Results 17
Schematics/ Verilog 26
1) Readable Verilog Code 26-36
2) Verilog Code for Electric 37-47
3) Leaf Cell: Mux2 (schematic) 48
4) Leaf Cell: Full adder (schematic) 48
5) Hand layout of the Exponent Bitslice (schematic) 49
6) Hand layout of Exponent Datapath (schematic) 49
7) Synthesized and hand layout of full datapath (schematic) 50
Layout
1) Leaf Cell: Mux2 (layout) 51
2) Leaf Cell: Full Adder (layout) 51
3) Hand layout of Exponent Datapath (layout) 52
4) Synthesized and hand layout of full datapath (layout) 52
2
Color Chip Plot
3
Functional Overview:
Two Function Calculator
The motivation for this project began at almost the very beginning of our HMC
careers. During the freshman year we worked on the giant calculator that was given to
Professor Benjamin. We used the logic from a hand-held calculator to generate the
results. For this project we would like to actually construct the logic on the transistor
level for a subset of the calculator functions.
Specifically, we propose to build an 8 bit floating point adder. Floating point
numbers allow computers to perform operations on numbers other than simple integers.
According to the IEEE standards, floating point numbers are of the form (-1)^S * 2^E *
M. Here, S is the sign bit, which determines whether the number is positive or negative.
The mantissa, M, holds the significant bits of the floating point number. Using a notation
similar to scientific notation, E is the exponent that the mantissa is raised to.
A 32 bit floating point number is standard, but due to size limitations in our
design, both in available I/O pins, and chip area, we will be using an 8 bit representation.
We will have a sign bit, 3 bits available for the exponent, and the remaining 4 bits will be
devoted to the mantissa. This will allow us to represent a resolution as small as 1/128
when the implicit leading 1 is taken into account. However the smallest number we can
represent is 1/8
We are aware that 8 bits are not terribly useful for performing extremely accurate
calculations, but it does demonstrate the operation of a floating point adder. The design
methodology is nearly identical for an 8 bit adder as for the larger adders, and the
learning gained from the 8 bit version will be just as valuable.
Our adder should perform correctly in the normal cases, but for extreme cases we
have devised ways of handling exceptions. For the subtraction of two equal numbers, the
result should be zero. For our implementation, zero will be denoted on a separate zero-
detect pin on the chip. When a calculation results in zero, that pin will be at logical 1.
When adding numbers that produce a result out of range, an overflow occurs. For this
exception, we will have a separate signal that indicates that an overflow has occurred, and
that the result [0:7] is not reliable.
Data will be loaded into our adder using 16 parallel inputs, [7:0] for A and [16:8]
for B and the result [7:0] will also be 8 bits in parallel. We will also need to assign a pin
to be function select. This selects whether we are performing subtraction or addition.
This project will be implemented in two different software packages. We first
designed the entire project in verilog to ensure that the logic was correct. The formal
layout for this project is quite large, so given the time constraints we will be laying out
the exponent datapath and synthesizing the mantissa datapath from the generated verilog
code. We will join the exponent datapath with the mantissa datapath to create the final
chip design.
The final test to see whether our design meets the specs in this proposal is simple:
can it correctly add and subtract two floating point numbers? Does it handle the
exceptions correctly, as described herein? Finally, although neither of us be here next
year, this might be something that would be useful to add to a micro-p’s project in the
future.
4
Inputs Outputs
A[0:7] Result[0:7]
B[0:7] Zero detect
Clk Overflow
Function select
Power
Ground
5
Chip Floorplan: Block Diagram
6
Chip Area Estimate
7
Area and Design Time Data
Cell Name Area Design Time Comments
2-Input Mux 4982λ2 1 hour Modified a design found in
an existing library
INV 3007λ2 5 minutes Taken from another library
Adder 20286λ2 4 hours Metal modifications to an
existing design
Exponent Bitslice 102729λ2 9 hours Assembled various parts,
required a lot of updating as
designs changed
Exponent Datapath 477252λ2 3 hours Assembled bitslices, also
took a lot of updating and
modifications
Synthesized Datapath NA See below
Complete layout NA
8
Simulation Results
Many simulation tests were performed on this project during various stages in the
development. The first set of waveforms following this section is the simulation done on
the complete Verilog code using the Xilinx simulation tool. The complete code includes
both the exponent and mantissa datapaths. By proving that the code is simulating
properly, we are fairly confident that the synthesized mantissa datapath will be correct,
but that we can also use the exponent datapath code as a guide for the hand drawn
exponent datapath. We tested the code with all of the cases listed in the testing protocol.
9
10
11
12
13
14
15
The next set of tests would have been to use IRSim to test the full schematic
datapath. This test could not be completed because Electric could not generate a .sim
file for the layout. It was unable to place two of our exports from the layout into the .sim
file. Below is a screen shot of the list of exports for the layout and also the error given
when IRSim is trying to generate the .sim file for the layout.
16
Screen shot of IRSim error message
As you can see, Electric clearly knows that the exports exist but when we looked
in the generated .sim file, there were no connected or even mention of exp_diff_sign or
exp_diff_signb.
We were told that since we managed to get NCC to check on Gemini if we can
prove that the simulation works on the schematic datapath then we can safely assume that
the simulation of the layout would also be successful. However when we tried to run the
generated .sim file for the schematic datapath of the exponent we were given the
following error.
17
Screen shot of IRSim message window
Since neither datapath was able to generate a proper .sim file, the full datapath
could not be simulated. We attempted to track down the bug which prevented Electric
from generating a correct .sim file. We check other facets such as INV and AND using
IRSim to simulate their functionality. Both gates simulated properly. In the end we still
could not find the problem.
18
Verification Results
DRC, ERC, and NCC verification was done in separate stages as our project
progressed. We verified DRC, ERC, and NCC on many smaller layouts and schematics
to make sure that our design was not going awry without us realizing it. DRC, ERC, and
NCC passed on the MUX and Adder. We also verified DRC and ERC on the exponent
datapath bitslice. However, we ran into some problems when we tried to verify NCC.
We eventually used Gemini to determine why NCC was not passing. We also used
Gemini to verify NCC on the full datapath of the exponent layout and schematic. Gemini
did identify minor modifications that needed to be made to our design. However, even
though Gemini verified both the bitslice and the datapath, Electric would not pass NCC
on either. We were told that Gemini is more reliable so we did not spend any more time
trying to get Electric to pass NCC for the exponent bitslice and the datapath.
After the rest of the datapath for a floating-point adder was synthesized, we
performed more verification tests on the full design. NCC was not expected to pass using
Electric since the exponent datapath did not pass. Again, we used Gemini to verify NCC
on the full datapath.
Results:
Cell DRC ERC NCC
MUX Pass Pass Pass
INV Pass Pass Pass
Adder Pass Pass Pass
Exponent Bitslice Pass Pass Pass in Gemini
Exponent Datapath Pass Pass Pass in Gemini
Full Datapath
19
Post-Fabrication Test Plan
Testing the chip just calls for enough runs to test a fair portion of the capabilities
of the chip and a few special cases. To test the chip, one can hook the chip to a
protoboard. Note the physical locations of each input and output pin. Once you have
verified the pin locations, hook dip switches to the inputs and LEDs to the outputs. The
dip switches will allow you to manually apply high and low values to each input pin. For
quick verification, the LEDs should light if the desired output is high.
Note that the test plan does not call for a test of every possible combination of
numbers. Each 8 bit floating point number can represent 28 different numbers. So it
would require 217 tests to check all possible combinations(including the function choice).
So instead of testing 217 different cases, we will only test the boundary cases.
Listed below are equations that should be applied and why it is important.
1) Same exponent, same mantissa value- these tests will verify if the chip is
functioning properly when no original shifting is required to add or subtract
two identical numbers.
• Addition of two identical numbers (but more importantly, since they have the
same exponent value, the mantissa does not need to be shifted)
5 + 5 = 10
Input Output
A[7:0] 01010100 Y[7:0] 01100100
B[7:0] 01010100 Zero 0
Funct 0 Overflow 0
20
• Subtraction of two identical numbers (assert the zero pin)
5-5=0
Input Output
A[7:0] 01010100 Y[7:0] XXXXXXXX
B[7:0] 01010100 Zero 1
Funct 0 Overflow 0
*Equivalent cases (–5 + 5), [-5 – (-5)]*
*X denotes “don’t care”*
(-5 + 5) = 0
Input Output
A[7:0] 11010100 Y[7:0] XXXXXXXX
B[7:0] 01010100 Zero 1
Funct 0 Overflow 0
[(-5) – (-5)] = 0
Input Output
A[7:0] 11010100 Y[7:0] XXXXXXXX
B[7:0] 11010100 Zero 1
Funct 1 Overflow 0
2) The next few cases will be used to determine if the shifting functions are
working properly. The shifting functions will be used since the exponents are
not equal, therefore the smaller mantissa will need to be shifted in order to
perform the calculation.
18 + 7 = 25
Input Output
A[7:0] 01110010 Y[7:0] 01111001
B[7:0] 01011100 Zero 0
Funct 0 Overflow 0
*note: the values given to input A and input B can be switched in order to do a more
thorough check, the output values should remain unchanged*
21
• Adding two negative numbers
• Adding a positive and negative number where the positive number is bigger
18 + (-7) = 11
Input Output
A[7:0] 01110010 Y[7:0] 01100110
B[7:0] 11011100 Zero 0
Funct 0 Overflow 0
*note: the values given to input A and input B can be switched in order to do a more
thorough check, the output values should remain unchanged*
• Adding a positive and negative number where the negative number is bigger
(-18) + 7 = -11
Input Output
A[7:0] 11110010 Y[7:0] 11100110
B[7:0] 01011100 Zero 0
Funct 0 Overflow 0
*note: the values given to input A and input B can be switched in order to do a more
thorough check, the output values should remain unchanged*
• Subtracting two positive numbers, where the larger positive is given to input A
18 – 7 = 11
Input Output
A[7:0] 01110010 Y[7:0] 01100110
B[7:0] 01011100 Zero 0
Funct 1 Overflow 0
22
• Subtracting two positive numbers, where the larger positive is given to input B
7 – 18 = -11
Input Output
A[7:0] 01011100 Y[7:0] 11100110
B[7:0] 01110010 Zero 0
Funct 1 Overflow 0
• Subtracting two negative numbers, where the larger positive is given to input A
• Subtracting two negative numbers, where the larger positive is given to input B
(-7) – (-18) = 11
Input Output
A[7:0] 11011100 Y[7:0] 01100110
B[7:0] 11110010 Zero 0
Funct 1 Overflow 0
• Subtracting a positive number from a negative number where the absolute value
of the positive number is smaller than the absolute value of the negative number
(-18) – 7 = -25
Input Output
A[7:0] 11110010 Y[7:0] 11111001
B[7:0] 01011100 Zero 0
Funct 1 Overflow 0
• Subtracting a positive number from a negative number where the absolute value
of the positive number is larger than the absolute value of the negative number
(-7) – 18 = -25
Input Output
A[7:0] 11011100 Y[7:0] 11100110
B[7:0] 01110010 Zero 0
Funct 1 Overflow 0
23
• Subtracting a negative number from a positive number where the absolute value
of the positive number is smaller than the absolute value of the negative number
7 – (-18) = 25
Input Output
A[7:0] 01011100 Y[7:0] 01100110
B[7:0] 11110010 Zero 0
Funct 1 Overflow 0
• Subtracting a negative number from a positive number where the absolute value
of the positive number is larger than the absolute value of the negative number
18 – (-7) = 25
Input Output
A[7:0] 01110010 Y[7:0] 01111001
B[7:0] 11011100 Zero 0
Funct 1 Overflow 0
3) Overflow case: this case just checks to see if the resulting number cannot be
represented in the 8 bits provided. (i.e. the absolute value of the number is
greater than 31)
31 + 1 = 32
Input Output
A[7:0] 01111111 Y[7:0] XXXXXXXX
B[7:0] 00110000 Zero 0
Funct 0 Overflow 1
31 – 30 = 1
Input Output
A[7:0] 01111111 Y[7:0] 00110000
B[7:0] 01111110 Zero 0
Funct 1 Overflow 0
24
• Changing the exponent value by 3
15 - 14 = 1
Input Output
A[7:0] 01101110 Y[7:0] 00110000
B[7:0] 01101100 Zero 0
Funct 1 Overflow 0
7–6=1
Input Output
A[7:0] 01011100 Y[7:0] 00110000
B[7:0] 01011000 Zero 0
Funct 1 Overflow 0
3 –2 = 1
Input Output
A[7:0] 01001000 Y[7:0] 00110000
B[7:0] 01000000 Zero 0
Funct 1 Overflow 0
5) Lowest number representation: These cases test the decimal numbers that
can be represented in an 8-bit floating-point scheme.
25
• Adding two fractions which result in a whole number, note also the ability to
express the smallest resolution in the output (the 1/16 bit location)
0.5 + 0.5 = 1
Input Output
A[7:0] 00100000 Y[7:0] 00110000
B[7:0] 00100000 Zero 0
Funct 0 Overflow 0
• Adding a whole number and a fraction to get a mixed number, note also the
ability to express the smallest resolution in the output (the 1/16 bit location)
1 + 0.1875 = 1.1875
Input Output
A[7:0] 00110000 Y[7:0] 00110011
B[7:0] 00001000 Zero 0
Funct 0 Overflow 0
30 + 1 = 31
Input Output
A[7:0] 01111110 Y[7:0] 01111111
B[7:0] 00110000 Zero 0
Funct 0 Overflow 0
14+ 1 = 15
Input Output
A[7:0] 01101100 Y[7:0] 01101110
B[7:0] 00110000 Zero 0
Funct 0 Overflow 0
26
• Shifting the mantissa by 2
6+1=7
Input Output
A[7:0] 01011000 Y[7:0] 01011100
B[7:0] 00110000 Zero 0
Funct 0 Overflow 0
2+1=3
Input Output
A[7:0] 01000000 Y[7:0] 01001000
B[7:0] 00110000 Zero 0
Funct 0 Overflow 0
27
Schematics and Verilog
In this section you will find versions of the same Verilog code. The first code is a
more readable version. It still have module separations and busses which represent
various inputs. This is also the code with comments since it is easier to follow.
The second code is the version of code with all of the busses flatted so that
Electric can handle the synthesized module. The hierarchy of this code was later
removed since the data analyzer outputs a hierarchical vhdl file which also cannot be
handled in Electric.
//Also, this code contains verilog code for both the exponent and mantissa datapaths
wire [2:0] exp_diff_norm; //used in the normalization module, tells the module
//what value to add or subtract to a temp exponent
//value
28
wire [1:0] exp_diff_sign; //tells the normalize module to add or subtract the
exp_diff_norm //value from the temp exp. value
wire [3:0] exp_diff; //result of exp_A - exp_B
//module call to the exponent datapath (this module was used as a guide to hand draw the
//exponent datapath
exp_part get_exp(exp_A, exp_B, exp_diff_norm, exp_diff_sign, exp_diff, exp_Y);
endmodule
//**********************************************************************
//Module: top level module for the synthesis mantissa datapath
module synth_part (A, B, funct, zero, exp_diff_norm, exp_diff_sign, exp_diff, sign_Y,
mant_Y);
29
wire temp_sign; //helps with holding sign_B value in case the bit
//needs to be swizzled to accommodate subtraction
//calls
wire [3:0] small_mant; //holds the mantissa of the number with the
//smaller exponent
//if the exponent value is equal, it is
//arbitrarily set to the mantissa of A
wire [2:0] shift_amount; //amount to shift the small_mant (equal to
//exp_diff) this shift is necessary in order to
//produce a correct output
30
//used if subtraction is used
//assign small_mant to be the value of the mantissa of the number with the smaller of the
//two exponents
big_small mants(mant_A, mant_B, exp_diff, exp_diffsig, mant_diffsig, big_mant,
small_mant);
//assign the shift amount, don't need the highest bit of exp_diff since it just tells you
//which exponent is larger. Also, if exp_B is larger, the exp_diff is in two's compliment
//form so perform another two's compliment to get a positive shift value
assign shift_amount = (exp_diffsig)? -(exp_diff[2:0]): exp_diff[2:0];
//code for addition or subtraction, if subtraction is being done, swizzle the sign bit of B
assign temp_sign = funct? ~sign_B: sign_B;
assign temp_sign_B = temp_sign;
31
right_shifter shift_mantissa(small_mant, shift_amount, shifted_mant);
//calculate the two's compliment of the shifted mant, only needed in the case of
//subtraction or equivalent case (i.e. adding a negative number to a positive number)
twos_comp two_small_mant(sign_A, sign_B, funct, shifted_mant, twos_small_mant);
//normalize the mantissa and exponent value so it's back in floating point representation
normalize normal(temp_mant_Y, mant_Y, exp_diff_norm, exp_diff_sign);
endmodule
//**********************************************************************
//Module: see if the result of the operation results in a zero
reg zero;
32
// a number plus a conjugate
else
zero <= 0;
endmodule
//**********************************************************************
//Module: perform two's compliment if subtraction operation is called for
endmodule
//**********************************************************************
//Module: Normalize the final exponent and mantissa value so it can be represented in
//floating point format
33
reg [2:0]exp_diff_norm;
//find the first "1" (i.e. locate a one and shift accordingly in order to get the implicite
//leading one for floating point representation
always@(in_mant)
begin
if (in_mant[5])
begin
out_mant <= in_mant[4:1];
exp_diff_norm <= 3'b001;
exp_diff_sign <= 2'b01; //0 means add to in_exp
//the value in exp_diff_sign[1] can
//be decoded to determine the
//operation
// 0 => add
// 1 => subtract
//the other bit is used in the exponent
//datapath for the select_bar line of a
//mux
end
else if (in_mant[4])
begin
out_mant <= in_mant[3:0];
exp_diff_norm <= 3'b000;
exp_diff_sign <=2'b01;
end
else if (in_mant[3])
begin
out_mant <= {in_mant[2:0], 1'b0};
exp_diff_norm <= 3'b001; //1
exp_diff_sign <= 2'b10; // 1 means to subtract
end
else if (in_mant[2])
begin
out_mant <= {in_mant[1:0], 2'b00};
exp_diff_norm <= 3'b010; //2
exp_diff_sign <= 2'b10; //subtract
end
else if (in_mant[1])
begin
out_mant <= {in_mant[0], 3'b000};
exp_diff_norm <= 3'b011; //3
exp_diff_sign <= 2'b10; //subtract
end
else if (in_mant[0])
34
begin
out_mant <= 4'b0000;
exp_diff_norm <= 3'b100; //4
exp_diff_sign <= 2'b10; //subtract
end
else
begin
out_mant <= in_mant;
exp_diff_norm <= 3'b001; //1
exp_diff_sign <= 2'b01; //add
end
end
endmodule
//**********************************************************************
//Module: Determines the sign of the resulting value
module final_sign (exp_diffsig, mant_diffsig, exp_diff, sign_A, sign_B, sign_Y);
reg sign_Y;
35
sign_Y <= sign_A; //if the exp_diff is 0 and the
//mant_diffsig != 1
end //A and B have the same exponent but the
//difference in the mantissas are zero or
//greater
else sign_Y <= sign_A; //give sign_Y the sign of A
end //give sign_Y the sign of A
//if exp_diffsig != 1
//(exp_A is bigger) and exp_diff is greater
//than zero
end
endmodule
//**********************************************************************
//Module: find which mantissa is bigger
module big_small (mant_A, mant_B, exp_diff, exp_diffsig, mant_diffsig, big_mant,
small_mant);
36
small_mant <= (mant_diffsig)? mant_A: mant_B;
end
//if the exponents are not equal
else
begin
big_mant <= (exp_diffsig)? mant_B: mant_A;
//big mant is the mantissa of the number with the larger exponent
small_mant <= (exp_diffsig)? mant_A: mant_B;
end
//small mant is the other mantissa
endmodule
//**********************************************************************
//Module: Shifts a given numner to the right by an amount (shift_amt)
module right_shifter(small_mant, shift_amt, shifted_mant);
endcase
endmodule
//**********************************************************************
//Module: Verilog representation of the exponent datapath
37
module exp_part(exp_A, exp_B, exp_diff_norm, exp_diff_sign, exp_diff, exp_Y);
else
//if =0 add
exp_Y <= (temp_exp_Y) + (exp_diff_norm);
endmodule
38
Flatten Code
//Same code but with flattened busses for Electric
//Not as many comments since it's already hard to read
module topadder(A7, A6, A5, A4, A3, A2, A1, A0, B7, B6, B5, B4, B3, B2, B1, B0,
funct, zero, Y7, Y6, Y5, Y4, Y3, Y2, Y1, Y0);
input A0;
input A1;
input A2;
input A3;
input A4;
input A5;
input A6;
input A7;
input B0;
input B1;
input B2;
input B3;
input B4;
input B5;
input B6;
input B7;
output zero ;
output Y0;
output Y1;
output Y2;
output Y3;
output Y4;
output Y5;
output Y6;
output Y7;
wire sign_Y;
wire exp_diff_norm0;
wire exp_diff_norm1;
wire exp_diff_norm2;
wire exp_diff_sign0;
wire exp_diff_sign1;
39
wire exp_diff0;
wire exp_diff1;
wire exp_diff2;
wire exp_diff3;
synth_part get_mant(A7, A3, A2, A1, A0, B7, B3, B2, B1, B0, funct, zero,
exp_diff_norm2, exp_diff_norm1, exp_diff_norm0, exp_diff_sign1, exp_diff_sign0,
exp_diff3, exp_diff2, exp_diff1, exp_diff0, Y7, Y3, Y2, Y1, Y0);
endmodule
//**********************************************************************
module synth_part (A7, A3, A2, A1, A0, B7, B3, B2, B1, B0, funct, zero,
exp_diff_norm2, exp_diff_norm1, exp_diff_norm0, exp_diff_sign1, exp_diff_sign0,
exp_diff3, exp_diff2, exp_diff1, exp_diff0, Y7, Y3, Y2, Y1, Y0);
output zero;
output Y7, Y3, Y2, Y1, Y0;
output exp_diff_norm2, exp_diff_norm1, exp_diff_norm0;
output exp_diff_sign1, exp_diff_sign0;
wire temp_sign;
wire temp_mant_Y5;
wire temp_mant_Y4;
wire temp_mant_Y3;
wire temp_mant_Y2;
wire temp_mant_Y1;
wire temp_mant_Y0;
wire mant_diff4;
wire mant_diff3;
wire mant_diff2;
wire mant_diff1;
wire mant_diff0;
40
wire mant_diffsig;
wire small_mant3;
wire small_mant2;
wire small_mant1;
wire small_mant0;
wire shift_amount0;
wire shift_amount1;
wire shift_amount2;
wire temp_sign_B;
wire twos_small_mant5;
wire twos_small_mant4;
wire twos_small_mant3;
wire twos_small_mant2;
wire twos_small_mant1;
wire twos_small_mant0;
wire exp_diff_sign1;
wire exp_diff_sign0;
wire exp_diff_norm2;
wire exp_diff_norm1;
wire exp_diff_norm0;
41
//assign small_mant to be the value of the mantissa of the number with the smaller of the
//two exponents
big_small mants(A3, A2, A1, A0, B3, B2, B1, B0, exp_diff3, exp_diff2, exp_diff1,
exp_diff0, mant_diffsig, big_mant3, big_mant2, big_mant1, big_mant0, small_mant3,
small_mant2, small_mant1, small_mant0);
endmodule
42
//**********************************************************************
output zero;
reg zero;
endmodule
//**********************************************************************
module twos_comp (A7, B7, funct, shifted_mant5, shifted_mant4, shifted_mant3,
shifted_mant2, shifted_mant1, shifted_mant0, twos_small_mant5, twos_small_mant4,
twos_small_mant3, twos_small_mant2, twos_small_mant1, twos_small_mant0);
43
endmodule
//**********************************************************************
module normalize (in_mant5, in_mant4, in_mant3, in_mant2, in_mant1, in_mant0,
out_mant3, out_mant2, out_mant1, out_mant0, exp_diff_norm2,
exp_diff_norm1, exp_diff_norm0, exp_diff_sign1, exp_diff_sign0);
if (in_mant5)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= {in_mant4,
in_mant3, in_mant2, in_mant1};
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b001;
{exp_diff_sign1, exp_diff_sign0} <= 2'b01;
end
else if (in_mant4)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= {in_mant3,
in_mant2, in_mant1, in_mant0};
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b000;
{exp_diff_sign1, exp_diff_sign0} <=2'b01;
end
else if (in_mant3)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <=
{{in_mant2, in_mant1, in_mant0}, 1'b0};
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b001;
{exp_diff_sign1, exp_diff_sign0} <= 2'b10;
end
else if (in_mant2)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= {{in_mant1,
in_mant0}, 2'b00};
44
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b010;
{exp_diff_sign1, exp_diff_sign0} <= 2'b10;
end
else if (in_mant1)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= {in_mant0,
3'b000};
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b011;
{exp_diff_sign1, exp_diff_sign0} <= 2'b10;
end
else if (in_mant0)
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= 4'b0000;
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b100;
{exp_diff_sign1, exp_diff_sign0} <= 2'b10;
end
else
begin
{out_mant3, out_mant2, out_mant1, out_mant0} <= {in_mant3,
in_mant2, in_mant1, in_mant0};
{exp_diff_norm2, exp_diff_norm1, exp_diff_norm0} <= 3'b001;
{exp_diff_sign1, exp_diff_sign0} <= 2'b01;
end
end
endmodule
//**********************************************************************
module final_sign (mant_diffsig, exp_diff3, exp_diff2, exp_diff1, exp_diff0, sign_A,
sign_B, sign_Y);
input mant_diffsig;
input exp_diff3, exp_diff2, exp_diff1, exp_diff0;
input sign_A;
input sign_B;
output sign_Y;
reg sign_Y;
45
else
begin
if ({exp_diff3, exp_diff2, exp_diff1, exp_diff0} == 4'b0000)
//if the exp_diff is 0 (the two exp are equal),
begin //check the mantissa values
if (mant_diffsig) //if the mant_diffsig is 1 (B is bigger)
sign_Y <=sign_B; //give sign_Y the sign
//of B
else
sign_Y <= sign_A; //if the exp_diff is 0
//and the mant_diffsig
//!= 1
end //(A and B have the
//same exponent but
//the difference in the
//mantissas are zero or
//greater
else sign_Y <= sign_A;
//give sign_Y the sign of A
end //give sign_Y the sign of A if exp_diffsig !=
//1 (exp_A is bigger)
//and exp_diff is greater than zero
end
endmodule
//**********************************************************************
//find which mantissa is bigger
module big_small (A3, A2, A1, A0, B3, B2, B1, B0, exp_diff3, exp_diff2, exp_diff1,
exp_diff0, mant_diffsig, big_mant3, big_mant2, big_mant1, big_mant0, small_mant3,
small_mant2, small_mant1, small_mant0);
reg A3, A2, A1, A0, B3, B2, B1, B0, exp_diff3, exp_diff2, exp_diff1, exp_diff0;
reg big_mant3, big_mant2, big_mant1, big_mant0, small_mant3, small_mant2,
small_mant1, small_mant0;
46
always@(A3 or A2 or A1 or A0 or B3 or B2 or B1 or B0 or exp_diff3 or exp_diff2 or
exp_diff1
or exp_diff0 or mant_diffsig)
endmodule
//**********************************************************************
module right_shifter(small_mant3, small_mant2, small_mant1, small_mant0,
shift_amount2, shift_amount1, shift_amount0, shifted_mant5, shifted_mant4,
shifted_mant3, shifted_mant2, shifted_mant1, shifted_mant0);
47
3'b001: {shifted_mant5, shifted_mant4, shifted_mant3,
shifted_mant2, shifted_mant1, shifted_mant0} <=
{3'b001, {small_mant3, small_mant2, small_mant1}};
endcase
endmodule
//**********************************************************************
//exponent stuff
module exp_part(A6, A5, A4, B6, B5, B4, exp_diff_norm2, exp_diff_norm1,
exp_diff_norm0, exp_diff_sign1, exp_diff_sign0, exp_diff3, exp_diff2, exp_diff1,
exp_diff0, Y6, Y5, Y4);
input A6, A5, A4, B6, B5, B4, exp_diff_norm2, exp_diff_norm1, exp_diff_norm0;
input exp_diff_sign1, exp_diff_sign0;
wire exp_diffsig;
wire temp_exp_Y2;
wire temp_exp_Y1;
wire temp_exp_Y0;
48
//find exponent difference
assign {exp_diff3, exp_diff2, exp_diff1, exp_diff0} = {A6, A5, A4} - {B6, B5, B4};
//give the exp_Y the exp value of the bigger exp value
assign {temp_exp_Y2, temp_exp_Y1, temp_exp_Y0} = (exp_diff3)? {B6, B5, B4}: {A6,
A5, A4};
else
//if =0 add
{Y6, Y5, Y4} <= ({temp_exp_Y2, temp_exp_Y1, temp_exp_Y0}) +
({exp_diff_norm2, exp_diff_norm1, exp_diff_norm0});
endmodule
49
Schematics
Leaf Cell: Mux2 Schematic
50
Exponent Bitslice Schematic
51
Exponent and Mantissa Datapath Schematic
You will note that the schematic for the mantissa is missing. A program called
data analyzer is supposed to be able to generate a schematic and layout from Verilog
code. However, the code cannot contain any hierarchy or busses for data lines. The
entire Verilog code was rewritten to accommodate Electric. However, even though the
Verilog code does not contain any module calls, it implies an adder and a subtractor. The
Data Analyzer program created an adder and a subtractor in submodules. The Data
Anaylzer has a “Flatten Hierarchy” option, however, when we applied it to the design it
said that the operation to flatten hierarchy was too expensive. The Data Analyzer creates
a .vhdl file which is supposed to be imported into the Silicon Compiler option in Electric.
Electric then reads the .vhdl netlist to create a layout and a schematic of your code. On
the off chance that Electric would be able to handle the adder and subtractor submodules,
we imported the Data Analyzer result to Electric. However, Electric was unable to create
the desired designs since it was unable to handle the .vhdl file sent by the Data Analyzer.
There is a slight possibility that one could trick the Data Analyzer into creating the adder
without generating a submodule. This would require someone to layout the result of each
bit on an adder using logic gates. This problem quickly turns into a gigantic undertaking.
52
Layout
Leaf Cell: Mux2
53
Exponent Bitslice Layout
54