Merge pull request #2480 from YosysHQ/dave/nexus-lram
[yosys.git] / backends / cxxrtl / cxxrtl_capi.h
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2020 whitequark <whitequark@whitequark.org>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
8 *
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.
16 *
17 */
18
19 #ifndef CXXRTL_CAPI_H
20 #define CXXRTL_CAPI_H
21
22 // This file is a part of the CXXRTL C API. It should be used together with `cxxrtl_capi.cc`.
23 //
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.
26
27 #include <stddef.h>
28 #include <stdint.h>
29 #include <assert.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 // Opaque reference to a design toplevel.
36 //
37 // A design toplevel can only be used to create a design handle.
38 typedef struct _cxxrtl_toplevel *cxxrtl_toplevel;
39
40 // The constructor for a design toplevel is provided as a part of generated code for that design.
41 // Its prototype matches:
42 //
43 // cxxrtl_toplevel <design-name>_create();
44
45 // Opaque reference to a design handle.
46 //
47 // A design handle is required by all operations in the C API.
48 typedef struct _cxxrtl_handle *cxxrtl_handle;
49
50 // Create a design handle from a design toplevel.
51 //
52 // The `design` is consumed by this operation and cannot be used afterwards.
53 cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design);
54
55 // Create a design handle at a given hierarchy position from a design toplevel.
56 //
57 // This operation is similar to `cxxrtl_create`, except the full hierarchical name of every object
58 // is prepended with `root`.
59 cxxrtl_handle cxxrtl_create_at(cxxrtl_toplevel design, const char *root);
60
61 // Release all resources used by a design and its handle.
62 void cxxrtl_destroy(cxxrtl_handle handle);
63
64 // Reinitialize the design, replacing the internal state with the reset values while preserving
65 // black boxes.
66 //
67 // This operation is essentially equivalent to a power-on reset. Values, wires, and memories are
68 // returned to their reset state while preserving the state of black boxes and keeping all of
69 // the interior pointers obtained with e.g. `cxxrtl_get` valid.
70 void cxxrtl_reset(cxxrtl_handle handle);
71
72 // Evaluate the design, propagating changes on inputs to the `next` value of internal state and
73 // output wires.
74 //
75 // Returns 1 if the design is known to immediately converge, 0 otherwise.
76 int cxxrtl_eval(cxxrtl_handle handle);
77
78 // Commit the design, replacing the `curr` value of internal state and output wires with the `next`
79 // value.
80 //
81 // Return 1 if any of the `curr` values were updated, 0 otherwise.
82 int cxxrtl_commit(cxxrtl_handle handle);
83
84 // Simulate the design to a fixed point.
85 //
86 // Returns the number of delta cycles.
87 size_t cxxrtl_step(cxxrtl_handle handle);
88
89 // Type of a simulated object.
90 //
91 // The type of a simulated object indicates the way it is stored and the operations that are legal
92 // to perform on it (i.e. won't crash the simulation). It says very little about object semantics,
93 // which is specified through flags.
94 enum cxxrtl_type {
95 // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by
96 // combinatorial cells, or toplevel input nodes.
97 //
98 // Values can be inspected via the `curr` pointer. If the `next` pointer is NULL, the value is
99 // driven by a constant and can never be modified. Otherwise, the value can be modified through
100 // the `next` pointer (which is equal to `curr` if not NULL). Note that changes to the bits
101 // driven by combinatorial cells will be ignored.
102 //
103 // Values always have depth 1.
104 CXXRTL_VALUE = 0,
105
106 // Wires correspond to doubly buffered netlist nodes, i.e. nodes driven, at least in part, by
107 // storage cells, or by combinatorial cells that are a part of a feedback path. They are also
108 // present in non-optimized builds.
109 //
110 // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are
111 // distinct for wires). Note that changes to the bits driven by combinatorial cells will be
112 // ignored.
113 //
114 // Wires always have depth 1.
115 CXXRTL_WIRE = 1,
116
117 // Memories correspond to memory cells.
118 //
119 // Memories can be inspected and modified via the `curr` pointer. Due to a limitation of this
120 // API, memories cannot yet be modified in a guaranteed race-free way, and the `next` pointer is
121 // always NULL.
122 CXXRTL_MEMORY = 2,
123
124 // Aliases correspond to netlist nodes driven by another node such that their value is always
125 // exactly equal.
126 //
127 // Aliases can be inspected via the `curr` pointer. They cannot be modified, and the `next`
128 // pointer is always NULL.
129 CXXRTL_ALIAS = 3,
130
131 // Outlines correspond to netlist nodes that were optimized in a way that makes them inaccessible
132 // outside of a module's `eval()` function. At the highest debug information level, every inlined
133 // node has a corresponding outline object.
134 //
135 // Outlines can be inspected via the `curr` pointer and can never be modified; the `next` pointer
136 // is always NULL. Unlike all other objects, the bits of an outline object are meaningful only
137 // after a call to `cxxrtl_outline_eval` and until any subsequent modification to the netlist.
138 // Observing this requirement is the responsibility of the caller; it is not enforced.
139 //
140 // Outlines always correspond to combinatorial netlist nodes that are not ports.
141 CXXRTL_OUTLINE = 4,
142
143 // More object types may be added in the future, but the existing ones will never change.
144 };
145
146 // Flags of a simulated object.
147 //
148 // The flags of a simulated object indicate its role in the netlist:
149 // * The flags `CXXRTL_INPUT` and `CXXRTL_OUTPUT` designate module ports.
150 // * The flags `CXXRTL_DRIVEN_SYNC`, `CXXRTL_DRIVEN_COMB`, and `CXXRTL_UNDRIVEN` specify
151 // the semantics of node state. An object with several of these flags set has different bits
152 // follow different semantics.
153 enum cxxrtl_flag {
154 // Node is a module input port.
155 //
156 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
157 // with `CXXRTL_OUTPUT`, as well as other flags.
158 CXXRTL_INPUT = 1 << 0,
159
160 // Node is a module output port.
161 //
162 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with `CXXRTL_INPUT`,
163 // as well as other flags.
164 CXXRTL_OUTPUT = 1 << 1,
165
166 // Node is a module inout port.
167 //
168 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with other flags.
169 CXXRTL_INOUT = (CXXRTL_INPUT|CXXRTL_OUTPUT),
170
171 // Node has bits that are driven by a storage cell.
172 //
173 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with
174 // `CXXRTL_DRIVEN_COMB` and `CXXRTL_UNDRIVEN`, as well as other flags.
175 //
176 // This flag is set on wires that have bits connected directly to the output of a flip-flop or
177 // a latch, and hold its state. Many `CXXRTL_WIRE` objects may not have the `CXXRTL_DRIVEN_SYNC`
178 // flag set; for example, output ports and feedback wires generally won't. Writing to the `next`
179 // pointer of these wires updates stored state, and for designs without combinatorial loops,
180 // capturing the value from every of these wires through the `curr` pointer creates a complete
181 // snapshot of the design state.
182 CXXRTL_DRIVEN_SYNC = 1 << 2,
183
184 // Node has bits that are driven by a combinatorial cell or another node.
185 //
186 // This flag can be set on objects of type `CXXRTL_VALUE`, `CXXRTL_WIRE`, and `CXXRTL_OUTLINE`.
187 // It may be combined with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_UNDRIVEN`, as well as other flags.
188 //
189 // This flag is set on objects that have bits connected to the output of a combinatorial cell,
190 // or directly to another node. For designs without combinatorial loops, writing to such bits
191 // through the `next` pointer (if it is not NULL) has no effect.
192 CXXRTL_DRIVEN_COMB = 1 << 3,
193
194 // Node has bits that are not driven.
195 //
196 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
197 // with `CXXRTL_DRIVEN_SYNC` and `CXXRTL_DRIVEN_COMB`, as well as other flags.
198 //
199 // This flag is set on objects that have bits not driven by an output of any cell or by another
200 // node, such as inputs and dangling wires.
201 CXXRTL_UNDRIVEN = 1 << 4,
202
203 // More object flags may be added in the future, but the existing ones will never change.
204 };
205
206 // Description of a simulated object.
207 //
208 // The `curr` and `next` arrays can be accessed directly to inspect and, if applicable, modify
209 // the bits stored in the object.
210 struct cxxrtl_object {
211 // Type of the object.
212 //
213 // All objects have the same memory layout determined by `width` and `depth`, but the type
214 // determines all other properties of the object.
215 uint32_t type; // actually `enum cxxrtl_type`
216
217 // Flags of the object.
218 uint32_t flags; // actually bit mask of `enum cxxrtl_flags`
219
220 // Width of the object in bits.
221 size_t width;
222
223 // Index of the least significant bit.
224 size_t lsb_at;
225
226 // Depth of the object. Only meaningful for memories; for other objects, always 1.
227 size_t depth;
228
229 // Index of the first word. Only meaningful for memories; for other objects, always 0;
230 size_t zero_at;
231
232 // Bits stored in the object, as 32-bit chunks, least significant bits first.
233 //
234 // The width is rounded up to a multiple of 32; the padding bits are always set to 0 by
235 // the simulation code, and must be always written as 0 when modified by user code.
236 // In memories, every element is stored contiguously. Therefore, the total number of chunks
237 // in any object is `((width + 31) / 32) * depth`.
238 //
239 // To allow the simulation to be partitioned into multiple independent units communicating
240 // through wires, the bits are double buffered. To avoid race conditions, user code should
241 // always read from `curr` and write to `next`. The `curr` pointer is always valid; for objects
242 // that cannot be modified, or cannot be modified in a race-free way, `next` is NULL.
243 uint32_t *curr;
244 uint32_t *next;
245
246 // Opaque reference to an outline. Only meaningful for outline objects.
247 //
248 // See the documentation of `cxxrtl_outline` for details. When creating a `cxxrtl_object`, set
249 // this field to NULL.
250 struct _cxxrtl_outline *outline;
251
252 // More description fields may be added in the future, but the existing ones will never change.
253 };
254
255 // Retrieve description of a simulated object.
256 //
257 // The `name` is the full hierarchical name of the object in the Yosys notation, where public names
258 // have a `\` prefix and hierarchy levels are separated by single spaces. For example, if
259 // the top-level module instantiates a module `foo`, which in turn contains a wire `bar`, the full
260 // hierarchical name is `\foo \bar`.
261 //
262 // The storage of a single abstract object may be split (usually with the `splitnets` pass) into
263 // many physical parts, all of which correspond to the same hierarchical name. To handle such cases,
264 // this function returns an array and writes its length to `parts`. The array is sorted by `lsb_at`.
265 //
266 // Returns the object parts if it was found, NULL otherwise. The returned parts are valid until
267 // the design is destroyed.
268 struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, size_t *parts);
269
270 // Retrieve description of a single part simulated object.
271 //
272 // This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that,
273 // if the object exists, it consists of a single part. If assertions are disabled, it returns NULL
274 // for multi-part objects.
275 static inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) {
276 size_t parts = 0;
277 struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts);
278 assert(object == NULL || parts == 1);
279 if (object == NULL || parts == 1)
280 return object;
281 return NULL;
282 }
283
284 // Enumerate simulated objects.
285 //
286 // For every object in the simulation, `callback` is called with the provided `data`, the full
287 // hierarchical name of the object (see `cxxrtl_get` for details), and the object parts.
288 // The provided `name` and `object` values are valid until the design is destroyed.
289 void cxxrtl_enum(cxxrtl_handle handle, void *data,
290 void (*callback)(void *data, const char *name,
291 struct cxxrtl_object *object, size_t parts));
292
293 // Opaque reference to an outline.
294 //
295 // An outline is a group of outline objects that are evaluated simultaneously. The identity of
296 // an outline can be compared to determine whether any two objects belong to the same outline.
297 typedef struct _cxxrtl_outline *cxxrtl_outline;
298
299 // Evaluate an outline.
300 //
301 // After evaluating an outline, the bits of every outline object contained in it are consistent
302 // with the current state of the netlist. In general, any further modification to the netlist
303 // causes every outline object to become stale, after which the corresponding outline must be
304 // re-evaluated, otherwise the bits read from that object are meaningless.
305 void cxxrtl_outline_eval(cxxrtl_outline outline);
306
307 #ifdef __cplusplus
308 }
309 #endif
310
311 #endif