You can convert a Hardcaml to either Verilog or VHDL The following is a trivial example We also provide basic Systemverilog support the generated RTL is basically the same as Verilog mode except we use the Systemverilog reserved words to correctly perform name mangling Circuit let circuit Circuit create_exn name test output b input a 1 # let Rtl print Verilog circuit module test a b input a output b assign b a endmodule # let Rtl print Vhdl circuit library ieee use ieee std_logic_1164 all use ieee numeric_std all entity test is port a in std_logic b out std_logic end entity architecture rtl of test is begin b < a end architecture
In Hardcaml a corresponds to a single module in Verilog or entity in VHDL s can contain s which reference some other module or entity within a hierarchical design The Hardcaml RTL generator is aware of the s and can recursively generate the RTL for them if they are provided in a A stores the implementation of s that can be instantiated It is essentially a mapping between circuit names and their implementations If a circuit implementation is not found in the Hardcaml will still generate the appropriate instantiation in the RTL output This allows for integration with external modules such as vendor IP that will be added later in the design flow or for module hierarchy to be described in Hardcaml Circuit Circuit Instantiation Instantiation Circuit_database Circuit_database Circuit Circuit_database
The function will output the RTL for a design and optionally any instantiations defined through a to It is simple and usable in most cases Rtl print Circuit_database stdout
The RTL API provides a way for the Hardcaml to discover the full design hierarchy and for the user to decide how to write it out It starts with the function the which contains implementations of found within the hierarchy of s Some configuration options for how to generate the RTL either Verilog or VHDL a list of top level circuits to generate returns a list which represent the design hierarchy Hierarchical circuits The returned by can be factored into the full design hierarchy using and These both return a list of s which contain functions to output a module implementation It should be noted that if a module is instantiated in multiple places it will still only be represented once within the design hierarchy Blackboxes A blackbox is a module or entity which describes just its interface and does not include its implementation The RTL generator can create black boxes if required Outputting RTL Hardcaml predefines 4 ways to output the hierarchy of modules generate full rtl for everything recursively This is the most common option and what uses only generate the given top levels and do not recuse into the hierarchy the top levels will be generated along with blackboxes for all modules in the hierarchy the top levels will be generated as blackboxes Each of these functions returns a Ropes Ropes are used by Hardcaml to generate code and are a fancy type of string All you need to know is they can be converted to a standard string with Example This creates a hierarchy where instantiates which in turn instantiates We now need to create a containing the inner circuits Now we can print the RTL for in various ways Find within the hierarchy and print that directly create # Rtl create database Circuit_database t > config Rtl Config t > Rtl Language t > Circuit t list > Rtl Hierarchical_circuits t list <fun> database Circuit_database Instantiations Circuit config Rtl Langauge t Circuit t list create Hierarchical_circuits Hierarchical_circuits create subcircuits top_level_circuits Circuit_instance Hierarchical_circuits full_hierarchy Rtl print top_levels_only top_levels_and_blackboxes top_levels_as_blackboxes Rope t Rope to_string let inner1 Circuit create_exn name inner1 output b input a 1 let inner2 let x input x 1 in let inst Instantiation create name inner1 inputs a x outputs b 1 in Circuit create_exn name inner2 output y Instantiation output inst b let top let s input s 1 in let inst Instantiation create name inner2 inputs x s outputs y 1 in Circuit create_exn name top output t Instantiation output inst y top inner1 inner2 Circuit_database let database Circuit_database create Circuit_database insert database inner1 Circuit_database insert database inner2 top let rtl Rtl create database Verilog top # Rtl top_levels_and_blackboxes rtl |> Rope to_string |> Stdio print_endline module inner1 a b input a output b endmodule module inner2 x y input x output y endmodule module top s t input s output t wire _4 wire _2 inner2 the_inner2 x s y _4 assign _2 _4 assign t _2 endmodule unit # Rtl top_levels_as_blackboxes rtl |> Rope to_string |> Stdio print_endline module top s t input s output t endmodule unit inner2 # let inner2 Rtl Hierarchical_circuits subcircuits rtl |> List find_exn f fun sub > String equal Rtl Circuit_instance module_name sub inner2 |> Rtl Circuit_instance rtl |> Rope to_string |> Stdio print_endline module inner2 x y input x output y wire _4 wire _2 inner1 the_inner1 a x b _4 assign _2 _4 assign y _2 endmodule val inner2 unit