By default the ppx uses the field name for the string name and attribute to specify the field width if not provided it defaults to The ppx supports nesting arrays lists and various tools to manage port naming Nesting Interfaces can contain other interfaces Nesting can go as deep as required Arrays and lists For s and s the lengths must be specified with an attribute Arrays of nested interfaces are also supported Options Fields in an interface may be optional Simple and nested fields are supported The attribute controls if they are included in the interface or not and must be specified Such fields can arise when describing a circuit generator where some configuration option may require extra inputs or outputs module Simple_interface struct type a t foo a @bits 32 bar a * Where a bit width is not specified it defaults to 1 * @@deriving hardcaml end # print_s %message Simple_interface port_names_and_widths string * int Simple_interface t Simple_interface port_names_and_widths foo foo 32 bar bar 1 unit @bits N 1 module Nested_interfaces struct type a t clock a clear a hello a Simple_interface t world a Simple_interface t @@deriving hardcaml end array list module Array_and_list_interfaces struct type a t my_array a array @length 2 my_list a list @length 10 @bits 10 @@deriving hardcaml end module Interface_with_option struct type a t maybe_x a option @exists true @bits 3 maybe_y a Simple_interface t option @exists false @@deriving hardcaml end exists
Naming simple fields By default the field name is used to derive a port name Port names will be used during RTL generation This can be modified with attributes overrides the fields name with the given string apply the given prefix and or suffix to the name and attributes may also be used with nested interfaces though will not work Naming nested interfaces and can be applied to nested interfaces and will apply the given prefix or suffix to each field within the nested interface By default we automatically mangle nested interface names by prefixing them with the field name and a separator to avoid name clashes This functionality can be disabled with or customized by specifying a different separator Global attributes The naming attributes can be specified for all fields as follows and are supported rtlname rtlprefix rtlsuffix module Unmodified_port_names struct type a t a a b a c a @@deriving hardcaml end module Modified_port_names struct type a t a a @rtlname aaa b a @rtlprefix x_ c a @rtlsuffix _x @@deriving hardcaml end # Unmodified_port_names port_names string Unmodified_port_names t Unmodified_port_names a a b b c c # Modified_port_names port_names string Modified_port_names t Modified_port_names a aaa b x_b c c_x rtlprefix rtlsuffix rtlmangle rtlname rtlprefix rtlsuffix $ # Nested_interfaces port_names string Nested_interfaces t Nested_interfaces clock clock clear clear hello Simple_interface foo hello$foo bar hello$bar world Simple_interface foo world$foo bar world$bar rtlmangle false module Nested_interfaces_mangled struct type a t clock a clear a hello a Simple_interface t world a Simple_interface t @@deriving hardcaml rtlmangle _ end # Nested_interfaces_mangled port_names string Nested_interfaces_mangled t Nested_interfaces_mangled clock clock clear clear hello Simple_interface foo hello_foo bar hello_bar world Simple_interface foo world_foo bar world_bar module Global_suffix struct type a t a a b a c a @@deriving hardcaml rtlsuffix _i end rtlprefix rtlsuffix rtlmangle