HDLRuby 2.7.11 → 2.8.1

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: 2c66f2d8f552623dabccc43ea54a7246d49eb42a6aaf0f6b8a1977e7675221ca
4
- data.tar.gz: 10f9b15022166b3fdb90a9a026653f3fec8b5a05f807e468dfed2d1c97d9adf7
3
+ metadata.gz: 90d139cd510b6600a32249a2e27969f6c415a49d9b26ba51ed84d20dcc82f2ba
4
+ data.tar.gz: b064d08cfbd46ae6fa4dffc7536a2dece4aed9c1c7588118502df79dd288c5bb
5
5
  SHA512:
6
- metadata.gz: 3c56c51a83e75ddd03d34d0c305a17595c362077010213e299baf60e8a7e0b52e745c6b8f9ada7db3c4931b99809376ffdc54f3f4bbb122e002a82419f39e7fb
7
- data.tar.gz: 3f056bd7523dea35b03188aa689a232afeadb7c24f7608f3207fc2479503081e1e1ce0a55c2ad3cc805721b60e7d559d464d9fa89a6f79f3f962388254eac6e7
6
+ metadata.gz: 40ced20f6723ff46f4c02a033c1d194e5ce267c75e7f2c22e6c70dd6f51ae9b530ebdc7dc7150970f3fefbf2ec4663c965a3a3fddf1c1b2369d6dac42317ba0c
7
+ data.tar.gz: 7782898ea6de9b5e42015f84dc56929ecd038baf42337c1f69f96bc644f0692ddd00ada0db0f9910b8ae7d93d2516ed4b3819c9f8735268d0a952f72b56bb37e
@@ -5,3 +5,25 @@ system :adder do |w|
5
5
 
6
6
  s <= x.as(bit[w+1]) + y
7
7
  end
8
+
9
+
10
+ # Testing the generic adder.
11
+ system :adder_bench do
12
+ width = 4
13
+ [width].inner :x,:y
14
+ [width+1].inner :z
15
+
16
+ adder(width).(:my_adder).(x,y,z)
17
+
18
+ timed do
19
+ x <= 0
20
+ y <= 0
21
+ !10.ns
22
+ x <= 1
23
+ !10.ns
24
+ y <= 1
25
+ !10.ns
26
+ x <= 15
27
+ !10.ns
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ # A simple generic adder
2
+ system :adder do |w|
3
+ [(w-1)..0].input :i,:j
4
+ [w..0].output :k
5
+
6
+ k <= i.as(bit[w+1]) + j
7
+ end
8
+
9
+ # A module embedding two generic adders.
10
+ system :two_adders do |w|
11
+ [w*2].input :x, :y
12
+ [(w+1)*2].output :z
13
+
14
+ adder(w).(:adderI0).(x[(w-1)..0],y[(w-1)..0],z[w..0])
15
+ adder(w).(:adderI1).(x[(w*2-1)..w],y[(w*2-1)..w],z[(w*2+1)..(w+1)])
16
+ end
17
+
18
+
19
+ # Testing the generic adder.
20
+ system :adder_bench do
21
+ width = 4
22
+ [width*2].inner :a,:b
23
+ [(width+1)*2].inner :c
24
+
25
+ two_adders(width).(:my_adders).(a,b,c)
26
+
27
+ timed do
28
+ a <= 0
29
+ b <= 0
30
+ !10.ns
31
+ a <= 1
32
+ !10.ns
33
+ b <= 1
34
+ !10.ns
35
+ a <= 255
36
+ !10.ns
37
+ b <= 128
38
+ !10.ns
39
+ end
40
+ end
@@ -6,7 +6,7 @@
6
6
  3.times do |i|
7
7
 
8
8
  # A simple D-FF
9
- system:"dff#{i}" do
9
+ system :"dff#{i}" do
10
10
  input :clk, :rst, :d
11
11
  output :q, :qb
12
12
 
@@ -0,0 +1,29 @@
1
+ # A test of def.
2
+ def lut84(content,addr)
3
+ bit[8][-4].inner tbl? => content.to_a
4
+ tbl![addr]
5
+ end
6
+
7
+
8
+ # A benchmark for testing the initialization of signals.
9
+ system :def_bench do
10
+
11
+ [2].inner :addr
12
+ [8].inner :val0, :val1
13
+
14
+ par do
15
+ val0 <= lut84([0,1,4,9],addr)
16
+ val1 <= lut84([0,1,4,9],3-addr)
17
+ end
18
+
19
+ timed do
20
+ addr <= 0
21
+ !10.ns
22
+ addr <= 1
23
+ !10.ns
24
+ addr <= 2
25
+ !10.ns
26
+ addr <= 3
27
+ !10.ns
28
+ end
29
+ end
@@ -4,60 +4,16 @@ include HDLRuby::High::Std
4
4
 
5
5
 
6
6
 
7
-
8
- # Implementation of a vivado partial reconfiguration system.
9
- reconf(:vivado_reconf) do |clk,rst|
10
-
11
- # Get access to the interface of the reconfigurable component.
12
- inputs = each_input
13
- outputs = each_output
14
- inouts = each_inout
15
-
16
- # Create the main system with the interface and a channel for
17
- # handling the reconfiguration.
18
- main = system do
19
- # Declares the inputs.
20
- inputs.each do |i|
21
- i.type.input(i.name)
22
- end
23
- # Declares the outputs.
24
- outputs.each do |o|
25
- o.type.output(o.name)
26
- end
27
- # Declares the inouts.
28
- inouts.each do |io|
29
- io.type.inout(io.name)
30
- end
31
- # An that's all: in vivado the main system is to be a black-box.
32
- end
33
-
34
- # And set it as the main system.
35
- set_main(main)
36
-
37
- # The switching circuit.
38
- # reconfer = vivado_reconfigurer :do_reconf # Will be that later
39
- # reconfer.clk <= clk
40
- # reconfer.rst <= rst
41
- reconfer = proc do |idx|
42
- puts "Instantiating reconfiguration circuits with #{idx}"
43
- end
44
-
45
- # Defines the reconfiguring procedure: switch to system idx.
46
- switcher do |idx,ruby_block|
47
- reconfer.call(idx)
48
- ruby_block.call
49
- end
50
-
51
- end
52
-
53
-
54
- # Some system that can be used for recponfiguration.
7
+ # Some system that can be used for reconfiguration.
55
8
  system :sys0 do
56
9
  input :clk,:rst
57
10
  input :d
58
11
  output :q
59
12
 
60
- q <= d
13
+ par(clk.posedge) do
14
+ hprint("sys0\n")
15
+ q <= d & ~rst
16
+ end
61
17
  end
62
18
 
63
19
  system :sys1 do
@@ -65,7 +21,10 @@ system :sys1 do
65
21
  input :d
66
22
  output :q
67
23
 
68
- (q <= d).at(clk.posedge)
24
+ par(clk.posedge, rst.posedge) do
25
+ hprint("sys1\n")
26
+ q <= d & ~rst
27
+ end
69
28
  end
70
29
 
71
30
  system :sys2 do
@@ -73,7 +32,10 @@ system :sys2 do
73
32
  input :d
74
33
  output :q
75
34
 
76
- (q <= d & ~rst).at(clk.posedge)
35
+ par(clk.posedge, rst.negedge) do
36
+ hprint("sys2\n")
37
+ q <= d & ~rst
38
+ end
77
39
  end
78
40
 
79
41
  # A system with a reconfifurable part.
@@ -81,23 +43,69 @@ system :with_reconf do
81
43
  input :clk,:rst
82
44
  input :d
83
45
  output :q
84
- [2].input :conf # The configuration number
85
-
86
- inner :wait_reconf
87
46
 
88
- # Create a reconfigurable component.
89
- vivado_reconf(clk,rst).(:my_reconf)
90
- # It is to be reconfigured to sys0, sys1 or sys2
91
- my_reconf.(sys0, sys1, sys2)
92
-
93
- # Connect the reconfigurable instance.
94
- my_reconf.instance.(clk,rst,d,q)
95
-
96
- par(clk.posedge) do
97
- hif(rst) { wait_reconf <= 0 }
98
- helsif(conf != 0 && my_reconf.index != conf && wait_reconf == 0) do
99
- wait_reconf <= 1
100
- my_reconf.switch(conf) { wait_reconf <= 0 }
47
+ # Instantiate the default configuration.
48
+ sys0(:my_dff).(clk,rst,d,q)
49
+
50
+ # Adds the additional configuration.
51
+ my_dff.choice(conf1: sys1, conf2: sys2)
52
+
53
+ timed do
54
+ clk <= 0
55
+ rst <= 0
56
+ d <= 0
57
+ !10.ns
58
+ clk <= 1
59
+ !10.ns
60
+ clk <= 0
61
+ rst <= 1
62
+ !10.ns
63
+ clk <= 1
64
+ !10.ns
65
+ clk <= 0
66
+ rst <= 0
67
+ !10.ns
68
+ 3.times do |i|
69
+ clk <= 1
70
+ !10.ns
71
+ clk <= 0
72
+ d <= 1
73
+ !10.ns
74
+ clk <= 1
75
+ !10.ns
76
+ clk <= 0
77
+ d <= 0
78
+ !10.ns
79
+ clk <= 1
80
+ my_dff.configure((i+1)%3)
81
+ !10.ns
82
+ clk <= 0
83
+ !10.ns
101
84
  end
85
+ clk <= 1
86
+ !10.ns
87
+ clk <= 0
88
+ d <= 1
89
+ !10.ns
90
+ clk <= 1
91
+ my_dff.configure(:conf1)
92
+ !10.ns
93
+ clk <= 0
94
+ d <= 0
95
+ !10.ns
96
+ clk <= 1
97
+ my_dff.configure(:conf2)
98
+ !10.ns
99
+ clk <= 0
100
+ d <= 1
101
+ !10.ns
102
+ clk <= 1
103
+ my_dff.configure(:my_dff)
104
+ !10.ns
105
+ clk <= 0
106
+ d <= 0
107
+ !10.ns
108
+ clk <= 1
109
+ !10.ns
102
110
  end
103
111
  end
@@ -0,0 +1,32 @@
1
+
2
+ # A benchmark for testing the terminate statement.
3
+ system :with_terminate do
4
+ [8].constant cst0: 127
5
+ constant cst1: _1
6
+ [8].inner sig0: _10000000
7
+ inner sig1: _1
8
+ [8].inner :sig2
9
+ [8].inner count: 0
10
+
11
+ timed do
12
+ !20.ns
13
+ 100.times do
14
+ count <= count + 1
15
+ !20.ns
16
+ end
17
+ end
18
+
19
+ timed do
20
+ !10.ns
21
+ sig2 <= cst0 + cst1
22
+ sig0 <= sig0 + sig1
23
+ !10.ns
24
+ sig2 <= sig2 + sig1
25
+ !10.ns
26
+ terminate
27
+ sig0 <= sig0 + sig0
28
+ !10.ns
29
+ sig0 <= sig0 + sig0
30
+ !10.ns
31
+ end
32
+ end
data/lib/HDLRuby/hdrcc.rb CHANGED
@@ -647,12 +647,19 @@ elsif $options[:clang] then
647
647
  init_visualizer = $options[:vcd] ? "init_vcd_visualizer" :
648
648
  "init_default_visualizer"
649
649
 
650
+ # Gather the system to generate and sort them in the right order
651
+ # to ensure references are generated before being used.
652
+ # Base: reverse order of the tree.
653
+ # Then, multiple configuration of a system instance must be
654
+ # reverversed so that the base configuration is generated first.
655
+ c_systems = $top_system.each_systemT_deep_ref
650
656
  # Generate the code of the main function.
651
657
  # HDLRuby start code
652
658
  $main << HDLRuby::Low::Low2C.main("hruby_simulator",
653
659
  init_visualizer,
654
660
  $top_system,
655
- $top_system.each_systemT_deep.to_a.reverse,$hnames)
661
+ c_systems,
662
+ $hnames)
656
663
  $main.close
657
664
 
658
665
  $top_system.each_systemT_deep do |systemT|
@@ -2119,6 +2119,54 @@ module HDLRuby::High
2119
2119
  self.eigen_extend(@systemT.public_namespace)
2120
2120
  end
2121
2121
 
2122
+ # Adds alternative system +systemT+
2123
+ def choice(configuration = {})
2124
+ # Process the argument.
2125
+ configuration.each do |k,v|
2126
+ k = k.to_sym
2127
+ unless v.is_a?(SystemT) then
2128
+ raise "Invalid class for a system type: #{v.class}"
2129
+ end
2130
+ # Create an eigen system.
2131
+ eigen = v.instantiate(HDLRuby.uniq_name(self.name)).systemT
2132
+ # Ensure its interface corresponds.
2133
+ my_signals = self.each_signal.to_a
2134
+ if (eigen.each_signal.with_index.find { |sig,i|
2135
+ !sig.eql?(my_signals[i])
2136
+ }) then
2137
+ raise "Invalid system for configuration: #{systemT.name}."
2138
+ end
2139
+ # Add it.
2140
+ # At the HDLRuby::High level
2141
+ @choices = { self.name => self.systemT } unless @choices
2142
+ @choices[k] = eigen
2143
+ # At the HDLRuby::Low level
2144
+ self.add_systemT(eigen)
2145
+ end
2146
+ end
2147
+
2148
+ # (Re)Configuration of system instance to systemT designated by +sys+.
2149
+ # +sys+ may be the index or the name of the configuration, the first
2150
+ # configuration being named by the systemI name.
2151
+ def configure(sys)
2152
+ if sys.respond_to?(:to_i) then
2153
+ # The argument is an index.
2154
+ # Create the (re)configuration node.
2155
+ High.top_user.add_statement(
2156
+ Configure.new(RefObject.new(RefThis.new,self),sys.to_i))
2157
+ else
2158
+ # The argument is a name (should be).
2159
+ # Get the index corresponding to the name.
2160
+ num = @choices.find_index { |k,_| k == sys.to_sym }
2161
+ unless num then
2162
+ raise "Invalid name for configuration: #{sys.to_s}"
2163
+ end
2164
+ # Create the (re)configuration node.
2165
+ High.top_user.add_statement(
2166
+ Configure.new(RefObject.new(RefThis.new,self),num))
2167
+ end
2168
+ end
2169
+
2122
2170
  # include Hmissing
2123
2171
 
2124
2172
  # Missing methods are looked for in the public namespace of the
@@ -2155,8 +2203,11 @@ module HDLRuby::High
2155
2203
  # systemIL.properties[:low2high] = self.hdr_id
2156
2204
  # self.properties[:high2low] = systemIL
2157
2205
  # Adds the other systemTs.
2158
- self.each_systemT do |systemT|
2159
- systemIL.add_systemT(systemT.to_low) unless systemT == self.systemT
2206
+ self.each_systemT do |systemTc|
2207
+ if systemTc != self.systemT
2208
+ systemTcL = systemTc.to_low
2209
+ systemIL.add_systemT(systemTcL)
2210
+ end
2160
2211
  end
2161
2212
  return systemIL
2162
2213
  end
@@ -2433,6 +2484,18 @@ module HDLRuby::High
2433
2484
  end
2434
2485
  end
2435
2486
 
2487
+ ##
2488
+ # Describes a timed terminate statement: not synthesizable!
2489
+ class TimeTerminate < Low::TimeTerminate
2490
+ include HStatement
2491
+
2492
+ # Converts the repeat statement to HDLRuby::Low.
2493
+ def to_low
2494
+ return HDLRuby::Low::TimeTerminate.new
2495
+ end
2496
+ end
2497
+
2498
+
2436
2499
 
2437
2500
  ##
2438
2501
  # Module giving high-level expression properties
@@ -3369,6 +3432,27 @@ module HDLRuby::High
3369
3432
  end
3370
3433
 
3371
3434
 
3435
+ ##
3436
+ # Describes a systemI (re)configure statement: not synthesizable!
3437
+ class Configure < Low::Configure
3438
+ High = HDLRuby::High
3439
+
3440
+ include HStatement
3441
+
3442
+ # Creates a new (re)configure statement for system instance refered
3443
+ # by +ref+ with system number +num+.
3444
+ def initialize(ref,num)
3445
+ super(ref,num)
3446
+ end
3447
+
3448
+ # Converts the connection to HDLRuby::Low.
3449
+ def to_low
3450
+ return HDLRuby::Low::Configure.new(self.ref.to_low, self.index)
3451
+ end
3452
+
3453
+ end
3454
+
3455
+
3372
3456
  ##
3373
3457
  # Describes a connection.
3374
3458
  class Connection < Low::Connection
@@ -3802,6 +3886,11 @@ module HDLRuby::High
3802
3886
  def hprint(*args)
3803
3887
  self.add_statement(Print.new(*args))
3804
3888
  end
3889
+
3890
+ # Terminate the simulation.
3891
+ def terminate
3892
+ self.add_statement(TimeTerminate.new)
3893
+ end
3805
3894
  end
3806
3895
 
3807
3896
 
@@ -165,6 +165,22 @@ module HDLRuby::Low
165
165
 
166
166
 
167
167
 
168
+ # Handling the (re)configuration.
169
+
170
+ # Gets the configuration wrapper if any.
171
+ def wrapper
172
+ return defined? @wrapper ? @wrapper : nil
173
+ end
174
+
175
+ # Sets the configuration wrapper to +systemT+.
176
+ def wrapper=(systemT)
177
+ unless systemT.is_a?(SystemT) then
178
+ raise "Invalid class for a wrapper system type: #{systemT}."
179
+ end
180
+ @wrapper = systemT
181
+ end
182
+
183
+
168
184
  # Handling the signals.
169
185
 
170
186
  # Adds input +signal+.
@@ -432,6 +448,27 @@ module HDLRuby::Low
432
448
  end
433
449
  end
434
450
  end
451
+
452
+ # Iterates over the systemT deeply if any in order of reference
453
+ # to ensure the refered elements are processed first.
454
+ #
455
+ # Returns an enumerator if no ruby block is given.
456
+ def each_systemT_deep_ref(&ruby_block)
457
+ # No ruby block? Return an enumerator.
458
+ return to_enum(:each_systemT_deep_ref) unless ruby_block
459
+ # A ruby block?
460
+ # Recurse on the systemT accessible through the instances.
461
+ self.scope.each_scope_deep do |scope|
462
+ scope.each_systemI do |systemI|
463
+ # systemI.systemT.each_systemT_deep(&ruby_block)
464
+ systemI.each_systemT do |systemT|
465
+ systemT.each_systemT_deep_ref(&ruby_block)
466
+ end
467
+ end
468
+ end
469
+ # Finally apply it to current.
470
+ ruby_block.call(self)
471
+ end
435
472
  end
436
473
 
437
474
 
@@ -2500,8 +2537,8 @@ module HDLRuby::Low
2500
2537
  # NOTE: an instance can actually represented muliple layers
2501
2538
  # of systems, the first one being the one actually instantiated
2502
2539
  # in the final RTL code.
2503
- # This layring can be used for describing software or partial
2504
- # reconfiguration.
2540
+ # This layering can be used for describing software or partial
2541
+ # (re)configuration.
2505
2542
  class SystemI
2506
2543
 
2507
2544
  include Hparent
@@ -2564,13 +2601,16 @@ module HDLRuby::Low
2564
2601
  @name = name.to_sym
2565
2602
  end
2566
2603
 
2567
- ## Adds a system layer.
2604
+ ## Adds a system configuration.
2568
2605
  def add_systemT(systemT)
2569
2606
  # puts "add_systemT #{systemT.name} to systemI #{self.name}"
2570
2607
  # Check and add the systemT.
2571
2608
  if !systemT.is_a?(SystemT) then
2572
2609
  raise AnyError, "Invalid class for a system type: #{systemT.class}"
2573
2610
  end
2611
+ # Set the base configuration of the added system.
2612
+ systemT.wrapper = self.systemT
2613
+ # Add it.
2574
2614
  @systemTs << systemT
2575
2615
  end
2576
2616
 
@@ -3781,6 +3821,93 @@ module HDLRuby::Low
3781
3821
  end
3782
3822
  end
3783
3823
  end
3824
+ end
3825
+
3826
+
3827
+ ##
3828
+ # Describes a system instance (re)configuration statement: not synthesizable!
3829
+ class Configure < Statement
3830
+
3831
+ # attr_reader :systemI, :systemT, :index
3832
+ attr_reader :ref, :index
3833
+
3834
+ # Creates a new (re)configure statement of system instance refered by
3835
+ # +ref+ with system number +index+
3836
+ def initialize(ref,index)
3837
+ super()
3838
+ # Process the arguments.
3839
+ index = index.to_i
3840
+ unless ref.is_a?(Ref) then
3841
+ raise "Invalid class for a reference: #{ref.class}."
3842
+ end
3843
+ # Sets the arguments.
3844
+ @ref = ref
3845
+ ref.parent = self
3846
+ @index = index
3847
+ # @systemT = systemI.each_systemT.to_a[index]
3848
+ # # Check the systemT is valid.
3849
+ # unless @systemT then
3850
+ # raise "Invalid configuration index: #{index}."
3851
+ # end
3852
+ end
3853
+
3854
+ # Comparison for hash: structural comparison.
3855
+ def eql?(obj)
3856
+ return false unless obj.is_a?(Configure)
3857
+ return false unless @ref.eql?(obj.ref)
3858
+ return false unless @index.eql?(obj.index)
3859
+ return true
3860
+ end
3861
+
3862
+ # Iterates over each object deeply.
3863
+ #
3864
+ # Returns an enumerator if no ruby block is given.
3865
+ def each_deep(&ruby_block)
3866
+ # No ruby block? Return an enumerator.
3867
+ return to_enum(:each_deep) unless ruby_block
3868
+ # A ruby block? First apply it to current.
3869
+ ruby_block.call(self)
3870
+ # Then apply on the reference.
3871
+ @ref.each_deep(&ruby_block)
3872
+ end
3873
+
3874
+ # Hash function.
3875
+ def hash
3876
+ return (@ref.hash + @index.hash).hash
3877
+ end
3878
+
3879
+ # Clones (deeply)
3880
+ def clone
3881
+ return Configure.new(@ref.clone,@index)
3882
+ end
3883
+
3884
+ # Iterates over the nodes deeply if any.
3885
+ def each_node_deep(&ruby_block)
3886
+ # No ruby block? Return an enumerator.
3887
+ return to_enum(:each_node_deep) unless ruby_block
3888
+ # A ruby block? First apply it to current.
3889
+ ruby_block.call(self)
3890
+ # And recurse on the reference.
3891
+ @ref.each_node_deep(&ruby_block)
3892
+ end
3893
+
3894
+ # Iterates over all the blocks contained in the current block.
3895
+ def each_block_deep(&ruby_block)
3896
+ # No ruby block? Return an enumerator.
3897
+ return to_enum(:each_block_deep) unless ruby_block
3898
+ # A ruby block?
3899
+ # Nothing more to do anyway.
3900
+ end
3901
+
3902
+ # Iterates over all the statements contained in the current block.
3903
+ def each_statement_deep(&ruby_block)
3904
+ # No ruby block? Return an enumerator.
3905
+ return to_enum(:each_statement_deep) unless ruby_block
3906
+ # A ruby block?
3907
+ # Apply it on self.
3908
+ ruby_block.call(self)
3909
+ # And that's all.
3910
+ end
3784
3911
 
3785
3912
  end
3786
3913
 
@@ -3989,6 +4116,82 @@ module HDLRuby::Low
3989
4116
  end
3990
4117
 
3991
4118
 
4119
+ ##
4120
+ # Describes a timed terminate statement: not synthesizable!
4121
+ class TimeTerminate < Statement
4122
+
4123
+ # Creates a new timed terminate statement that terminate execution.
4124
+ def initialize
4125
+ super()
4126
+ end
4127
+
4128
+ # Iterates over each object deeply.
4129
+ #
4130
+ # Returns an enumerator if no ruby block is given.
4131
+ def each_deep(&ruby_block)
4132
+ # No ruby block? Return an enumerator.
4133
+ return to_enum(:each_deep) unless ruby_block
4134
+ # A ruby block? First apply it to current.
4135
+ ruby_block.call(self)
4136
+ # And that's all.
4137
+ end
4138
+
4139
+ # Iterates over all the nodes.
4140
+ def each_node(&ruby_block)
4141
+ # No ruby block? Return an enumerator.
4142
+ return to_enum(:each_node) unless ruby_block
4143
+ # A ruby block?
4144
+ # Nothing to do anyway.
4145
+ end
4146
+
4147
+ # Iterates over all the nodes deeply.
4148
+ def each_node_deep(&ruby_block)
4149
+ # No ruby block? Return an enumerator.
4150
+ return to_enum(:each_node_deep) unless ruby_block
4151
+ # A ruby block?
4152
+ # Apply of current node.
4153
+ ruby_block.call(self)
4154
+ # And that's all.
4155
+ end
4156
+
4157
+ # Iterates over all the statements deeply.
4158
+ def each_statement_deep(&ruby_block)
4159
+ # No ruby block? Return an enumerator.
4160
+ return to_enum(:each_statement_deep) unless ruby_block
4161
+ # A ruby block?
4162
+ # Apply of current node.
4163
+ ruby_block.call(self)
4164
+ # And that's all.
4165
+ end
4166
+
4167
+ # Iterates over all the blocks contained in the current block.
4168
+ def each_block_deep(&ruby_block)
4169
+ # No ruby block? Return an enumerator.
4170
+ return to_enum(:each_block_deep) unless ruby_block
4171
+ # A ruby block?
4172
+ # Nothing to do anyway.
4173
+ end
4174
+
4175
+ # Comparison for hash: structural comparison.
4176
+ def eql?(obj)
4177
+ return false unless obj.is_a?(TimeTerminate)
4178
+ return true
4179
+ end
4180
+
4181
+ # Hash function.
4182
+ def hash
4183
+ return TimeTerminate.hash
4184
+ end
4185
+
4186
+ # Clones the TimeRepeat (deeply)
4187
+ def clone
4188
+ return TimeTerminate.new
4189
+ end
4190
+ end
4191
+
4192
+
4193
+
4194
+
3992
4195
  ##
3993
4196
  # Describes a block.
3994
4197
  class Block < Statement
@@ -135,6 +135,8 @@ module HDLRuby::Low
135
135
  objs.each { |obj| res << " " << Low2C.make_name(obj) << "();\n" }
136
136
  # Sets the top systemT.
137
137
  res << " top_system = " << Low2C.obj_name(top) << ";\n"
138
+ # Enable it.
139
+ res << " set_enable_system(top_system,1);\n"
138
140
  # Starts the simulation.
139
141
  res<< " hruby_sim_core(\"#{name}\",#{init_visualizer},-1);\n"
140
142
  # Close the main.
@@ -170,6 +172,7 @@ module HDLRuby::Low
170
172
  # is the list of extra h files to include.
171
173
  # def to_c(level = 0, *hnames)
172
174
  def to_c(res, level = 0, *hnames)
175
+ # puts "SystemT.to_c with name=#{Low2C.obj_name(self)}#{@wrapper ? " and wrapper=#{Low2C.obj_name(@wrapper)}" : ""}"
173
176
  # The header
174
177
  # res = Low2C.includes(*hnames)
175
178
  res << Low2C.includes(*hnames)
@@ -179,7 +182,16 @@ module HDLRuby::Low
179
182
 
180
183
  # Generate the signals of the system.
181
184
  # self.each_signal { |signal| signal.to_c(level) }
182
- self.each_signal { |signal| signal.to_c(res,level) }
185
+ if ((defined? @wrapper) && @wrapper) then
186
+ # It is a reconfiguring system, alias the signals.
187
+ wrap_signals = @wrapper.each_signal.to_a
188
+ self.each_signal.with_index do |signal,i|
189
+ signal.to_c_alias(res,wrap_signals[i],level)
190
+ end
191
+ else
192
+ # It is a single system, default generation.
193
+ self.each_signal { |signal| signal.to_c(res,level) }
194
+ end
183
195
 
184
196
  # Generate the code for all the blocks included in the system.
185
197
  self.scope.each_scope_deep do |scope|
@@ -686,6 +698,10 @@ module HDLRuby::Low
686
698
  res << "behavior->owner = NULL;\n"
687
699
  end
688
700
 
701
+ # Set the behavior as not enabled. */
702
+ res << " " * (level+1)*3
703
+ res << "behavior->enabled = 0;\n"
704
+
689
705
  # Set the behavior as inactive. */
690
706
  res << " " * (level+1)*3
691
707
  res << "behavior->activated = 0;\n"
@@ -842,11 +858,8 @@ module HDLRuby::Low
842
858
  # +level+ is the hierachical level of the object.
843
859
  # def to_c(level = 0)
844
860
  def to_c(res,level = 0)
845
- # The resulting string.
846
- # res = ""
847
-
861
+ # puts "Signal.to_c with name: #{Low2C.obj_name(self)}"
848
862
  # Declare the global variable holding the signal.
849
- # res << "SignalI #{self.to_c_signal(level+1)};\n\n"
850
863
  res << "SignalI "
851
864
  self.to_c_signal(res,level+1)
852
865
  res << ";\n\n"
@@ -854,6 +867,7 @@ module HDLRuby::Low
854
867
  # The header of the signal generation.
855
868
  res << " " * level*3
856
869
  res << "SignalI " << Low2C.make_name(self) << "() {\n"
870
+
857
871
  # res << " " * level*3
858
872
  # res << "Value l,r,d;\n"
859
873
  # res << " " * (level+1)*3
@@ -866,7 +880,6 @@ module HDLRuby::Low
866
880
  # Sets the global variable of the signal.
867
881
  res << "\n"
868
882
  res << " " * (level+1)*3
869
- # res << "#{self.to_c_signal(level+1)} = signalI;\n"
870
883
  self.to_c_signal(res,level+1)
871
884
  res << " = signalI;\n"
872
885
 
@@ -958,6 +971,43 @@ module HDLRuby::Low
958
971
 
959
972
  return res;
960
973
  end
974
+
975
+ ## Generates the C text of the equivalent HDLRuby code in case
976
+ # the signals is actually an alias to another signal.
977
+ # +other+ is the target signal of the alias.
978
+ # +level+ is the hierachical level of the object.
979
+ def to_c_alias(res,target,level = 0)
980
+ # puts "Signal.to_c_alias with name: #{Low2C.obj_name(self)}"
981
+ # The resulting string.
982
+ # res = ""
983
+
984
+ # Declare the global variable holding the signal.
985
+ res << "SignalI "
986
+ self.to_c_signal(res,level+1)
987
+ res << ";\n\n"
988
+
989
+ # The header of the signal generation.
990
+ res << " " * level*3
991
+ res << "SignalI " << Low2C.make_name(self) << "() {\n"
992
+
993
+ res << "SignalI signalI = #{Low2C.obj_name(target)};\n"
994
+
995
+ # Sets the global variable of the signal.
996
+ res << "\n"
997
+ res << " " * (level+1)*3
998
+ self.to_c_signal(res,level+1)
999
+ res << " = signalI;\n"
1000
+
1001
+ # Generate the return of the signal.
1002
+ res << "\n"
1003
+ res << " " * (level+1)*3
1004
+ res << "return signalI;\n"
1005
+
1006
+ # Close the signal.
1007
+ res << " " * level*3
1008
+ res << "};\n\n"
1009
+ return res
1010
+ end
961
1011
  end
962
1012
 
963
1013
 
@@ -999,9 +1049,22 @@ module HDLRuby::Low
999
1049
  # Set the name
1000
1050
  res << " " * (level+1)*3
1001
1051
  res << "systemI->name = \"#{self.name}\";\n"
1002
- # Set the type.
1052
+ # # Set the type.
1053
+ # res << " " * (level+1)*3
1054
+ # res << "systemI->system = " << Low2C.obj_name(self.systemT) << ";\n"
1055
+ # Set the systems.
1056
+ num_sys = self.each_systemT.to_a.size
1003
1057
  res << " " * (level+1)*3
1004
- res << "systemI->system = " << Low2C.obj_name(self.systemT) << ";\n"
1058
+ res << "systemI->num_systems = #{num_sys};\n"
1059
+ res << " " * (level+1)*3
1060
+ res << "systemI->systems = calloc(sizeof(SystemT), #{num_sys});\n"
1061
+ self.each_systemT.with_index do |sysT,i|
1062
+ res << " " * (level+1)*3
1063
+ res << "systemI->systems[#{i}] = #{Low2C.obj_name(sysT)};\n"
1064
+ end
1065
+
1066
+ # Configure the instance to current systemT.
1067
+ res << (" " * (level*3)) << "configure(systemI,0);\n"
1005
1068
 
1006
1069
  # Generate the return of the signal.
1007
1070
  res << "\n"
@@ -1100,6 +1163,10 @@ module HDLRuby::Low
1100
1163
  res << "code->owner = NULL;\n"
1101
1164
  end
1102
1165
 
1166
+ # Set the code as enabled (for now, may change in a near future). */
1167
+ res << " " * (level+1)*3
1168
+ res << "code->enabled = 1;\n"
1169
+
1103
1170
  # Set the code as inactive. */
1104
1171
  res << " " * (level+1)*3
1105
1172
  res << "code->activated = 0;\n"
@@ -1392,6 +1459,28 @@ module HDLRuby::Low
1392
1459
  end
1393
1460
  end
1394
1461
 
1462
+ ## Extends the TimeTerminate class with generation of C text.
1463
+ class TimeTerminate
1464
+
1465
+ # Generates the C text of the equivalent HDLRuby code.
1466
+ # +level+ is the hierachical level of the object.
1467
+ def to_c(res,level = 0)
1468
+ # Save the value pool state.
1469
+ res << (" " * (level*3)) << "terminate();\n"
1470
+ end
1471
+ end
1472
+
1473
+ ## Extends the Configure class with generation of C text.
1474
+ class Configure
1475
+
1476
+ # Generates the C text of the equivalent HDLRuby code.
1477
+ # +level+ is the hierachical level of the object.
1478
+ def to_c(res,level = 0)
1479
+ # Save the value pool state.
1480
+ res << (" " * (level*3)) << "configure(#{Low2C.obj_name(self.ref.resolve)},#{self.index});\n"
1481
+ end
1482
+ end
1483
+
1395
1484
 
1396
1485
  ## Extends the If class with generation of C text.
1397
1486
  class If
@@ -925,6 +925,18 @@ module HDLRuby::Low
925
925
  end.join(" & ") + ";\n"
926
926
  end
927
927
  end
928
+
929
+ ## Extends the TimeTerminate class with generation of HDLRuby::High text.
930
+ class TimeTerminate
931
+
932
+ # Generates the text of the equivalent HDLRuby::High code.
933
+ # +vars+ is the list of the variables and
934
+ # +level+ is the hierachical level of the object.
935
+ def to_vhdl(vars,level = 0)
936
+ # Generate a report statement.
937
+ return " " * (level*3) + "finish;\n"
938
+ end
939
+ end
928
940
 
929
941
  ## Extends the If class with generation of HDLRuby::High text.
930
942
  class If
@@ -75,6 +75,18 @@ module HDLRuby::Low
75
75
  end
76
76
  end
77
77
 
78
+
79
+ ## Extends the TimeTerminate class with functionality for converting booleans
80
+ # in assignments to select operators.
81
+ class TimeTerminate
82
+
83
+ # Converts booleans in assignments to select operators.
84
+ def boolean_in_assign2select!
85
+ # Nothing to do.
86
+ return self
87
+ end
88
+ end
89
+
78
90
 
79
91
  ## Extends the If class with functionality for converting booleans
80
92
  # in assignments to select operators.
@@ -71,7 +71,7 @@ module HDLRuby::Low
71
71
  class Statement
72
72
  # Explicit the types conversions in the statement.
73
73
  def explicit_types!
74
- raise "Should implement explicit_types for class #{self.class}."
74
+ raise "Should implement explicit_types! for class #{self.class}."
75
75
  end
76
76
  end
77
77
 
@@ -98,7 +98,26 @@ module HDLRuby::Low
98
98
  self.map_args!(&:explicit_types)
99
99
  return self
100
100
  end
101
+ end
102
+
103
+
104
+ ## Extends the Configure class with fixing of types and constants.
105
+ class Configure
106
+ # Explicit the types conversions in the statement.
107
+ def explicit_types!
108
+ # Nothing to do.
109
+ return self
110
+ end
111
+ end
101
112
 
113
+
114
+ ## Extends the TimeTerminate class with fixing of types and constants.
115
+ class TimeTerminate
116
+ # Explicit the types conversions in the statement.
117
+ def explicit_types!
118
+ # Nothing to do.
119
+ return self
120
+ end
102
121
  end
103
122
 
104
123
 
@@ -242,7 +242,7 @@ module HDLRuby::Low
242
242
  parent = parent.parent
243
243
  end
244
244
  # Not found.
245
- # puts "Not found!"
245
+ puts "Not found!"
246
246
  return nil
247
247
  end
248
248
  end
@@ -163,7 +163,7 @@ module HDLRuby::Low
163
163
  end
164
164
  end
165
165
 
166
- ## Extends the String class with functionality for converting select
166
+ ## Extends the Print class with functionality for converting select
167
167
  # expressions to case statements.
168
168
  class Print
169
169
  # Extract the Select expressions.
@@ -175,6 +175,16 @@ module HDLRuby::Low
175
175
  return selects
176
176
  end
177
177
  end
178
+
179
+ ## Extends the TimeTerminate class with functionality for converting select
180
+ # expressions to case statements.
181
+ class TimeTerminate
182
+ # Extract the Select expressions.
183
+ def extract_selects!
184
+ # Nothing to extract.
185
+ return []
186
+ end
187
+ end
178
188
 
179
189
  ## Extends the If class with functionality for converting select
180
190
  # expressions to case statements.
@@ -171,7 +171,7 @@ module HDLRuby::Low
171
171
 
172
172
  # Enhance Print with generation of verilog code.
173
173
  class Print
174
- # Converts the system to Verilog code.
174
+ # Converts the print to Verilog code.
175
175
  def to_verilog(spc = 3)
176
176
  code = "#{" " * spc}$write(#{self.each_arg.map do |arg|
177
177
  arg.to_verilog
@@ -180,6 +180,14 @@ module HDLRuby::Low
180
180
  end
181
181
  end
182
182
 
183
+ # Enhance TimeTerminate with generation of verilog code.
184
+ class TimeTerminate
185
+ # Converts the terminate to Verilog code.
186
+ def to_verilog(spc = 3)
187
+ return "#{" " * spc}$finish;"
188
+ end
189
+ end
190
+
183
191
  # To scheduling to the Block.
184
192
  # Enhance Block with generation of verilog code.
185
193
  class Block
@@ -467,7 +467,10 @@ typedef struct SystemIS_ {
467
467
  Object owner; /* The owner if any. */
468
468
 
469
469
  char* name; /* The name of the signal. */
470
- SystemT system; /* The instantiated system. */
470
+ SystemT system; /* The currently instantiated system. */
471
+
472
+ int num_systems; /* The number of systems possibly instantiated here. */
473
+ SystemT* systems; /* The systems possibly instantiated here. */
471
474
  } SystemIS;
472
475
 
473
476
 
@@ -499,6 +502,8 @@ typedef struct BehaviorS_ {
499
502
  Event* events; /* The events of the behavior. */
500
503
  Block block; /* The block of the behavior. */
501
504
 
505
+ int enabled; /* Tells if the behavior is enabled or not. */
506
+
502
507
  int activated; /* Tells if the behavior is activated or not. */
503
508
 
504
509
  int timed; /* Tell if the behavior is timed or not:
@@ -519,6 +524,8 @@ typedef struct CodeS_ {
519
524
  Event* events; /* The events of the behavior. */
520
525
  void (*function)(); /* The function to execute for the code. */
521
526
 
527
+ int enabled; /* Tells if the behavior is enabled or not. */
528
+
522
529
  int activated; /* Tells if the code is activated or not. */
523
530
  } CodeS;
524
531
 
@@ -623,6 +630,16 @@ extern unsigned long long make_delay(int value, Unit unit);
623
630
  * @param func function to applie on each signal. */
624
631
  extern void each_all_signal(void (*func)(SignalI));
625
632
 
633
+
634
+ /** Configure a system instance.
635
+ * @param systemI the system instance to configure.
636
+ * @param idx the index of the target system. */
637
+ extern void configure(SystemI systemI, int idx);
638
+
639
+
640
+ /** Terminates the simulation. */
641
+ extern void terminate();
642
+
626
643
  /* Interface to the visualization engine. */
627
644
 
628
645
  typedef struct {
@@ -701,6 +718,11 @@ extern void init_vcd_visualizer(char* name);
701
718
 
702
719
  /* The interface to the simulator core. */
703
720
 
721
+ /** Sets the enable status of the behaviors of a system type.
722
+ * @param systemT the system type to process.
723
+ * @param status the enable status. */
724
+ extern void set_enable_system(SystemT systemT, int status);
725
+
704
726
  /** The simulation core function.
705
727
  * @param name the name of the simulation.
706
728
  * @param init_vizualizer the vizualizer engine initializer.
@@ -253,8 +253,8 @@ void hruby_sim_update_signals() {
253
253
  if (obj->kind == BEHAVIOR) {
254
254
  /* Behavior case. */
255
255
  Behavior beh = (Behavior)obj;
256
- /* Is the code really activated? */
257
- if (beh->activated) {
256
+ /* Is the code really enabled and activated? */
257
+ if (beh->enabled && beh->activated) {
258
258
  /* Yes, execute it. */
259
259
  beh->block->function();
260
260
  /* And deactivate it. */
@@ -264,7 +264,7 @@ void hruby_sim_update_signals() {
264
264
  /* Other code case. */
265
265
  Code cod = (Code)obj;
266
266
  /* Is the code really activated? */
267
- if (cod->activated) {
267
+ if (cod->enabled && cod->activated) {
268
268
  /* Yes, execute it. */
269
269
  cod->function();
270
270
  /* And deactivate it. */
@@ -294,6 +294,35 @@ void hruby_sim_advance_time() {
294
294
  }
295
295
 
296
296
 
297
+ /** Sets the enamble status of the behaviors of a scope.
298
+ * @param scope the scope to process.
299
+ * @param status the enable status. */
300
+ static void set_enable_scope(Scope scope, int status) {
301
+ int i;
302
+ int num_beh = scope->num_behaviors;
303
+ Behavior* behs = scope->behaviors;
304
+ int num_scp = scope->num_scopes;
305
+ Scope* scps = scope->scopes;
306
+
307
+ /* Enable the behaviors. */
308
+ for(i=0; i<num_beh; ++i) {
309
+ behs[i]->enabled = status;
310
+ }
311
+
312
+ /* Recurse on the sub scopes. */
313
+ for(i=0; i<num_scp; ++i) {
314
+ set_enable_scope(scps[i],status);
315
+ }
316
+ }
317
+
318
+ /** Sets the enable status of the behaviors of a system type.
319
+ * @param systemT the system type to process.
320
+ * @param status the enable status. */
321
+ void set_enable_system(SystemT systemT, int status) {
322
+ set_enable_scope(systemT->scope,status);
323
+ }
324
+
325
+
297
326
  /** Activates a behavior.
298
327
  * @param behavior the behavior to activate. */
299
328
  void activate_behavior(Behavior behavior) {
@@ -359,7 +388,8 @@ void* behavior_run(void* arg) {
359
388
  pthread_mutex_unlock(&hruby_sim_mutex);
360
389
  // printf("#2\n");
361
390
  /* Now can start the execution of the behavior. */
362
- behavior->block->function();
391
+ if (behavior->enabled)
392
+ behavior->block->function();
363
393
  // printf("#3\n");
364
394
  /* Now can start the execution of the behavior. */
365
395
  /* Stops the behavior. */
@@ -635,11 +665,35 @@ unsigned long long make_delay(int value, Unit unit) {
635
665
 
636
666
 
637
667
 
638
- /* Iterate over all the signals.
639
- * @param func function to applie on each signal. */
668
+ /** Iterates over all the signals.
669
+ * @param func function to applie on each signal. */
640
670
  void each_all_signal(void (*func)(SignalI)) {
641
671
  int i;
642
672
  for(i = 0; i<num_all_signals; ++i) {
643
673
  func(all_signals[i]);
644
674
  }
645
675
  }
676
+
677
+
678
+ /** Configure a system instance.
679
+ * @param systemI the system instance to configure.
680
+ * @param idx the index of the target system. */
681
+ void configure(SystemI systemI, int idx) {
682
+ int i;
683
+ // printf("Configure to: %i\n",idx);
684
+ /* Sets the current system type. */
685
+ systemI->system = systemI->systems[idx];
686
+ /* Disable all the behaviors of the system instance. */
687
+ for(i=0; i<systemI->num_systems; ++i) {
688
+ if (i != idx)
689
+ set_enable_system(systemI->systems[i],0);
690
+ }
691
+ /* Enable the current system. */
692
+ set_enable_system(systemI->systems[idx],1);
693
+ }
694
+
695
+
696
+ /** Terminates the simulation. */
697
+ void terminate() {
698
+ exit(0);
699
+ }
@@ -85,7 +85,7 @@ static void vcd_print_name(Object object) {
85
85
  vcd_print("%s",name);
86
86
  } else {
87
87
  /* No name, use the address of the object as name generator.*/
88
- vcd_print("$%p",(void*)object);
88
+ vcd_print("x$%p",(void*)object);
89
89
  }
90
90
  break;
91
91
  default: /* Nothing to do */
@@ -8,6 +8,9 @@ module HDLRuby::High::Std
8
8
  ## Describes a high-level reconfigurable component type.
9
9
  class ReconfT
10
10
 
11
+ extend Gem::Deprecate
12
+ deprecate :initialize, Configure, 2022, 3
13
+
11
14
  # The name of the reconfigurable component type.
12
15
  attr_reader :name
13
16
 
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.7.11"
2
+ VERSION = "2.8.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: HDLRuby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.11
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-01 00:00:00.000000000 Z
11
+ date: 2022-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,6 +76,7 @@ files:
76
76
  - lib/HDLRuby/hdr_samples/adder_assign_error.rb
77
77
  - lib/HDLRuby/hdr_samples/adder_bench.rb
78
78
  - lib/HDLRuby/hdr_samples/adder_gen.rb
79
+ - lib/HDLRuby/hdr_samples/adder_gen_gen.rb
79
80
  - lib/HDLRuby/hdr_samples/adder_kadai.rb
80
81
  - lib/HDLRuby/hdr_samples/adder_nodef_error.rb
81
82
  - lib/HDLRuby/hdr_samples/addsub.rb
@@ -150,6 +151,7 @@ files:
150
151
  - lib/HDLRuby/hdr_samples/with_connector.rb
151
152
  - lib/HDLRuby/hdr_samples/with_connector_memory.rb
152
153
  - lib/HDLRuby/hdr_samples/with_decoder.rb
154
+ - lib/HDLRuby/hdr_samples/with_def.rb
153
155
  - lib/HDLRuby/hdr_samples/with_fixpoint.rb
154
156
  - lib/HDLRuby/hdr_samples/with_fsm.rb
155
157
  - lib/HDLRuby/hdr_samples/with_function_generator.rb
@@ -165,6 +167,7 @@ files:
165
167
  - lib/HDLRuby/hdr_samples/with_ref_array.rb
166
168
  - lib/HDLRuby/hdr_samples/with_str2value.rb
167
169
  - lib/HDLRuby/hdr_samples/with_subsums.rb
170
+ - lib/HDLRuby/hdr_samples/with_terminate.rb
168
171
  - lib/HDLRuby/hdr_samples/with_to_a.rb
169
172
  - lib/HDLRuby/hdr_samples/with_to_array.rb
170
173
  - lib/HDLRuby/hdr_samples/with_values.rb