<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Vorformatiert Zchn";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:36.0pt;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
span.E-MailFormatvorlage19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
span.HTMLVorformatiertZchn
{mso-style-name:"HTML Vorformatiert Zchn";
mso-style-priority:99;
mso-style-link:"HTML Vorformatiert";
font-family:"Courier New";}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:97334686;
mso-list-type:hybrid;
mso-list-template-ids:-1730660458 -1 -1 -1 -1 -1 -1 -1 -1 -1;}
@list l0:level1
{mso-level-number-format:alpha-lower;
mso-level-text:"%1\)";
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1
{mso-list-id:613099571;
mso-list-type:hybrid;
mso-list-template-ids:-1730660458 67567639 67567641 67567643 67567631 67567641 67567643 67567631 67567641 67567643;}
@list l1:level1
{mso-level-number-format:alpha-lower;
mso-level-text:"%1\)";
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l1:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2
{mso-list-id:1226795538;
mso-list-type:hybrid;
mso-list-template-ids:1389545008 67567639 67567641 67567643 67567631 67567641 67567643 67567631 67567641 67567643;}
@list l2:level1
{mso-level-number-format:alpha-lower;
mso-level-text:"%1\)";
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l2:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l3
{mso-list-id:2095546361;
mso-list-type:hybrid;
mso-list-template-ids:-732139332 1531232760 67567619 67567621 67567617 67567619 67567621 67567617 67567619 67567621;}
@list l3:level1
{mso-level-start-at:0;
mso-level-number-format:bullet;
mso-level-text:-;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:"Calibri",sans-serif;
mso-fareast-font-family:Calibri;}
@list l3:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:"Courier New";}
@list l3:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7 ;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:Wingdings;}
@list l3:level4
{mso-level-number-format:bullet;
mso-level-text:\F0B7 ;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:Symbol;}
@list l3:level5
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:"Courier New";}
@list l3:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7 ;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:Wingdings;}
@list l3:level7
{mso-level-number-format:bullet;
mso-level-text:\F0B7 ;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:Symbol;}
@list l3:level8
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:"Courier New";}
@list l3:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7 ;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:Wingdings;}
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
--></style>
</head>
<body lang="DE-CH" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Hi<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I ported the Verilog code of the floating multiplication to Oberon-07.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Some of the Oberon code could be written more elegantly in Oberon, but for the sake of comparing 1:1, I let the code as it is in Verlog.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">PROCEDURE Bit(x: INTEGER; hi, lo: INTEGER): INTEGER;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> RETURN ROR(x, lo) MOD LSL(2, hi-lo)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> END Bit;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">PROCEDURE FML*(x, y: REAL; VAR z: REAL); (* floating multiply *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> VAR<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> S: INTEGER; (* state *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> P0, P24: INTEGER; (* 48 bit product: 0..23 and 24..47 *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> sign: BOOLEAN;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> xe, ye: INTEGER; (* 8 bits *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">
</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">e0, e1: INTEGER; (* 9 bits *)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US"> w0: INTEGER; (* 24 bits *)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US">
</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">w1, z0: INTEGER; (* 25 bits *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> BEGIN<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> sign := Bit(ORD(x), 31, 31) # Bit(ORD(y), 31, 31);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> xe := Bit(ORD(x), 30, 23);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> ye := Bit(ORD(y), 30, 23);
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> Out.printf("xe = %d, ye = %d\n", xe, ye, "");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> e0 := xe + ye;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> P24 := 0; P0 := 800000H + Bit(ORD(x), 22, 0);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> FOR S := 0 TO 23 DO (* look at all bits in p0 aka x *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> IF ODD(P0) THEN w0 := 800000H + Bit(ORD(y), 22, 0) ELSE w0 := 0 END;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> w1 := P24 + w0; (* 25 bit result *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> (* P <= {w1, P[23:1]} *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> P0 := Bit(P0, 23, 1); (* this is P0 := P0 DIV 2 *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> IF ODD(w1) THEN P0 := P0 + 800000H END;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> P24 := w1 DIV 2<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> END;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> Out.printf("product P =%x%x\n", P24, P0, "");<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> IF Bit(P24, 23, 23) = 1 THEN<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> z0 := P24*2 + Bit(P0, 23, 23) + 1<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> ELSE<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> z0 := P24*4 + Bit(P0, 23, 22) + 1 (* e1 is not adjusted if rounding sets the highest bit!! *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> END;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> e1 := e0 - 127 + Bit(P24, 23, 23); (* P[47] *)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">
</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">Out.printf("z0 = %x, e1 = %d\n", z0, e1, "");<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US">
</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">IF (xe = 0) OR (ye = 0) THEN z := 0R<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> ELSIF Bit(e1, 8, 8) = 0 THEN z := SYSTEM.VAL(REAL, Bit(e1, 7, 0)* 800000H + Bit(z0, 23, 1))<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> ELSIF Bit(e1, 7, 7) = 0 THEN z := SYSTEM.VAL(REAL, 7F800000H+ Bit(z0, 23, 1))<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> ELSE z := 0R<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> END;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> IF sign THEN z := -z END<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">
</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">END FML;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">If the highest bit of the 48 bit product is set, we have to adjust the final exponent e1 by one.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">There are TWO possibilities how the highest bit of the product P is set<o:p></o:p></span></p>
<ol style="margin-top:0cm" start="1" type="a">
<li class="MsoListParagraph" style="margin-left:0cm;mso-list:l1 level1 lfo2"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Either the values of x and y are big enough, so their products sets the highest bit.<o:p></o:p></span></li></ol>
<p class="MsoListParagraph"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">This case is taken care of by
</span><span lang="EN-US">assign e1 = e0 - 127 + P[47];<o:p></o:p></span></p>
<p class="MsoListParagraph">Or in Oberon<span style="font-size:11.0pt;mso-fareast-language:EN-US"> e1 := e0 - 127 + Bit(P24, 23, 23);<o:p></o:p></span></p>
<p class="MsoListParagraph"><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<ol style="margin-top:0cm" start="2" type="a">
<li class="MsoListParagraph" style="margin-left:0cm;mso-list:l1 level1 lfo2"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">During the final rounding step from P to z0 a carry might flow over to the highest bit<br>
If this is the case e1 is not adjusted. So basically this step is wrong<o:p></o:p></span></li></ol>
<pre><span lang="EN-US"> assign z0 = P[47] ? P[47:23]+1 : P[46:22]+1; // round and normalize<o:p></o:p></span></pre>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">So far the analysis. I’ll try to come up with a solution.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">br<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Jörg
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">Von:
</span></b><span style="font-size:12.0pt;color:black">Oberon <oberon-bounces@lists.inf.ethz.ch> im Auftrag von Michael Schierl <schierlm@gmx.de><br>
<b>Datum: </b>Freitag, 13. Oktober 2023 um 23:55<br>
<b>An: </b>oberon@lists.inf.ethz.ch <oberon@lists.inf.ethz.ch><br>
<b>Betreff: </b>Re: [Oberon] Wrong results of selected REAL multiplications<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">Hello,<br>
<br>
<br>
Am 13.10.2023 um 18:39 schrieb Hans Klaver:<br>
<br>
>> The problem does not occur on a April 2016 verison of Peter's<br>
>> emulator. This leads me to suspect that the problem may have been<br>
>> introduced during the changes to the Floating Point-related Verilog<br>
>> files that were made between 8 Aug 2016 and 3 Oct 2016 as<br>
>> summarised here:<br>
>><br>
>> <a href="https://people.inf.ethz.ch/wirth/news.txt">https://people.inf.ethz.ch/wirth/news.txt</a><br>
<br>
For the record, the changes talked about are in this diff:<br>
<<a href="https://github.com/Spirit-of-Oberon/wirth-personal/commit/359240b9d1c63d23aff6c90aa90fdd46917c743b">https://github.com/Spirit-of-Oberon/wirth-personal/commit/359240b9d1c63d23aff6c90aa90fdd46917c743b</a>>.<br>
<br>
> Thanks for checking this.<br>
><br>
> As I don't know much about Verilog programming I am afraid that I<br>
> can't be of much help to pinpoint this bug and propose a solution.<br>
<br>
I don't think having experience about Verilog programming really helps<br>
me much in understanding this very dense code of parallel bit-twiddling<br>
(and a significant part of the twiddling and its state machine is for<br>
doing the "integer" multiplication of the mantissae).<br>
<br>
> Hoping others in the community are able and willing to look into<br>
> this.<br>
<br>
Just starting from the facts you stated (sometimes, when multiplying a<br>
value with mantissa # 1.0 with a value with mantissa # 1.0 and the<br>
result has a mantissa = 1.0, the exponent is off by one), and when<br>
looking at the changes to FPMultiplier in the commit above, I have a<br>
suspicion ...<br>
<br>
Just picking a few lines of the assignments from the new version (I<br>
slightly reordered them for the argument, but that does not matter as<br>
all those assignments happen in parallel anyway):<br>
<br>
<br>
reg [47:0] P; // product<br>
wire [24:0] z0;<br>
<br>
assign e1 = e0 - 127 + P[47];<br>
<br>
assign z0 = P[47] ? P[47:23]+1 : P[46:22]+1; // round and normalize<br>
<br>
assign z = (xe == 0) | (ye == 0) ? 0 :<br>
(~e1[8]) ? {sign, e1[7:0], z0[23:1]} :<br>
(~e1[7]) ? {sign, 8'b11111111, z0[23:1]} : 0;<br>
<br>
<br>
Or condensed to the part I'd like to point out<br>
<br>
<br>
assign e1 = <something> + P[47];<br>
<br>
assign z0 = P[47] ? P[47:23]+1 : P[46:22]+1; // round and normalize<br>
<br>
assign z = <some corner cases omitted, but the main case is><br>
{sign, e1[7:0], z0[23:1]};<br>
<br>
<br>
z is our final output, and in the final step of the state machine it<br>
gets set by using e1 as exponent and the "middle" of z0 as mantissa<br>
(while z0 is a 25-bit value, we omit the first and last bit of it. First<br>
bit has to be 1 and is omitted in IEEE float representation, and last<br>
bit was there for better rounding).<br>
<br>
Both exponent and mantissa have special logic for handing the most<br>
significant bit of the intermediate product, P[47], to be 1. In that<br>
case we increase the exponent by 1, while at the same time shifting the<br>
mantissa one more bit. That way, even if P[47] is not 1, P[46] is 1, so<br>
we end up with a normalized mantissa.<br>
<br>
Or at least, that is what you might think at first point.<br>
<br>
Now consider the case, where (the relevant part of) P has the value of<br>
<br>
0111111111111111111111111<br>
<br>
<br>
The most significant bit is 0. Yet for the actual computation of the<br>
mantissa, we add 1 after shifting (this bit is cut off afterwards and as<br>
the comment suggests, this is to improve rounding of results), resulting<br>
in a mantissa of all zeros (as the top bit is cut off as well), instead<br>
of a mantissa of 1000000000000000000000000. The leading bit does not<br>
matter, though, as we will discard it anyway, assuming it to be a 1.<br>
<br>
But what does matter: For the computation of the exponent we don't take<br>
care of the overflow of the addition and do not add an extra 1.<br>
<br>
An easy fix would be to remove the rounding (the two +1), but then your<br>
result would be 437FFFFFH instead of 43800000H (still a lot better than<br>
43000000H, though). But a correct fix that keeps the rounding does not<br>
seem to be trivial.<br>
<br>
In the emulator source, I could easily fix this by adding an additional<br>
if statement and just do the addition again before comparing the most<br>
significant bit for incrementing the exponent, but I don't feel able to<br>
do this in Verilog (while still keeping the whole circuit being fast),<br>
especially since I don't have a way to test it on real hardware. Maybe<br>
somebody else wants to give it a stab?<br>
<br>
So either, change the computation of P in the previous states to add 1<br>
there (while for the best rounding you would have to add 2 in case the<br>
value is shifted one bit later). Or account for the extra 1 exponent in<br>
case of overflow.<br>
<br>
As a compromise, one could also just omit the rounding in case the value<br>
before rounding but after normalization (or at least a significant part<br>
of its digits) happens to be all ones; in that case, the rounding would<br>
still happen in most cases but not in the one that currently triggers<br>
the bug.<br>
<br>
<br>
Or did I miss anything obvious? :)<br>
<br>
<br>
Regards,<br>
<br>
<br>
Michael<br>
--<br>
Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems<br>
<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</body>
</html>