HDLRuby 3.7.1 → 3.7.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 01c5cc3826577779dad647fb9c8811d4bec3445bc19ca873f1015990aa689e68
4
- data.tar.gz: 84985eda69036fe35175cc5255786c53839d7611a98170d2d1d131b3d4c0ec1d
3
+ metadata.gz: 78d08a6a222a4f33398c1d92e8b1f7d9462597b22ea2c48306318fb3e3e9c82d
4
+ data.tar.gz: 4a52c34a1355369260b0c162df38b7714ad1cedf4ed56ab7bc023eb01d2b7e40
5
5
  SHA512:
6
- metadata.gz: 45fbf8ad20c226c543770c85e3b41fd3dabf9fb337830c518544f67b86afd417240e3309575993e58a13de17233b8a197b08e9ca3a7ba7eb9a6e505900b41251
7
- data.tar.gz: 8728928e73e6ccd092c5741be652d8f0730c7cf07f04ddbb4af64615b8472df2db50dfa6d0ad4c310c09270f61cc6d3e760fe6d4a87850ca97156ef64e2518ed
6
+ metadata.gz: d35ac48b9832cd591a03be9db90574021ccf2ee73a784fd3b608487f8addff48295f7043ee2c0a31aeccec0cba00866828da94b63aa6f319e61c9ac812be64bb
7
+ data.tar.gz: ddd87fe50aedb38521627cbaf5c6467c7ea59146d10c2e62f1069de2ae90859013d20e312b1b40fdc36a94d04cc02278aeaafa59227c3d71f340544e31f03067
data/README.md CHANGED
@@ -17,6 +17,20 @@ hdrcc --get-tuto
17
17
 
18
18
  __What's new__
19
19
 
20
+ For HDLRuby version 3.7.3:
21
+
22
+ * Added the possibility to use software sequencers inside HDLRuby's program construct, and use within them program ports like they were input or output signals.
23
+
24
+ For HDLRuby version 3.7.2:
25
+
26
+ * Added the `text` command for the sequencers in software.
27
+
28
+ * Added the `value_text` method to sequencers in software's signal for generatign Ruby/C code for accessing a value with correct typing.
29
+
30
+ * Added the `alive?` and `reset!` commands for HDLRuby sequencers.
31
+
32
+ * Added the `require_ruby` method for loading Ruby (i.e., non-HDLRuby) libraries.
33
+
20
34
  For HDLRuby version 3.7.x:
21
35
 
22
36
  * Added the possibility to run [sequencers in software](#sequencers-as-software-code). (WIP)
@@ -255,7 +269,9 @@ hdr_vhdl
255
269
  hdr_sim
256
270
  ```
257
271
 
272
+ ## HDLRuby files.
258
273
 
274
+ HDLRuby being built on top of the Ruby language, we choose as convension to name the HDLRuby file with the `.rb` extension. For the same reason, including external HDLRuby files is done using the `require` or `require_relative` methods, that are identical to their Ruby counterpart. Those method however can only be used for including HDLRuby description file and not Ruby ones, for the later, the method `require_ruby` and `require_relative_ruby` must be used instead.
259
275
 
260
276
 
261
277
  # HDLRuby programming guide
@@ -739,7 +755,7 @@ __Notes__:
739
755
  - Since this is Ruby code, the body can also be delimited by the `do` and `end` Ruby keywords (in which case the parentheses can be omitted) as follows:
740
756
 
741
757
  ```ruby
742
- system :box does
758
+ system :box do
743
759
  end
744
760
  ```
745
761
 
@@ -927,9 +943,17 @@ inner sig: 0
927
943
  As another example, an 8-bit 8-word ROM could be declared and initialized as follows:
928
944
 
929
945
  ```ruby
930
- bit[8][-8] rom: [ 0,1,2,3,4,5,6,7 ]
946
+ bit[8][-8] rom: [ _h00,_h01,_h02,_h03,_h04,_h05,_h06,_h07 ]
931
947
  ```
932
948
 
949
+ __Note__:
950
+
951
+ * The notation `_hXY` is used for indicating a 2-digit, `X` and `Y`, hexadecimal.
952
+
953
+ * By default, Ruby integers (not preceded by the `_` prefix) are typed as 64-bit HDLRuby values, whereas HDLRuby explicit values (preceded by the `_ ` prefix) have a bit-width corresponding to their representation.
954
+
955
+ * When declaring the contents of a ROM, the bit-width of the elements must match that of the declared type; otherwise, misalignments may occur.
956
+
933
957
 
934
958
  ### Scope in a system
935
959
 
@@ -3255,6 +3279,29 @@ A sequence is a specific case of a `seq` block that includes the following softw
3255
3279
 
3256
3280
  - `sterminate`: ends the execution of the sequence.
3257
3281
 
3282
+ - `alive?`: is 0 if the sequencer is still running and not 0 otherwise.
3283
+ Can be used outside the sequencer.
3284
+
3285
+ - `reset!`: resets the sequencer to its start.
3286
+ Can be used outside the sequencer.
3287
+
3288
+ The two last commands can be used to control a sequencer outside of it. For that purpose, a reference must be assigned to the sequencer as follows, where `ref_sequencer` is a Ruby variable that will refer to the sequencer:
3289
+
3290
+ ```ruby
3291
+ ref_sequencer = sequencer(clk,start) do
3292
+ < some sequencer code >
3293
+ end
3294
+
3295
+ < somewhere else in the code. >
3296
+
3297
+ # Reset the sequencer if it ended its execution.
3298
+ hif(ref_sequencer.alive? == 0) do
3299
+ ref_sequencer.reset!
3300
+ end
3301
+ ```
3302
+
3303
+
3304
+
3258
3305
  It is also possible to use enumerators (iterators) similar to the Ruby `each` using the following methods within sequences:
3259
3306
 
3260
3307
  - `<object>.seach`: `object` any enumerable Ruby object or any signal. If a block is given, it works like `sfor`, otherwise, it returns a HDLRuby enumerator (please see [enumerator](#hdlruby-enumerators-and-enumerable-objects-stdsequencerrb) for details about them).
@@ -3917,17 +3964,48 @@ sequencer do
3917
3964
  end.()
3918
3965
  ```
3919
3966
 
3920
- Another possibility is to put the code into a string as follows:
3967
+ Another possibility is to put the code into a string using the command `text` as follows:
3921
3968
 
3922
3969
  ```
3923
3970
  sequencer do
3924
3971
  stimes.10 do
3925
- ruby('puts "Hello"')
3972
+ text('puts "Hello"')
3926
3973
  end
3927
3974
  end.()
3928
3975
  ```
3929
3976
 
3930
- Both method are functionally equivalent. However, the first is faster and safer but is incompatible with separated code generation, while the second allows separate code generation but is slower and less safe.
3977
+ Both method are functionally equivalent. However, the first is safer as potential errors are detected at the compile stage, but is incompatible with separated code generation and is slow, while the second allows separate code generation, if fast, but is less safe since it is only at the execution stage that the code is checked.
3978
+
3979
+ __Note__: Since the string in text is grafted as is into the generated Ruby (or C) code, you cannot directly access the value of a signal. However, you can use to_ruby or to_c to access the underlying raw value, or use value_text to retrieve the value with proper type adjustment in case of overflow or underflow. For example, the following will display the raw value of signal sig0 and the hardware-accurate value of signal sig1:
3980
+
3981
+ ```ruby
3982
+ sequencer do
3983
+ text("puts #{sig0.to_ruby}")
3984
+ text("puts #{sig1.value_text}")
3985
+ end
3986
+ ```
3987
+
3988
+ #### Using Software Sequencer Inside a HDLRuby program.
3989
+
3990
+ HDLRuby supports hardware/software co-design through the `program` [construct](#declaring-a-software-component). Since software sequencers are software components, they can be used within this construct when the selected language is Ruby. They can also be used with the C language, but in that case, the corresponding C code must first be generated.
3991
+
3992
+ For Ruby, software sequencer signals can be automatically connected to the ports of the program construct by declaring them as input signals for `inport` and output signals for `outport`. For example, the following code describes a software sequencer that echoes the value from the input port `inP` to the output port `outP` (`sig0` and `sig1` are signals from the upper RTL design).
3993
+
3994
+ ```ruby
3995
+ program(:ruby) do
3996
+ actport clk.posedge
3997
+ inport inP: sig0
3998
+ outport outP: sig1
3999
+ code do
4000
+ input :inP
4001
+ output :outP
4002
+ sequencer do
4003
+ outP <= inP
4004
+ end
4005
+ end
4006
+ end
4007
+ ```
4008
+
3931
4009
 
3932
4010
 
3933
4011
  ## Fixed-point (fixpoint): `std/fixpoint.rb`
@@ -1682,7 +1682,7 @@ VALUE rcsim_transmit_fixnum_to_signal(VALUE mod, VALUE signalV, VALUE valR) {
1682
1682
  /* Get the C signal from the Ruby value. */
1683
1683
  SignalI signal;
1684
1684
  value_to_rcsim(SignalIS,signalV,signal);
1685
- /* Compute the simualtion value from valR. */
1685
+ /* Compute the simulation value from valR. */
1686
1686
  Value value = get_value();
1687
1687
  value->type = signal->type;
1688
1688
  value->numeric = 1;
@@ -1699,7 +1699,7 @@ VALUE rcsim_transmit_fixnum_to_signal_seq(VALUE mod, VALUE signalV, VALUE valR)
1699
1699
  /* Get the C signal from the Ruby value. */
1700
1700
  SignalI signal;
1701
1701
  value_to_rcsim(SignalIS,signalV,signal);
1702
- /* Compute the simualtion value from valR. */
1702
+ /* Compute the simulation value from valR. */
1703
1703
  Value value = get_value();
1704
1704
  value->type = signal->type;
1705
1705
  value->numeric = 1;
@@ -1711,6 +1711,49 @@ VALUE rcsim_transmit_fixnum_to_signal_seq(VALUE mod, VALUE signalV, VALUE valR)
1711
1711
  }
1712
1712
 
1713
1713
 
1714
+ /** Reads an elements of a C signal array at an index and returns
1715
+ * the result as a Ruby fixnum.
1716
+ * Sets 0 if the value contains x or z bits. */
1717
+ VALUE rcsim_read_index_fixnum(VALUE mod, VALUE signalV, VALUE idxV) {
1718
+ Value value = get_value();
1719
+ /* Get the C signal from the Ruby value. */
1720
+ SignalI signal;
1721
+ value_to_rcsim(SignalIS,signalV,signal);
1722
+ /* Get its base type.*/
1723
+ Type base = get_type_vector(get_type_bit(),signal->type->base);
1724
+ /* Get the index. */
1725
+ unsigned long long idx = FIX2LONG(idxV);
1726
+ /* Access the value. */
1727
+ read_range(signal->c_value,idx,idx,base,value);
1728
+ /* Get the value from the signal. */
1729
+ return LONG2FIX(value2integer(value));
1730
+ }
1731
+
1732
+ /** Transmit a Ruby fixnum inside a C signal array at an index in
1733
+ * a blocking fashion.
1734
+ * NOTE: the simulator events are updated. */
1735
+ VALUE rcsim_write_index_fixnum_seq(VALUE mod, VALUE signalV, VALUE idxV, VALUE valR) {
1736
+ /* Get the C signal from the Ruby value. */
1737
+ SignalI signal;
1738
+ value_to_rcsim(SignalIS,signalV,signal);
1739
+ // /* Get its base type.*/
1740
+ // Type base = get_type_vector(get_type_bit(),signal->type->base);
1741
+ /* Get the index. */
1742
+ unsigned long long idx = FIX2LONG(idxV);
1743
+ /* Compute the simulation value from valR. */
1744
+ Value value = get_value();
1745
+ value->type = signal->type;
1746
+ value->numeric = 1;
1747
+ value->data_int = FIX2LONG(valR);
1748
+ /* Transmit it. */
1749
+ transmit_to_signal_range_num_seq(value, signal, idx,idx);
1750
+ /* End, return the transmitted expression. */
1751
+ return valR;
1752
+ }
1753
+
1754
+
1755
+
1756
+
1714
1757
  // /** Execute a behavior. */
1715
1758
  // VALUE rcsim_execute_behavior(VALUE mod, VALUE behaviorV) {
1716
1759
  // /* Get the behavior. */
@@ -1900,6 +1943,8 @@ void Init_hruby_sim() {
1900
1943
  /* The Ruby software interface. */
1901
1944
  rb_define_singleton_method(mod,"rcsim_get_signal_fixnum",rcsim_get_signal_fixnum,1);
1902
1945
  rb_define_singleton_method(mod,"rcsim_transmit_fixnum_to_signal_seq",rcsim_transmit_fixnum_to_signal_seq,2);
1946
+ rb_define_singleton_method(mod,"rcsim_read_index_fixnum",rcsim_read_index_fixnum,2);
1947
+ rb_define_singleton_method(mod,"rcsim_write_index_fixnum_seq",rcsim_write_index_fixnum_seq,3);
1903
1948
  // rb_define_singleton_method(mod,"rcsim_execute_behavior",rcsim_execute_behavior,1);
1904
1949
 
1905
1950
  }
@@ -901,6 +901,14 @@ extern void transmit_to_signal_seq(Value value, SignalI signal);
901
901
  * value to. */
902
902
  extern void transmit_to_signal_range_seq(Value value, RefRangeS ref);
903
903
 
904
+ /** Transmit a value to a range within a signal in case of sequential
905
+ * execution model.
906
+ * @param value the value to transmit
907
+ * @param ref the reference to the range in the signal to transmit the
908
+ * value to. */
909
+ extern void transmit_to_signal_range_num_seq(Value value, SignalI signal,
910
+ unsigned long long first, unsigned long long last);
911
+
904
912
  /** Creates an event.
905
913
  * @param edge the edge of the event
906
914
  * @param signal the signal of the event */
@@ -2449,7 +2449,7 @@ static int same_content_value_range_numeric(Value value0,
2449
2449
  Value read_range_numeric(Value value,
2450
2450
  unsigned long long first, unsigned long long last,
2451
2451
  Type base, Value dst) {
2452
- /* printf("read_range_numeric with value=%llx and first=%llu and last=%llu\n",value->data_int,first,last); */
2452
+ // printf("read_range_numeric with value=%llx and first=%llu and last=%llu\n",value->data_int,first,last);
2453
2453
  /* Ensure first is the smaller. */
2454
2454
  if (first > last) {
2455
2455
  long long tmp = last;
@@ -2465,7 +2465,7 @@ Value read_range_numeric(Value value,
2465
2465
  first *= bw;
2466
2466
  last *= bw;
2467
2467
  length *= bw;
2468
- /* printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length); */
2468
+ // printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length); */
2469
2469
 
2470
2470
  /* Set the type and size of the destination from the type of the source.*/
2471
2471
  dst->type = make_type_vector(get_type_bit(),length);
@@ -3427,6 +3427,7 @@ unsigned long long value2integer(Value value) {
3427
3427
  Value read_range(Value value,
3428
3428
  unsigned long long first, unsigned long long last,
3429
3429
  Type base, Value dst) {
3430
+ // printf("Read range with first=%d, last=%d\n",first,last);
3430
3431
  /* Is the value numeric? */
3431
3432
  if (value->numeric) {
3432
3433
  /* Yes, do a numeric range read. */
@@ -735,18 +735,35 @@ void transmit_to_signal_seq(Value value, SignalI signal) {
735
735
  * @param value the value to transmit
736
736
  * @param ref the reference to the range in the signal to transmit the
737
737
  * value to. */
738
+ void transmit_to_signal_range_num_seq(Value value, SignalI signal,
739
+ unsigned long long first, unsigned long long last) {
740
+ // printf("Tansmit to signal range seq: %s(%p) [%llu,%llu]\n",signal->name,signal,first,last);
741
+ /* The base type is stored here to avoid allocating a new type each time.
742
+ * It have an arbitrary base size a single element. */
743
+ static TypeS baseT = { 1, 1 };
744
+ baseT.base = signal->f_value->type->base;
745
+ // printf("Tansmit to signal range: %s(%p) [%lld:%lld]\n",signal->name,signal,first,last);
746
+ /* Can transmit, copy the content. */
747
+ if (signal->fading)
748
+ signal->f_value = write_range(value,first,last,&baseT,
749
+ signal->f_value);
750
+ else
751
+ signal->f_value = write_range_no_z(value,first,last,&baseT,
752
+ signal->f_value);
753
+ /* And touch the signal. */
754
+ touch_signal_seq(signal);
755
+ }
756
+
757
+ /** Transmit a value to a range given with by first and last values, within a signal in case of sequential
758
+ * execution model.
759
+ * @param value the value to transmit
760
+ * @param ref the reference to the range in the signal to transmit the
761
+ * value to. */
738
762
  void transmit_to_signal_range_seq(Value value, RefRangeS ref) {
739
763
  SignalI signal = ref.signal;
740
764
  unsigned long long first = ref.first;
741
765
  unsigned long long last = ref.last;
742
766
  // printf("Tansmit to signal range seq: %s(%p) [%llu,%llu]\n",signal->name,signal,first,last);
743
- // /* Can transmit, copy the content. */
744
- // if (signal->fading)
745
- // // write_range(value,first,last,signal->f_value->type,signal->f_value);
746
- // write_range(value,first,last,ref.type,signal->f_value);
747
- // else
748
- // // write_range_no_z(value,first,last,signal->f_value->type,signal->f_value);
749
- // write_range_no_z(value,first,last,ref.type,signal->f_value);
750
767
  /* The base type is stored here to avoid allocating a new type each time.
751
768
  * It have an arbitrary base size a single element. */
752
769
  static TypeS baseT = { 1, 1 };
@@ -63,6 +63,7 @@ puts "b=#{b}"
63
63
  puts "c=#{c}"
64
64
  puts "d=#{d}"
65
65
  puts "ar=#{ar}"
66
+ puts "ar[1]=#{ar.value[1]}"
66
67
  puts "res0=#{res0}"
67
68
  puts "res1=#{res1}"
68
69
  puts "clk=#{clk}"
@@ -0,0 +1,31 @@
1
+ require 'HDLRuby/std/sequencer_sw'
2
+
3
+ include RubyHDL::High
4
+ using RubyHDL::High
5
+
6
+ # Sequencer for testing arithmetic computations.
7
+
8
+ sdef(:truc) do |m,n|
9
+ sreturn(n+m*2)
10
+ end
11
+
12
+ signed[32].inner :x,:y, :result
13
+ signed[32].inner :clk
14
+
15
+ my_seq = sequencer(clk) do
16
+ x <= 0
17
+ y <= 0
18
+ 100.stimes do
19
+ x <= x + 1
20
+ 10.times do
21
+ y <= truc(x,y)
22
+ end
23
+ end
24
+ result <= y
25
+ end
26
+
27
+ puts "code=" + my_seq.source
28
+
29
+ my_seq.()
30
+
31
+ puts "result=#{result}"
@@ -0,0 +1,48 @@
1
+
2
+ # A benchmark for testing the use of Ruby software code with array ports.
3
+ system :with_ruby_prog do
4
+ inner :clk
5
+ bit[8][-8].inner ar: [ _h00, _h01, _h04, _h09, _h10, _h19, _h24, _h31 ]
6
+
7
+ program(:ruby,:show) do
8
+ actport clk.posedge
9
+ arrayport arP: ar
10
+ code(proc do
11
+ def show
12
+ 8.times do |i|
13
+ val = RubyHDL.arP[i]
14
+ puts "# ar[#{i}]=#{val}"
15
+ RubyHDL.arP[i] = i+i
16
+ end
17
+ end
18
+ end)
19
+ end
20
+
21
+
22
+ timed do
23
+ clk <= 0
24
+ hprint("ar[0]=",ar[0],"\n")
25
+ hprint("ar[1]=",ar[1],"\n")
26
+ hprint("ar[2]=",ar[2],"\n")
27
+ hprint("ar[3]=",ar[3],"\n")
28
+ hprint("ar[4]=",ar[4],"\n")
29
+ hprint("ar[5]=",ar[5],"\n")
30
+ hprint("ar[6]=",ar[6],"\n")
31
+ hprint("ar[7]=",ar[7],"\n")
32
+ !10.ns
33
+ repeat(8) do
34
+ clk <= ~clk
35
+ !10.ns
36
+ end
37
+ !10.ns
38
+ hprint("ar[0]=",ar[0],"\n")
39
+ hprint("ar[1]=",ar[1],"\n")
40
+ hprint("ar[2]=",ar[2],"\n")
41
+ hprint("ar[3]=",ar[3],"\n")
42
+ hprint("ar[4]=",ar[4],"\n")
43
+ hprint("ar[5]=",ar[5],"\n")
44
+ hprint("ar[6]=",ar[6],"\n")
45
+ hprint("ar[7]=",ar[7],"\n")
46
+ !10.ns
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+
2
+ # A benchmark for testing the use of Ruby software code including a
3
+ # sequencer.
4
+ #
5
+ system :with_ruby_prog_seq do
6
+ inner :clk
7
+ [8].inner :count, :echo
8
+
9
+ program(:ruby,:echo) do
10
+ actport clk.posedge
11
+ inport inP: count
12
+ outport outP: echo
13
+ code(proc do
14
+ activate_sequencer_sw(binding)
15
+
16
+ $my_seq = nil
17
+
18
+ def echo
19
+ unless $my_seq then
20
+ [32].input :inP
21
+ [32].output :outP
22
+ $my_seq = sequencer do
23
+ sloop do
24
+ outP <= inP
25
+ sync
26
+ end
27
+ end
28
+ end
29
+ $my_seq.()
30
+ end
31
+ end)
32
+ end
33
+
34
+
35
+ timed do
36
+ clk <= 0
37
+ count <= 0
38
+ !10.ns
39
+ repeat(10) do
40
+ clk <= 1
41
+ hprint("echo=",echo,"\n")
42
+ !10.ns
43
+ count <= count + 1
44
+ clk <= 0
45
+ !10.ns
46
+ end
47
+
48
+ end
49
+ end
@@ -1466,6 +1466,11 @@ module HDLRuby::High
1466
1466
  sys.no_parent!
1467
1467
  systemT.scope.add_systemI(sys)
1468
1468
  end
1469
+ # Adds it programs.
1470
+ included.scope.each_program do |program|
1471
+ program.no_parent!
1472
+ systemT.scope.add_program(program)
1473
+ end
1469
1474
  # Adds its code.
1470
1475
  included.scope.each_code do |code|
1471
1476
  code.no_parent!
@@ -2579,6 +2584,8 @@ module HDLRuby::High
2579
2584
  self.each_inport { |p| progL.add_inport(p[0],p[1].to_low) }
2580
2585
  # Add the output signals references.
2581
2586
  self.each_outport { |p| progL.add_outport(p[0],p[1].to_low) }
2587
+ # Add the array signals references.
2588
+ self.each_arrayport { |p| progL.add_arrayport(p[0],p[1].to_low) }
2582
2589
  # Return the resulting program.
2583
2590
  return progL
2584
2591
  end
@@ -2602,6 +2609,11 @@ module HDLRuby::High
2602
2609
  def outport(ports = {})
2603
2610
  ports.each { |k,v| self.add_outport(k,v) }
2604
2611
  end
2612
+
2613
+ # Adds new array ports.
2614
+ def arrayport(ports = {})
2615
+ ports.each { |k,v| self.add_arrayport(k,v) }
2616
+ end
2605
2617
  end
2606
2618
 
2607
2619
 
@@ -5495,6 +5507,16 @@ module HDLRuby::High
5495
5507
 
5496
5508
  end
5497
5509
 
5510
+ # Require a Ruby file.
5511
+ def self.require_ruby(str)
5512
+ require(str)
5513
+ end
5514
+
5515
+ # Require a Ruby file from current path.
5516
+ def self.require_relative_ruby(str)
5517
+ require_relative(str)
5518
+ end
5519
+
5498
5520
  # Tell if already configured.
5499
5521
  $HDLRuby_configure = false
5500
5522
 
@@ -5540,4 +5562,20 @@ def self.configure_high
5540
5562
  def self.booting?
5541
5563
  false
5542
5564
  end
5565
+
5566
+
5543
5567
  end
5568
+
5569
+
5570
+
5571
+
5572
+ # Activate the software sequencer for Ruby code embedded in HDLRuby
5573
+ def activate_sequencer_sw(binding_context)
5574
+ eval <<~RUBY, binding_context
5575
+ alias require_ruby require
5576
+ require_ruby 'HDLRuby/std/sequencer_sw'
5577
+ include RubyHDL::High
5578
+ using RubyHDL::High
5579
+ RUBY
5580
+ end
5581
+
@@ -3019,6 +3019,7 @@ module HDLRuby::Low
3019
3019
  @codes = [] # The code files.
3020
3020
  @inports = {} # The input ports.
3021
3021
  @outports = {} # The output ports.
3022
+ @arrayports ={}# The array ports.
3022
3023
  end
3023
3024
 
3024
3025
  # Add a new activation port.
@@ -3063,6 +3064,20 @@ module HDLRuby::Low
3063
3064
  @outports[name] = sig
3064
3065
  end
3065
3066
 
3067
+ # Add a new array port.
3068
+ def add_arrayport(name, sig)
3069
+ # Ensure name is a symbol.
3070
+ unless name.is_a?(Symbol) then
3071
+ name = name.to_s.to_sym
3072
+ end
3073
+ # Ensure sig is a signal.
3074
+ unless sig.is_a?(SignalI) then
3075
+ raise AnyError, "Invalid class for a signal: #{sig.class}"
3076
+ end
3077
+ # Add the new port.
3078
+ @arrayports[name] = sig
3079
+ end
3080
+
3066
3081
 
3067
3082
  # Iterates over each activation event.
3068
3083
  #
@@ -3104,6 +3119,16 @@ module HDLRuby::Low
3104
3119
  @outports.each(&ruby_block)
3105
3120
  end
3106
3121
 
3122
+ # Iterate over each array port.
3123
+ #
3124
+ # Returns an enumerator if no ruby block is given.
3125
+ def each_arrayport(&ruby_block)
3126
+ # No block? Return an enumerator.
3127
+ return to_enum(:each_arrayport) unless ruby_block
3128
+ # A block is given, apply it.
3129
+ @arrayports.each(&ruby_block)
3130
+ end
3131
+
3107
3132
  end
3108
3133
 
3109
3134
 
@@ -559,7 +559,7 @@ module HDLRuby::High
559
559
  # Loads the code files.
560
560
  self.each_code do |code|
561
561
  if code.is_a?(Proc)
562
- TOPLEVEL_BINDING.eval(&code)
562
+ Object.instance_eval(&code)
563
563
  else
564
564
  Kernel.require("./"+code.to_s)
565
565
  end
@@ -572,6 +572,10 @@ module HDLRuby::High
572
572
  self.each_outport do |sym, sig|
573
573
  RubyHDL.outport(sym,sig.rcsignalI)
574
574
  end
575
+ # Add the array ports.
576
+ self.each_arrayport do |sym, sig|
577
+ RubyHDL.arrayport(sym,sig.rcsignalI)
578
+ end
575
579
  elsif self.language == :c then
576
580
  # Loads the code file: only the last one remains.
577
581
  self.each_code do |code|
@@ -601,6 +605,10 @@ module HDLRuby::High
601
605
  self.each_outport do |sym, sig|
602
606
  RCSim::CPorts[sym] = sig.rcsignalI
603
607
  end
608
+ # Add the array ports.
609
+ self.each_arrayport do |sym, sig|
610
+ RCSim::CPorts[sym] = sig.rcsignalI
611
+ end
604
612
  end
605
613
 
606
614
 
@@ -315,6 +315,21 @@ module HDLRuby::High::Std
315
315
  expr.seach.with_index(&ruby_block)
316
316
  end
317
317
 
318
+ # Does nothing: just for compatibility with the software
319
+ # implementation of sequencers.
320
+ def sync
321
+ end
322
+
323
+ # Tell if the sequencer ends it execution.
324
+ def alive?
325
+ return @fsm.cur_state_sig != self.end_state_value
326
+ end
327
+
328
+ # Resets the sequencer.
329
+ def reset!
330
+ @fsm.next_state_sig <= self.start_state_value
331
+ end
332
+
318
333
 
319
334
  # Fills the top user with the content of block +blk+.
320
335
  def fill_top_user(blk)