Module Hardcaml__.Signal
type signal_op=|Signal_add|Signal_sub|Signal_mulu|Signal_muls|Signal_and|Signal_or|Signal_xor|Signal_eq|Signal_ltsimple operators
val sexp_of_signal_op : signal_op -> Ppx_sexp_conv_lib.Sexp.tval compare_signal_op : signal_op -> signal_op -> Hardcaml__.Import.intval hash_fold_signal_op : Base.Hash.state -> signal_op -> Base.Hash.stateval hash_signal_op : signal_op -> Base.Hash.hash_value
module Uid : sig ... endmodule Uid_map : Hardcaml__.Map.S with module Key := Uidmodule Uid_set : sig ... endtype signal_id={s_id : Uid.t;mutable s_names : Hardcaml__.Import.string Hardcaml__.Import.list;s_width : Hardcaml__.Import.int;mutable s_attributes : Hardcaml.Rtl_attribute.t Hardcaml__.Import.list;Making this mutable turns hardcaml from pretty functional to pretty imperative. however, if used carefully and only with the library, we can provide a potentially easier way of changing the graph structure in some cases
mutable s_deps : t Hardcaml__.Import.list;caller_id : Hardcaml.Caller_id.t Hardcaml__.Import.option;}internal structure for tracking signals
and t=|Empty|Const of{signal_id : signal_id;constant : Hardcaml.Bits.t;}|Op2 of{signal_id : signal_id;op : signal_op;arg_a : t;arg_b : t;}|Mux of{signal_id : signal_id;select : t;cases : t Hardcaml__.Import.list;}|Cat of{signal_id : signal_id;args : t Hardcaml__.Import.list;}|Not of{signal_id : signal_id;arg : t;}|Wire of{signal_id : signal_id;driver : t Hardcaml__.Import.ref;}|Select of{signal_id : signal_id;arg : t;high : Hardcaml__.Import.int;low : Hardcaml__.Import.int;}|Reg of{signal_id : signal_id;register : register;d : t;}|Mem of{signal_id : signal_id;extra_uid : Uid.t;register : register;memory : memory;}|Multiport_mem of{signal_id : signal_id;size : Hardcaml__.Import.int;write_ports : write_port Hardcaml__.Import.array;}|Mem_read_port of{signal_id : signal_id;memory : t;read_address : t;}|Inst of{signal_id : signal_id;extra_uid : Uid.t;instantiation : instantiation;}main signal data type
and write_port={write_clock : t;write_address : t;write_enable : t;write_data : t;}and read_port={read_clock : t;read_address : t;read_enable : t;}and register={reg_clock : t;clock
reg_clock_edge : Hardcaml.Edge.t;active clock edge
reg_reset : t;asynchronous reset
reg_reset_edge : Hardcaml.Edge.t;asynchronous reset edge
reg_reset_value : t;asychhronous reset value
reg_clear : t;synchronous clear
reg_clear_level : Hardcaml.Level.t;synchronous clear level
reg_clear_value : t;sychhronous clear value
reg_enable : t;global system enable
}These types are used to define a particular type of register as per the following template, where each part is optional:
always @(?edge clock, ?edge reset) if (reset == reset_level) d <= reset_value; else if (clear == clear_level) d <= clear_value; else if (enable) d <= ...;
and memory={mem_size : Hardcaml__.Import.int;mem_read_address : t;mem_write_address : t;mem_write_data : t;}and instantiation={inst_name : Hardcaml__.Import.string;name of circuit
inst_instance : Hardcaml__.Import.string;instantiation label
inst_generics : Hardcaml.Parameter.t Hardcaml__.Import.list;Parameter.int ...inst_inputs : (Hardcaml__.Import.string * t) Hardcaml__.Import.list;name and input signal
inst_outputs : (Hardcaml__.Import.string * (Hardcaml__.Import.int * Hardcaml__.Import.int)) Hardcaml__.Import.list;name, width and low index of output
inst_lib : Hardcaml__.Import.string;inst_arch : Hardcaml__.Import.string;}type signal= t
val signal_id : t -> signal_id Hardcaml__.Import.optionreturns the (private) signal_id. For internal use only.
val deps : t -> t Hardcaml__.Import.listreturns the signal's dependencies
val names : t -> Hardcaml__.Import.string Hardcaml__.Import.listreturns the list of names assigned to the signal
val add_attribute : t -> Hardcaml.Rtl_attribute.t -> tAdd an attribute to node. This is currently supported only in Verilog.
val attributes : t -> Hardcaml.Rtl_attribute.t Hardcaml__.Import.listReturns attributes associated to the signal
val has_name : t -> Hardcaml__.Import.boolval is_reg : t -> Hardcaml__.Import.boolis the signal a register?
val is_mem : t -> Hardcaml__.Import.boolis the signal a memory, or multiport memory?
val is_multiport_mem : t -> Hardcaml__.Import.boolis the signal a multiport memory?
val is_mem_read_port : t -> Hardcaml__.Import.boolis the signal a memory read port?
val is_inst : t -> Hardcaml__.Import.boolis the signal an instantiation?
val is_const : t -> Hardcaml__.Import.boolis the signal a constant?
val is_select : t -> Hardcaml__.Import.boolis the signal a part selection?
val is_wire : t -> Hardcaml__.Import.boolis the signal a wire?
val is_op2 : signal_op -> t -> Hardcaml__.Import.boolis the signal the given operator?
val is_cat : t -> Hardcaml__.Import.boolis the signal concatenation?
val is_mux : t -> Hardcaml__.Import.boolis the signal a multiplexer?
val is_not : t -> Hardcaml__.Import.boolis the signal a not>
val const_value : t -> Hardcaml.Bits.treturn the (binary) string representing a constants value
val new_id : Hardcaml__.Import.unit -> Uid.tcreates a new signal uid
val reset_id : Hardcaml__.Import.unit -> Hardcaml__.Import.unitresets the signal identifiers
val make_id : Hardcaml__.Import.int -> t Hardcaml__.Import.list -> signal_idconstructs a signal_id type
val structural_compare : ?check_names:Hardcaml__.Import.bool -> ?check_deps:Hardcaml__.Import.bool -> ?initial_deps:Uid_set.t -> t -> t -> Uid_set.t * Hardcaml__.Import.boolperform a recursive structural comparison of two signals
val sexp_of_signal_recursive : ?show_uids:Hardcaml__.Import.bool -> depth:Hardcaml__.Import.int -> t -> Hardcaml__.Import.Sexp.tsexp_of_signal_recursive ~depth signalconverts a signal recursively to a sexp for up todepthlevels. Ifshow_uidsis false then signal identifiers will not be printed.max_list_lengthcontrols how manymuxandconcatarguments (dependancies) are printed.
Combinatorial signal API. This API automatically performs constant propogations (eg: replacing (a + 1 + 5) with (a + 6)). This reduces the amount of work that needs to be done during simulation by simply reducing the number of simulation nodes.
To use raw signals, ie: keeping the simulation nodes as described, use Raw below.
include Hardcaml.Comb.S with type t := t
val sexp_of_t : t -> Ppx_sexp_conv_lib.Sexp.t
val empty : tthe empty signal
val is_empty : t -> Hardcaml__.Import.boolval (--) : t -> Hardcaml__.Import.string -> tnames a signal
let a = a -- "a" in ...signals may have multiple names.
val width : t -> Hardcaml__.Import.intreturns the width (number of bits) of a signal.
let w = width s in ...
val address_bits_for : Hardcaml__.Import.int -> Hardcaml__.Import.intaddess_bits_for num_elementsreturns the address width required to indexnum_elements.It is the same as
Int.ceil_log2, except it wll return a minimum value of 1 (since you cannot have 0 width vectors). Raises ifnum_elementsis< 0.
val num_bits_to_represent : Hardcaml__.Import.int -> Hardcaml__.Import.intnum_bits_to_represent xreturns the number of bits required to represent the numberx, which should be>= 0.
val of_constant : Hardcaml.Constant.t -> tval to_constant : t -> Hardcaml.Constant.tval constb : Hardcaml__.Import.string -> tconvert binary string to constant
val of_bit_string : Hardcaml__.Import.string -> tval of_int : width:Hardcaml__.Import.int -> Hardcaml__.Import.int -> tconvert integer to constant
val of_int32 : width:Hardcaml__.Import.int -> Hardcaml__.Import.int32 -> tval of_int64 : width:Hardcaml__.Import.int -> Hardcaml__.Import.int64 -> tval of_hex : ?signedness:Hardcaml.Constant.Signedness.t -> width:Hardcaml__.Import.int -> Hardcaml__.Import.string -> tconvert hex string to a constant. If the target width is greater than the hex length and
signednessisSignedthen the result is sign extended. Otherwise the result is zero padded.
val of_string : Hardcaml__.Import.string -> tconvert verilog style or binary string to constant
val of_bit_list : Hardcaml__.Import.int Hardcaml__.Import.list -> tconvert IntbitsList to constant
val of_decimal_string : width:Hardcaml__.Import.int -> Hardcaml__.Import.string -> tval of_char : Hardcaml__.Import.char -> tconvert a
charto an 8 bit constant
val constv : Hardcaml__.Import.string -> tval consti : width:Hardcaml__.Import.int -> Hardcaml__.Import.int -> tval consti32 : width:Hardcaml__.Import.int -> Hardcaml__.Import.int32 -> tval consti64 : width:Hardcaml__.Import.int -> Hardcaml__.Import.int64 -> tval constibl : Hardcaml__.Import.int Hardcaml__.Import.list -> tval consthu : width:Hardcaml__.Import.int -> Hardcaml__.Import.string -> tval consths : width:Hardcaml__.Import.int -> Hardcaml__.Import.string -> tval const : Hardcaml__.Import.string -> tval constd : width:Hardcaml__.Import.int -> Hardcaml__.Import.string -> tval concat_msb : t Hardcaml__.Import.list -> tconcat tsconcatenates a list of signals - the msb of the head of the list will become the msb of the result.let c = concat [ a; b; c ] in ...concatraises iftsis empty or if anytintsis empty.
val concat_lsb : t Hardcaml__.Import.list -> tSimilar to
concat_msbexcept the lsb of the head of the list will become the lsb of the result.
val concat_msb_e : t Hardcaml__.Import.list -> tsame as
concat_msbexcept empty signals are first filtered out
val concat_lsb_e : t Hardcaml__.Import.list -> tsame as
concat_lsbexcept empty signals are first filtered out
val vdd : tlogic 1
val is_vdd : t -> Hardcaml__.Import.boolval gnd : tlogic 0
val is_gnd : t -> Hardcaml__.Import.boolval zero : Hardcaml__.Import.int -> tzero wmakes a the zero valued constant of widthw
val ones : Hardcaml__.Import.int -> tones wmakes a constant of all ones of widthw
val one : Hardcaml__.Import.int -> tone wmakes a one valued constant of widthw
val select : t -> Hardcaml__.Import.int -> Hardcaml__.Import.int -> tselect t hi loselects fromtbits in the rangehi...lo, inclusive.selectraises unlesshiandlofall within0 .. width t - 1andhi >= lo.
val select_e : t -> Hardcaml__.Import.int -> Hardcaml__.Import.int -> tsame as
selectexcept invalid indices returnempty
val bit : t -> Hardcaml__.Import.int -> tselect a single bit
val drop_bottom : t -> Hardcaml__.Import.int -> tdrop_bottom s ndrop bottomnbits ofs
val drop_top : t -> Hardcaml__.Import.int -> tdrop_top s ndrop topnbits ofs
val sel_bottom : t -> Hardcaml__.Import.int -> tsel_bottom s nselect bottomnbits ofs
val sel_top : t -> Hardcaml__.Import.int -> tsel_top s nselect topnbits ofs
val (.:[]) : t -> (Hardcaml__.Import.int * Hardcaml__.Import.int) -> tx.:[hi, lo]==select x hi lo
val (.:+[]) : t -> (Hardcaml__.Import.int * Hardcaml__.Import.int Hardcaml__.Import.option) -> tx.:+[lo, width]==select x (lo + width - 1) lo. IfwidthisNoneit selects all remaining msbs of the vector iex.:+[lo,None]==drop_bottom x lo
val (.:-[]) : t -> (Hardcaml__.Import.int Hardcaml__.Import.option * Hardcaml__.Import.int) -> tx.:-[hi, width]==select x hi (hi - width + 1). IfhiisNoneit defaults to the msb of the vector iex.:-[None, width]==sel_top x width
val (.:()) : t -> Hardcaml__.Import.int -> tx.(i)==bit x i
val insert : into:t -> t -> at_offset:Hardcaml__.Import.int -> tinsert ~into:t x ~at_offsetinsertxintotat given offet
val mux : t -> t Hardcaml__.Import.list -> tmultiplexer.
let m = mux sel inputs in ...Given
l=List.length inputsandw=width selthe following conditions must hold.l<= 2**w,l>= 2If
l< 2**w, the last input is repeated.All inputs provided must have the same width, which will in turn be equal to the width of
m.
val mux2 : t -> t -> t -> tmux2 c t f2 input multiplexer. Selectstifcis high otherwisef.tandfmust have same width andcmust be 1 bit.Equivalent to
mux c [f; t]
val mux_init : t -> Hardcaml__.Import.int -> f:(Hardcaml__.Import.int -> t) -> tval (&:) : t -> t -> tlogical and
val (^:.) : t -> Hardcaml__.Import.int -> tval (~:) : t -> tlogical not
val (-:.) : t -> Hardcaml__.Import.int -> tval negate : t -> tnegation
val (>=+.) : t -> Hardcaml__.Import.int -> tval to_string : t -> Hardcaml__.Import.stringcreate string from signal
val to_int : t -> Hardcaml__.Import.intto_int ttreatstas unsigned and resizes it to fit exactly within an OCamlInt.t.- If
width t > Int.num_bitsthen the upper bits are truncated. - If
width t >= Int.num_bitsandbit t (Int.num_bits-1) = vdd(i.e. the msb of the resultingInt.tis set), then the result is negative. - If
tisSignal.tand not a constant value, an exception is raised.
- If
val to_sint : t -> Hardcaml__.Import.intto_sint ttreatstas signed and resizes it to fit exactly within an OCamlInt.t.- If
width t > Int.num_bitsthen the upper bits are truncated. - If
tisSignal.tand not a constant value, an exception is raised.
- If
val to_int32 : t -> Hardcaml__.Import.int32val to_sint32 : t -> Hardcaml__.Import.int32val to_int64 : t -> Hardcaml__.Import.int64val to_sint64 : t -> Hardcaml__.Import.int64val to_char : t -> Hardcaml__.Import.charConvert signal to a
char. The signal must be 8 bits wide.
val to_bstr : t -> Hardcaml__.Import.stringcreate binary string from signal
val bits_msb : t -> t Hardcaml__.Import.listconvert signal to a list of bits with msb at head of list
val bits_lsb : t -> t Hardcaml__.Import.listconvert signal to a list of bits with lsb at head of list
val to_array : t -> t Hardcaml__.Import.arrayto_array sconvert signalsto array of bits with lsb at index 0
val of_array : t Hardcaml__.Import.array -> tof_array aconvert arrayaof bits to signal with lsb at index 0
val repeat : t -> Hardcaml__.Import.int -> trepeat signal n times
val split_in_half_msb : t -> t * tsplit signal in half. The most significant bits will be in the left half of the returned tuple.
val split_lsb : ?exact:Hardcaml__.Import.bool -> part_width:Hardcaml__.Import.int -> t -> t Hardcaml__.Import.listSplit signal into a list of signals with width equal to
part_width. The least significant bits are at the head of the returned list. Ifexactistruethe input signal width must be exactly divisable bypart_width. Whenexactisfalseand the input signal width is not exactly divisible bypart_width, the last element will contains residual bits.eg:
split_lsb ~part_width:4 16b0001_0010_0011_0100 = [ 4b0100; 4b0011; 4b0010; 4b0001 ] split_lsb ~exact:false ~part_width:4 17b11_0001_0010_0011_0100 = [ 4b0100; 4b0011; 4b0010; 4b0001; 2b11 ]
val split_msb : ?exact:Hardcaml__.Import.bool -> part_width:Hardcaml__.Import.int -> t -> t Hardcaml__.Import.listLike
split_lsbexcept the most significant bits are at the head of the returned list. Residual bits whenexactisfalsegoes to the last element of the list, so in the general casesplit_lsbis not necessarily equivalent tosplit_msb |> List.rev.
val bswap : t -> tval sll : t -> Hardcaml__.Import.int -> tshift left logical
val srl : t -> Hardcaml__.Import.int -> tshift right logical
val sra : t -> Hardcaml__.Import.int -> tshift right arithmetic
val rotl : t -> Hardcaml__.Import.int -> trotate left
val rotr : t -> Hardcaml__.Import.int -> trotate right
val uresize : t -> Hardcaml__.Import.int -> turesize t wreturns the unsigned resize oftto widthw. Ifw = width t, this is a no-op. Ifw < width t, thisselects thewlow bits oft. Ifw > width t, this extendstwithzero (width t - w).
val sresize : t -> Hardcaml__.Import.int -> tsresize t wreturns the signed resize oftto widthw. Ifw = width t, this is a no-op. Ifw < width t, thisselects thewlow bits oft. Ifw > width t, this extendstwithwidth t - wcopies ofmsb t.
val resize_list : resize:(t -> Hardcaml__.Import.int -> t) -> t Hardcaml__.Import.list -> t Hardcaml__.Import.listresize_list ?resize lfinds the maximum width inland appliesresize el maxto each element.
val resize_op2 : resize:(t -> Hardcaml__.Import.int -> t) -> (t -> t -> t) -> t -> t -> tresize_op2 ~resize f a bappliesresize x wtoaandbwherewis the maximum of their widths. It then returnsf a b
val reduce : f:('a -> 'a -> 'a) -> 'a Hardcaml__.Import.list -> 'afold 'op' though list
val mod_counter : max:Hardcaml__.Import.int -> t -> tmod_counter max tisif t = max then 0 else (t + 1), and can be used to count from 0 to (max-1) then from zero again. If max == 1<<n, then a comparator is not generated and overflow arithmetic used instead. If
val tree : arity:Hardcaml__.Import.int -> f:('a Hardcaml__.Import.list -> 'a) -> 'a Hardcaml__.Import.list -> 'atree ~arity ~f inputcreates a tree of operations. The arity of the operator is configurable.treeraises ifinput = [].
val priority_select : (t Hardcaml.With_valid.t Hardcaml__.Import.list -> t Hardcaml.With_valid.t) Hardcaml__.Comb_intf.optional_branching_factorpriority_select casesreturns the value associated with the first case whosevalidsignal is high.validwill be set low in the returnedWith_valid.tif no case is selected.
val priority_select_with_default : (t Hardcaml.With_valid.t Hardcaml__.Import.list -> default:t -> t) Hardcaml__.Comb_intf.optional_branching_factorSame as
priority_selectexcept returnsdefaultif no case matches.
val onehot_select : (t Hardcaml.With_valid.t Hardcaml__.Import.list -> t) Hardcaml__.Comb_intf.optional_branching_factorSelect a case where one and only one
validsignal is enabled. If more than one case isvalidthen the return value is undefined. If no cases are valid,0is returned by the current implementation, though this should not be relied upon.
val popcount : (t -> t) Hardcaml__.Comb_intf.optional_branching_factorpopcount treturns the number of bits set int.
val is_pow2 : (t -> t) Hardcaml__.Comb_intf.optional_branching_factoris_pow2 treturns a bit to indicate iftis a power of 2.
val leading_ones : (t -> t) Hardcaml__.Comb_intf.optional_branching_factorleading_ones treturns the number of consecutive1s from the most significant bit oftdown.
val trailing_ones : (t -> t) Hardcaml__.Comb_intf.optional_branching_factortrailing_ones treturns the number of consecutive1s from the least significant bit oftup.
val leading_zeros : (t -> t) Hardcaml__.Comb_intf.optional_branching_factorleading_zeros treturns the number of consecutive0s from the most significant bit oftdown.
val trailing_zeros : (t -> t) Hardcaml__.Comb_intf.optional_branching_factortrailing_zeros treturns the number of consecutive0s from the least significant bit oftup.
val floor_log2 : (t -> t Hardcaml.With_valid.t) Hardcaml__.Comb_intf.optional_branching_factorfloor_log2 xreturns the floor of log-base-2 ofx.xis treated as unsigned and an error is indicated byvalid = gndin the return value ifx = 0.
val ceil_log2 : (t -> t Hardcaml.With_valid.t) Hardcaml__.Comb_intf.optional_branching_factorceil_log2 xreturns the ceiling of log-base-2 ofx.xis treated as unsigned and an error is indicated byvalid = gndin the return value ifx = 0.
val random : width:Hardcaml__.Import.int -> tcreate random constant vector of given width
module type TypedMath = Hardcaml__.Comb_intf.TypedMath with type t := tval wire : Hardcaml__.Import.int -> tcreates an unassigned wire
val (<==) : t -> t -> Hardcaml__.Import.unitassigns to wire
val assign : t -> t -> Hardcaml__.Import.unitval input : Hardcaml__.Import.string -> Hardcaml__.Import.int -> tcreates an input
val output : Hardcaml__.Import.string -> t -> tcreates an output
module Unoptimized : Hardcaml.Comb.S with type t = tComb logic API without constant propogation optimizations.
module Reg_spec_ : sig ... endReg_spec_is a register specification. It is namedReg_spec_rather thanReg_specso that people consistently use the nameHardcaml.Reg_specrather thanHardcaml.Signal.Reg_spec_.
val reg : Reg_spec_.t -> enable:t -> t -> tval reg_fb : Reg_spec_.t -> enable:t -> w:Hardcaml__.Import.int -> (t -> t) -> tval pipeline : Reg_spec_.t -> n:Hardcaml__.Import.int -> enable:t -> t -> tval memory : Hardcaml__.Import.int -> write_port:write_port -> read_address:t -> tval ram_wbr : ?attributes:Hardcaml.Rtl_attribute.t Hardcaml__.Import.list -> write_port:write_port -> read_port:read_port -> Hardcaml__.Import.int -> tval ram_rbw : ?attributes:Hardcaml.Rtl_attribute.t Hardcaml__.Import.list -> write_port:write_port -> read_port:read_port -> Hardcaml__.Import.int -> tval multiport_memory : ?name:Hardcaml__.Import.string -> ?attributes:Hardcaml.Rtl_attribute.t Hardcaml__.Import.list -> Hardcaml__.Import.int -> write_ports:write_port Hardcaml__.Import.array -> read_addresses:t Hardcaml__.Import.array -> t Hardcaml__.Import.arrayval pp : Hardcaml__.Import.Formatter.t -> t -> Hardcaml__.Import.unitPretty printer.