Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file fixed.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466open!ImportincludeFixed_intfmoduleMake(B:Comb.S)=structopenBtypeunsignedtypesignedtype'around=int->B.t->B.ttype'aoverflow=int->int->B.t->B.tmoduletypeRound=RoundwithmoduleB:=BmoduletypeOverflow=OverflowwithmoduleB:=BmoduletypeFixed=Fixed_pointwithmoduleB:=Bletget_intfps=selects(widths-1)fpletget_fracfps=iffp=0thenemptyelseselects(fp-1)0letfloor=get_intletceilfps=letib=widths-fpinletmax_frac=concat_e[zeroib;onesfp]inget_intfp(s+:max_frac)lethalffps=letib=widths-fpinzeroib@:reverse(onefp)moduleUnsigned=structmoduleRound=structtypet=unsignedroundletneg_infinityfps=floorfp(ues)letpos_infinityfps=ceilfp(ues)letto_zerofps=floorfp(ues)letaway_from_zerofps=ceilfp(ues)lettie_to_neg_infinityfps=lethalf=halffp(ues)inceilfp((ues)-:half)lettie_to_pos_infinityfps=lethalf=halffp(ues)infloorfp(ues+:half)lettie_to_zerofps=lethalf=halffp(ues)inceilfp((ues)-:half)lettie_away_from_zerofps=lethalf=halffp(ues)infloorfp(ues+:half)lettie_to_nearest_evenfps=lethalf=halffp(ues)inletlsb=lsb(get_intfps)inmux2lsb(floorfp(ues+:half))(ceilfp(ues-:half))lettie_to_nearest_oddfps=lethalf=halffp(ues)inletlsb=lsb(get_intfps)inmux2lsb(ceilfp(ues-:half))(floorfp(ues+:half))letgenericselfps=lets=uesinletz=zero(widths)inlethalf=halffpsinletlsb=lsb(get_intfps)inletrnd=muxsel[z;z;z;z;half]inletceil=ceilfp(s-:rnd)inletfloor=floorfp(s+:rnd)inletsel=muxsel[vdd;gnd;vdd;gnd(* directed rounding *);gnd;vdd;gnd;vdd;lsb;~:lsb(* round with tie break *)]inmux2selfloorceilletevalf=fendmoduleOverflow=structtypet=unsignedoverflowletwrapfpibs=concat_e[select(get_intfps)(ib-1)0;get_fracfps]letsaturatefpibs=leti=get_intfpsinletf=get_fracfpsinifwidthi=ibthenselseifwidthi<ibthen(*failwith "Overflow.Unsigned.Saturate"*)concat_e[zero(ib-widthi);i;f]elseletdropped=selecti(widthi-1)ibinletremaining=selecti(ib-1)0inletoverflow=reduce~f:(|:)(bitsdropped)inletclipped=mux2overflow(ones(ib+fp))(concat_e[remaining;f])inclippedletevalf=fendmoduletypeSpec=sigvalround:unsignedroundvaloverflow:unsignedoverflowendmoduleMake(S:Spec)=structtypet={s:B.t;fp:int}letmkfps=ifB.widths<=fpthen(* could drop this requirement ... *)failwith"Fixed.Signal.mk: there must be at least 1 integer bit";{s=s;fp=fp}letints=B.selects.s(B.widths.s-1)s.fpletfracs=ifs.fp<0thenfailwith"Fixed.Unsigned.frac fp < 0"elseifs.fp=0thenB.emptyelseB.selects.s(s.fp-1)0letsignals=s.sletwidth_ints=B.width(ints)letwidth_fracs=B.width(fracs)letto_floats=letfp=2.**(Float.of_ints.fp)inleti=Float.of_int(B.to_ints.s)ini/.fpletextendsn=ifn<0thenfailwith"Fixed.Unsigned.extend"elseifn=0thenselse{s=B.concat[B.zeron;s.s];fp=s.fp}letselect_intsi=ifi<=0thenfailwith"Fixed.Unsigned.select_int i<=0"elseletsi=intsinletwi=width_intsinifi<=withenB.selectsi(i-1)0elseB.concat[(B.zero(i-wi));si]letselect_fracsf=iff<0thenfailwith"Fixed.Unsigned.select_frac f<0"elseiff=0thenB.emptyelseletwf=width_fracsinifwf=0thenB.zerofelseletsf=fracsiniff<=wfthenB.selectsf(wf-1)(wf-f)elseB.concat[sf;B.zero(f-wf)]letselectsif=leti'=select_intsiinletf'=select_fracsfinmkf(B.concat_e[i';f'])letnorml=leti=List.foldl~init:0~f:(funab->maxa(B.width(intb)))inletf=List.foldl~init:0~f:(funab->maxa(B.width(fracb)))inList.mapl~f:(funs->selectsif)letnorm2ab=letl=norm[a;b]inmatchlwith|[a;b]->a,b|_->failwith"Fixed.Unsigned.norm2"letconstipfpf=letfp'=Float.of_intfpinletfp'=2.0**fp'inmkfp(B.consti~width:(ip+fp)(Int.of_float(f*.fp')))(* basic arithmetic *)let(+:)ab=leta,b=norm2abinleta,b=extenda1,extendb1in{s=B.(+:)a.sb.s;fp=a.fp}let(-:)ab=leta,b=norm2abinleta,b=extenda1,extendb1in{s=B.(-:)a.sb.s;fp=a.fp}let(*:)ab={s=B.(*:)a.sb.s;fp=a.fp+b.fp}(* comparison *)let(==:)ab=leta,b=norm2abinB.(==:)a.sb.slet(<>:)ab=leta,b=norm2abinB.(<>:)a.sb.slet(<:)ab=leta,b=norm2abinB.(<:)a.sb.slet(<=:)ab=leta,b=norm2abinB.(<=:)a.sb.slet(>:)ab=leta,b=norm2abinB.(>:)a.sb.slet(>=:)ab=leta,b=norm2abinB.(>=:)a.sb.s(* mux *)letmuxsell=letl=normlinletfp=width_frac(List.hd_exnl)inletq=B.muxsel(List.mapl~f:signal)inmkfpq(* resize with rounding and saturation control *)letresizesif=leti'=width_intsinletf'=width_fracsin(* perform rounding *)lets=iff>=f'thenselectsi'felsemkf(S.round(f'-f)s.s)in(* perform overflow control *)mkf(S.overflowfis.s)endendmoduleSigned=structmoduleRound=structtypet=signedroundletneg_infinityfps=floorfp(ses)letpos_infinityfps=ceilfp(ses)letto_zerofps=letsign=msbsinmux2sign(ceilfp(ses))(floorfp(ses))letaway_from_zerofps=letsign=msbsinmux2sign(floorfp(ses))(ceilfp(ses))lettie_to_neg_infinityfps=lethalf=halffp(ses)inceilfp(ses-:half)lettie_to_pos_infinityfps=lethalf=halffp(ses)infloorfp(ses+:half)lettie_to_zerofps=lethalf=halffp(ses)inletsign=msbsinmux2sign(floorfp(ses+:half))(ceilfp(ses-:half))lettie_away_from_zerofps=lethalf=halffp(ses)inletsign=msbsinmux2sign(ceilfp(ses-:half))(floorfp(ses+:half))lettie_to_nearest_evenfps=lethalf=halffp(ses)inletlsb=lsb(get_intfps)inmux2lsb(floorfp(ses+:half))(ceilfp(ses-:half))lettie_to_nearest_oddfps=lethalf=halffp(ses)inletlsb=lsb(get_intfps)inmux2lsb(ceilfp(ses-:half))(floorfp(ses+:half))letgenericselfps=lets=sesinletz=zero(widths)inlethalf=halffpsinletlsb=lsb(get_intfps)inletsign=msbsinletrnd=muxsel[z;z;z;z;half]inletceil=ceilfp(s-:rnd)inletfloor=floorfp(s+:rnd)inletsel=muxsel[vdd;gnd;~:sign;sign(* directed rounding *);gnd;vdd;sign;~:sign;lsb;~:lsb(* round with tie break *)]inmux2selfloorceilletevalf=fendmoduleOverflow=structtypet=signedoverflowletwrapfpibs=concat_e[select(get_intfps)(ib-1)0;get_fracfps]letsaturatefpibs=leti=get_intfpsinletf=get_fracfpsinifwidthi=ibthenselseifwidthi<ibthen(*failwith "Overflow.Signed.Saturate"*)concat_e[repeat(msbi)(ib-widthi);i;f]elseletdropped=selecti(widthi-1)ibinletremaining=selecti(ib-1)0inletoverflow_n=repeat(msbremaining)(widthdropped)==:droppedinletmin=reverse(one(ib+fp))inletmax=~:mininletclipped=mux2overflow_n(concat_e[remaining;f])(mux2(msbdropped)minmax)inclippedletevalf=fendmoduletypeSpec=sigvalround:signedroundvaloverflow:signedoverflowendmoduleMake(S:Spec)=structtypet={s:B.t;fp:int}letmkfps=ifB.widths<=fpthen(* could drop this requirement ... *)failwith"Fixed.Signal.mk: there must be at least 1 integer bit";{s=s;fp=fp}letints=B.selects.s(B.widths.s-1)s.fpletfracs=ifs.fp<0thenfailwith"Fixed.Signed.frac fp < 0"elseifs.fp=0thenB.emptyelseB.selects.s(s.fp-1)0letsignals=s.sletwidth_ints=B.width(ints)letwidth_fracs=B.width(fracs)letto_floats=letfp=2.**(Float.of_ints.fp)inlets=B.sresizes.sNativeint.num_bitsinleti=Float.of_int(B.to_ints)ini/.fpletextendsn=ifn<0thenfailwith"Fixed.Signed.extend"elseifn=0thenselse{s=B.concat[B.repeat(B.msbs.s)n;s.s];fp=s.fp}letselect_intsi=ifi<=0thenfailwith"Fixed.Signed.select_int i<=0"elseletsi=intsinletwi=width_intsinifi<=withenB.selectsi(i-1)0elseB.concat[(B.repeat(B.msbsi)(i-wi));si]letselect_fracsf=iff<0thenfailwith"Fixed.Signed.select_frac f<0"elseiff=0thenB.emptyelseletwf=width_fracsinifwf=0thenB.zerofelseletsf=fracsiniff<=wfthenB.selectsf(wf-1)(wf-f)elseB.concat[sf;B.zero(f-wf)]letselectsif=leti'=select_intsiinletf'=select_fracsfinmkf(B.concat_e[i';f'])letnorml=leti=List.foldl~init:0~f:(funab->maxa(B.width(intb)))inletf=List.foldl~init:0~f:(funab->maxa(B.width(fracb)))inList.mapl~f:(funs->selectsif)letnorm2ab=letl=norm[a;b]inmatchlwith|[a;b]->a,b|_->failwith"Fixed.Signed.norm2"letconstipfpf=letfp'=Float.of_intfpinletfp'=2.0**fp'inmkfp(B.consti~width:(ip+fp)(Int.of_float(f*.fp')))(* basic arithmetic *)let(+:)ab=leta,b=norm2abinleta,b=extenda1,extendb1in{s=B.(+:)a.sb.s;fp=a.fp}let(-:)ab=leta,b=norm2abinleta,b=extenda1,extendb1in{s=B.(-:)a.sb.s;fp=a.fp}let(*:)ab={s=B.(*+)a.sb.s;fp=a.fp+b.fp}(* comparison *)let(==:)ab=leta,b=norm2abinB.(==:)a.sb.slet(<>:)ab=leta,b=norm2abinB.(<>:)a.sb.slet(<:)ab=leta,b=norm2abinB.(<+)a.sb.slet(<=:)ab=leta,b=norm2abinB.(<=+)a.sb.slet(>:)ab=leta,b=norm2abinB.(>+)a.sb.slet(>=:)ab=leta,b=norm2abinB.(>=+)a.sb.s(* mux *)letmuxsell=letl=normlinletfp=width_frac(List.hd_exnl)inletq=B.muxsel(List.mapl~f:signal)inmkfpq(* resize with rounding and saturation control *)letresizesif=leti'=width_intsinletf'=width_fracsin(* perform rounding *)lets=iff>=f'thenselectsi'felsemkf(S.round(f'-f)s.s)in(* perform overflow control *)mkf(S.overflowfis.s)endendend