HDLRuby 2.4.27 → 2.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/HDLRuby/drivers/xcd.rb +79 -0
  3. data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
  4. data/lib/HDLRuby/hdr_samples/adder.rb +1 -1
  5. data/lib/HDLRuby/hdr_samples/adder_bench.rb +1 -1
  6. data/lib/HDLRuby/hdr_samples/adder_gen.rb +1 -1
  7. data/lib/HDLRuby/hdr_samples/constant_in_function.rb +27 -0
  8. data/lib/HDLRuby/hdr_samples/dff_properties.rb +19 -0
  9. data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
  10. data/lib/HDLRuby/hdr_samples/huge_rom.rb +25 -0
  11. data/lib/HDLRuby/hdr_samples/logic_bench.rb +21 -0
  12. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
  13. data/lib/HDLRuby/hdr_samples/music.rb +79 -0
  14. data/lib/HDLRuby/hdr_samples/named_sub.rb +42 -0
  15. data/lib/HDLRuby/hdr_samples/rom.rb +16 -0
  16. data/lib/HDLRuby/hdr_samples/seqpar_bench.rb +59 -0
  17. data/lib/HDLRuby/hdr_samples/with_function_generator.rb +25 -0
  18. data/lib/HDLRuby/hdrcc.rb +140 -24
  19. data/lib/HDLRuby/hruby_decorator.rb +250 -0
  20. data/lib/HDLRuby/hruby_high.rb +468 -91
  21. data/lib/HDLRuby/hruby_low.rb +913 -45
  22. data/lib/HDLRuby/hruby_low2c.rb +189 -168
  23. data/lib/HDLRuby/hruby_low2hdr.rb +738 -0
  24. data/lib/HDLRuby/hruby_low2high.rb +331 -549
  25. data/lib/HDLRuby/hruby_low2vhd.rb +39 -2
  26. data/lib/HDLRuby/hruby_low_bool2select.rb +29 -0
  27. data/lib/HDLRuby/hruby_low_casts_without_expression.rb +27 -0
  28. data/lib/HDLRuby/hruby_low_fix_types.rb +25 -0
  29. data/lib/HDLRuby/hruby_low_mutable.rb +70 -0
  30. data/lib/HDLRuby/hruby_low_resolve.rb +28 -0
  31. data/lib/HDLRuby/hruby_low_without_connection.rb +6 -3
  32. data/lib/HDLRuby/hruby_low_without_namespace.rb +7 -4
  33. data/lib/HDLRuby/hruby_low_without_parinseq.rb +151 -0
  34. data/lib/HDLRuby/hruby_low_without_select.rb +13 -0
  35. data/lib/HDLRuby/hruby_tools.rb +11 -1
  36. data/lib/HDLRuby/hruby_verilog.rb +1602 -1629
  37. data/lib/HDLRuby/sim/hruby_sim.h +25 -2
  38. data/lib/HDLRuby/sim/hruby_sim_calc.c +63 -6
  39. data/lib/HDLRuby/sim/hruby_sim_vcd.c +5 -1
  40. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +22 -6
  41. data/lib/HDLRuby/std/fixpoint.rb +9 -0
  42. data/lib/HDLRuby/std/function_generator.rb +139 -0
  43. data/lib/HDLRuby/std/hruby_unit.rb +75 -0
  44. data/lib/HDLRuby/template_expander.rb +61 -0
  45. data/lib/HDLRuby/version.rb +1 -1
  46. metadata +22 -5
@@ -573,10 +573,15 @@ extern void each_all_signal(void (*func)(SignalI));
573
573
  /* Interface to the visualization engine. */
574
574
 
575
575
  typedef struct {
576
+ /* The simulation prints. */
576
577
  void (*print_time)(unsigned long long);
577
578
  void (*print_name)(Object);
578
579
  void (*print_value)(Value);
579
580
  void (*print_signal)(SignalI);
581
+ /* The custom 'string' prints. */
582
+ void (*print_string)(const char*);
583
+ void (*print_string_name)(Object);
584
+ void (*print_string_value)(Value);
580
585
  } PrinterS;
581
586
 
582
587
  extern PrinterS printer;
@@ -585,11 +590,29 @@ extern PrinterS printer;
585
590
  * @param print_time the time printer
586
591
  * @param print_name the name printer
587
592
  * @param print_value the value printer
588
- * @param print_signal the signal state printer. */
593
+ * @param print_signal the signal state printer
594
+ * @param print_string the string printer
595
+ * @param print_string_name the string name printer
596
+ * @param print_string_value the string value printer */
589
597
  extern void init_visualizer(void (*print_time)(unsigned long long),
590
598
  void (*print_name)(Object),
591
599
  void (*print_value)(Value),
592
- void (*print_signal)(SignalI));
600
+ void (*print_signal)(SignalI),
601
+ void (*print_string)(const char*),
602
+ void (*print_string_name)(Object),
603
+ void (*print_string_value)(Value));
604
+
605
+ /** Prints a name (default).
606
+ * @param signal the signal to show */
607
+ extern void default_print_name(Object);
608
+
609
+ /** Prints a value (default).
610
+ * @param signal the signal to show */
611
+ extern void default_print_value(Value);
612
+
613
+ /** Prints a string (default).
614
+ * @param str the string to print. */
615
+ extern void default_print_string(const char* str);
593
616
 
594
617
  // /** Prints the time.
595
618
  // * @param time the time to show. */
@@ -325,6 +325,9 @@ Value copy_value(Value src, Value dst) {
325
325
  /* Declared afterward. */
326
326
  static Value set_bitstring_value(Value src, Value dst);
327
327
 
328
+ /* Declared afterward. */
329
+ static Value set_numeric_value(Value src, Value dst);
330
+
328
331
  /** Copies a value to another but without overwritting with Z, the type of
329
332
  * the destination is preserved.
330
333
  * @param src the source value
@@ -393,6 +396,35 @@ static Value set_bitstring_value(Value src, Value dst) {
393
396
  return dst;
394
397
  }
395
398
 
399
+ /** Creates a numeric value from a bitstring value.
400
+ * @param src the bitstring source value
401
+ * @param dst the numeric destination value
402
+ * @return dst. */
403
+ static Value set_numeric_value(Value src, Value dst) {
404
+ /* Compute the width in bits of the source. */
405
+ unsigned long long width = type_width(src->type);
406
+ unsigned long long i;
407
+ /* Set the type and size of the destination from the type of the source.*/
408
+ dst->type = src->type;
409
+ dst->numeric = 1;
410
+
411
+ /* Access the data of the source and the destination. */
412
+ char* data_str = src->data_str;
413
+ unsigned long long data_int = 0;
414
+
415
+ /* Make the conversion. */
416
+ for(i=0; i < width; ++i) {
417
+ /* Get the bit from the source. */
418
+ unsigned long long bit = data_str[i] - '0';
419
+ /* And write it. */
420
+ data_int |= bit << i;
421
+ }
422
+ /* Update the destination. */
423
+ dst->data_int = data_int;
424
+ /* Return the destination. */
425
+ return dst;
426
+ }
427
+
396
428
 
397
429
  /** Sets a value to undefined.
398
430
  * @param dst the destination value
@@ -1620,7 +1652,7 @@ static Value not_value_numeric(Value src, Value dst) {
1620
1652
  dst->numeric = 1;
1621
1653
 
1622
1654
  /* Perform the not. */
1623
- dst->data_int = fix_numeric_type(dst->type,!src->data_int);
1655
+ dst->data_int = fix_numeric_type(dst->type,~src->data_int);
1624
1656
  return dst;
1625
1657
  }
1626
1658
 
@@ -1731,7 +1763,8 @@ static Value equal_value_numeric(Value src0, Value src1, Value dst) {
1731
1763
  dst->numeric = 1;
1732
1764
 
1733
1765
  /* Perform the !XOR. */
1734
- dst->data_int = (src0->data_int == src1->data_int);
1766
+ // dst->data_int = (src0->data_int == src1->data_int);
1767
+ dst->data_int = ~(src0->data_int ^ src1->data_int);
1735
1768
  return dst;
1736
1769
  }
1737
1770
 
@@ -2068,15 +2101,39 @@ Value sub_value(Value src0, Value src1, Value dst) {
2068
2101
  * @param dst the destination value
2069
2102
  * @return dst */
2070
2103
  Value mul_value(Value src0, Value src1, Value dst) {
2104
+ // printf("mul_value with src0=%llx src1=%llx\n",value2integer(src0),value2integer(src1));
2105
+ // printf("src0->numeric=%d src1->numeric=%d\n",src0->numeric,src1->numeric);
2106
+ // printf("is_defined_value(src0)=%d is_defined_value(src1)=%d\n",is_defined_value(src0),is_defined_value(src1));
2071
2107
  /* Might allocate a new value so save the current pool state. */
2072
2108
  unsigned int pos = get_value_pos();
2073
2109
  /* Do a numeric computation if possible, otherwise fallback to bitstring
2074
2110
  * computation. */
2075
- if (src0->numeric && src1->numeric) {
2076
- /* Both sources are numeric. */
2077
- return mul_value_numeric(src0,src1,dst);
2111
+ if (src0->numeric) {
2112
+ if (src1->numeric) {
2113
+ /* Both sources are numeric. */
2114
+ return mul_value_numeric(src0,src1,dst);
2115
+ } else if (is_defined_value(src1)) {
2116
+ // /* src1 is a defined bitstring, convert src0 to bitstring. */
2117
+ // src0 = set_bitstring_value(src0,get_value());
2118
+ // /* And do a bitstring multiplying. */
2119
+ // return mul_value_defined_bitstring(src0,src1,dst);
2120
+ /* src1 is a defined bitstring, convert it to a numeric. */
2121
+ src1 = set_numeric_value(src1,get_value());
2122
+ /* And do a numeri multiplying. */
2123
+ return mul_value_numeric(src0,src1,dst);
2124
+ }
2125
+ } else if (src1->numeric && is_defined_value(src0)) {
2126
+ // /* src1 is numeric but src0 is a defined bitstring, convert src1 to
2127
+ // * bitstring. */
2128
+ // src1 = set_bit_string_value(src1,get_value());
2129
+ // /* And do a bitstring multiplying. */
2130
+ // return mul_value_defined_bitstring(src0,src1,dst);
2131
+ /* src0 is a defined bitstring, convert it to a numeric. */
2132
+ src0 = set_numeric_value(src0,get_value());
2133
+ /* And do a numeri multiplying. */
2134
+ return mul_value_numeric(src0,src1,dst);
2078
2135
  } else if (is_defined_value(src0) && is_defined_value(src1)) {
2079
- /* Both sources can be converted to numeric values. */
2136
+ /* Both sources are defined bitstrings. */
2080
2137
  return mul_value_defined_bitstring(src0,src1,dst);
2081
2138
  } else {
2082
2139
  /* Cannot compute (for now), simply undefines the destination. */
@@ -357,6 +357,7 @@ static void vcd_print_header() {
357
357
  }
358
358
 
359
359
 
360
+
360
361
  /* The configuration and initialization of the vcd vizualizer. */
361
362
 
362
363
 
@@ -373,7 +374,10 @@ extern void init_vcd_visualizer(char* name) {
373
374
  init_visualizer(&vcd_print_time,
374
375
  &vcd_print_full_name,
375
376
  &vcd_print_value,
376
- &vcd_print_signal_fvalue);
377
+ &vcd_print_signal_fvalue,
378
+ &default_print_string,
379
+ &default_print_name,
380
+ &default_print_value);
377
381
 
378
382
  /* Prints the header of the vcd file. */
379
383
  vcd_print_header();
@@ -16,15 +16,22 @@ PrinterS printer;
16
16
  * @param print_time the time printer
17
17
  * @param print_name the name printer
18
18
  * @param print_value the value printer
19
- * @param print_signal the signal state printer. */
19
+ * @param print_signal the signal state printer
20
+ * @param print_string the string printer. */
20
21
  void init_visualizer(void (*print_time)(unsigned long long),
21
22
  void (*print_name)(Object),
22
23
  void (*print_value)(Value),
23
- void (*print_signal)(SignalI)) {
24
+ void (*print_signal)(SignalI),
25
+ void (*print_string)(const char*),
26
+ void (*print_string_name)(Object),
27
+ void (*print_string_value)(Value)) {
24
28
  printer.print_time = print_time;
25
29
  printer.print_name = print_name;
26
30
  printer.print_value = print_value;
27
31
  printer.print_signal = print_signal;
32
+ printer.print_string = print_string;
33
+ printer.print_string_name = print_string_name;
34
+ printer.print_string_value = print_string_value;
28
35
  }
29
36
 
30
37
 
@@ -34,7 +41,7 @@ void init_visualizer(void (*print_time)(unsigned long long),
34
41
 
35
42
  /** Prints the time.
36
43
  * @param time the time to show. */
37
- static void default_print_time(unsigned long long time) {
44
+ void default_print_time(unsigned long long time) {
38
45
  printf("# %llups",time);
39
46
  }
40
47
 
@@ -47,7 +54,7 @@ static void default_println_time(unsigned long long time) {
47
54
 
48
55
  /** Prints the name of an object.
49
56
  * @param object the object to print the name. */
50
- static void default_print_name(Object object) {
57
+ void default_print_name(Object object) {
51
58
  /* Recurse on the owner if any. */
52
59
  // printf("owner=%p\n",object->owner);
53
60
  if (object->owner != NULL) {
@@ -73,7 +80,7 @@ static void default_print_name(Object object) {
73
80
 
74
81
  /** Prints a value.
75
82
  * @param value the value to print */
76
- static void default_print_value(Value value) {
83
+ void default_print_value(Value value) {
77
84
  if (value->numeric) {
78
85
  unsigned long long width = type_width(value->type);
79
86
  unsigned long long mask = 1ULL << (width-1);
@@ -100,6 +107,12 @@ static void default_print_value(Value value) {
100
107
  }
101
108
  }
102
109
 
110
+ /** Prints a string.
111
+ * @param str the string to print. */
112
+ void default_print_string(const char* str) {
113
+ printf("%s", str);
114
+ }
115
+
103
116
  /** Prints a signal.
104
117
  * @param signal the signal to show */
105
118
  static void default_print_signal(SignalI signal) {
@@ -126,5 +139,8 @@ void init_default_visualizer(char* name) {
126
139
  init_visualizer(&default_println_time,
127
140
  &default_print_name,
128
141
  &default_print_value,
129
- &default_println_signal);
142
+ &default_println_signal,
143
+ &default_print_string,
144
+ &default_print_name,
145
+ &default_print_value);
130
146
  }
@@ -65,6 +65,15 @@ module HDLRuby::High::Std
65
65
  (left.as([isize+fsize*2]) << fsize) / right
66
66
  end
67
67
  end
68
+ # Define the removal of the point.
69
+ typ.define_singleton_method(:no_point) do
70
+ if (typ.signed?) then
71
+ signed[typ.width]
72
+ else
73
+ bit[typ.width]
74
+ end
75
+ end
76
+ # Return the resulting typ.
68
77
  typ
69
78
  end
70
79
  end
@@ -0,0 +1,139 @@
1
+ ##
2
+ # Standard HDLRuby::High library: universal generic function generator
3
+ # based on the work of Ryota Sakai from NN4H
4
+ #
5
+ ########################################################################
6
+
7
+
8
+ module HDLRuby::High::Std
9
+
10
+ # Module describing a function generator using linear approximation between
11
+ # fixed precalculated values.
12
+ # Generic parameters:
13
+ # +func+ procedure generating the discret values of the functions.
14
+ # +ityp+ the type of the input
15
+ # +otyp+ the type of the output
16
+ # +awidth+ width of the address bus for accessing the discret values
17
+ # +xrange+ the range for x values when computing the function
18
+ # +yrange+ the range for y values when computing the function
19
+ system :function_generator do |func, ityp, otyp, awidth, xrange, yrange|
20
+ # Check the generic parameters.
21
+ func = func.to_proc
22
+ ityp = ityp.to_type
23
+ otyp = otyp.to_type
24
+ awidth = awidth.to_i
25
+ xrange = xrange.first.to_f..xrange.last.to_f
26
+ yrange = yrange.first.to_f..yrange.last.to_f
27
+
28
+ # Declare the interface of the generator.
29
+ ityp.input :x
30
+ otyp.output :y
31
+
32
+ # Discrete values used for interpolating.
33
+ otyp.inner :base, :next_data
34
+
35
+ # Address
36
+ [awidth].inner :address
37
+ # Remainder
38
+ ityp.inner :remaining
39
+ x
40
+ # Compute the address and the remainder from the input.
41
+ address <= x[(ityp.width-1)..(ityp.width-awidth)]
42
+ remaining <= [[_b1b0] * awidth, x[(ityp.width-1-awidth)..0]]
43
+
44
+ # Instantiate the lut holding the discrete values.
45
+ lut(func,ityp,otyp,awidth,xrange,yrange).(:my_lut).(address,base,next_data)
46
+
47
+ # Instantiate the interpolator.
48
+ interpolator(ityp,otyp,awidth).(:my_iterpolator).(base,next_data, remaining, y)
49
+ end
50
+
51
+
52
+ # The LUT containing the discre values.
53
+ system :lut do |func,ityp, otyp, awidth, xrange, yrange|
54
+ # Check the generic arguments.
55
+ func = func.to_proc
56
+ ityp = ityp.to_type
57
+ otyp = otyp.to_type
58
+ awidth = awidth.to_i
59
+ xrange = xrange.first.to_f..xrange.last.to_f
60
+ yrange = yrange.first.to_f..yrange.last.to_f
61
+
62
+ # lut_size = 2 ** address_width
63
+ # Compute the size of the lut.
64
+ lut_size = 2 ** awidth
65
+
66
+ # Declare the input and output of the lut.
67
+ [awidth].input :address
68
+ otyp.output :base, :next_data
69
+
70
+ # Declare the lut
71
+ otyp[-lut_size].constant lut:
72
+ initialize_lut(func,otyp,awidth,xrange,yrange)
73
+
74
+ # Assign the base discret value.
75
+ base <= lut[address]
76
+
77
+ # Assign the next_data discrete value.
78
+ next_data <= lut[address+1]
79
+ end
80
+
81
+
82
+ # compute tanh
83
+ # LUTの点の間の値を計算するモジュール
84
+ # system :interpolator do |typ, integer_width, address_width|
85
+ # Module making linear interpolation between two discrete values.
86
+ # Generic parameters:
87
+ # +ityp+: the function input value type
88
+ # +otyp+: the function output value type
89
+ # +width+: the step width between discrete values
90
+ system :interpolator do |ityp,otyp,width|
91
+ # Check the generic arguments
92
+ ityp = ityp.to_type
93
+ otyp = otyp.to_type
94
+ width = width.to_i
95
+ # Compute the scale factor and convert it to a shift value.
96
+ shift_bits = ityp.width - width
97
+
98
+ # Declare the input and outputs.
99
+ otyp.input :base, :next_data
100
+ ityp.input :remaining
101
+ otyp.output :interpolated_value
102
+
103
+ if (otyp.signed?) then
104
+ signed[otyp.width+ityp.width].inner :diff
105
+ else
106
+ bit[otyp.width+ityp.width].inner :diff
107
+ end
108
+
109
+ # Make the interpolation.
110
+ diff <= (next_data-base).as(diff.type) * remaining
111
+ if(otyp.signed?) then
112
+ interpolated_value <= base +
113
+ ([[diff[diff.type.width-1]]*shift_bits,
114
+ diff[diff.type.width-1..shift_bits]]).to_expr
115
+ else
116
+ interpolated_value <= base + (diff >> shift_bits)
117
+ end
118
+ end
119
+
120
+ # Make an array consists of a point of any activation function.
121
+ # @param [Integer] lut_size the lut_size of LUT
122
+ # @return [Array] table an array consists of a point of tanh
123
+ def initialize_lut(func, otyp, awidth, xrange, yrange)
124
+ # Compute the x step between discret values.
125
+ xstep = (xrange.last-xrange.first)/(2 ** awidth)
126
+
127
+ # Generate the discrete set of x values.
128
+ x_values = xrange.step(xstep)
129
+ # Generate the table.
130
+ table = x_values.map do |x_value|
131
+ ((func.call(x_value)-yrange.first)/(yrange.last-yrange.first)*
132
+ 2**otyp.width).to_i.to_expr.as(otyp)
133
+ end
134
+
135
+ return table
136
+ end
137
+
138
+
139
+ end
@@ -0,0 +1,75 @@
1
+ require "HDLRuby/hruby_high"
2
+
3
+
4
+
5
+ ##
6
+ # Library for building unit test systems.
7
+ #
8
+ ########################################################################
9
+ module HDLRuby::Unit
10
+
11
+ ## The HDLRuby unit test error class.
12
+ class UnitError < ::StandardError
13
+ end
14
+
15
+ # The set of the unit systems by name.
16
+ @@unit_systems = {}
17
+
18
+
19
+ # Declares system +name+ for unit testing.
20
+ # The system is built by executing +ruby_block+.
21
+ #
22
+ # NOTE: the name of the system is not registered within the HDLRuby
23
+ # namespace since it is not meant to be used directly.
24
+ def self.system(name,&ruby_block)
25
+ # Ensure name is a symbol.
26
+ name = name.to_s.to_sym unless name.is_a?(Symbol)
27
+ # Check if the name is already used or not.
28
+ if @@unit_systems.key?(name) then
29
+ raise UnitError, "Unit test system #{name} already declared."
30
+ end
31
+ # @@unit_systems[name] = HDLRuby::High.system(&ruby_block)
32
+ @@unit_systems[name] = ruby_block
33
+ end
34
+
35
+
36
+ # Create a system named +test_name+ executing the unit tests given from
37
+ # +names+.
38
+ def self.test(test_name = :test, *names)
39
+ # If there is no name given, use all the test systems.
40
+ names = @@unit_systems.each_key if names.empty?
41
+ # Declare the system.
42
+ HDLRuby::High.system test_name do
43
+
44
+ # The timed block that contains the bench execurtion code.
45
+ @@tester = timed {}
46
+
47
+ # Generate the test code for each selected test units.
48
+ names.each do |name|
49
+ name = name.to_s.to_sym unless name.is_a?(Symbol)
50
+ unless @@unit_systems.key?(name) then
51
+ raise UnitError, "Unit test #{name} does not exist."
52
+ end
53
+ sub(name) do
54
+ @@myself = self
55
+ instance_exec do
56
+ # Define the test command that insert code of
57
+ # the current test unit to the tester timed block.
58
+ def test(&ruby_block)
59
+ @@tester.block.open do
60
+ # Here the signals are to be taken from
61
+ # the test unit and not the timed block.
62
+ set_this(@@myself)
63
+ ruby_block.call
64
+ # Go back to the default current this.
65
+ set_this
66
+ end
67
+ end
68
+ end
69
+ # Process the test unit.
70
+ instance_exec(&@@unit_systems[name])
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end