#ifndef GSIM_H #define GSIM_H /* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ #include #include #include #include #include #if defined(__GNUC__) && (__GNUC__ >= 4) #define GSIM_MUST_USE __attribute__ ((warn_unused_result)) #elif defined(_MSC_VER) && (_MSC_VER >= 1700) #define GSIM_MUST_USE _Check_return_ #else #define GSIM_MUST_USE #endif #define INVALID_WIRE_ID 0xFFFFFFFF #define INVALID_COMPONENT_ID 0xFFFFFFFF #define GSIM_RESULT_SUCCESS 0 #define GSIM_RESULT_MAX_STEPS_REACHED 1 #define GSIM_RESULT_FALSE 0 #define GSIM_RESULT_TRUE 1 #define GSIM_RESULT_HIGH_Z 0 #define GSIM_RESULT_UNDEFINED 1 #define GSIM_RESULT_LOGIC_0 2 #define GSIM_RESULT_LOGIC_1 3 #define GSIM_RESULT_NULL_POINTER -0x0000_0001 #define GSIM_RESULT_POINTER_MISALIGNED -0x0000_0002 #define GSIM_RESULT_INVALID_ARGUMENT -0x0000_0003 #define GSIM_RESULT_ARGUMENT_OUT_OF_RANGE -0x0000_0004 #define GSIM_RESULT_UTF8_ENCODING -0x0000_0005 #define GSIM_RESULT_IO -0x0000_0006 #define GSIM_RESULT_INVALID_OPERATION -0x0000_0007 #define GSIM_RESULT_RESOURCE_LIMIT_REACHED -0x0001_0001 #define GSIM_RESULT_WIRE_WIDTH_MISMATCH -0x0001_0002 #define GSIM_RESULT_WIRE_WIDTH_INCOMPATIBLE -0x0001_0003 #define GSIM_RESULT_OFFSET_OUT_OF_RANGE -0x0001_0004 #define GSIM_RESULT_TOO_FEW_INPUTS -0x0001_0005 #define GSIM_RESULT_INVALID_INPUT_COUNT -0x0001_0006 #define GSIM_RESULT_INVALID_COMPONENT_TYPE -0x0001_0007 #define GSIM_RESULT_CONFLICT -0x0002_0001 #define GSIM_RESULT_INVALID_WIRE_ID -0x0002_0002 #define GSIM_RESULT_INVALID_COMPONENT_ID -0x0002_0003 #define GSIM_RESULT_MALFORMED_FORMAT -0x0003_0001 #define GSIM_RESULT_UNSUPPORTED -0x0003_0002 /** * An opaque type representing a logic state of up to 255 bits. * Use only behind a pointer. */ typedef struct LogicState LogicState; /** * An opaque type used to build up a simulation graph. * Use only behind a pointer. */ typedef struct Builder Builder; /** * An opaque type representing a simulation. * Use only behind a pointer. */ typedef struct Simulator Simulator; /** * One of the `GSIM_RESULT_*` constants */ typedef int32_t GsimResult; /** * A unique identifier for a wire inside a simulation */ typedef uint32_t WireId; /** * A unique identifier for a component inside a simulation */ typedef uint32_t ComponentId; typedef struct PortList { size_t len; const char *const *names; const WireId *wires; } PortList; typedef struct SimulationErrors { size_t conflicts_len; const WireId *conflicts; } SimulationErrors; /** * Frees a string that was returned by other functions in the API. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult string_free(const char *s); /** * Creates a new `Builder` object. * The resulting `Builder` must be freed by calling `simulator_build`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_new(Builder **builder); /** * Writes the simulation graph into a Graphviz DOT file. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_write_dot(const Builder *builder, const char *dot_file); /** * Gets the width of a wire. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_wire_width(const Builder *builder, WireId wire, uint8_t *width); /** * Drives a wire to a certain state without needing a component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_set_wire_drive(Builder *builder, WireId wire, const LogicState *drive); /** * Gets the current drive of a wire. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_wire_drive(const Builder *builder, WireId wire, const LogicState **drive); /** * Gets the width of a register in the simulation. * The ID passed to `register` must refer to a register component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_register_width(const Builder *builder, ComponentId register_, uint8_t *width); /** * Gets the current state of a register in the simulation. * The ID passed to `register` must refer to a register component. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_read_register_state(const Builder *builder, ComponentId register_, const LogicState **state); /** * Sets the state of a register in the simulation. * The ID passed to `register` must refer to a register component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_write_register_state(Builder *builder, ComponentId register_, const LogicState *state); /** * Gets the size and width of a memory block in the simulation. * The ID passed to `memory` must refer to a memory component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_memory_metrics(const Builder *builder, ComponentId memory, size_t *size, uint8_t *width); /** * Gets the current state of a memory location in the simulation. * The ID passed to `memory` must refer to a memory component. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_read_memory_state(const Builder *builder, ComponentId memory, size_t addr, const LogicState **state); /** * Sets the state of a memory location in the simulation. * The ID passed to `memory` must refer to a memory component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_write_memory_state(Builder *builder, ComponentId memory, size_t addr, const LogicState *state); /** * Sets the name of a wire. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_set_wire_name(Builder *builder, WireId wire, const char *name); /** * Gets the name of a wire, if one has been assigned. * If no name has been assigned to the wire, name will be set to `null`. * The resulting string (if any) must be freed by calling `string_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_wire_name(const Builder *builder, WireId wire, const char **name); /** * Sets the name of a wire. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_set_component_name(Builder *builder, ComponentId component, const char *name); /** * Gets the name of a component, if one has been assigned. * If no name has been assigned to the component, name will be set to `null`. * The resulting string (if any) must be freed by calling `string_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult builder_get_component_name(const Builder *builder, ComponentId component, const char **name); GSIM_MUST_USE GsimResult builder_add_wire(Builder *builder, uint8_t width, WireId *wire); GSIM_MUST_USE GsimResult builder_add_and_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_or_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_xor_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_nand_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_nor_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_xnor_gate(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_merge(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_priority_decoder(Builder *builder, const WireId *inputs, size_t input_len, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_buffer(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_add(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_sub(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_mul(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_left_shift(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_logical_right_shift(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_arithmetic_right_shift(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_equal(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_not_equal(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_less_than(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_greater_than(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_less_than_or_equal(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_greater_than_or_equal(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_less_than_signed(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_greater_than_signed(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_less_than_or_equal_signed(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_compare_greater_than_or_equal_signed(Builder *builder, WireId input_a, WireId input_b, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_not_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_neg(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_and_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_or_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_xor_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_nand_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_nor_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_horizontal_xnor_gate(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_zero_extend(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_sign_extend(Builder *builder, WireId input, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_slice(Builder *builder, WireId input, uint8_t offset, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_adder(Builder *builder, WireId input_a, WireId input_b, WireId carry_in, WireId output, WireId carry_out, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_multiplexer(Builder *builder, const WireId *inputs, size_t input_len, WireId select, WireId output, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_register(Builder *builder, WireId data_in, WireId data_out, WireId enable, WireId clock, uint8_t clock_polarity, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_ram(Builder *builder, WireId write_addr, WireId data_in, WireId read_addr, WireId data_out, WireId write, WireId clock, uint8_t clock_polarity, ComponentId *component); GSIM_MUST_USE GsimResult builder_add_rom(Builder *builder, WireId addr, WireId data, ComponentId *component); /** * Frees all allocations of a `PortList` struct that was returned by other functions in the API. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult port_list_free(struct PortList port_list); /** * Imports a module defined by a Yosys netgraph into the circuit. * On success, `inputs` and `outputs` will contain a list of the imported modules ports. * The resulting `PortList` objects must be freed by calling `port_list_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. * * Valid netgraphs can be generated with this command: * `yosys -p "read_verilog ; synth -top -flatten -noalumacc -nordff -run begin:fine; hierarchy -check; check; write_json ` */ GSIM_MUST_USE GsimResult builder_import_yosys_module(Builder *builder, const char *json_file, struct PortList *inputs, struct PortList *outputs); /** * Creates a `LogicState` with all bits set to the high impedance state. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE const LogicState *logic_state_high_z(void); /** * Creates a `LogicState` with all bits set to an undefined state. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE const LogicState *logic_state_undefined(void); /** * Creates a `LogicState` with all bits set to the logic low state. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE const LogicState *logic_state_logic_0(void); /** * Creates a `LogicState` with all bits set to the logic high state. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE const LogicState *logic_state_logic_1(void); /** * Creates a `LogicState` representing the given integer. High bits are set to 0. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE const LogicState *logic_state_from_int(uint32_t value); /** * Creates a `LogicState` representing the given integer. Integer words are given in little endian order, high bits are set to 0. * Will fail if `word_len` is not between 1 and 8 inclusive. * Returns `GSIM_RESULT_SUCCESS` on success. * The returned `LogicState` must be freed by calling `logic_state_free`. */ GSIM_MUST_USE GsimResult logic_state_from_big_int(const uint32_t *value, size_t word_len, const LogicState **state); /** * Parses a `LogicState` from a string representation. High bits are set to high impedance. * Will fail if the string is longer than 255 characters, shorter than one character, or contains characters other than `'z'`, `'Z'`, `'x'`, `'X'`, `'0'` and `'1'`. * Returns `GSIM_RESULT_SUCCESS` on success. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. */ GSIM_MUST_USE GsimResult logic_state_parse(const char *s, const LogicState **state); /** * Clones a `LogicState` into a new allocation. * Returns `GSIM_RESULT_SUCCESS` on success. * The cloned `LogicState` must be freed separately by calling `logic_state_free`, only if the operation succeeded. */ GSIM_MUST_USE GsimResult logic_state_clone(const LogicState *state, const LogicState **clone); /** * Attempts to convert the first `width` bits of a `LogicState` to an integer. * `width` must be between 1 and 32 inclusive. Will fail if any of the bits are either in the `Z` or `X` state. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult logic_state_to_int(const LogicState *state, uint8_t width, uint32_t *value); /** * Attempts to convert the first `width` bits of a `LogicState` to an integer. Integer words are returned in little endian order. * `value` must contain at least `width / 32` words rounded up. Will fail if any of the bits are either in the `Z` or `X` state. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult logic_state_to_big_int(const LogicState *state, uint8_t width, uint32_t *value); /** * Gets the state of a single bit in a `LogicState`. * On success, returns one of the following values: `GSIM_RESULT_HIGH_Z`, `GSIM_RESULT_UNDEFINED`, `GSIM_RESULT_LOGIC_0`, `GSIM_RESULT_LOGIC_1` */ GSIM_MUST_USE GsimResult logic_state_get_bit_state(const LogicState *state, uint8_t bit_index); /** * Prints the string representation of a `LogicState` into a buffer. * The buffer must be big enough to hold at least `width` bytes and will not be null terminated by this function. * Since the buffer is owned by the caller, it must not be freed by `string_free`. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult logic_state_print(const LogicState *state, uint8_t width, char *buffer); /** * Checks the first `width` bits of two `LogicState` objects for equality. * On success, returns one of the following values: `GSIM_RESULT_FALSE`, `GSIM_RESULT_TRUE` */ GSIM_MUST_USE GsimResult logic_state_eq(const LogicState *a, const LogicState *b, uint8_t width); /** * Frees a `LogicState` that was returned by other functions in the API. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult logic_state_free(LogicState *state); /** * Creates a new `Simulator` object from a `Builder`. * If the operation succeeded, the specified `Builder` will be freed and be set to `null`. * The resulting `Simulator` must be freed by calling `simulator_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_build(Builder **builder, struct Simulator **simulator); /** * Creates a new `Simulator` object from a `Builder`, with VCD tracing enabled. * If the operation succeeded, the specified `Builder` will be freed and be set to `null`. * The `Builder` may be freed even if the operation failed. In this case it will also be set to `null`. * The resulting `Simulator` must be freed by calling `simulator_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_build_with_trace(Builder **builder, const char *trace_file, const struct Simulator **simulator); /** * Writes the simulation graph into a Graphviz DOT file. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_write_dot(const struct Simulator *simulator, const char *dot_file, uint8_t show_states); /** * Gets the width of a wire. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_wire_width(const struct Simulator *simulator, WireId wire, uint8_t *width); /** * Drives a wire to a certain state without needing a component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_set_wire_drive(struct Simulator *simulator, WireId wire, const LogicState *drive); /** * Gets the current drive of a wire. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_wire_drive(const struct Simulator *simulator, WireId wire, const LogicState **drive); /** * Gets the current state of a wire. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_wire_state(const struct Simulator *simulator, WireId wire, const LogicState **state); /** * Gets the width of a register in the simulation. * The ID passed to `register` must refer to a register component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_register_width(const struct Simulator *simulator, ComponentId register_, uint8_t *width); /** * Gets the current state of a register in the simulation. * The ID passed to `register` must refer to a register component. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_read_register_state(const struct Simulator *simulator, ComponentId register_, const LogicState **state); /** * Sets the state of a register in the simulation. * The ID passed to `register` must refer to a register component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_write_register_state(struct Simulator *simulator, ComponentId register_, const LogicState *state); /** * Gets the size and width of a memory block in the simulation. * The ID passed to `memory` must refer to a memory component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_memory_metrics(const struct Simulator *simulator, ComponentId memory, size_t *size, uint8_t *width); /** * Gets the current state of a memory location in the simulation. * The ID passed to `memory` must refer to a memory component. * The resulting `LogicState` must be freed by calling `logic_state_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_read_memory_state(const struct Simulator *simulator, ComponentId memory, size_t addr, const LogicState **state); /** * Sets the state of a memory location in the simulation. * The ID passed to `memory` must refer to a memory component. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_write_memory_state(struct Simulator *simulator, ComponentId memory, size_t addr, const LogicState *state); /** * Gets the name of a wire, if one has been assigned. * If no name has been assigned to the wire, name will be set to `null`. * The resulting string (if any) must be freed by calling `string_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_wire_name(struct Simulator *simulator, WireId wire, const char **name); /** * Gets the name of a component, if one has been assigned. * If no name has been assigned to the component, name will be set to `null`. * The resulting string (if any) must be freed by calling `string_free`, only if the operation succeeded. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_get_component_name(struct Simulator *simulator, ComponentId component, const char **name); /** * Resets the simulation. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_reset(struct Simulator *simulator); /** * Frees all allocations of a `SimulationErrors` struct that was returned by other functions in the API. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulation_errors_free(struct SimulationErrors error); /** * Runs the simulation until it settles, but at most for `max_steps` steps. * On success, returns one of the following values: * - `GSIM_RESULT_SUCCESS`: the simulation settled within `max_steps` steps * - `GSIM_RESULT_MAX_STEPS_REACHED`: the simulation did not settle within `max_steps` steps * * If a `Conflict` failure is reported, `errors` will contain additional information about which wires had a driver conflict. * In this case, `errors` must later be freed by calling `simulation_errors_free`. */ GSIM_MUST_USE GsimResult simulator_run_sim(struct Simulator *simulator, uint64_t max_steps, struct SimulationErrors *errors); /** * Writes the current state of the simulation into the simulators associated VCD file at the specified time in nanoseconds. * Calling this function with a `Simulator` that was not constructed by `simulator_build_with_trace` is not illegal, but will have no effect. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_trace(struct Simulator *simulator, uint64_t time); /** * Frees a `Simulator` object. * Returns `GSIM_RESULT_SUCCESS` on success. */ GSIM_MUST_USE GsimResult simulator_free(struct Simulator *simulator); #endif /* GSIM_H */