Merge pull request #2085 from rswarbrick/select
[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
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 // Opaque reference to a design toplevel.
35 //
36 // A design toplevel can only be used to create a design handle.
37 typedef struct _cxxrtl_toplevel *cxxrtl_toplevel;
38
39 // The constructor for a design toplevel is provided as a part of generated code for that design.
40 // Its prototype matches:
41 //
42 // cxxrtl_toplevel <design-name>_create();
43
44 // Opaque reference to a design handle.
45 //
46 // A design handle is required by all operations in the C API.
47 typedef struct _cxxrtl_handle *cxxrtl_handle;
48
49 // Create a design handle from a design toplevel.
50 //
51 // The `design` is consumed by this operation and cannot be used afterwards.
52 cxxrtl_handle cxxrtl_create(cxxrtl_toplevel design);
53
54 // Release all resources used by a design and its handle.
55 void cxxrtl_destroy(cxxrtl_handle handle);
56
57 // Simulate the design to a fixed point.
58 //
59 // Returns the number of delta cycles.
60 size_t cxxrtl_step(cxxrtl_handle handle);
61
62 // Type of a simulated object.
63 enum cxxrtl_type {
64 // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by
65 // combinatorial cells, or toplevel input nodes.
66 //
67 // Values can be inspected via the `curr` pointer and modified via the `next` pointer (which are
68 // equal for values); however, note that changes to the bits driven by combinatorial cells will
69 // be ignored.
70 //
71 // Values always have depth 1.
72 CXXRTL_VALUE = 0,
73
74 // Wires correspond to doubly buffered netlist nodes, i.e. nodes driven, at least in part, by
75 // storage cells, or by combinatorial cells that are a part of a feedback path.
76 //
77 // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are
78 // distinct for wires); however, note that changes to the bits driven by combinatorial cells will
79 // be ignored.
80 //
81 // Wires always have depth 1.
82 CXXRTL_WIRE = 1,
83
84 // Memories correspond to memory cells.
85 //
86 // Memories can be inspected and modified via the `curr` pointer. Due to a limitation of this
87 // API, memories cannot yet be modified in a guaranteed race-free way, and the `next` pointer is
88 // always NULL.
89 CXXRTL_MEMORY = 2,
90
91 // More object types will be added in the future, but the existing ones will never change.
92 };
93
94 // Description of a simulated object.
95 //
96 // The `data` array can be accessed directly to inspect and, if applicable, modify the bits
97 // stored in the object.
98 struct cxxrtl_object {
99 // Type of the object.
100 //
101 // All objects have the same memory layout determined by `width` and `depth`, but the type
102 // determines all other properties of the object.
103 uint32_t type; // actually `enum cxxrtl_type`
104
105 // Width of the object in bits.
106 size_t width;
107
108 // Depth of the object. Only meaningful for memories; for other objects, always 1.
109 size_t depth;
110
111 // Bits stored in the object, as 32-bit chunks, least significant bits first.
112 //
113 // The width is rounded up to a multiple of 32; the padding bits are always set to 0 by
114 // the simulation code, and must be always written as 0 when modified by user code.
115 // In memories, every element is stored contiguously. Therefore, the total number of chunks
116 // in any object is `((width + 31) / 32) * depth`.
117 //
118 // To allow the simulation to be partitioned into multiple independent units communicating
119 // through wires, the bits are double buffered. To avoid race conditions, user code should
120 // always read from `curr` and write to `next`. The `curr` pointer is always valid; for objects
121 // that cannot be modified, or cannot be modified in a race-free way, `next` is NULL.
122 uint32_t *curr;
123 uint32_t *next;
124
125 // More description fields will be added in the future, but the existing ones will never change.
126 };
127
128 // Retrieve description of a simulated object.
129 //
130 // The `name` is the full hierarchical name of the object in the Yosys notation, where public names
131 // have a `\` prefix and hierarchy levels are separated by single spaces. For example, if
132 // the top-level module instantiates a module `foo`, which in turn contains a wire `bar`, the full
133 // hierarchical name is `\foo \bar`.
134 //
135 // Returns the object if it was found, NULL otherwise. The returned value is valid until the design
136 // is destroyed.
137 struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name);
138
139 // Enumerate simulated objects.
140 //
141 // For every object in the simulation, `callback` is called with the provided `data`, the full
142 // hierarchical name of the object (see `cxxrtl_get` for details), and the object description.
143 // The provided `name` and `object` values are valid until the design is destroyed.
144 void cxxrtl_enum(cxxrtl_handle handle, void *data,
145 void (*callback)(void *data, const char *name, struct cxxrtl_object *object));
146
147 #ifdef __cplusplus
148 }
149 #endif
150
151 #endif