/usr/include/freehdl/kernel-driver-info.hh is in libfreehdl0-dev 0.0.8-2.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | #ifndef FREEHDL_KERNEL_DRIVER_INFO_H
#define FREEHDL_KERNEL_DRIVER_INFO_H
#include <assert.h>
#include <freehdl/kernel-classes.hh>
#include <freehdl/kernel-list.hh>
#include <freehdl/std-standard.hh>
extern const vtime zero_time;
class driver_info {
public:
// If the signal is of a scalar type then the queue stores long long
// int values which can be used to take all other scalar VHDL type
// values if the signal is of a scalar type. Otherwise, the queue
// does not store any useful information
fqueue<long long int, vtime> transactions;
// Points to the corresponding reader_info instance
reader_info *rinfo;
// Type of the corresponding signal
type_info_interface *type;
// Signal this driver is connected with
sig_info_base *signal;
// Process this driver belongs to
process_base *process;
// Start index number. If the signal is of a composite type then
// index_start stores the first index identifier of the SCALAR
// signal which is driven by this driver. size is the length of the
// drivers array.
int index_start, size;
// If the driven signal is of a composite
// type then drivers is pointing to an array which stores
// driver_info pointers for the corresponding scalar drivers.
driver_info **drivers;
// Constructors
driver_info(process_base *proc, sig_info_base *sig, int i = 0);
driver_info(process_base *proc, sig_info_base *sig, type_info_interface *t, int i, driver_info **drvs, int sz);
// Returns scalar driver. Note, this method return invalid results
// if it is called for a scalar driver_info instance!
inline driver_info *scalar_driver(acl *a) const {
int first = 0, last;
return drivers[type->acl_to_index(a, first, last) - index_start];
}
// Returns scalar driver of a composite signal. Note, this method
// return invalid results if it is called for a scalar driver_info
// instance! It is used to create a transaction for a scalar element
// of an composite signal. Index i denotes the index identifier of
// the scalar element.
inline driver_info *scalar_driver(int i) const {
return drivers[i - index_start];
}
// Notes on composite signals: Each scalar element of a composite
// signal is assigend an unique INDEX identifier. Index identifier
// calculation is based on index offsets:
//
// 1. The index offset value of a scalar type is 0.
// 2. The index offset value of an array element (which is either
// scalar or non scalar) is the absolute value of the
// corresponding array index of the element minus
// array'left and then multiplied by the number of scalars
// each array element consists of.
// 3. The index offset value of a specific record element "x" is
// sum of the scalar elements of all record items preceeding
// the corresponding element definition "x" within the record.
//
// Finally, the index identifier of a scalar element is calculated
// by summing up the index offset values of all composite elements
// which cover the corresponding scalar element.
// Create transactions for array signals. This methods are used to
// create transactions for more than a single scalar element of a
// array signal (or if the compiler can not determine the number of
// scalar elements which are affected by the assignment
// operation). first is the (smallest) index identifier of the first
// SCALAR element affected by the assignment, last is the last
// (greatest) index identifier of the target SCALAR element.
void transport_assign(const array_base &value, int first, const vtime &time_value);
void transport_assign(const array_base &value, const vtime &time_value) {
transport_assign(value, 0, time_value);
}
void inertial_assign(const array_base &value, int first, const vtime &time_value,
const vtime &start_time = zero_time);
void transport_assign(const record_base &value, int first, const vtime &time_value);
void transport_assign(const record_base &value, const vtime &time_value) {
transport_assign(value, 0, time_value);
}
void inertial_assign(const record_base &value, int first, const vtime &time_value,
const vtime &start_time = zero_time);
// Similar to the methods before but the start index is derived form
// the acl instance a.
void transport_assign(const array_base &value, acl *a, const vtime &time_value) {
transport_assign(value, type->acl_to_index(a), time_value);
}
void inertial_assign(const array_base &value, acl *a, const vtime &time_value,
const vtime &start_time = zero_time) {
inertial_assign(value, type->acl_to_index(a), time_value, start_time);
}
void transport_assign(const record_base &value, acl *a, const vtime &time_value)
{
transport_assign(value, type->acl_to_index(a), time_value);
}
void inertial_assign(const record_base &value, acl *a, const vtime &time_value,
const vtime &start_time = zero_time)
{
inertial_assign(value, type->acl_to_index(a), time_value, start_time);
}
// Creates transactios for scalar signals
void transport_assign(const enumeration value, const vtime &time_value);
void inertial_assign(const enumeration value, const vtime &time_value);
void inertial_assign(const enumeration value, const vtime &time_value,
const vtime &start_time);
void transport_assign(const integer value, const vtime &time_value);
void inertial_assign(const integer value, const vtime &time_value);
void inertial_assign(const integer value, const vtime &time_value,
const vtime &start_time);
void transport_assign(const floatingpoint value, const vtime &time_value);
void inertial_assign(const floatingpoint value, const vtime &time_value);
void inertial_assign(const floatingpoint value, const vtime &time_value,
const vtime &start_time);
void transport_assign(const physical value, const vtime &time_value);
void inertial_assign(const physical value, const vtime &time_value);
void inertial_assign(const physical value, const vtime &time_value,
const vtime &start_time);
// A special method which removes all pending transactions from the
// current driver list, initializes the driver to the given value
// and assigns a new transaction.
void reset_assign(const enumeration reset_value, const enumeration value,
const vtime &time_value);
// This methods assigns the first transactions with time stamp time_value
// on the local driver list on the corresponding reader. It returns whether
// there was really a transaction with a corresponding time stamp or not.
// Note that the method is defined in "global_event_queue.cc"!!!!
inline bool assign_first_transactions(const vtime &time_value);
};
/******************************************************
* Some definitions which are used by the kernel only
******************************************************/
#ifdef KERNEL
// Assign a scalar. This function is NOT used by the generated code
// but is called by kernel code.
inline void
do_scalar_zero_delay_assignment(type_id id, driver_info *driver, void *reader)
{
switch (id) {
case INTEGER:
driver->transport_assign(*(integer*)reader, zero_time);
break;
case ENUM:
driver->transport_assign(*(enumeration*)reader, zero_time);
break;
case FLOAT:
driver->transport_assign(*(floatingpoint*)reader, zero_time);
break;
case PHYSICAL:
driver->transport_assign(*(physical*)reader, zero_time);
break;
default:
assert(true);
}
}
#endif
#endif
|