12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667open!ImportmoduleEntry=structtypet={name:string(* actual circuit name *);mangled_name:string;circuit:Circuit.t}[@@derivingfields]endtypet={mangler:Mangler.t;entry_by_mangled_name:(string,Entry.t)Hashtbl.t}(* Show a summary of the name mapping *)letsexp_of_tt=letmapping=List.map(Hashtbl.datat.entry_by_mangled_name)~f:(fune->e.name,e.mangled_name)|>List.sort~compare:[%compare:string*string]in[%sexp(mapping:(string*string)list)];;letcreate()=(* Choose caseless mangling and add all reserved words so module names are compatible
with VHDL and Verilog. *)letmangler=Mangler.create~case_sensitive:falseinList.iterReserved_words.(verilog@vhdl)~f:(funr->ignore(Mangler.add_identifiermanglerr:[`Ok|`Duplicate]));{mangler;entry_by_mangled_name=Hashtbl.create(moduleString)};;letaddtcircuit=letname=Circuit.namecircuitinletmangled_name=Mangler.manglet.manglernameinletentry={Entry.name;mangled_name;circuit=Circuit.with_namecircuit~name:mangled_name}inHashtbl.add_exnt.entry_by_mangled_name~key:mangled_name~data:entry;mangled_name;;letadd_if_uniquetcircuit=(* find the existing circuits which started off with this (un-mangled) name *)matchList.find(Hashtbl.datat.entry_by_mangled_name)~f:(funentry->String.equalentry.name(Circuit.namecircuit)&&Circuit.structural_compareentry.circuitcircuit)with|Somee->e.mangled_name|None->addtcircuit;;letinsert?(share=true)databasecircuit=ifsharethenadd_if_uniquedatabasecircuitelseadddatabasecircuit;;letfindt~mangled_name=Hashtbl.findt.entry_by_mangled_namemangled_name|>Option.map~f:Entry.circuit;;letget_circuits(t:t)=List.map(Hashtbl.datat.entry_by_mangled_name)~f:(fun(e:Entry.t)->e.circuit);;