123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512open!Core0moduletypePre_partial=Hardcaml_interface_types.Pre_partialmoduletypePre=Hardcaml_interface_types.PremoduletypeAst=sig(** The PPX can optionally generate an [ast] field containing an [Ast.t]. This
represents the structure of the interface, including how it is constructed from
fields, arrays, lists and sub-modules.
This is of particular use when generating further code from the interface i.e. a
register interace specification.
[ast]s are not generated by default. *)modulerecAst:sigtypet=Field.tlist[@@derivingsexp_of]endandField:sigtypet={name:string(** Name of the field *);type_:Type.t(** Field type - a signal or a sub-module *);sequence:Sequence.toption(** Is the field type an array or list? *);doc:stringoption(** OCaml documentation string, if any. Note that this must be placed in the [ml]
and not [mli]. *)}[@@derivingsexp_of]endandType:sigtypet=|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]endtypet=Ast.t[@@derivingsexp_of]end(** Monomorphic combinatorial operations on Hardcaml interfaces. *)moduletypeComb_monomorphic=sigtypecombtypet[@@derivingsexp_of](** Raise if the widths of [t] do not match those specified in the interface. *)valassert_widths:t->unit(** Checks the port widths of the signals in the interface. Raises if they mismatch. *)valvalidate:t->unit(** Each field is set to the constant integer value provided. *)valof_int_trunc:int->tvalof_unsigned_int:int->tvalof_signed_int:int->t(** Identical to [of_unsigned_int 0] *)valzero:unit->t(** Pack interface into a vector. *)valpack:?rev:bool->t->comb(** Unpack interface from a vector. *)valunpack:?rev:bool->comb->t(** Multiplex a list of interfaces. *)valmux:comb->tlist->tvalmux2:comb->t->t->t(** Concatenate a list of interfaces. *)valconcat:tlist->tvalpriority_select:((comb,t)Comb.with_valid2list->(comb,t)Comb.with_valid2)Comb.optional_branching_factorvalpriority_select_with_default:((comb,t)Comb.with_valid2list->default:t->t)Comb.optional_branching_factorvalonehot_select:((comb,t)Comb.with_valid2list->t)Comb.optional_branching_factorendmoduletypeComb=sigtype'ainterfacetypecombtypet=combinterface[@@derivingsexp_of]includeComb_monomorphicwithtypet:=combinterfaceandtypecomb:=comb(** Actual bit widths of each field. *)valwidths:t->intinterface(** [of_ints_trunc c] sets each field to the integer value in [c] using the declared
field bit width. *)valof_ints_trunc:intinterface->tvalof_unsigned_ints:intinterface->tvalof_signed_ints:intinterface->tendmoduletypeNames_and_widths=sigvalport_names_and_widths:(string*int)listtypetagvalport_names:stringlistvalport_widths:intlistvaltags:taglistendmoduletypeOf_signal_functions=sigmoduleSignal:Signal.Stypettypebits_t(** Create a wire for each field. If [named] is true then wires are given the RTL field
name. If [from] is provided the wire is attached to each given field in [from]. *)valwires:?named:bool(** default is [false]. *)->?from:t(** No default *)->unit->t(** Defines a register over values in this interface. [enable] defaults to vdd. *)valreg:?enable:Signal.t->?initialize_to:bits_t->?reset_to:bits_t->?clear:Signal.t->?clear_to:t->Signal.Reg_spec.t->t->t(** Defines a cut through register over values in this interface. *)valcut_through_reg:?initialize_to:bits_t->?reset_to:bits_t->?clear:Signal.t->?clear_to:t->Signal.Reg_spec.t->enable:Signal.t->t->t(** Defines a register pipeline over values in this interface. [enable] defaults to vdd
and [attributes] defaults to an empty list. *)valpipeline:?attributes:Rtl_attribute.tlist->?enable:Signal.t->?initialize_to:bits_t->?reset_to:bits_t->?clear:Signal.t->?clear_to:t->Signal.Reg_spec.t->n:int->t->tvalassign:t->t->unitval(<--):t->t->unit(** [inputs t] is [wires () ~named:true]. *)valinputs:unit->t(** [outputs t] is [wires () ~from:t ~named:true]. *)valoutputs:t->t(** Apply name to field of the interface. Add [prefix] and [suffix] if specified. *)valapply_names:?prefix:string(** Default is [""] *)->?suffix:string(** Default is [""] *)->?naming_op:(loc:[%call_pos]->Signal.t->string->Signal.t)(** Default is [Signal.(--)] *)->t->tval__ppx_auto_name:t->string->tendmoduletypeS=sigincludePreinclude%templateEqual.S1[@modelocal]withtype'at:='at(** RTL names specified in the interface definition - commonly also the OCaml field
name. *)valport_names:stringt(** Bit widths specified in the interface definition. *)valport_widths:intt(** [const x] sets each port to [x] *)valconst:'a->'attypetag[@@derivingequal~localize]valtags:tagt(** Create association list indexed by tag. *)valto_alist:'at->(tag*'a)list(** Create interface from association list indexed by tag. *)valof_alist:(tag*'a)list->'at(** Sum of all port widths specified in the interface definition. *)valsum_of_port_widths:intmoduleUnsafe_assoc_by_port_name:sig(** Create association list indexed by field names. *)valto_alist:'at->(string*'a)list(** Create interface from association list indexed by field names. *)valof_alist:(string*'a)list->'atendvalzip:'at->'bt->('a*'b)tvalzip3:'at->'bt->'ct->('a*'b*'c)tvalzip4:'at->'bt->'ct->'dt->('a*'b*'c*'d)tvalzip5:'at->'bt->'ct->'dt->'et->('a*'b*'c*'d*'e)tvalmap3:'at->'bt->'ct->f:('a->'b->'c->'d)@local->'dtvalmap4:'at->'bt->'ct->'dt->f:('a->'b->'c->'d->'e)@local->'etvalmap5:'at->'bt->'ct->'dt->'et->f:('a->'b->'c->'d->'e->'f)@local->'ftvaliter3:'at->'bt->'ct->f:('a->'b->'c->unit)@local->unitvaliter4:'at->'bt->'ct->'dt->f:('a->'b->'c->'d->unit)@local->unitvaliter5:'at->'bt->'ct->'dt->'et->f:('a->'b->'c->'d->'e->unit)@local->unitvalfold:'at->init:'acc->f:('acc->'a->'acc)@local->'accvalfold2:'at->'bt->init:'acc->f:('acc->'a->'b->'acc)@local->'accvalscan:'at->init:'acc->f:('acc->'a->'acc*'b)@local->'btvalscan2:'at->'bt->init:'acc->f:('acc->'a->'b->'acc*'c)@local->'ct(** Offset of each field within the interface. The first field is placed at the least
significant bit, unless the [rev] argument is true. *)valoffsets:?rev:bool(** default is [false]. *)->unit->intt(** Take a list of interfaces and produce a single interface where each field is a list. *)valof_interface_list:'atlist->'alistt(** Create a list of interfaces from a single interface where each field is a list.
Raises if all lists don't have the same length. *)valto_interface_list:'alistt->'atlist(** Similar to [Monad.all] for lists -- combine and lift the monads to outside the
interface. *)moduleAll(M:Monad.S):sigvalall:'aM.tt->'atM.tend(** Equivalent to All(Or_error).all. This is made a special case for convenience. *)valor_error_all:'aOr_error.tt->'atOr_error.tmoduletypeComb=Combwithtype'ainterface:='atmoduleMake_comb(Comb:Comb.S):Combwithtypecomb=Comb.tmoduleOf_bits:Combwithtypecomb=Bits.tmoduleOf_signal:sigtype'ainterface:='atincludeCombwithtypecomb=Signal.tincludeOf_signal_functionswithtypet:=tandtypebits_t=Bits.tinterfaceandmoduleSignal:=SignalendmoduleOf_clocked_signal:sigtype'ainterface:='atincludeCombwithtypecomb=Clocked_signal.tincludeOf_signal_functionswithtypet:=tandmoduleSignal:=Clocked_signalvalwires:?named:bool(** default is [false]. *)->[`Fromoft|`DomainsofClock_domain.Runtime.tinterface]->tvalinputs:Clock_domain.Runtime.tinterface->t(** Apply name to field of the interface. Add [prefix] and [suffix] if specified. *)valapply_names:?prefix:string(** Default is [""] *)->?suffix:string(** Default is [""] *)->?naming_op:(loc:[%call_pos]->Signal.t->string->Signal.t)(** Default is [Signal.(--)] *)->t->tend(** Helper functions to ease usage of the Always API when working with interfaces. *)moduleOf_always:sigvalvalue:Always.Variable.tt->Signal.tt(** Assign a interface containing variables in an always block. *)valassign:Always.Variable.tt->Signal.tt->Always.t(** Shorthand for [assign]. *)val(<--):Always.Variable.tt->Signal.tt->Always.t(** Creates a interface container with register variables. *)valreg:?enable:Signal.t->?initialize_to:Bits.tt->?reset_to:Bits.tt->?clear:Signal.t->?clear_to:Signal.tt->Signal.Reg_spec.t->Always.Variable.tt(** Creates a interface container of cut through register variables. *)valcut_through_reg:?enable:Signal.t->?initialize_to:Bits.tt->?reset_to:Bits.tt->?clear:Signal.t->?clear_to:Signal.tt->Signal.Reg_spec.t->Always.Variable.tt(** Creates a interface container with wire variables, e.g.
[Foo.Of_always.wire Signal.zero], which would yield wires defaulting to zero. *)valwire:(int->Signal.t)->Always.Variable.tt(** Apply names to field of the interface. Add [prefix] and [suffix] if specified. *)valapply_names:?prefix:string(** Default is [""] *)->?suffix:string(** Default is [""] *)->?naming_op:(loc:[%call_pos]->Signal.t->string->Signal.t)(** Default is [Signal.(--)] *)->Always.Variable.tt->unitval__ppx_auto_name:Always.Variable.tt->string->Always.Variable.ttendmoduleNames_and_widths:Names_and_widthswithtypetag:=tag(** {2 Optional Metadata} *)valwave_formats:Wave_format.ttend(** Monomorphic functions on Hardcaml interfaces. Note that a functor (or a function)
accepting a argument on this monomorphic module type will type check successfully
against [S] above, since [S] more general than the monomorphic type below. *)moduletypeS_monomorphic=sigtypeatypettypetagvaliter:t->f:(a->unit)@local->unitvaliter2:t->t->f:(a->a->unit)@local->unitvalmap:t->f:(a->a)@local->tvalmap2:t->t->f:(a->a->a)@local->tvalto_list:t->alistvalto_alist:t->(tag*a)listvalof_alist:(tag*a)list->tmoduleUnsafe_assoc_by_port_name:sigvalto_alist:t->(string*a)listvalof_alist:(string*a)list->tendvalmap3:t->t->t->f:(a->a->a->a)@local->tvalmap4:t->t->t->t->f:(a->a->a->a->a)@local->tvalmap5:t->t->t->t->t->f:(a->a->a->a->a->a)@local->tvaliter3:t->t->t->f:(a->a->a->unit)@local->unitvaliter4:t->t->t->t->f:(a->a->a->a->unit)@local->unitvaliter5:t->t->t->t->t->f:(a->a->a->a->a->unit)@local->unitvalfold:t->init:'acc->f:('acc->a->'acc)@local->'accvalfold2:t->t->init:'acc->f:('acc->a->a->'acc)@local->'accmoduleNames_and_widths:Names_and_widthswithtypetag:=tagendmoduletypeS_Of_signal=sigmoduleOf_signal:sigincludeComb_monomorphicwithtypecomb:=Signal.tincludeOf_signal_functionswithtypet:=tandmoduleSignal:=SignalendincludeS_monomorphicwithtypet:=Of_signal.tandtypea:=Signal.tendmoduletypeEmpty=sigtype'at=EmptyincludeSwithtype'at:='atendmoduletypeInterface=sigmoduletypePre_partial=Pre_partialmoduletypePre=PremoduletypeS=SmoduletypeS_Of_signal=S_Of_signalmoduletypeAst=AstmoduletypeEmpty=EmptymoduleAst:AstmoduleEmpty:EmptymoduletypeS_with_ast=sigincludeSvalast:Ast.tendmoduletypeS_with_clock_domains=sigincludeSvaldomains:Clock_domain.ttend(** Type of functions representing the implementation of a circuit from an input to
output interface. *)moduleCreate_fn(I:S)(O:S):sigtypet=Signal.tI.t->Signal.tO.t[@@derivingsexp_of]endmoduleMake(X:Pre):Swithtype'at:='aX.tmoduleMake_with_wave_formats(X:sigincludePrevalwave_formats:Wave_format.ttend):Swithtype'at:='aX.t(** Recreate a Hardcaml Interface with the same type, but different port names / widths. *)moduleUpdate(Pre:Pre)(M:sigvalport_names_and_widths:(string*int)Pre.tend):Swithtype'at='aPre.t(** Creates a new hardcaml interface by converting between functions. This can be used
to implement Hardcaml.Interface.S on types that otherwise can't use
[@@deriving hardcaml] *)moduleMake_interface_with_conversion(Repr:S)(M:sigtype'at[@@derivingequal~localize,compare~localize,sexp_of]valt_of_repr:'aRepr.t->'atvalrepr_of_t:'at->'aRepr.tend):Swithtype'at='aM.tend