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 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
|
/* $Id$
* Interpreter library, internal API.
*
* 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 __FAUHDLI_PRIVATE_H_INCLUDED
#define __FAUHDLI_PRIVATE_H_INCLUDED
#include "fauhdli.h"
#include <stdbool.h>
#include <stdlib.h> /* for size_t */
#include "list.h"
#include "slset.h"
#include "vhdl_sched.h"
#include "basetypes.h"
/* ********************* types *********************** */
enum opcode_kind {
OPCODE_MOV, /* 0 */
OPCODE_ADD,
OPCODE_SUB,
OPCODE_IMUL,
OPCODE_DIV,
OPCODE_CALL, /* 5 */
OPCODE_PROC,
OPCODE_RETURN,
OPCODE_BEGINTRANS,
OPCODE_ENDTRANS,
OPCODE_SETPARAM, /* 10 */
OPCODE_GETPARAM,
OPCODE_UPDATE,
OPCODE_GETSIG,
OPCODE_JMP,
OPCODE_JE, /* 15 */
OPCODE_JB,
OPCODE_JNE,
OPCODE_JBE,
OPCODE_AOFFSET,
OPCODE_ROFFSET, /* 20 */
OPCODE_LABEL,
OPCODE_SUSPEND,
OPCODE_CONNECT,
OPCODE_WAKEAT,
OPCODE_WAKEON, /* 25 */
OPCODE_LOG,
OPCODE_ABORT,
OPCODE_GETSIMTIME
};
/** kind of operand */
enum operand_kind {
/** register operand */
OPERAND_REGISTER,
/** indirect memory access via register */
OPERAND_INDIRECT,
/** immediate operand */
OPERAND_IMMEDIATE,
/** reference to a data object. (= pointer to data) */
OPERAND_REFERENCE,
/** reference to a label */
OPERAND_TARGET
};
/** basic type enumeration */
enum type_kind {
/** integral type */
TYPE_INT,
/** float type */
TYPE_FLOAT,
/** pointer type */
TYPE_POINTER,
};
/** storage kinds of data elements */
enum storage_kind {
/** plain storage, only the value is stored. */
STORAGE_VARIABLE,
/** signal storage, defining a signal */
STORAGE_SIGNAL,
/** driver storage, a driver to a signal */
STORAGE_DRIVER
};
/** code container */
struct code_container {
/** name of the container */
char *name;
/** list of types */
struct slist *type_definitions;
/** architecture segment */
struct slist *transfer_segment;
/** stack segment */
struct slist *stack_segment;
/** nested code containers */
struct slist *sub_containers;
/** data size of stack segment */
size_t stack_size;
/** data size of transfer segment */
size_t transfer_size;
/** text segment */
struct slist *text_segment;
/** nesting level of container */
unsigned int nesting_level;
/** number of used virtual registers by code_container */
unsigned int num_vregs;
};
/** one intermediate code operand */
struct operand {
/** kind of operand */
enum operand_kind kind;
/** type of operand */
enum type_kind type;
/** union by kind of operand */
union {
/** register for register and indirect operands */
unsigned int reg;
/** immediate value */
union fauhdli_value immediate;
/** reference to a label */
struct {
/** name of the label */
char *name;
/** resolved reference or NULL if unresolved */
const struct slist_entry *ref;
} target;
/** reference to a data object, or a code container */
struct {
/** name of the reference */
char *name;
/** resolved reference or NULL if unresolved */
const struct data_definition *ref;
/** for setparam, begintrans, endtrans:
* reference to the code container
*/
const struct code_container *container;
} data;
} bytype;
};
struct opcode {
/** kind of opcode */
enum opcode_kind kind;
/** first operand (if any) */
struct operand *op1;
/** second operand (if any) */
struct operand *op2;
/** third operand (if any) */
struct operand *op3;
/** label, in case it's no opcode but a label. */
char *label;
/** type element referring to the indexed type in caes of
* aoffset/roffset opcodes */
struct type_element *indexed_type;
/** line number in parsed file */
int lineno;
/** list of annotations (optional) */
struct slist *annotations;
};
/** generic annotation specification */
struct annotation_spec {
/** name of the annotation specification */
char *name;
/** string value */
char *string_value;
/** int value */
int int_value;
};
/** Element of a type.
*
* A type_element represents one element of a possibly composite type.
* It can represent an array of either a basic type or another composite
* type.
* A basic type would be universal_integer or universal_real, or a driver
* of it, or a signal of it.
*
* elem_count represents the number of basic types that this type_element
* refers to.
* offset means the number of basic type elements in a composite type
* that reside before this type.
*
* Example:
* type t is { a: u[10], b: v }
* type u is { c: universal_integer[5] }
* type v is { d: universal_real, e: universal_integer }
*
* type_element d has offset 0 and elem_count 1
* type_element e has offset 1 and elem_count 1
* type v has elem_count 2
*
* type_element c has offset 0 and elem_count 5
* type u has elem_count 5
*
* type_elment a has offset 0 and elem_count 10 * 5 = 50 (and elements = 10)
* type_element b has offset 50 and elem_count 2 (and elements = 1)
* type t has elem_count 52
*/
struct type_element {
/** name of the referred to type */
char *name;
/** referred to type */
const struct type_declaration *type;
/** number of elements of an array */
universal_integer elements;
/** list of initial values */
struct slist *initial_list;
/** number of basic subelements. -1 means unset. */
int elem_count;
/** element offset from beginning of type (not a size!) */
int offset;
/** annotations (optional) */
struct slist *annotations;
};
struct type_declaration {
/** name of the type */
char *name;
/** subelements of the type */
struct slist *elements;
/** number of basic subelements. -1 means unset. */
int elem_count;
};
enum segment_kind {
SEGMENT_TRANSFER,
SEGMENT_STACK
};
struct data_definition {
/** name of the definition */
char *name;
/** type of the definition (local type_element) */
struct type_element *type;
/** storage kind of the data definition */
enum storage_kind storage;
/** location of the data. */
enum segment_kind loc;
/** nesting level, 0=current stack seg., 1=parent stack seg..) */
unsigned int nesting_level;
/** offset of data in segment (bytes) */
size_t offset;
/** storage size in byte of the resulting data */
size_t storage_size;
/** annotations (optional) */
struct slist *annotations;
/** reference to a resolution function */
struct {
/** name of resolution function */
char *name;
/** container of the resolution function */
const struct code_container *container;
} resolver;
};
/** value of a virtual register */
struct reg_value {
/** actual value */
union fauhdli_value value;
/** type of register (mainly useful for debugging */
enum type_kind kind;
/** was the register written to already?
* (only useful to debug intermediate code) */
bool initialized;
};
/** foreign mode for port/generic SetParams. */
enum foreign_mode_e {
/** component instantiation mode */
FOREIGN_MODE_COMPONENT,
/** architecture create mode */
FOREIGN_MODE_ARCHITECTURE
};
/** main instance of vhdl interpreter */
struct fauhdli {
/** top code container. */
struct code_container *container;
/** set containing various allocated pointers that should get free'd
* on exit. (order must not be relevant!)
*/
struct slset *cleanup_ptrs;
/** scheduler instance */
struct vhdl_sched *scheduler;
/** set of created signals */
struct slset *signals;
/** set of created, but not free'd stack_frames */
struct slset *pending_stack_frames;
/** all vhdl processes */
struct slset *processes;
/** current simulation time */
universal_integer sim_time;
/** tracer instance (NULL if no tracing is desired) */
struct trace_t *tracer;
/** debugging enabled/disabled? */
bool debug;
/** opaque glue_vhdl pointer. */
void *glue_vhdl;
/** set containing all (non-foreign) drivers */
struct slset *drivers;
/** set of all "foreign" drivers. A foreign driver means that the
* signal of a process is written to from VHDL but the signal itself
* is foreign. */
struct slset *foreign_drivers;
/** helper structure for setting foreign generics of arrays */
struct {
/** component id */
unsigned int comp_id;
/** pointer to base (NULL means not yet set) */
union fauhdli_value base;
/** name of generic (formal name) */
const char *formal_name;
/** element type name */
const char *element_type;
/** left bound */
universal_integer left;
/** left bound set */
bool left_set;
/** right bound */
universal_integer right;
/** right bound set */
bool right_set;
/** direction */
universal_integer direction;
/** direction set? */
bool direction_set;
} foreign_g_array_params;
/** mode for foreign generics/ports */
enum foreign_mode_e foreign_mode;
/** callbacks for foreign interface. */
struct glue_vhdl_cb callbacks;
/** wakeup event already scheduled? */
bool wakeup_scheduled;
/** list of entities to trace */
struct slist *trace_list;
};
/* ********************* functions *********************** */
/** allocate memory for an opcode an initialize the members.
* @param kind kind of opcode.
* @param callbacks for malloc
* @return opcode with kind set, and pointers set to 0.
*/
extern
__attribute__((__malloc__))
struct opcode *
fauhdli_alloc_opcode(
enum opcode_kind kind,
const struct glue_vhdl_cb *callbacks
);
/** find the annotation with name in the list of annotations.
* @param name name tag of the annotation
* @param annotations list of annotations
* @return the spec in question or NULL if not found.
*/
extern
const struct annotation_spec *
fauhdli_find_annotation(const char *name, const struct slist *annotations);
#endif /* __FAUHDLI_PRIVATE_H_INCLUDED */
|