📄 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; endend/* 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;endwire [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]; endendassign r[31] = sr6;assign r[30:23] = er6;assign r[22:0] = fr6;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -