cxxrtl: expose port direction in debug information.
[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 // Release all resources used by a design and its handle.
56 void cxxrtl_destroy(cxxrtl_handle handle);
57
58 // Evaluate the design, propagating changes on inputs to the `next` value of internal state and
59 // output wires.
60 //
61 // Returns 1 if the design is known to immediately converge, 0 otherwise.
62 int cxxrtl_eval(cxxrtl_handle handle);
63
64 // Commit the design, replacing the `curr` value of internal state and output wires with the `next`
65 // value.
66 //
67 // Return 1 if any of the `curr` values were updated, 0 otherwise.
68 int cxxrtl_commit(cxxrtl_handle handle);
69
70 // Simulate the design to a fixed point.
71 //
72 // Returns the number of delta cycles.
73 size_t cxxrtl_step(cxxrtl_handle handle);
74
75 // Type of a simulated object.
76 enum cxxrtl_type {
77 // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by
78 // combinatorial cells, or toplevel input nodes.
79 //
80 // Values can be inspected via the `curr` pointer. If the `next` pointer is NULL, the value is
81 // driven by a constant and can never be modified. Otherwise, the value can be modified through
82 // the `next` pointer (which is equal to `curr` if not NULL). Note that changes to the bits
83 // driven by combinatorial cells will be ignored.
84 //
85 // Values always have depth 1.
86 CXXRTL_VALUE = 0,
87
88 // Wires correspond to doubly buffered netlist nodes, i.e. nodes driven, at least in part, by
89 // storage cells, or by combinatorial cells that are a part of a feedback path.
90 //
91 // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are
92 // distinct for wires). Note that changes to the bits driven by combinatorial cells will be
93 // ignored.
94 //
95 // Wires always have depth 1.
96 CXXRTL_WIRE = 1,
97
98 // Memories correspond to memory cells.
99 //
100 // Memories can be inspected and modified via the `curr` pointer. Due to a limitation of this
101 // API, memories cannot yet be modified in a guaranteed race-free way, and the `next` pointer is
102 // always NULL.
103 CXXRTL_MEMORY = 2,
104
105 // Aliases correspond to netlist nodes driven by another node such that their value is always
106 // exactly equal.
107 //
108 // Aliases can be inspected via the `curr` pointer. They cannot be modified, and the `next`
109 // pointer is always NULL.
110 CXXRTL_ALIAS = 3,
111
112 // More object types may be added in the future, but the existing ones will never change.
113 };
114
115 // Flags of a simulated object.
116 enum cxxrtl_flag {
117 // Node is a module input port.
118 //
119 // This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
120 // with `CXXRTL_OUTPUT`, as well as other flags.
121 CXXRTL_INPUT = 1 << 0,
122
123 // Node is a module output port.
124 //
125 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with `CXXRTL_INPUT`,
126 // as well as other flags.
127 CXXRTL_OUTPUT = 1 << 1,
128
129 // Node is a module inout port.
130 //
131 // This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with other flags.
132 CXXRTL_INOUT = (CXXRTL_INPUT|CXXRTL_OUTPUT),
133
134 // More object flags may be added in the future, but the existing ones will never change.
135 };
136
137 // Description of a simulated object.
138 //
139 // The `data` array can be accessed directly to inspect and, if applicable, modify the bits
140 // stored in the object.
141 struct cxxrtl_object {
142 // Type of the object.
143 //
144 // All objects have the same memory layout determined by `width` and `depth`, but the type
145 // determines all other properties of the object.
146 uint32_t type; // actually `enum cxxrtl_type`
147
148 // Flags of the object.
149 uint32_t flags; // actually bit mask of `enum cxxrtl_flags`
150
151 // Width of the object in bits.
152 size_t width;
153
154 // Index of the least significant bit.
155 size_t lsb_at;
156
157 // Depth of the object. Only meaningful for memories; for other objects, always 1.
158 size_t depth;
159
160 // Index of the first word. Only meaningful for memories; for other objects, always 0;
161 size_t zero_at;
162
163 // Bits stored in the object, as 32-bit chunks, least significant bits first.
164 //
165 // The width is rounded up to a multiple of 32; the padding bits are always set to 0 by
166 // the simulation code, and must be always written as 0 when modified by user code.
167 // In memories, every element is stored contiguously. Therefore, the total number of chunks
168 // in any object is `((width + 31) / 32) * depth`.
169 //
170 // To allow the simulation to be partitioned into multiple independent units communicating
171 // through wires, the bits are double buffered. To avoid race conditions, user code should
172 // always read from `curr` and write to `next`. The `curr` pointer is always valid; for objects
173 // that cannot be modified, or cannot be modified in a race-free way, `next` is NULL.
174 uint32_t *curr;
175 uint32_t *next;
176
177 // More description fields may be added in the future, but the existing ones will never change.
178 };
179
180 // Retrieve description of a simulated object.
181 //
182 // The `name` is the full hierarchical name of the object in the Yosys notation, where public names
183 // have a `\` prefix and hierarchy levels are separated by single spaces. For example, if
184 // the top-level module instantiates a module `foo`, which in turn contains a wire `bar`, the full
185 // hierarchical name is `\foo \bar`.
186 //
187 // The storage of a single abstract object may be split (usually with the `splitnets` pass) into
188 // many physical parts, all of which correspond to the same hierarchical name. To handle such cases,
189 // this function returns an array and writes its length to `parts`. The array is sorted by `lsb_at`.
190 //
191 // Returns the object parts if it was found, NULL otherwise. The returned parts are valid until
192 // the design is destroyed.
193 struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, size_t *parts);
194
195 // Retrieve description of a single part simulated object.
196 //
197 // This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that,
198 // if the object exists, it consists of a single part. If assertions are disabled, it returns NULL
199 // for multi-part objects.
200 inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) {
201 size_t parts = 0;
202 struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts);
203 assert(object == NULL || parts == 1);
204 if (object == NULL || parts == 1)
205 return object;
206 return NULL;
207 }
208
209 // Enumerate simulated objects.
210 //
211 // For every object in the simulation, `callback` is called with the provided `data`, the full
212 // hierarchical name of the object (see `cxxrtl_get` for details), and the object parts.
213 // The provided `name` and `object` values are valid until the design is destroyed.
214 void cxxrtl_enum(cxxrtl_handle handle, void *data,
215 void (*callback)(void *data, const char *name,
216 struct cxxrtl_object *object, size_t parts));
217
218 #ifdef __cplusplus
219 }
220 #endif
221
222 #endif