123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102(** Hardware generation in an imperative style *)(** create sequential hardware designs using [if], [while] and [assignment] *)open!ImportmoduletypeSame=sigtypevartype'arecipetype'asamevalsmap:f:(var->Signal.t)->varsame->Signal.tsamevalszip:varsame->Signal.tsame->(var*Signal.t)listvalnewVar:unit->varsamerecipevalread:varsame->Signal.tsamerecipevalrewrite:(Signal.tsame->Signal.tsame)->varsame->varsame->unitrecipevalapply:(Signal.tsame->Signal.tsame)->varsame->unitrecipevalset:varsame->Signal.tsame->unitrecipevalifte:(Signal.tsame->Signal.t)->varsame->'arecipe->'brecipe->unitrecipevalwhile_:(Signal.tsame->Signal.t)->varsame->'arecipe->'arecipeendmoduletypeRecipe=sigtypevartypeinptypeenvtype'arecipemoduleMonad:sigvalreturn:'a->'arecipevalbind:'arecipe->('a->'brecipe)->'brecipeval(>>=):'arecipe->('a->'brecipe)->'brecipeval(>>):'arecipe->'brecipe->'brecipeend(** skip 1 cycle *)valskip:unitrecipe(** skip n cycles *)valwait:int->unitrecipe(** Perform recipes in parallel. [comb_fin] controls the finish signal generation. When
false and extra cycle is taken after the recipes complete to generate the [fin]
signal. Otherwise extra combinatorial logic is generated to ensure the [fin] signal
toggles on the same cycle as the last recipe to complete. *)valpar:?comb_fin:bool->'arecipelist->'alistrecipevalpar2:?comb_fin:bool->'arecipe->'brecipe->('a*'b)recipeval(|||):'arecipe->'brecipe->('a*'b)recipe(** [cond c t f] performs [t] if [c] is high, otherwise performs [f] *)valcond:Signal.t->'arecipe->'brecipe->unitrecipe(** [iter c t] perform [t] while [c] is high *)valiter:Signal.t->'arecipe->'arecipe(** perform recipe forever *)valforever:'arecipe->'arecipe(** wait until [t] is low *)valwaitWhile:Signal.t->unitrecipe(** wait until [t] is high *)valwaitUntil:Signal.t->unitrecipe(** follow recipe and get result *)valfollow:Signal.t->'arecipe->Signal.t*'a(** create an new [n] bit register *)valnewVar:?name:string->int->varrecipe(** read value of register *)valreadVar:var->Signal.trecipe(** assign list of registers - takes 1 cycle *)valassign:(var*Signal.t)list->unitrecipe(** write register with value *)valwriteVar:var->Signal.t->unitrecipe(** modify current value of resgiter *)valmodifyVar:(Signal.t->Signal.t)->var->unitrecipe(** read a register, modify value, write a second register *)valrewriteVar:(Signal.t->Signal.t)->var->var->unitrecipemoduletypeSame=Samewithtypevar:=varwithtype'arecipe:='arecipemoduleSame(X:Interface.Pre):Samewithtype'asame='aX.tmoduleSVar:Samewithtype'asame='amoduleSList:Samewithtype'asame='alistmoduleSArray:Samewithtype'asame='aarraymoduleSTuple2:Samewithtype'asame='a*'amoduleSTuple3:Samewithtype'asame='a*'a*'aend