Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file fixed.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568open!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_msb_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 *)]inmux2selfloorceil;;letevalf=fendmoduleOverflow=structtypet=unsignedoverflowletwrapfpibs=concat_msb_e[select(get_intfps)(ib-1)0;get_fracfps]letsaturatefpibs=leti=get_intfpsinletf=get_fracfpsinifwidthi=ibthenselseifwidthi<ibthen(*failwith "Overflow.Unsigned.Saturate"*)concat_msb_e[zero(ib-widthi);i;f]else(letdropped=selecti(widthi-1)ibinletremaining=selecti(ib-1)0inletoverflow=reduce~f:(|:)(bits_msbdropped)inletclipped=mux2overflow(ones(ib+fp))(concat_msb_e[remaining;f])inclipped);;letevalf=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;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)0;;letsignals=s.sletwidth_ints=B.width(ints)letwidth_fracs=B.width(fracs)letto_floats=letfp=2.**Float.of_ints.fpinleti=Float.of_int(B.to_ints.s)ini/.fp;;letextendsn=ifn<0thenfailwith"Fixed.Unsigned.extend"elseifn=0thenselse{s=B.concat_msb[B.zeron;s.s];fp=s.fp};;letselect_intsi=ifi<=0thenfailwith"Fixed.Unsigned.select_int i<=0"else(letsi=intsinletwi=width_intsinifi<=withenB.selectsi(i-1)0elseB.concat_msb[B.zero(i-wi);si]);;letselect_fracsf=iff<0thenfailwith"Fixed.Unsigned.select_frac f<0"elseiff=0thenB.emptyelse(letwf=width_fracsinifwf=0thenB.zerofelse(letsf=fracsiniff<=wfthenB.selectsf(wf-1)(wf-f)elseB.concat_msb[sf;B.zero(f-wf)]));;letselectsif=leti'=select_intsiinletf'=select_fracsfinmkf(B.concat_msb_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.of_int~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.s;;let(<>:)ab=leta,b=norm2abinB.(<>:)a.sb.s;;let(<:)ab=leta,b=norm2abinB.(<:)a.sb.s;;let(<=:)ab=leta,b=norm2abinB.(<=:)a.sb.s;;let(>:)ab=leta,b=norm2abinB.(>:)a.sb.s;;let(>=:)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 *)]inmux2selfloorceil;;letevalf=fendmoduleOverflow=structtypet=signedoverflowletwrapfpibs=concat_msb_e[select(get_intfps)(ib-1)0;get_fracfps]letsaturatefpibs=leti=get_intfpsinletf=get_fracfpsinifwidthi=ibthenselseifwidthi<ibthen(*failwith "Overflow.Signed.Saturate"*)concat_msb_e[repeat(msbi)(ib-widthi);i;f]else(letdropped=selecti(widthi-1)ibinletremaining=selecti(ib-1)0inletoverflow_n=repeat(msbremaining)(widthdropped)==:droppedinletmin=reverse(one(ib+fp))inletmax=~:mininletclipped=mux2overflow_n(concat_msb_e[remaining;f])(mux2(msbdropped)minmax)inclipped);;letevalf=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;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)0;;letsignals=s.sletwidth_ints=B.width(ints)letwidth_fracs=B.width(fracs)letto_floats=letfp=2.**Float.of_ints.fpinlets=B.sresizes.sNativeint.num_bitsinleti=Float.of_int(B.to_ints)ini/.fp;;letextendsn=ifn<0thenfailwith"Fixed.Signed.extend"elseifn=0thenselse{s=B.concat_msb[B.repeat(B.msbs.s)n;s.s];fp=s.fp};;letselect_intsi=ifi<=0thenfailwith"Fixed.Signed.select_int i<=0"else(letsi=intsinletwi=width_intsinifi<=withenB.selectsi(i-1)0elseB.concat_msb[B.repeat(B.msbsi)(i-wi);si]);;letselect_fracsf=iff<0thenfailwith"Fixed.Signed.select_frac f<0"elseiff=0thenB.emptyelse(letwf=width_fracsinifwf=0thenB.zerofelse(letsf=fracsiniff<=wfthenB.selectsf(wf-1)(wf-f)elseB.concat_msb[sf;B.zero(f-wf)]));;letselectsif=leti'=select_intsiinletf'=select_fracsfinmkf(B.concat_msb_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.of_int~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.s;;let(<>:)ab=leta,b=norm2abinB.(<>:)a.sb.s;;let(<:)ab=leta,b=norm2abinB.(<+)a.sb.s;;let(<=:)ab=leta,b=norm2abinB.(<=+)a.sb.s;;let(>:)ab=leta,b=norm2abinB.(>+)a.sb.s;;let(>=:)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