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 */
|