HDLRuby 2.6.23 → 2.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/case_bench.rb +35 -0
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +1 -1
- data/lib/HDLRuby/hdr_samples/if_bench.rb +24 -0
- data/lib/HDLRuby/hdr_samples/index_bench.rb +37 -0
- data/lib/HDLRuby/hdr_samples/range_bench.rb +47 -0
- data/lib/HDLRuby/hdr_samples/with_casts.rb +30 -0
- data/lib/HDLRuby/hdr_samples/with_concat.rb +26 -0
- data/lib/HDLRuby/hdr_samples/with_init.rb +18 -0
- data/lib/HDLRuby/hdr_samples/with_instance.rb +42 -0
- data/lib/HDLRuby/hdr_samples/with_ref_array.rb +26 -0
- data/lib/HDLRuby/hdr_samples/with_subsums.rb +33 -0
- data/lib/HDLRuby/hdr_samples/with_values.rb +61 -0
- data/lib/HDLRuby/hdrcc.rb +38 -25
- data/lib/HDLRuby/hruby_high.rb +37 -5
- data/lib/HDLRuby/hruby_low.rb +13 -1
- data/lib/HDLRuby/hruby_low2c.rb +1339 -556
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +1 -1
- data/lib/HDLRuby/hruby_low_mutable.rb +12 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +21 -6
- data/lib/HDLRuby/hruby_low_without_namespace.rb +4 -2
- data/lib/HDLRuby/hruby_tools.rb +8 -1
- data/lib/HDLRuby/hruby_verilog.rb +218 -149
- data/lib/HDLRuby/sim/hruby_sim.h +117 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +38 -9
- data/lib/HDLRuby/sim/hruby_sim_stack_calc.c +250 -0
- data/lib/HDLRuby/sim/hruby_sim_stack_calc.c.sav +100 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +36 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +15 -2
data/lib/HDLRuby/sim/hruby_sim.h
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
**/
|
5
5
|
|
6
6
|
#include <pthread.h>
|
7
|
+
#include <stdarg.h>
|
7
8
|
|
8
9
|
|
9
10
|
/* The interface to the HDLRuby objects C models. */
|
@@ -220,6 +221,20 @@ Value shift_right_value(Value src0, Value src1, Value dst);
|
|
220
221
|
* @return dst */
|
221
222
|
extern Value equal_value(Value src0, Value src1, Value dst);
|
222
223
|
|
224
|
+
/** Computes the C equal of two general values.
|
225
|
+
* @param src0 the first source value of the addition
|
226
|
+
* @param src1 the second source value of the addition
|
227
|
+
* @param dst the destination value
|
228
|
+
* @return the destination value */
|
229
|
+
extern Value equal_value_c(Value src0, Value src1, Value dst);
|
230
|
+
|
231
|
+
/** Computes the C not equal of two general values.
|
232
|
+
* @param src0 the first source value of the addition
|
233
|
+
* @param src1 the second source value of the addition
|
234
|
+
* @param dst the destination value
|
235
|
+
* @return the destination value */
|
236
|
+
extern Value not_equal_value_c(Value src0, Value src1, Value dst);
|
237
|
+
|
223
238
|
/** Computes the greater comparision of two values.
|
224
239
|
* @param src0 the first source value of the comparison
|
225
240
|
* @param src1 the second source value of the comparison
|
@@ -261,6 +276,8 @@ extern Value select_value(Value cond, Value dst, unsigned int num, ...);
|
|
261
276
|
* @param dst the destination value
|
262
277
|
* @return dst */
|
263
278
|
extern Value concat_value(int num, int dir, Value dst, ...);
|
279
|
+
extern Value concat_valueV(int num, int dir, Value dst, va_list args);
|
280
|
+
extern Value concat_valueP(int num, int dir, Value dst, Value* args);
|
264
281
|
|
265
282
|
/** Casts a value to another type.
|
266
283
|
* @param src the source value
|
@@ -373,6 +390,9 @@ extern Elem remove_list(List list);
|
|
373
390
|
/** Get a fresh value. */
|
374
391
|
extern Value get_value();
|
375
392
|
|
393
|
+
/** Get the current top value. */
|
394
|
+
Value get_top_value();
|
395
|
+
|
376
396
|
/** Frees the last value of the pool. */
|
377
397
|
extern void free_value();
|
378
398
|
|
@@ -383,6 +403,20 @@ extern unsigned int get_value_pos();
|
|
383
403
|
* @param pos the new position in the pool */
|
384
404
|
extern void set_value_pos(unsigned int pos);
|
385
405
|
|
406
|
+
/** Saves the current state+1 of the value pool to the pool state stack. */
|
407
|
+
extern void save_value_pos();
|
408
|
+
|
409
|
+
/** Restores the state of the value pool from the state stack. */
|
410
|
+
extern void restore_value_pos();
|
411
|
+
|
412
|
+
/** Macros for short control of the pool of values. */
|
413
|
+
#define SV save_value_pos();
|
414
|
+
#define PV push(get_value());save_value_pos();
|
415
|
+
#define RV restore_value_pos();
|
416
|
+
|
417
|
+
|
418
|
+
|
419
|
+
|
386
420
|
/** An HDLRuby object. */
|
387
421
|
typedef struct ObjectS_ {
|
388
422
|
Kind kind; /* The kind of object. */
|
@@ -712,3 +746,86 @@ extern Value write_range(Value src, long long first, long long last,
|
|
712
746
|
* @return dst */
|
713
747
|
extern Value write_range_no_z(Value src, long long first, long long last,
|
714
748
|
Type base, Value dst);
|
749
|
+
|
750
|
+
|
751
|
+
/** Stack-based computations. */
|
752
|
+
|
753
|
+
/** Push a value.
|
754
|
+
* @param val the value to push. */
|
755
|
+
extern void push(Value val);
|
756
|
+
|
757
|
+
/** Duplicates a value in the stack. */
|
758
|
+
extern void dup();
|
759
|
+
|
760
|
+
/** Pops a value.
|
761
|
+
* @return the value. */
|
762
|
+
extern Value pop();
|
763
|
+
|
764
|
+
/** Access the top value of the stack without removing it.
|
765
|
+
* @return the value. */
|
766
|
+
extern Value peek();
|
767
|
+
|
768
|
+
/** Unary calculation.
|
769
|
+
* @param oper the operator function
|
770
|
+
* @return the destination
|
771
|
+
**/
|
772
|
+
extern Value unary(Value (*oper)(Value,Value));
|
773
|
+
|
774
|
+
/** Binary calculation.
|
775
|
+
* @param oper the operator function
|
776
|
+
* @return the destination
|
777
|
+
**/
|
778
|
+
extern Value binary(Value (*oper)(Value,Value,Value));
|
779
|
+
|
780
|
+
/** Cast calculation.
|
781
|
+
* @param typ the type to cast to.
|
782
|
+
* @return the destination.
|
783
|
+
**/
|
784
|
+
extern Value cast(Type typ);
|
785
|
+
|
786
|
+
/* Concat values.
|
787
|
+
* @param num the number of values to concat.
|
788
|
+
* @param dir the direction. */
|
789
|
+
extern Value sconcat(int num, int dir);
|
790
|
+
|
791
|
+
/* Index read calculation.
|
792
|
+
* @param typ the data type of the access. */
|
793
|
+
extern Value sreadI(Type typ);
|
794
|
+
|
795
|
+
/* Index write calculation.
|
796
|
+
* @param typ the data type of the access. */
|
797
|
+
extern Value swriteI(Type typ);
|
798
|
+
|
799
|
+
/* Range read calculation.
|
800
|
+
* @param typ the data type of the access. */
|
801
|
+
extern Value sreadR(Type typ);
|
802
|
+
|
803
|
+
/* Range write calculation.
|
804
|
+
* @param typ the data type of the access. */
|
805
|
+
extern Value swriteR(Type typ);
|
806
|
+
|
807
|
+
/** Check if the top value is defined. */
|
808
|
+
extern int is_defined();
|
809
|
+
|
810
|
+
/** Convert the top value to an integer. */
|
811
|
+
extern unsigned long long to_integer();
|
812
|
+
|
813
|
+
/** Check if a value is true.
|
814
|
+
* Actually check if it is defined and convert it to integer. */
|
815
|
+
extern unsigned long long is_true();
|
816
|
+
|
817
|
+
/* Transmit the top value to a signal in parallel.
|
818
|
+
* @param sig the signal to transmit to. */
|
819
|
+
extern void transmit(SignalI sig);
|
820
|
+
|
821
|
+
/* Transmit the top value to a signal in sequence.
|
822
|
+
* @param sig the signal to transmit to. */
|
823
|
+
extern void transmit_seq(SignalI sig);
|
824
|
+
|
825
|
+
/* Transmit the top value to a range in a signal in parallel.
|
826
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
827
|
+
extern void transmitR(RefRangeS ref);
|
828
|
+
|
829
|
+
/* Transmit the top value to a range in a signal in sequence.
|
830
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
831
|
+
extern void transmitR_seq(RefRangeS ref);
|
@@ -2657,6 +2657,28 @@ Value equal_value(Value src0, Value src1, Value dst) {
|
|
2657
2657
|
}
|
2658
2658
|
|
2659
2659
|
|
2660
|
+
/** Computes the C equal of two general values.
|
2661
|
+
* @param src0 the first source value of the addition
|
2662
|
+
* @param src1 the second source value of the addition
|
2663
|
+
* @param dst the destination value
|
2664
|
+
* @return the destination value */
|
2665
|
+
Value equal_value_c(Value src0, Value src1, Value dst) {
|
2666
|
+
dst = equal_value(src0,src1,dst);
|
2667
|
+
return reduce_or_value(dst,dst);
|
2668
|
+
}
|
2669
|
+
|
2670
|
+
|
2671
|
+
/** Computes the C not equal of two general values.
|
2672
|
+
* @param src0 the first source value of the addition
|
2673
|
+
* @param src1 the second source value of the addition
|
2674
|
+
* @param dst the destination value
|
2675
|
+
* @return the destination value */
|
2676
|
+
Value not_equal_value_c(Value src0, Value src1, Value dst) {
|
2677
|
+
dst = xor_value(src0,src1,dst);
|
2678
|
+
return reduce_or_value(dst,dst);
|
2679
|
+
}
|
2680
|
+
|
2681
|
+
|
2660
2682
|
|
2661
2683
|
/** Computes the greater comparision of two general values.
|
2662
2684
|
* @param src0 the first source value of the addition
|
@@ -2790,16 +2812,9 @@ Value select_value(Value cond, Value dst, unsigned int num, ...) {
|
|
2790
2812
|
* @param num the number of values to concat
|
2791
2813
|
* @param dst the destination value
|
2792
2814
|
* @return dst */
|
2793
|
-
Value
|
2815
|
+
Value concat_valueP(int num, int dir, Value dst, Value* values) {
|
2794
2816
|
unsigned long long width = 0;
|
2795
2817
|
int numeric = 1, i;
|
2796
|
-
va_list args;
|
2797
|
-
Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
2798
|
-
va_start(args,dst);
|
2799
|
-
/* Copy the arguments to values for easier processing. */
|
2800
|
-
for(i=0; i<num; ++i) {
|
2801
|
-
values[i] = va_arg(args,Value);
|
2802
|
-
}
|
2803
2818
|
/* check if all the sub values are numeric. */
|
2804
2819
|
for(i=0; i<num; ++i) {
|
2805
2820
|
if (!values[i]->numeric) {
|
@@ -2831,11 +2846,25 @@ Value concat_value(int num, int dir, Value dst, ...) {
|
|
2831
2846
|
/* The sub values are now all bitstrings. */
|
2832
2847
|
concat_value_bitstring_array(num,dir,dst,values);
|
2833
2848
|
}
|
2849
|
+
return dst;
|
2850
|
+
}
|
2851
|
+
Value concat_valueV(int num, int dir, Value dst, va_list args) {
|
2852
|
+
int i;
|
2853
|
+
Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
2854
|
+
/* Copy the arguments to values for easier processing. */
|
2855
|
+
for(i=0; i<num; ++i) {
|
2856
|
+
values[i] = va_arg(args,Value);
|
2857
|
+
}
|
2858
|
+
return concat_valueP(num,dir,dst,values);
|
2859
|
+
}
|
2860
|
+
Value concat_value(int num, int dir, Value dst, ...) {
|
2861
|
+
va_list args;
|
2862
|
+
va_start(args,dst);
|
2863
|
+
dst = concat_valueV(num,dir,dst,args);
|
2834
2864
|
va_end(args);
|
2835
2865
|
return dst;
|
2836
2866
|
}
|
2837
2867
|
|
2838
|
-
|
2839
2868
|
/** Casts a value to another type.
|
2840
2869
|
* @param src the source value
|
2841
2870
|
* @param type the type to cast to
|
@@ -0,0 +1,250 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdarg.h>
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <limits.h>
|
6
|
+
#include "hruby_sim.h"
|
7
|
+
|
8
|
+
|
9
|
+
/**
|
10
|
+
* The HDLRuby simulation stack calculation engine, to be used with C code
|
11
|
+
* generated by hruby_low2c.
|
12
|
+
**/
|
13
|
+
|
14
|
+
/* The stack variables. */
|
15
|
+
#define STACK_SIZE 0x10000
|
16
|
+
static Value stack[STACK_SIZE];
|
17
|
+
static int head = STACK_SIZE;
|
18
|
+
|
19
|
+
/** Push a value.
|
20
|
+
* @param val the value to push. */
|
21
|
+
void push(Value val) {
|
22
|
+
if (head > 0) {
|
23
|
+
stack[--head] = val;
|
24
|
+
} else {
|
25
|
+
perror("Computation stack full.\n");
|
26
|
+
exit(1);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
/** Duplicates a value in the stack. */
|
31
|
+
void dup() {
|
32
|
+
if (head > 0 && head < STACK_SIZE) {
|
33
|
+
Value val = stack[head];
|
34
|
+
stack[--head] = val;
|
35
|
+
} else {
|
36
|
+
perror("Cannot dup in computation stack.\n");
|
37
|
+
exit(1);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/** Pops a value.
|
42
|
+
* @return the value. */
|
43
|
+
Value pop() {
|
44
|
+
if (head < STACK_SIZE) {
|
45
|
+
return stack[head++];
|
46
|
+
} else {
|
47
|
+
perror("Computation stack empty.\n");
|
48
|
+
exit(1);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
/** Access the top value of the stack without removing it.
|
53
|
+
* @return the value. */
|
54
|
+
Value peek() {
|
55
|
+
if (head < STACK_SIZE) {
|
56
|
+
return stack[head];
|
57
|
+
} else {
|
58
|
+
perror("Computation stack empty.\n");
|
59
|
+
exit(1);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
/** Pops multiple values.
|
64
|
+
* @param num the number of values to pop.
|
65
|
+
* @return a pointer on the first value (in heap order!). */
|
66
|
+
static Value* popn(int num) {
|
67
|
+
if (head+num <= STACK_SIZE) {
|
68
|
+
head += num;
|
69
|
+
return &stack[head-num];
|
70
|
+
} else {
|
71
|
+
perror("Not enough values in computation stack.\n");
|
72
|
+
exit(1);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
/** Unary calculation.
|
78
|
+
* @param oper the operator function
|
79
|
+
* @return the destination
|
80
|
+
**/
|
81
|
+
Value unary(Value (*oper)(Value,Value)) {
|
82
|
+
// printf("unary\n");
|
83
|
+
// Value dst = get_top_value();
|
84
|
+
// dst = oper(pop(),dst);
|
85
|
+
// push(dst);
|
86
|
+
// return dst;
|
87
|
+
return oper(pop(),peek());
|
88
|
+
}
|
89
|
+
|
90
|
+
/** Binary calculation.
|
91
|
+
* @param oper the operator function
|
92
|
+
* @return the destination
|
93
|
+
**/
|
94
|
+
Value binary(Value (*oper)(Value,Value,Value)) {
|
95
|
+
// printf("binary\n");
|
96
|
+
// Value dst = get_top_value();
|
97
|
+
// Value r = pop();
|
98
|
+
// Value l = pop();
|
99
|
+
// dst = oper(l,r,dst);
|
100
|
+
// push(dst);
|
101
|
+
// return dst;
|
102
|
+
Value r = pop();
|
103
|
+
Value l = pop();
|
104
|
+
return oper(l,r,peek());
|
105
|
+
}
|
106
|
+
|
107
|
+
/** Cast calculation.
|
108
|
+
* @param typ the type to cast to.
|
109
|
+
* @return the destination.
|
110
|
+
**/
|
111
|
+
Value cast(Type typ) {
|
112
|
+
// printf("cast\n");
|
113
|
+
// Value dst = get_top_value();
|
114
|
+
// Value src = pop();
|
115
|
+
// dst = cast_value(src,typ,dst);
|
116
|
+
// push(dst);
|
117
|
+
// return dst;
|
118
|
+
return cast_value(pop(),typ,peek());
|
119
|
+
}
|
120
|
+
|
121
|
+
/* Concat values.
|
122
|
+
* @param num the number of values to concat.
|
123
|
+
* @param dir the direction. */
|
124
|
+
Value sconcat(int num, int dir) {
|
125
|
+
// Value* vals = alloca(num*sizeof(Value));
|
126
|
+
// Value dst = get_top_value();
|
127
|
+
// int i;
|
128
|
+
// // printf("sconcat\n");
|
129
|
+
// /* Get the values to concat from the stack. */
|
130
|
+
// for(i=1;i<=num;++i) vals[num-i] = pop();
|
131
|
+
// dst = concat_valueP(num,dir,dst,vals);
|
132
|
+
// push(dst);
|
133
|
+
// return dst;
|
134
|
+
Value* vals = alloca(num*sizeof(Value));
|
135
|
+
int i;
|
136
|
+
// printf("sconcat\n");
|
137
|
+
/* Get the values to concat from the stack. */
|
138
|
+
for(i=1;i<=num;++i) vals[num-i] = pop();
|
139
|
+
return concat_valueP(num,dir,peek(),vals);
|
140
|
+
}
|
141
|
+
|
142
|
+
/* Index read calculation.
|
143
|
+
* @param typ the data type of the access. */
|
144
|
+
Value sreadI(Type typ) {
|
145
|
+
// // printf("sreadI\n");
|
146
|
+
// Value dst = get_top_value();
|
147
|
+
// unsigned long long idx = value2integer(pop());
|
148
|
+
// dst = read_range(pop(),idx,idx,typ,dst);
|
149
|
+
// push(dst);
|
150
|
+
// return dst;
|
151
|
+
// printf("sreadI\n");
|
152
|
+
unsigned long long idx = value2integer(pop());
|
153
|
+
return read_range(pop(),idx,idx,typ,peek());
|
154
|
+
}
|
155
|
+
|
156
|
+
/* Index write calculation.
|
157
|
+
* @param typ the data type of the access. */
|
158
|
+
Value swriteI(Type typ) {
|
159
|
+
// // printf("swriteI\n");
|
160
|
+
// Value dst = get_top_value();
|
161
|
+
// unsigned long long idx = value2integer(pop());
|
162
|
+
// dst = write_range(pop(),idx,idx,typ,dst);
|
163
|
+
// push(dst);
|
164
|
+
// return dst;
|
165
|
+
// printf("swriteI\n");
|
166
|
+
unsigned long long idx = value2integer(pop());
|
167
|
+
return write_range(pop(),idx,idx,typ,peek());
|
168
|
+
}
|
169
|
+
|
170
|
+
/* Range read calculation.
|
171
|
+
* @param typ the data type of the access. */
|
172
|
+
Value sreadR(Type typ) {
|
173
|
+
// // printf("sreadR\n");
|
174
|
+
// Value dst = get_top_value();
|
175
|
+
// unsigned long long last = value2integer(pop());
|
176
|
+
// unsigned long long first = value2integer(pop());
|
177
|
+
// dst = read_range(pop(),first,last,typ,dst);
|
178
|
+
// push(dst);
|
179
|
+
// return dst;
|
180
|
+
// printf("sreadR\n");
|
181
|
+
unsigned long long last = value2integer(pop());
|
182
|
+
unsigned long long first = value2integer(pop());
|
183
|
+
return read_range(pop(),first,last,typ,peek());
|
184
|
+
}
|
185
|
+
|
186
|
+
/* Range write calculation.
|
187
|
+
* @param typ the data type of the access. */
|
188
|
+
Value swriteR(Type typ) {
|
189
|
+
// // printf("swriteR\n");
|
190
|
+
// Value dst = get_top_value();
|
191
|
+
// unsigned long long last = value2integer(pop());
|
192
|
+
// unsigned long long first = value2integer(pop());
|
193
|
+
// dst = write_range(pop(),first,last,typ,dst);
|
194
|
+
// push(dst);
|
195
|
+
// return dst;
|
196
|
+
// printf("swriteR\n");
|
197
|
+
unsigned long long last = value2integer(pop());
|
198
|
+
unsigned long long first = value2integer(pop());
|
199
|
+
return write_range(pop(),first,last,typ,peek());
|
200
|
+
}
|
201
|
+
|
202
|
+
/** Check if the top value is defined. */
|
203
|
+
int is_defined() {
|
204
|
+
return is_defined_value(pop());
|
205
|
+
}
|
206
|
+
|
207
|
+
/** Convert the top value to an integer. */
|
208
|
+
unsigned long long to_integer() {
|
209
|
+
return value2integer(pop());
|
210
|
+
}
|
211
|
+
|
212
|
+
/** Check if a value is true.
|
213
|
+
* Actually check if it is defined and convert it to integer. */
|
214
|
+
unsigned long long is_true() {
|
215
|
+
Value val = pop();
|
216
|
+
if (is_defined_value(val)) {
|
217
|
+
return value2integer(val);
|
218
|
+
} else {
|
219
|
+
return 0;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
/** Transmit the top value to a signal in parallel.
|
224
|
+
* @param sig the signal to transmit to. */
|
225
|
+
void transmit(SignalI sig) {
|
226
|
+
// printf("transmit\n");
|
227
|
+
transmit_to_signal(pop(),sig);
|
228
|
+
}
|
229
|
+
|
230
|
+
/** Transmit the top value to a signal in sequence.
|
231
|
+
* @param sig the signal to transmit to. */
|
232
|
+
void transmit_seq(SignalI sig) {
|
233
|
+
// printf("transmit_seq\n");
|
234
|
+
transmit_to_signal_seq(pop(),sig);
|
235
|
+
}
|
236
|
+
|
237
|
+
/** Transmit a value to a range in a signal in parallel.
|
238
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
239
|
+
void transmitR(RefRangeS ref) {
|
240
|
+
// printf("transmitR\n");
|
241
|
+
transmit_to_signal_range(pop(),ref);
|
242
|
+
}
|
243
|
+
|
244
|
+
/** Transmit a value to a range in a signal in sequence.
|
245
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
246
|
+
void transmitR_seq(RefRangeS ref) {
|
247
|
+
// printf("transmitR_seq\n");
|
248
|
+
transmit_to_signal_range_seq(pop(),ref);
|
249
|
+
}
|
250
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdarg.h>
|
3
|
+
#include <stdlib.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <limits.h>
|
6
|
+
#include "hruby_sim.h"
|
7
|
+
|
8
|
+
#ifndef alloca
|
9
|
+
#define alloca(x) __builtin_alloca(x)
|
10
|
+
#endif
|
11
|
+
|
12
|
+
|
13
|
+
/**
|
14
|
+
* The HDLRuby simulation stack calculation engine, to be used with C code
|
15
|
+
* generated by hruby_low2c.
|
16
|
+
**/
|
17
|
+
|
18
|
+
|
19
|
+
/** Unary calculation.
|
20
|
+
* @param src0 the left value
|
21
|
+
* @param oper the operator function
|
22
|
+
* @return the destination
|
23
|
+
**/
|
24
|
+
Value unary(Value src0, Value (*oper)(Value,Value)) {
|
25
|
+
Value dst = get_value();
|
26
|
+
unsigned int pool_state = get_value_pos();
|
27
|
+
dst = oper(src0,dst);
|
28
|
+
set_value_pos(pool_state);
|
29
|
+
return dst;
|
30
|
+
}
|
31
|
+
|
32
|
+
/** Binary calculation.
|
33
|
+
* @param src0 the left value
|
34
|
+
* @param src1 the right value
|
35
|
+
* @param oper the operator function
|
36
|
+
* @return the destination
|
37
|
+
**/
|
38
|
+
Value binary(Value src0, Value src1, Value (*oper)(Value,Value,Value)) {
|
39
|
+
Value dst = get_value();
|
40
|
+
unsigned int pool_state = get_value_pos();
|
41
|
+
dst = oper(src0,src1,dst);
|
42
|
+
set_value_pos(pool_state);
|
43
|
+
return dst;
|
44
|
+
}
|
45
|
+
|
46
|
+
/** Cast calculation.
|
47
|
+
* @param src0 the value to cast.
|
48
|
+
* @param typ the type to cast to.
|
49
|
+
* @return the destination.
|
50
|
+
**/
|
51
|
+
Value cast(Value src0, Type typ) {
|
52
|
+
Value dst = get_value();
|
53
|
+
unsigned int pool_state = get_value_pos();
|
54
|
+
dst = cast_value(src0,typ,dst);
|
55
|
+
set_value_pos(pool_state);
|
56
|
+
return dst;
|
57
|
+
}
|
58
|
+
|
59
|
+
/* Concat values.
|
60
|
+
* @param num the number of values to concat.
|
61
|
+
* @param dir the direction.
|
62
|
+
* @param vals the values to concat. */
|
63
|
+
Value sconcat(int num, int dir, ...) {
|
64
|
+
Value dst = get_value();
|
65
|
+
unsigned int pool_state = get_value_pos();
|
66
|
+
va_list args;
|
67
|
+
va_start(args,dir);
|
68
|
+
dst = concat_valueV(num,dir,dst,args);
|
69
|
+
va_end(args);
|
70
|
+
set_value_pos(pool_state);
|
71
|
+
return dst;
|
72
|
+
}
|
73
|
+
|
74
|
+
/* Read access calculation.
|
75
|
+
* @param src0 the value to access in.
|
76
|
+
* @param first the start index.
|
77
|
+
* @param last the end index.
|
78
|
+
* @param typ the data type of the access. */
|
79
|
+
Value sread(Value src0, unsigned long long first,
|
80
|
+
unsigned long long last, Type typ) {
|
81
|
+
Value dst = get_value();
|
82
|
+
unsigned int pool_state = get_value_pos();
|
83
|
+
dst = read_range(src0,first,last,typ,dst);
|
84
|
+
set_value_pos(pool_state);
|
85
|
+
return dst;
|
86
|
+
}
|
87
|
+
|
88
|
+
/* Write access calculation.
|
89
|
+
* @param src0 the value to access in.
|
90
|
+
* @param first the start index.
|
91
|
+
* @param last the end index.
|
92
|
+
* @param typ the data type of the access. */
|
93
|
+
Value swrite(Value src0, unsigned long long first,
|
94
|
+
unsigned long long last, Type typ) {
|
95
|
+
Value dst = get_value();
|
96
|
+
unsigned int pool_state = get_value_pos();
|
97
|
+
dst = write_range(src0,first,last,typ,dst);
|
98
|
+
set_value_pos(pool_state);
|
99
|
+
return dst;
|
100
|
+
}
|
@@ -47,6 +47,16 @@ Value get_value() {
|
|
47
47
|
return pool_values[pool_pos++];
|
48
48
|
}
|
49
49
|
|
50
|
+
/** Get the current top value. */
|
51
|
+
Value get_top_value() {
|
52
|
+
if (pool_pos > 0)
|
53
|
+
return pool_values[pool_pos-1];
|
54
|
+
else {
|
55
|
+
perror("Pool of values is empty.");
|
56
|
+
exit(1);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
50
60
|
/** Frees the last value of the pool. */
|
51
61
|
void free_value() {
|
52
62
|
if (pool_pos > 0) pool_pos--;
|
@@ -62,3 +72,29 @@ unsigned int get_value_pos() {
|
|
62
72
|
void set_value_pos(unsigned int pos) {
|
63
73
|
pool_pos = pos;
|
64
74
|
}
|
75
|
+
|
76
|
+
|
77
|
+
#define POOL_STATE_STACK_SIZE 0x10000
|
78
|
+
/* The stack of pool states. */
|
79
|
+
static unsigned int pool_state_stack[POOL_STATE_STACK_SIZE];
|
80
|
+
static int pool_state_head = POOL_STATE_STACK_SIZE;
|
81
|
+
|
82
|
+
/** Saves to current state of the value pool to the pool state stack. */
|
83
|
+
extern void save_value_pos() {
|
84
|
+
if (pool_state_head > 0) {
|
85
|
+
pool_state_stack[--pool_state_head] = get_value_pos();
|
86
|
+
} else {
|
87
|
+
perror("Pool state stack full.");
|
88
|
+
exit(1);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/** Restores the state of the value pool from the state stack. */
|
93
|
+
extern void restore_value_pos() {
|
94
|
+
if (pool_state_head < POOL_STATE_STACK_SIZE) {
|
95
|
+
set_value_pos(pool_state_stack[pool_state_head++]);
|
96
|
+
} else {
|
97
|
+
perror("Pool state stack empty.");
|
98
|
+
exit(1);
|
99
|
+
}
|
100
|
+
}
|
data/lib/HDLRuby/version.rb
CHANGED