HDLRuby 2.6.19 → 2.6.25
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 +30 -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_reduce.rb +38 -0
- data/lib/HDLRuby/hdr_samples/with_str2value.rb +14 -0
- data/lib/HDLRuby/hdr_samples/with_to_a.rb +90 -0
- data/lib/HDLRuby/hdrcc.rb +38 -25
- data/lib/HDLRuby/hruby_high.rb +11 -1
- data/lib/HDLRuby/hruby_low.rb +11 -0
- data/lib/HDLRuby/hruby_low2c.rb +1342 -551
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +78 -55
- data/lib/HDLRuby/hruby_low_mutable.rb +33 -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 +113 -2
- data/lib/HDLRuby/sim/hruby_sim_calc.c +46 -13
- data/lib/HDLRuby/sim/hruby_sim_core.c +5 -3
- data/lib/HDLRuby/sim/hruby_sim_stack_calc.c +203 -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 +13 -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. */
|
@@ -101,6 +102,7 @@ typedef struct ValueS_ {
|
|
101
102
|
/* The tructure of a reference to a range in a value. */
|
102
103
|
typedef struct RefRangeS_ {
|
103
104
|
SignalI signal; /* The refered signal. */
|
105
|
+
Type type; /* The tyep of the elements. */
|
104
106
|
unsigned long long first; /* The first index in the range. */
|
105
107
|
unsigned long long last; /* The last index in the range. */
|
106
108
|
} RefRangeS;
|
@@ -219,6 +221,20 @@ Value shift_right_value(Value src0, Value src1, Value dst);
|
|
219
221
|
* @return dst */
|
220
222
|
extern Value equal_value(Value src0, Value src1, Value dst);
|
221
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
|
+
|
222
238
|
/** Computes the greater comparision of two values.
|
223
239
|
* @param src0 the first source value of the comparison
|
224
240
|
* @param src1 the second source value of the comparison
|
@@ -260,6 +276,8 @@ extern Value select_value(Value cond, Value dst, unsigned int num, ...);
|
|
260
276
|
* @param dst the destination value
|
261
277
|
* @return dst */
|
262
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);
|
263
281
|
|
264
282
|
/** Casts a value to another type.
|
265
283
|
* @param src the source value
|
@@ -308,11 +326,12 @@ extern int same_content_value_range(Value value0, unsigned long long first,
|
|
308
326
|
|
309
327
|
/** Creates a reference to a range inside a signal.
|
310
328
|
* @param signal the signal to refer
|
329
|
+
* @param typ the type of the elements.
|
311
330
|
* @param first the start index of the range
|
312
331
|
* @param last the end index of the range
|
313
332
|
* @return the resulting reference */
|
314
|
-
extern RefRangeS make_ref_rangeS(SignalI signal,
|
315
|
-
unsigned long long last);
|
333
|
+
extern RefRangeS make_ref_rangeS(SignalI signal, Type typ,
|
334
|
+
unsigned long long first, unsigned long long last);
|
316
335
|
|
317
336
|
|
318
337
|
/* The interface for the lists. */
|
@@ -371,6 +390,9 @@ extern Elem remove_list(List list);
|
|
371
390
|
/** Get a fresh value. */
|
372
391
|
extern Value get_value();
|
373
392
|
|
393
|
+
/** Get the current top value. */
|
394
|
+
Value get_top_value();
|
395
|
+
|
374
396
|
/** Frees the last value of the pool. */
|
375
397
|
extern void free_value();
|
376
398
|
|
@@ -381,6 +403,19 @@ extern unsigned int get_value_pos();
|
|
381
403
|
* @param pos the new position in the pool */
|
382
404
|
extern void set_value_pos(unsigned int pos);
|
383
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 get_value();save_value_pos();
|
414
|
+
#define RV restore_value_pos();
|
415
|
+
|
416
|
+
|
417
|
+
|
418
|
+
|
384
419
|
/** An HDLRuby object. */
|
385
420
|
typedef struct ObjectS_ {
|
386
421
|
Kind kind; /* The kind of object. */
|
@@ -710,3 +745,79 @@ extern Value write_range(Value src, long long first, long long last,
|
|
710
745
|
* @return dst */
|
711
746
|
extern Value write_range_no_z(Value src, long long first, long long last,
|
712
747
|
Type base, Value dst);
|
748
|
+
|
749
|
+
|
750
|
+
/** Stack-based computations. */
|
751
|
+
|
752
|
+
/** Push a value.
|
753
|
+
* @param val the value to push. */
|
754
|
+
extern void push(Value val);
|
755
|
+
|
756
|
+
/** Pops a value.
|
757
|
+
* @return the value. */
|
758
|
+
extern Value pop();
|
759
|
+
|
760
|
+
/** Unary calculation.
|
761
|
+
* @param oper the operator function
|
762
|
+
* @return the destination
|
763
|
+
**/
|
764
|
+
extern Value unary(Value (*oper)(Value,Value));
|
765
|
+
|
766
|
+
/** Binary calculation.
|
767
|
+
* @param oper the operator function
|
768
|
+
* @return the destination
|
769
|
+
**/
|
770
|
+
extern Value binary(Value (*oper)(Value,Value,Value));
|
771
|
+
|
772
|
+
/** Cast calculation.
|
773
|
+
* @param typ the type to cast to.
|
774
|
+
* @return the destination.
|
775
|
+
**/
|
776
|
+
extern Value cast(Type typ);
|
777
|
+
|
778
|
+
/* Concat values.
|
779
|
+
* @param num the number of values to concat.
|
780
|
+
* @param dir the direction. */
|
781
|
+
extern Value sconcat(int num, int dir);
|
782
|
+
|
783
|
+
/* Index read calculation.
|
784
|
+
* @param typ the data type of the access. */
|
785
|
+
extern Value sreadI(Type typ);
|
786
|
+
|
787
|
+
/* Index write calculation.
|
788
|
+
* @param typ the data type of the access. */
|
789
|
+
extern Value swriteI(Type typ);
|
790
|
+
|
791
|
+
/* Range read calculation.
|
792
|
+
* @param typ the data type of the access. */
|
793
|
+
extern Value sreadR(Type typ);
|
794
|
+
|
795
|
+
/* Range write calculation.
|
796
|
+
* @param typ the data type of the access. */
|
797
|
+
extern Value swriteR(Type typ);
|
798
|
+
|
799
|
+
/** Check if the top value is defined. */
|
800
|
+
extern int is_defined();
|
801
|
+
|
802
|
+
/** Convert the top value to an integer. */
|
803
|
+
extern unsigned long long to_integer();
|
804
|
+
|
805
|
+
/** Check if a value is true.
|
806
|
+
* Actually check if it is defined and convert it to integer. */
|
807
|
+
extern unsigned long long is_true();
|
808
|
+
|
809
|
+
/* Transmit the top value to a signal in parallel.
|
810
|
+
* @param sig the signal to transmit to. */
|
811
|
+
extern void transmit(SignalI sig);
|
812
|
+
|
813
|
+
/* Transmit the top value to a signal in sequence.
|
814
|
+
* @param sig the signal to transmit to. */
|
815
|
+
extern void transmit_seq(SignalI sig);
|
816
|
+
|
817
|
+
/* Transmit the top value to a range in a signal in parallel.
|
818
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
819
|
+
extern void transmitR(RefRangeS ref);
|
820
|
+
|
821
|
+
/* Transmit the top value to a range in a signal in sequence.
|
822
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
823
|
+
extern void transmitR_seq(RefRangeS ref);
|
@@ -2171,7 +2171,8 @@ Value read_range_numeric(Value value, long long first, long long last,
|
|
2171
2171
|
/* Compute the read mask. */
|
2172
2172
|
// unsigned long long mask = ((-1LL) << first) & (~((-1LL) << (last+1)));
|
2173
2173
|
/* NOTE: once again, << 64 does not work like expected. */
|
2174
|
-
unsigned long long mask =
|
2174
|
+
unsigned long long mask = last+bw < 64 ? (~((-1LL) << (last+bw))) : -1LL;
|
2175
|
+
// printf("mask=%llx\n",mask);
|
2175
2176
|
/* Performs the read. */
|
2176
2177
|
unsigned long long data = (value->data_int & mask) >> first;
|
2177
2178
|
/* Write it to the destination. */
|
@@ -2216,7 +2217,9 @@ Value write_range_numeric(Value src, long long first, long long last,
|
|
2216
2217
|
/* Copy from the source. */
|
2217
2218
|
unsigned long long src_data = src->data_int & ~((-1LL) << (last-first+1));
|
2218
2219
|
/* Cleans the destination where to place the data. */
|
2219
|
-
unsigned long long mask
|
2220
|
+
unsigned long long mask;
|
2221
|
+
if (last<63) mask = ~(((-1LL) << first) & ~((-1LL) << (last+1)));
|
2222
|
+
else mask = ~((-1LL)<<first);
|
2220
2223
|
unsigned long long dst_data = dst->data_int & mask;
|
2221
2224
|
// printf("src_data=%llx mask=%llx dst_data=%llx\n",src_data,mask,dst_data);
|
2222
2225
|
/* Write the data. */
|
@@ -2654,6 +2657,28 @@ Value equal_value(Value src0, Value src1, Value dst) {
|
|
2654
2657
|
}
|
2655
2658
|
|
2656
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
|
+
|
2657
2682
|
|
2658
2683
|
/** Computes the greater comparision of two general values.
|
2659
2684
|
* @param src0 the first source value of the addition
|
@@ -2787,16 +2812,9 @@ Value select_value(Value cond, Value dst, unsigned int num, ...) {
|
|
2787
2812
|
* @param num the number of values to concat
|
2788
2813
|
* @param dst the destination value
|
2789
2814
|
* @return dst */
|
2790
|
-
Value
|
2815
|
+
Value concat_valueP(int num, int dir, Value dst, Value* values) {
|
2791
2816
|
unsigned long long width = 0;
|
2792
2817
|
int numeric = 1, i;
|
2793
|
-
va_list args;
|
2794
|
-
Value* values = alloca(num*sizeof(Value)); /* The values to concatenate. */
|
2795
|
-
va_start(args,dst);
|
2796
|
-
/* Copy the arguments to values for easier processing. */
|
2797
|
-
for(i=0; i<num; ++i) {
|
2798
|
-
values[i] = va_arg(args,Value);
|
2799
|
-
}
|
2800
2818
|
/* check if all the sub values are numeric. */
|
2801
2819
|
for(i=0; i<num; ++i) {
|
2802
2820
|
if (!values[i]->numeric) {
|
@@ -2828,11 +2846,25 @@ Value concat_value(int num, int dir, Value dst, ...) {
|
|
2828
2846
|
/* The sub values are now all bitstrings. */
|
2829
2847
|
concat_value_bitstring_array(num,dir,dst,values);
|
2830
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);
|
2831
2864
|
va_end(args);
|
2832
2865
|
return dst;
|
2833
2866
|
}
|
2834
2867
|
|
2835
|
-
|
2836
2868
|
/** Casts a value to another type.
|
2837
2869
|
* @param src the source value
|
2838
2870
|
* @param type the type to cast to
|
@@ -2947,12 +2979,13 @@ int same_content_value_range(Value value0,
|
|
2947
2979
|
|
2948
2980
|
/** Creates a reference to a range inside a signal.
|
2949
2981
|
* @param signal the signal to refer
|
2982
|
+
* @param typ the type of the elements
|
2950
2983
|
* @param first the start index of the range
|
2951
2984
|
* @param last the end index of the range
|
2952
2985
|
* @return the resulting reference */
|
2953
|
-
RefRangeS make_ref_rangeS(SignalI signal, unsigned long long first,
|
2986
|
+
RefRangeS make_ref_rangeS(SignalI signal, Type typ, unsigned long long first,
|
2954
2987
|
unsigned long long last) {
|
2955
|
-
RefRangeS result = { signal, first, last };
|
2988
|
+
RefRangeS result = { signal, typ, first, last };
|
2956
2989
|
return result;
|
2957
2990
|
}
|
2958
2991
|
|
@@ -586,12 +586,14 @@ void transmit_to_signal_range_seq(Value value, RefRangeS ref) {
|
|
586
586
|
SignalI signal = ref.signal;
|
587
587
|
unsigned long long first = ref.first;
|
588
588
|
unsigned long long last = ref.last;
|
589
|
-
// printf("Tansmit to signal range: %s(%p)\n",signal->name,signal);
|
589
|
+
// printf("Tansmit to signal range: %s(%p) [%llu,%llu]\n",signal->name,signal,first,last);
|
590
590
|
/* Can transmit, copy the content. */
|
591
591
|
if (signal->fading)
|
592
|
-
write_range(value,first,last,signal->f_value->type,signal->f_value);
|
592
|
+
// write_range(value,first,last,signal->f_value->type,signal->f_value);
|
593
|
+
write_range(value,first,last,ref.type,signal->f_value);
|
593
594
|
else
|
594
|
-
write_range_no_z(value,first,last,signal->f_value->type,signal->f_value);
|
595
|
+
// write_range_no_z(value,first,last,signal->f_value->type,signal->f_value);
|
596
|
+
write_range_no_z(value,first,last,ref.type,signal->f_value);
|
595
597
|
/* And touch the signal. */
|
596
598
|
touch_signal_seq(signal);
|
597
599
|
}
|
@@ -0,0 +1,203 @@
|
|
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
|
+
/** Pops a value.
|
31
|
+
* @return the value. */
|
32
|
+
Value pop() {
|
33
|
+
if (head < STACK_SIZE) {
|
34
|
+
return stack[head++];
|
35
|
+
} else {
|
36
|
+
perror("Computation stack empty.\n");
|
37
|
+
exit(1);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/** Pops multiple values.
|
42
|
+
* @param num the number of values to pop.
|
43
|
+
* @return a pointer on the first value (in heap order!). */
|
44
|
+
static Value* popn(int num) {
|
45
|
+
if (head+num <= STACK_SIZE) {
|
46
|
+
head += num;
|
47
|
+
return &stack[head-num];
|
48
|
+
} else {
|
49
|
+
perror("Not enough values in computation stack.\n");
|
50
|
+
exit(1);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
/** Unary calculation.
|
56
|
+
* @param oper the operator function
|
57
|
+
* @return the destination
|
58
|
+
**/
|
59
|
+
Value unary(Value (*oper)(Value,Value)) {
|
60
|
+
// printf("unary\n");
|
61
|
+
Value dst = get_top_value();
|
62
|
+
dst = oper(pop(),dst);
|
63
|
+
push(dst);
|
64
|
+
return dst;
|
65
|
+
}
|
66
|
+
|
67
|
+
/** Binary calculation.
|
68
|
+
* @param oper the operator function
|
69
|
+
* @return the destination
|
70
|
+
**/
|
71
|
+
Value binary(Value (*oper)(Value,Value,Value)) {
|
72
|
+
// printf("binary\n");
|
73
|
+
Value dst = get_top_value();
|
74
|
+
Value r = pop();
|
75
|
+
Value l = pop();
|
76
|
+
dst = oper(l,r,dst);
|
77
|
+
push(dst);
|
78
|
+
return dst;
|
79
|
+
}
|
80
|
+
|
81
|
+
/** Cast calculation.
|
82
|
+
* @param typ the type to cast to.
|
83
|
+
* @return the destination.
|
84
|
+
**/
|
85
|
+
Value cast(Type typ) {
|
86
|
+
// printf("cast\n");
|
87
|
+
Value dst = get_top_value();
|
88
|
+
Value src = pop();
|
89
|
+
dst = cast_value(src,typ,dst);
|
90
|
+
push(dst);
|
91
|
+
return dst;
|
92
|
+
}
|
93
|
+
|
94
|
+
/* Concat values.
|
95
|
+
* @param num the number of values to concat.
|
96
|
+
* @param dir the direction. */
|
97
|
+
Value sconcat(int num, int dir) {
|
98
|
+
Value* vals = alloca(num*sizeof(Value));
|
99
|
+
Value dst = get_top_value();
|
100
|
+
int i;
|
101
|
+
// printf("sconcat\n");
|
102
|
+
/* Get the values to concat from the stack. */
|
103
|
+
for(i=1;i<=num;++i) vals[num-i] = pop();
|
104
|
+
dst = concat_valueP(num,dir,dst,vals);
|
105
|
+
push(dst);
|
106
|
+
return dst;
|
107
|
+
}
|
108
|
+
|
109
|
+
/* Index read calculation.
|
110
|
+
* @param typ the data type of the access. */
|
111
|
+
Value sreadI(Type typ) {
|
112
|
+
// printf("sreadI\n");
|
113
|
+
Value dst = get_top_value();
|
114
|
+
unsigned long long idx = value2integer(pop());
|
115
|
+
dst = read_range(pop(),idx,idx,typ,dst);
|
116
|
+
push(dst);
|
117
|
+
return dst;
|
118
|
+
}
|
119
|
+
|
120
|
+
/* Index write calculation.
|
121
|
+
* @param typ the data type of the access. */
|
122
|
+
Value swriteI(Type typ) {
|
123
|
+
// printf("swriteI\n");
|
124
|
+
Value dst = get_top_value();
|
125
|
+
unsigned long long idx = value2integer(pop());
|
126
|
+
dst = write_range(pop(),idx,idx,typ,dst);
|
127
|
+
push(dst);
|
128
|
+
return dst;
|
129
|
+
}
|
130
|
+
|
131
|
+
/* Range read calculation.
|
132
|
+
* @param typ the data type of the access. */
|
133
|
+
Value sreadR(Type typ) {
|
134
|
+
// printf("sreadR\n");
|
135
|
+
Value dst = get_top_value();
|
136
|
+
unsigned long long last = value2integer(pop());
|
137
|
+
unsigned long long first = value2integer(pop());
|
138
|
+
dst = read_range(pop(),first,last,typ,dst);
|
139
|
+
push(dst);
|
140
|
+
return dst;
|
141
|
+
}
|
142
|
+
|
143
|
+
/* Range write calculation.
|
144
|
+
* @param typ the data type of the access. */
|
145
|
+
Value swriteR(Type typ) {
|
146
|
+
// printf("swriteR\n");
|
147
|
+
Value dst = get_top_value();
|
148
|
+
unsigned long long last = value2integer(pop());
|
149
|
+
unsigned long long first = value2integer(pop());
|
150
|
+
dst = write_range(pop(),first,last,typ,dst);
|
151
|
+
push(dst);
|
152
|
+
return dst;
|
153
|
+
}
|
154
|
+
|
155
|
+
/** Check if the top value is defined. */
|
156
|
+
int is_defined() {
|
157
|
+
return is_defined_value(pop());
|
158
|
+
}
|
159
|
+
|
160
|
+
/** Convert the top value to an integer. */
|
161
|
+
unsigned long long to_integer() {
|
162
|
+
return value2integer(pop());
|
163
|
+
}
|
164
|
+
|
165
|
+
/** Check if a value is true.
|
166
|
+
* Actually check if it is defined and convert it to integer. */
|
167
|
+
unsigned long long is_true() {
|
168
|
+
Value val = pop();
|
169
|
+
if (is_defined_value(val)) {
|
170
|
+
return value2integer(val);
|
171
|
+
} else {
|
172
|
+
return 0;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
/** Transmit the top value to a signal in parallel.
|
177
|
+
* @param sig the signal to transmit to. */
|
178
|
+
void transmit(SignalI sig) {
|
179
|
+
// printf("transmit\n");
|
180
|
+
transmit_to_signal(pop(),sig);
|
181
|
+
}
|
182
|
+
|
183
|
+
/** Transmit the top value to a signal in sequence.
|
184
|
+
* @param sig the signal to transmit to. */
|
185
|
+
void transmit_seq(SignalI sig) {
|
186
|
+
// printf("transmit_seq\n");
|
187
|
+
transmit_to_signal_seq(pop(),sig);
|
188
|
+
}
|
189
|
+
|
190
|
+
/** Transmit a value to a range in a signal in parallel.
|
191
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
192
|
+
void transmitR(RefRangeS ref) {
|
193
|
+
// printf("transmitR\n");
|
194
|
+
transmit_to_signal_range(pop(),ref);
|
195
|
+
}
|
196
|
+
|
197
|
+
/** Transmit a value to a range in a signal in sequence.
|
198
|
+
* @param ref the ref to the range of the signal to transmit to. */
|
199
|
+
void transmitR_seq(RefRangeS ref) {
|
200
|
+
// printf("transmitR_seq\n");
|
201
|
+
transmit_to_signal_range_seq(pop(),ref);
|
202
|
+
}
|
203
|
+
|
@@ -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