HDLRuby 2.7.11 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
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