2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2020 whitequark <whitequark@whitequark.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 // This file is a part of the CXXRTL C API. It should be used together with `cxxrtl_capi.cc`.
24 // The CXXRTL C API makes it possible to drive CXXRTL designs using C or any other language that
25 // supports the C ABI, for example, Python. It does not provide a way to implement black boxes.
35 // Opaque reference to a design toplevel.
37 // A design toplevel can only be used to create a design handle.
38 typedef struct _cxxrtl_toplevel
*cxxrtl_toplevel
;
40 // The constructor for a design toplevel is provided as a part of generated code for that design.
41 // Its prototype matches:
43 // cxxrtl_toplevel <design-name>_create();
45 // Opaque reference to a design handle.
47 // A design handle is required by all operations in the C API.
48 typedef struct _cxxrtl_handle
*cxxrtl_handle
;
50 // Create a design handle from a design toplevel.
52 // The `design` is consumed by this operation and cannot be used afterwards.
53 cxxrtl_handle
cxxrtl_create(cxxrtl_toplevel design
);
55 // Release all resources used by a design and its handle.
56 void cxxrtl_destroy(cxxrtl_handle handle
);
58 // Reinitialize the design, replacing the internal state with the reset values while preserving
61 // This operation is essentially equivalent to a power-on reset. Values, wires, and memories are
62 // returned to their reset state while preserving the state of black boxes and keeping all of
63 // the interior pointers obtained with e.g. `cxxrtl_get` valid.
64 void cxxrtl_reset(cxxrtl_handle handle
);
66 // Evaluate the design, propagating changes on inputs to the `next` value of internal state and
69 // Returns 1 if the design is known to immediately converge, 0 otherwise.
70 int cxxrtl_eval(cxxrtl_handle handle
);
72 // Commit the design, replacing the `curr` value of internal state and output wires with the `next`
75 // Return 1 if any of the `curr` values were updated, 0 otherwise.
76 int cxxrtl_commit(cxxrtl_handle handle
);
78 // Simulate the design to a fixed point.
80 // Returns the number of delta cycles.
81 size_t cxxrtl_step(cxxrtl_handle handle
);
83 // Type of a simulated object.
85 // The type of a simulated object indicates the way it is stored and the operations that are legal
86 // to perform on it (i.e. won't crash the simulation). It says very little about object semantics,
87 // which is specified through flags.
89 // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by
90 // combinatorial cells, or toplevel input nodes.
92 // Values can be inspected via the `curr` pointer. If the `next` pointer is NULL, the value is
93 // driven by a constant and can never be modified. Otherwise, the value can be modified through
94 // the `next` pointer (which is equal to `curr` if not NULL). Note that changes to the bits
95 // driven by combinatorial cells will be ignored.
97 // Values always have depth 1.
100 // Wires correspond to doubly buffered netlist nodes, i.e. nodes driven, at least in part, by
101 // storage cells, or by combinatorial cells that are a part of a feedback path. They are also
102 // present in non-optimized builds.
104 // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are
105 // distinct for wires). Note that changes to the bits driven by combinatorial cells will be
108 // Wires always have depth 1.
111 // Memories correspond to memory cells.
113 // Memories can be inspected and modified via the `curr` pointer. Due to a limitation of this
114 // API, memories cannot yet be modified in a guaranteed race-free way, and the `next` pointer is
118 // Aliases correspond to netlist nodes driven by another node such that their value is always
121 // Aliases can be inspected via the `curr` pointer. They cannot be modified, and the `next`
122 // pointer is always NULL.
125 // More object types may be added in the future, but the existing ones will never change.
128 // Flags of a simulated object.
130 // The flags of a simulated object indicate its role in the netlist:
131 // * The flags `CXXRTL_INPUT` and `CXXRTL_OUTPUT` designate module ports.
132 // * The flags `CXXRTL_DRIVEN_SYNC`, `CXXRTL_DRIVEN_COMB`, and `CXXRTL_UNDRIVEN` specify
133 // the semantics of node state. An object with several of these flags set has different bits
134 // follow different semantics.
136 // Node is a module input port.
138 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
139 // with `CXXRTL_OUTPUT`, as well as other flags.
140 CXXRTL_INPUT
= 1 << 0,
142 // Node is a module output port.
144 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with `CXXRTL_INPUT`,
145 // as well as other flags.
146 CXXRTL_OUTPUT
= 1 << 1,
148 // Node is a module inout port.
150 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with other flags.
151 CXXRTL_INOUT
= (CXXRTL_INPUT
|CXXRTL_OUTPUT
),
153 // Node has bits that are driven by a storage cell.
155 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with
156 // `CXXRTL_DRIVEN_COMB` and `CXXRTL_UNDRIVEN`, as well as other flags.
158 // This flag is set on wires that have bits connected directly to the output of a flip-flop or
159 // a latch, and hold its state. Many `CXXRTL_WIRE` objects may not have the `CXXRTL_DRIVEN_SYNC`
160 // flag set; for example, output ports and feedback wires generally won't. Writing to the `next`
161 // pointer of these wires updates stored state, and for designs without combinatorial loops,
162 // capturing the value from every of these wires through the `curr` pointer creates a complete
163 // snapshot of the design state.
164 CXXRTL_DRIVEN_SYNC
= 1 << 2,
166 // Node has bits that are driven by a combinatorial cell or another node.
168 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
169 // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags.
171 // This flag is set on objects that have bits connected to the output of a combinatorial cell,
172 // or directly to another node. For designs without combinatorial loops, writing to such bits
173 // through the `next` pointer (if it is not NULL) has no effect.
174 CXXRTL_DRIVEN_COMB
= 1 << 3,
176 // Node has bits that are not driven.
178 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
179 // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_DRIVEN_COMB`, as well as other flags.
181 // This flag is set on objects that have bits not driven by an output of any cell or by another
182 // node, such as inputs and dangling wires.
183 CXXRTL_UNDRIVEN
= 1 << 4,
185 // More object flags may be added in the future, but the existing ones will never change.
188 // Description of a simulated object.
190 // The `data` array can be accessed directly to inspect and, if applicable, modify the bits
191 // stored in the object.
192 struct cxxrtl_object
{
193 // Type of the object.
195 // All objects have the same memory layout determined by `width` and `depth`, but the type
196 // determines all other properties of the object.
197 uint32_t type
; // actually `enum cxxrtl_type`
199 // Flags of the object.
200 uint32_t flags
; // actually bit mask of `enum cxxrtl_flags`
202 // Width of the object in bits.
205 // Index of the least significant bit.
208 // Depth of the object. Only meaningful for memories; for other objects, always 1.
211 // Index of the first word. Only meaningful for memories; for other objects, always 0;
214 // Bits stored in the object, as 32-bit chunks, least significant bits first.
216 // The width is rounded up to a multiple of 32; the padding bits are always set to 0 by
217 // the simulation code, and must be always written as 0 when modified by user code.
218 // In memories, every element is stored contiguously. Therefore, the total number of chunks
219 // in any object is `((width + 31) / 32) * depth`.
221 // To allow the simulation to be partitioned into multiple independent units communicating
222 // through wires, the bits are double buffered. To avoid race conditions, user code should
223 // always read from `curr` and write to `next`. The `curr` pointer is always valid; for objects
224 // that cannot be modified, or cannot be modified in a race-free way, `next` is NULL.
228 // More description fields may be added in the future, but the existing ones will never change.
231 // Retrieve description of a simulated object.
233 // The `name` is the full hierarchical name of the object in the Yosys notation, where public names
234 // have a `\` prefix and hierarchy levels are separated by single spaces. For example, if
235 // the top-level module instantiates a module `foo`, which in turn contains a wire `bar`, the full
236 // hierarchical name is `\foo \bar`.
238 // The storage of a single abstract object may be split (usually with the `splitnets` pass) into
239 // many physical parts, all of which correspond to the same hierarchical name. To handle such cases,
240 // this function returns an array and writes its length to `parts`. The array is sorted by `lsb_at`.
242 // Returns the object parts if it was found, NULL otherwise. The returned parts are valid until
243 // the design is destroyed.
244 struct cxxrtl_object
*cxxrtl_get_parts(cxxrtl_handle handle
, const char *name
, size_t *parts
);
246 // Retrieve description of a single part simulated object.
248 // This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that,
249 // if the object exists, it consists of a single part. If assertions are disabled, it returns NULL
250 // for multi-part objects.
251 inline struct cxxrtl_object
*cxxrtl_get(cxxrtl_handle handle
, const char *name
) {
253 struct cxxrtl_object
*object
= cxxrtl_get_parts(handle
, name
, &parts
);
254 assert(object
== NULL
|| parts
== 1);
255 if (object
== NULL
|| parts
== 1)
260 // Enumerate simulated objects.
262 // For every object in the simulation, `callback` is called with the provided `data`, the full
263 // hierarchical name of the object (see `cxxrtl_get` for details), and the object parts.
264 // The provided `name` and `object` values are valid until the design is destroyed.
265 void cxxrtl_enum(cxxrtl_handle handle
, void *data
,
266 void (*callback
)(void *data
, const char *name
,
267 struct cxxrtl_object
*object
, size_t parts
));