@@ -17,6 +17,9 @@ export mkNonPipelinedSquareRooter;
17
17
18
18
module mkSquareRooter# ( Integer n)( Server# ( UInt # ( m) , Tuple2# ( UInt # ( m) , Bool )))
19
19
provisos (
20
+ Div # ( m, 2 , m2) ,
21
+ // m must be even for this implementation to work
22
+ Mul # ( m2, 2 , m) ,
20
23
// per request of bsc
21
24
Add # ( a__, 2 , m) ,
22
25
Log # ( TAdd # ( 1 , m) , TLog # ( TAdd # ( m, 1 )))
@@ -48,7 +51,7 @@ module mkSquareRooter#(Integer n)(Server#(UInt#(m),Tuple2#(UInt#(m),Bool)))
48
51
FIFO # ( Tuple4# ( Maybe # ( Bit # ( m)) , Bit # ( m) , Bit # ( m) , Bit # ( m))) fThis = fFirst;
49
52
FIFO # ( Tuple4# ( Maybe # ( Bit # ( m)) , Bit # ( m) , Bit # ( m) , Bit # ( m))) fNext;
50
53
51
- for ( Integer i = 0 ; i < ( valueOf( m ) / 2 ) / n+ 1 ; i = i + 1 ) begin
54
+ for ( Integer i = 0 ; i < valueOf( m2 ) / n+ 1 ; i = i + 1 ) begin
52
55
fNext < - mkLFIFO;
53
56
rule work;
54
57
// match {.res, .s, .r, .b} <- toGet(fThis).get;
@@ -59,7 +62,7 @@ module mkSquareRooter#(Integer n)(Server#(UInt#(m),Tuple2#(UInt#(m),Bool)))
59
62
Bit # ( m) b = tpl_4( x) ;
60
63
61
64
for ( Integer j = 0 ; j < n; j = j + 1 ) begin
62
- if (( i + j) <= ( valueOf( m ) / 2 )) begin
65
+ if (( i + j) <= valueOf( m2 )) begin
63
66
if ( res matches tagged Invalid) begin
64
67
if ( b == 0 ) begin
65
68
res = tagged Valid r;
@@ -101,6 +104,7 @@ module mkFixedPointSquareRooter#(Integer n)(Server#(FixedPoint#(isize,fsize),Tup
101
104
provisos (
102
105
Add # ( isize, fsize, m) ,
103
106
// per request of bsc
107
+ Mul # ( TDiv # ( m, 2 ) , 2 , m) ,
104
108
Add # ( a__, 2 , m) ,
105
109
Add # ( b__, TLog # ( TAdd # ( 1 , m)) , TAdd # ( TLog # ( m) , 1 )) ,
106
110
Log # ( TAdd # ( 1 , m) , TLog # ( TAdd # ( m, 1 ))) ,
@@ -120,17 +124,24 @@ module mkFixedPointSquareRooter#(Integer n)(Server#(FixedPoint#(isize,fsize),Tup
120
124
let zeros = countZerosMSB( pack( value)) ;
121
125
Int # ( TAdd # ( TLog # ( m) , 1 )) shift;
122
126
127
+ // if (fsize + zeros) is not even, round zeros down
128
+ if ( valueOf( fsize) % 2 == 0 )
129
+ zeros = zeros & ( ~ 1 ) ;
130
+ else
131
+ zeros = ( zeros & 1 ) == 0 ? zeros - 1 : zeros;
132
+
123
133
// align input
124
- value = value << ( zeros - 1 ) ;
134
+ value = value << zeros;
125
135
126
- // compute shift for output
127
- shift = ( fromInteger( valueOf( isize)) - cExtend( zeros)) >> 1 ;
128
- shift = shift + 1 ;
129
- if (( shift & 1 ) == 0 ) begin
130
- value = value >> 1 ;
131
- end
136
+ // A conversion to UInt behaves like the value was multiplied by 2**fsize.
137
+ // Then, the value is shifted by zeros, which multiplies it by 2**zeros.
138
+ // Therefore, after computing the square root of the resulting value,
139
+ // it must be divided by sqrt(2**(fsize + zeros)) = 2**((fsize + zeros) / 2)
140
+ shift = extend( unpack( pack( ( zeros + fromInteger( valueOf( fsize))) >> 1 ))) ;
132
141
133
- shift = fromInteger( valueOf( isize)) - shift;
142
+ // Converting the value back from UInt to FixedPoint will already divide it
143
+ // by 2**fsize, therefore this is excluded from the shift
144
+ shift = shift - fromInteger( valueOf( fsize)) ;
134
145
135
146
sqrt.request.put( value) ;
136
147
fShift.enq( shift) ;
@@ -141,11 +152,14 @@ module mkFixedPointSquareRooter#(Integer n)(Server#(FixedPoint#(isize,fsize),Tup
141
152
let shift < - toGet( fShift) .get;
142
153
143
154
// shift result as necessary
144
- result = result >> shift;
155
+ if ( shift >= 0 )
156
+ result = result >> shift;
157
+ else // invert direction if shift is negative
158
+ result = result << ( - shift) ;
145
159
146
160
FixedPoint# ( isize, fsize) fx;
147
- fx.i = cExtendLSB ( result) ;
148
- fx.f = cExtend ( result) ;
161
+ fx.i = truncateLSB ( pack ( result) );
162
+ fx.f = truncate ( pack ( result) );
149
163
150
164
fResponse.enq( tuple2( fx, inexact)) ;
151
165
endrule
@@ -287,6 +301,8 @@ module mkTb(Empty);
287
301
testSqrtPipe( 'hffff0000_00000000 ) ;
288
302
testSqrtPipe( 'hfffe0000 ) ;
289
303
304
+ testSqrtPipe( 536870912.9375 ) ;
305
+ testSqrtPipe( 1073741824.96875 ) ;
290
306
testSqrtPipe( 0.5 ) ;
291
307
testSqrtPipe( 0.25 ) ;
292
308
@@ -307,10 +323,10 @@ module mkTb(Empty);
307
323
end
308
324
309
325
if ( rfx != rrfx) begin
310
- $display ( " sqrtfx(" , fshow( nfx) , " ) = " , fshow( rfx ) , " (expected " , fshow( rrfx ) , " )" ) ;
326
+ $display ( " sqrtfx(" , fshow( nfx) , " ) = " , fshow( rrfx ) , " (expected " , fshow( rfx ) , " )" ) ;
311
327
end
312
328
else begin
313
- $display ( " sqrtfx(" , fshow( nfx) , " ) = " , fshow( rfx )) ;
329
+ $display ( " sqrtfx(" , fshow( nfx) , " ) = " , fshow( rrfx )) ;
314
330
end
315
331
endrule
316
332
0 commit comments