File: signals.h

package info (click to toggle)
fauhdlc 20180504-2
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,956 kB
  • sloc: cpp: 23,188; ansic: 6,077; yacc: 3,764; lex: 763; makefile: 605; sh: 494; xml: 403
file content (198 lines) | stat: -rw-r--r-- 5,541 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* $Id$
 *
 * Signal/Driver handling related functions.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#ifndef __SIGNALS_H_INCLUDED
#define __SIGNALS_H_INCLUDED

#include "fauhdli_private.h"
#include <stdbool.h>

/** a VHDL signal */
struct signal {
	/** current signal value */
	union fauhdli_value value;
	/** set of drivers, that are connected to the signal */
	struct slset *connected_drivers;
	/** signal value was changed in the delta cycle. */
	bool event;
	/** is this a "foreign" signal? */
	bool is_foreign;
	/** id of the foreign signal */
	unsigned int foreign_id;
	/** associated resolution function (if any) */
	const struct code_container *resolver;
};

/** a VHDL driver */
struct driver {
	/** current driving value of the driver */
	union fauhdli_value driving_value;
	/** signal to which the driver is connected to (or NULL) */
	struct signal *connected_signal;
	/** is the driver active during this delta cycle? (i.e. it 
	 *  recieved any update) 
	 *  FIXME not set correctly!
	 */
	bool active;
	/** transactions on the driver */
	struct slset *transactions;
	/** is this a foreign out driver? */
	bool foreign_out;
	/** id of the foreign signal (if any) */
	unsigned int foreign_id;
};


/** connect a driver to a signal
 *  @param driver driver that should get connected to signal
 *  @param signal signal that the driver should get connected to.
 *  @param instance fauhdli instance.
 *  @return true if it is a foreign driver, false otherwise.
 */
extern bool
driver_connect(
	struct driver *driver, 
	struct signal *_signal, 
	struct fauhdli *instance
);

/** create a driver at *driver_p.
 *  @param init initial value of the driver.
 *  @param callbacks callbacks (for malloc)
 *  @return created driver instance.
 */
extern
struct driver *
driver_create(union fauhdli_value init, const struct glue_vhdl_cb *callbacks);

/** destroy a driver (freeing the memory). 
 *  @param driver driver to destroy 
 *  @param callbacks for free.
 */
extern void
driver_destroy(struct driver *driver, const struct glue_vhdl_cb *callbacks);

/** update a driver with a new value after a specific delay.
 *  @param driver driver instance.
 *  @param val new driving value.
 *  @param sim_time simulation time at which the update should be 
 *         performed.
 *  @param callbacks callbacks for malloc.
 */
extern void
driver_update(
	struct driver *driver,
	union fauhdli_value val,
	universal_integer sim_time,
	const struct glue_vhdl_cb *callbacks
);

/** propagate the driving value to the (foreign) signal via 
 *  glue-vhdl.
 *  @param instance fauhdli instance.
 *  @param driver driver to propagate the value to the signal
 *  @param sim_time current simulation time.
 */
extern void
driver_forward_foreign(
	struct fauhdli *instance,
	struct driver *driver,
	universal_integer sim_time
);

/** propagate all driving values of the drivers to the signal.
 *  foreign_out drivers will not get propagated.
 *
 *  @param instance fauhdli instance
 *  @param sig signal which should get updated.
 *  @param sim_time current simulation time.
 */
extern void
signal_drivers_propagate(
	struct fauhdli *instance,
	struct signal *sig, 
	universal_integer sim_time
);


/** determine the time of the next event on a driver.
 *  @param drv driver instance.
 *  @return scheduled simulation time of next event, or INT64_MAX in case
 *          no event is scheduled.
 */
extern 
universal_integer
driver_get_next_event(const struct driver *drv);

/** create a VHDL signal. If foreign is specified, a foreign signal will
 *  additionally get created.
 *  @param init initial value of the signal.
 *  @param foreign name of foreign signal to create, or NULL if not foreign.
 *  @param instance fauhdli instance.
 *  @param name name for debugging only
 *  @param resolver resolution function container (or NULL if unresolved)
 *  @return pointer to newly created signal.
 */
extern struct signal *
signal_create(
	union fauhdli_value init,
	const char *foreign,
	struct fauhdli *instance,
	const char *name,
	const struct code_container *resolver
);

/** destroy a signal. This won't destroy the associated drivers.
 *  @param signal signal to destroy
 *  @param callbacks for free
 */
extern void
signal_destroy(struct signal *_signal, const struct glue_vhdl_cb *callbacks);

/** read the current value of a signal.
 *  @param signal read the signal value from this signal instance.
 *  @param val read value will be stored there.
 */
static inline void 
__attribute__((__always_inline__))
signal_read(
	const struct signal *sig, 
	union fauhdli_value *val
)
{
	*val = sig->value;
}

/** clear the event flag of the signal 
 *  @param sig signal to clear the event flag */
static inline void
__attribute__((__always_inline__))
signal_clear_event(struct signal *sig) {
	sig->event = false;
}

/* If a foreign signal is read, create a driver for it, add the callback
 * to glue_vhdl, and set the initial value.
 * Will do nothing, if not a foreign signal, or the foreign driver is
 * already created.
 *
 * @param sig signal instance.
 * @param glue_vhdl glue_vhdl instance
 * @param driver_set add the driver to driver_set.
 */
extern void
signal_connect_foreign_in_driver(
	struct signal *sig,
	struct fauhdli *instance,
	struct slset *driver_set
);


#endif /* __SIGNALS_H_INCLUDED */