|
Message
From: cvs at opencores.org<cvs@o...>
Date: Tue May 20 12:57:53 CEST 2008
Subject: [cvs-checkins] MODIFIED: fpipelines ...
Date: 00/08/05 20:12:57 Added: fpipelines fadd.v Log: Floating point adder Revision Changes Path 1.1 fpipelines/fadd.v http://www.opencores.org/cvsweb.shtml/fpipelines/fadd.v?rev=1.1&content-type=text/x-cvsweb-markup Index: fadd.v =================================================================== /* * Pipelined floating point adder/substracter * Copyright (C) 2008 Sebastien Bourdeauducq - http://lekernel.net * This file is part of Milkymist. * * Milkymist is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ module fadd( input clk, input sub, input [31:0] a, input [31:0] b, output [31:0] r ); wire sa; wire [7:0] ea; wire [22:0] fa; assign sa = a[31]; assign ea = a[30:23]; assign fa = a[22:0]; wire sb; wire [7:0] eb; wire [22:0] fb; assign sb = b[31]; assign eb = b[30:23]; assign fb = b[22:0]; /* Stage 1 * Sort the numbers according to the exponent. * A becomes the number with the biggest exponent. * Negate b in case of substraction. */ reg sa1; reg [7:0] ea1; reg [22:0] fa1; reg sb1; reg [7:0] eb1; reg [22:0] fb1; always @(posedge clk) begin if(ea > eb) begin sa1 <= sa; ea1 <= ea; fa1 <= fa; sb1 <= sb ^ sub; eb1 <= eb; fb1 <= fb; end else begin sa1 <= sb ^ sub; ea1 <= eb; fa1 <= fb; sb1 <= sa; eb1 <= ea; fb1 <= fa; end end /* Stage 2 * Add leading (integer) bits on the mantissas. * Compute the difference between the exponents. */ reg [7:0] diff2; reg sa2; reg [7:0] ea2; reg [23:0] fa2; reg sb2;
reg [23:0] fb2;
always @(posedge clk) begin
diff2 <= ea1 - eb1;
sa2 <= sa1;
ea2 <= ea1;
fa2 <= {~(ea1 == 8'h00), fa1};
sb2 <= sb1;
fb2 <= {~(eb1 == 8'h00), fb1};
end
/* Stage 3
* Shift B's mantissa.
* We add trailing zeros to improve precision,
* and a leading zero (at stage 4) for the possible carry.
*/
reg sa3;
reg [7:0] ea3;
reg [23:0] fa3;
reg sb3;
reg [30:0] fb3;
always @(posedge clk) begin
sa3 <= sa2;
ea3 <= ea2;
fa3 <= fa2;
sb3 <= sb2;
fb3 <= {fb2, 7'b0000000} >> diff2;
end
/* Stage 4
* Compute fa+fb, fa-fb and fb-fa.
* Determine which one we will choose at stage 5.
*/
reg sa4;
reg [7:0] ea4;
reg [31:0] fapfb4;
reg [31:0] famfb4;
reg [31:0] fbmfa4;
reg sub4;
reg fcompare4;
always @(posedge clk) begin
sa4 <= sa3;
ea4 <= ea3;
fapfb4 <= {1'b0, fa3, 7'b0000000} + {1'b0, fb3};
famfb4 <= {1'b0, fa3, 7'b0000000} - {1'b0, fb3};
fbmfa4 <= {1'b0, fb3} - {1'b0, fa3, 7'b0000000};
sub4 <= sa3 ^ sb3;
fcompare4 <= {fa3, 7'b0000000} > fb3;
end
/* Stage 5
* Choose the right operation.
* Count leading zeros (clz32 module).
* Compute the sign of the result.
* Test for zero result.
*/
reg sr5;
reg [7:0] er5;
reg [31:0] fr5;
reg [31:0] fr4;
always @(sub4 or fcompare4 or famfb4 or fbmfa4 or fapfb4) begin
if(sub4) begin
if(fcompare4)
fr4 <= famfb4;
else
fr4 <= fbmfa4;
end else
fr4 <= fapfb4;
end
wire [4:0] lz4;
reg [4:0] lz5;
clz32 clz(
.d(fr4),
.clz(lz4)
);
reg zero5;
always @(posedge clk) begin
sr5 <= sa4 ^ (sub4 & ~fcompare4);
er5 <= ea4;
fr5 <= fr4;
zero5 <= fr4 == 32'h00000000;
lz5 <= lz4;
end
/* Stage 6
* Normalize.
*/
reg sr6;
reg [7:0] er6;
reg [22:0] fr6;
wire [31:0] sfr5;
assign sfr5 = fr5 << lz5;
always @(posedge clk) begin
if(zero5) begin
sr6 <= 1'b0;
er6 <= 8'h00;
fr6 <= 23'b00000000_00000000_0000000;
end else begin
sr6 <= sr5;
er6 <= er5 + 1 - lz5;
fr6 <= sfr5[30:8];
end
end
assign r[31] = sr6;
assign r[30:23] = er6;
assign r[22:0] = fr6;
endmodule
|
 |