HDLRuby 2.6.19 → 2.6.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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