Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file interface.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357open!ImportincludeInterface_intfmoduleCreate_fn(I:S)(O:S)=structtype'at='aI.t->'aO.tletsexp_of_t__=[%message""~inputs:(I.t:(string*int)I.t)~outputs:(O.t:(string*int)O.t)];;endmoduleAst=structmodulerecAst:sigtypet=Field.tlist[@@derivingsexp_of]end=structtypet=Field.tlist[@@derivingsexp_of]endandField:sigtypet={name:string;type_:Type.t;sequence:Sequence.toption;doc:stringoption}[@@derivingsexp_of]end=structtypet={name:string;type_:Type.t;sequence:Sequence.toption;doc:stringoption}[@@derivingsexp_of]endandType:sigtypet=|Signalof{bits:int;rtlname:string}|Moduleof{name:string;ast:Ast.t}[@@derivingsexp_of]end=structtypet=|Signalof{bits:int;rtlname:string}|Moduleof{name:string;ast:Ast.t}[@@derivingsexp_of]endandSequence:sigmoduleKind:sigtypet=|Array|List[@@derivingsexp_of]endtypet={kind:Kind.t;length:int}[@@derivingsexp_of]end=structmoduleKind=structtypet=|Array|List[@@derivingsexp_of]endtypet={kind:Kind.t;length:int}[@@derivingsexp_of]endtypet=Ast.t[@@derivingsexp_of]endmoduleMake(X:Pre):Swithtype'at:='aX.t=structincludeXletport_names=mapt~f:fstletport_widths=mapt~f:sndletto_list_revx=to_listx|>List.revletto_alistx=to_list(map2port_namesx~f:(funnamex->name,x))letof_alistx=mapport_names~f:(funname->matchList.Assoc.findxname~equal:String.equalwith|Somex->x|None->raise_s[%message"[Interface_extended.of_alist] Field not found in interface"~missing_field_name:(name:string)~input:(x:(string*_)list)~interface:(port_widths:intX.t)]);;letzipab=map2ab~f:(funab->a,b)letzip3abc=map2(zipab)c~f:(fun(a,b)c->a,b,c)letzip4abcd=map2(zipab)(zipcd)~f:(fun(a,b)(c,d)->a,b,c,d)letzip5abcde=map2(zip3abc)(zipde)~f:(fun(a,b,c)(d,e)->a,b,c,d,e);;letmap3abc~f=map~f:(fun(a,b,c)->fabc)(zip3abc)letmap4abcd~f=map~f:(fun(a,b,c,d)->fabcd)(zip4abcd)letmap5abcde~f=map~f:(fun(a,b,c,d,e)->fabcde)(zip5abcde)letiter3abc~f=ignore@@map3~fabcletiter4abcd~f=ignore@@map4~fabcdletiter5abcde~f=ignore@@map5~fabcdeletequalequal_at1t2=With_return.with_return(funr->iter2t1t2~f:(funa1a2->ifnot(equal_aa1a2)thenr.returnfalse);true);;letfolda~init~f=letinit=refinitinitera~f:(funa->init:=f!inita);!init;;letfold2ab~init~f=fold(zipab)~init~f:(func(a,b)->fcab)letoffsets?(rev=false)()=letrecloopfields~offset=matchfieldswith|[]->[]|(name,width)::fields->(name,offset)::loopfields~offset:(offset+width)inloop(ifrevthento_list_revtelseto_listt)~offset:0|>of_alist;;letof_interface_listts=List.fold(List.revts)~init:(mapt~f:(fun_->[]))~f:(funact->map2tac~f:(funht->h::t));;letto_interface_listt=letlengths=mapt~f:List.lengthinletdistinct_lengths=foldlengths~init:(Set.empty(moduleInt))~f:Set.addinmatchSet.to_listdistinct_lengthswith|[]->[]|[length]->letreclooplengtht=iflength=0then[]elsemapt~f:List.hd_exn::loop(length-1)(mapt~f:List.tl_exn)inlooplengtht|_->raise_s[%message"[Interface_extended.to_interface_list] field list lengths must be the same"(lengths:intt)];;moduleMake_comb(Comb:Comb.S)=structtypecomb=Comb.t[@@derivingsexp_of]typet=Comb.tX.t[@@derivingsexp_of]letwidthst=mapt~f:Comb.widthletassert_widthsx=iter2(widthsx)t~f:(funactual_width(port_name,expected_width)->ifactual_width<>expected_widththenraise_s[%message"Port width mismatch in interface"(port_name:string)(expected_width:int)(actual_width:int)]);;letconsti=mapport_widths~f:(funb->Comb.consti~width:bi)letconstsi=map2port_widthsi~f:(funwidth->Comb.consti~width)letpack?(rev=false)t=ifrevthento_listt|>Comb.concat_msbelseto_list_revt|>Comb.concat_msb;;letunpack?(rev=false)comb=letrecloopfields~offset=matchfieldswith|[]->[]|(name,width)::fields->(name,Comb.selectcomb(offset+width-1)offset)::loopfields~offset:(offset+width)inloop(ifrevthento_list_revtelseto_listt)~offset:0|>of_alist;;letmuxsl=map~f:(Comb.muxs)(of_interface_listl)letmux2shl=muxs[l;h]letconcatl=map~f:Comb.concat_msb(of_interface_listl)endmoduletypeComb=Combwithtype'ainterface:='atmoduleOf_bits=Make_comb(Bits)moduleOf_signal=structincludeMake_comb(Signal)letassignt1t2=iter2t1t2~f:Signal.assignlet(<==)=assignletwires?(named=false)?from()=letwires=matchfromwith|None->mapport_widths~f:Signal.wire|Somex->mapx~f:Signal.wireofinifnamedthenmap2wiresport_names~f:Signal.(--)elsewires;;letinputs()=wires()~named:trueletoutputst=wires()~from:t~named:trueletapply_names?(prefix="")?(suffix="")?(naming_op=Signal.(--))t=map2tport_names~f:(funsn->naming_ops(prefix^n^suffix));;endendmoduleMake_enums(Enum:Interface_intf.Enum)=structmoduleMake_pre(M:sigvalt:string*intend)=structtype'at='a[@@derivingsexp_of]letto_listt=[t]letmapt~f=ftletmap2ab~f=fabletitera~f=faletiter2ab~f=fablett=M.tendletnum_enums=List.lengthEnum.allmoduleBinary=structletwidth=Int.ceil_log2(List.lengthEnum.all)modulePre=Make_pre(structlett="binary_variant",widthend)includePreincludeMake(Pre)letof_enum(typea)(moduleComb:Comb.Swithtypet=a)enum=Comb.consti~width(Enum.Variants.to_rankenum);;letto_enum=List.mapEnum.all~f:(funvariant->Enum.Variants.to_rankvariant,variant)|>Map.of_alist_exn(moduleInt);;letto_enumt=Map.find_exnto_enum(Bits.to_intt)letmux(typea)(moduleComb:Comb.Swithtypet=a)~(default:a)selectorcases=letout_cases=Array.create~len:num_enumsdefaultinList.itercases~f:(fun(enum,value)->out_cases.(Enum.Variants.to_rankenum)<-value);Comb.muxselector(Array.to_listout_cases);;moduleFor_testing=structletsettenum=t:=of_enum(moduleBits)enumletgett=to_enum!tendendmoduleOne_hot=structletwidth=List.lengthEnum.allmodulePre=Make_pre(structlett="ont_hot_variant",widthend)includePreincludeMake(Pre)letof_enum(typea)(moduleComb:Comb.Swithtypet=a)enum=Comb.consti~width(1lslEnum.Variants.to_rankenum);;letto_enum=List.mapEnum.all~f:(funvariant->1lslEnum.Variants.to_rankvariant,variant)|>Map.of_alist_exn(moduleInt);;letto_enumt=Map.find_exnto_enum(Bits.to_intt)letmux(typea)(moduleComb:Comb.Swithtypet=a)~(default:a)selectorcases=letout_cases=Array.create~len:num_enumsdefaultinList.itercases~f:(fun(enum,value)->out_cases.(Enum.Variants.to_rankenum)<-value);List.map2_exn(Comb.bits_lsbselector)(Array.to_listout_cases)~f:(funvalidvalue->{With_valid.valid;value})|>Comb.onehot_select;;moduleFor_testing=structletsettenum=t:=of_enum(moduleBits)enumletgett=to_enum!tendendendmoduleEmpty=structtype'at=None[@@derivingsexp_of]includeMake(structtypenonrec'at='at[@@derivingsexp_of]lett=Noneletiter_~f:_=()letiter2__~f:_=()letmap_~f:_=Noneletmap2__~f:_=Noneletto_list_=[]end)endmoduletypeS_with_ast=sigincludeSvalast:Ast.tend