source: vis_dev/vis-2.1/examples/fpmpy/fpmpy.v @ 11

Last change on this file since 11 was 11, checked in by cecile, 13 years ago

Add vis

File size: 6.1 KB
Line 
1// VIS testbench for a sequential floating point multiplier.
2// The purpose of this testbench is exclusively to latch the inputs, so
3// that CTL properties may refer to them.
4//
5// Author: Fabio Somenzi <Fabio@Colorado.EDU>
6//
7module fvFPMult(clock,i,j);
8    parameter             MBITS = 3;    // size of significand minus hidden bit
9    parameter             EBITS = 4;    // size of exponent
10    input                 clock;        // global clock
11    input [MBITS+EBITS:0] i;            // multiplicand
12    input [MBITS+EBITS:0] j;            // multiplier
13    reg   [MBITS+EBITS:0] x;            // multiplicand
14    reg   [MBITS+EBITS:0] y;            // multiplier
15    wire  [MBITS+EBITS:0] z;            // output register
16    reg                   start;        // starts multiplier
17
18    IEEEfpMult #(MBITS,EBITS) FPM (clock,start,x,y,z);
19
20    always @ (posedge clock) begin
21        x = i;
22        y = j;
23    end // always @ (posedge clock)
24
25endmodule // fvFPMult
26
27// Floating point multiplier.
28// Not exactly IEEE 754-compliant, but largely inspired to the standard.
29//
30// The significand uses the hidden bit and is between 1 (included) and 2
31// (excluded).
32// The exponent uses the excess (2**(n-1) - 1) representation. For single
33// precision, this is excess 127.
34// The smallest exponent (0) is used for the represenation of 0. Denormals
35// are not supported.
36// The largest exponent is used for infinities and NaNs. Infinities use
37// the smallest possible significand (all zeroes). Everything else is deemed
38// a NaN. No distinction is made between signalling and non-signalling NaNs.
39// When the multiplier generates a NaN, it uses the all-one significand.
40// One multiplication takes three clock cycles and it is not pipelined.
41//
42// Author: Fabio Somenzi <Fabio@Colorado.EDU>
43//
44module IEEEfpMult(clock,start,x,y,z);
45    parameter              MBITS = 3; // size of significand minus hidden bit
46    parameter              EBITS = 4; // size of exponent
47    input                  clock;
48    input                  start;
49    input [MBITS+EBITS:0]  x, y;
50    output [MBITS+EBITS:0] z;
51
52    reg [MBITS+EBITS:0]    z;
53    reg                    xSign;       // unpacked x with hidden bit exposed
54    reg [EBITS-1:0]        xExp;
55    reg [MBITS:0]          xMant;
56    reg                    ySign;       // unpacked y with hidden bit exposed
57    reg [EBITS-1:0]        yExp;
58    reg [MBITS:0]          yMant;
59    reg [1:0]              state;       // idle, computing, postprocessing
60    reg                    signProd;    // components of the product
61    reg [EBITS+1:0]        expProd;     // before rounding and normalization
62    reg [2*MBITS+1:0]      mantProd;
63    wire                   msb;
64    wire                   lsb;
65    wire                   guard;
66    wire                   round;
67    wire                   sticky;
68    wire [MBITS+1:0]       preMant;
69    wire [EBITS+1:0]       scaledExp;
70    wire [MBITS-1:0]       scaledMant;
71    wire [2*MBITS+1:0]     combZ;
72
73    intMult im(xMant, yMant, combZ);
74
75    function NaN;
76        input [EBITS-1:0] aExp;
77        input [MBITS-1:0] aMant;
78    begin: isNaN
79        if (aExp == {EBITS{1'b1}} && aMant != 0)
80            NaN = 1;
81        else
82            NaN = 0;
83    end // block: isNaN
84    endfunction // NaN
85
86    function Zero;
87        input [EBITS-1:0] aExp;
88        input [MBITS-1:0] aMant;
89    begin: isZero
90        if (aExp == 0 && aMant == 0)
91            Zero = 1;
92        else
93            Zero = 0;
94    end // block: isZero
95    endfunction // Zero
96
97    function Infinity;
98        input [EBITS-1:0] aExp;
99        input [MBITS-1:0] aMant;
100    begin: isInfinity
101        if (aExp == {EBITS{1'b1}} && aMant == 0)
102            Infinity = 1;
103        else
104            Infinity = 0;
105    end // block: isInfinity
106    endfunction // Infinity
107
108    parameter
109        idle = 2'd0,
110        computing = 2'd1,
111        postprocessing = 2'd2;
112
113    initial begin
114        xSign    = 0;
115        xExp     = 0;
116        xMant    = 0;
117        ySign    = 0;
118        yExp     = 0;
119        yMant    = 0;
120        signProd = 0;
121        expProd  = 0;
122        mantProd = 0;
123        z        = 0;
124        state    = idle;
125    end
126
127    always @ (posedge clock) begin
128        case (state)
129          idle:
130              begin
131                  if (start) begin      // unpack operands
132                      xSign = x[MBITS+EBITS];
133                      xExp  = x[MBITS+EBITS-1:MBITS];
134                      xMant = {1'b1,x[MBITS-1:0]};
135                      ySign = y[MBITS+EBITS];
136                      yExp  = y[MBITS+EBITS-1:MBITS];
137                      yMant = {1'b1,y[MBITS-1:0]};
138                      state = computing;
139                  end // if (start)
140              end // case: idle
141          computing:
142              begin
143                  mantProd = combZ;
144                  if (Zero(xExp,xMant) || Zero(yExp,yMant))
145                      expProd = 0;
146                  else
147                      expProd  = xExp + yExp - {EBITS-1{1'b1}};
148                  signProd = xSign ^ ySign;
149                  state = postprocessing;
150              end // case: computing
151          postprocessing:
152              begin
153                  if (NaN(xExp,xMant) || NaN(yExp,yMant) ||
154                      Infinity(xExp,xMant) && Zero(yExp,yMant) ||
155                      Zero(xExp,xMant) && Infinity(yExp,yMant))
156                      z = {1'b0,{EBITS{1'b1}},{MBITS{1'b1}}}; // NaN
157                  else if (Infinity(xExp,xMant) || Infinity(yExp,yMant))
158                      z = {signProd,{EBITS{1'b1}},{MBITS{1'b0}}}; // +/- Infinity
159                  else
160                      // check for underflow and overflow
161                      if (scaledExp[EBITS+1] || scaledExp == 0)
162                          z = {signProd,{MBITS+EBITS{1'b0}}}; // signed zero
163                      else if (scaledExp >= {EBITS{1'b1}}) // overflow
164                          z = {signProd,{EBITS{1'b1}},{MBITS{1'b0}}}; // +/- Infinity
165                      else
166                          z = {signProd,scaledExp[EBITS-1:0],scaledMant};
167                  state = idle;
168              end // case: postprocessing
169        endcase // case (state)
170    end // always @ (posedge clock)
171
172    // Combinational logic for rounding and normalization
173    assign msb    = mantProd[2*MBITS+1];        // MSB of the product
174    assign lsb    = mantProd[MBITS+1];          // LSB of the result
175    assign guard  = mantProd[MBITS];            // guard bit
176    assign round  = mantProd[MBITS-1];          // round bit
177    assign sticky = | mantProd[MBITS-2:0];      // sticky bit
178    // round to nearest even
179    assign preMant = msb ?
180        mantProd[2*MBITS+1:MBITS] +
181            {{MBITS{1'b0}}, guard & (round | sticky | lsb), 1'b0}
182            :
183            mantProd[2*MBITS+1:MBITS] +
184                {{MBITS+1{1'b0}}, round & (sticky | guard)};
185    // normalize
186    assign scaledExp = preMant[MBITS+1] ?
187        expProd + 1 :
188            expProd;
189    assign scaledMant = preMant[MBITS+1] ?
190        preMant[MBITS:1] :
191            preMant[MBITS-1:0];
192
193endmodule // IEEEfpMult
194
195module intMult(x,y,z);
196    input  [3:0] x, y;
197    output [7:0] z;
198
199    wire [3:0] int0;
200    wire [5:0] int1;
201    wire [6:0] int2;
202    wire [7:0] int3;
203
204    assign int0 = {4{y[0]}} & x;
205    assign int1 = int0 + {{4{y[1]}} & x, {1{1'b0}}};
206    assign int2 = int1 + {{4{y[2]}} & x, {2{1'b0}}};
207    assign int3 = int2 + {{4{y[3]}} & x, {3{1'b0}}};
208
209    assign z = int3;
210
211endmodule // intMult
Note: See TracBrowser for help on using the repository browser.