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 +4 -4
- data/README.md +83 -5
- data/ext/hruby_sim/hruby_rcsim_build.c +47 -2
- data/ext/hruby_sim/hruby_sim.h +8 -0
- data/ext/hruby_sim/hruby_sim_calc.c +3 -2
- data/ext/hruby_sim/hruby_sim_core.c +24 -7
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby.rb +1 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby_function.rb +31 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_array.rb +48 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_sequencer.rb +49 -0
- data/lib/HDLRuby/hruby_high.rb +38 -0
- data/lib/HDLRuby/hruby_low.rb +25 -0
- data/lib/HDLRuby/hruby_rcsim.rb +9 -1
- data/lib/HDLRuby/std/sequencer.rb +15 -0
- data/lib/HDLRuby/std/sequencer_sw.rb +497 -112
- data/lib/HDLRuby/version.rb +1 -1
- data/lib/rubyHDL.rb +26 -0
- data/tuto/tutorial_sw.html +6 -0
- data/tuto/tutorial_sw.md +12 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78d08a6a222a4f33398c1d92e8b1f7d9462597b22ea2c48306318fb3e3e9c82d
|
4
|
+
data.tar.gz: 4a52c34a1355369260b0c162df38b7714ad1cedf4ed56ab7bc023eb01d2b7e40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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: [
|
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
|
-
|
3972
|
+
text('puts "Hello"')
|
3926
3973
|
end
|
3927
3974
|
end.()
|
3928
3975
|
```
|
3929
3976
|
|
3930
|
-
Both method are functionally equivalent. However, the first is
|
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
|
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
|
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
|
}
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
@@ -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
|
-
|
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
|
-
|
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 };
|
@@ -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
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -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
|
+
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -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
|
|
data/lib/HDLRuby/hruby_rcsim.rb
CHANGED
@@ -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
|
-
|
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)
|