HDLRuby 2.1.2 → 2.1.5

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.
@@ -0,0 +1,29 @@
1
+ require 'HDLRuby'
2
+
3
+ configure_high
4
+
5
+
6
+ # A example of behavior with some unshifted statements in the top block
7
+ # of a behavior.
8
+ system :with_top_unshift do
9
+ [15..0].input :x,:y, :clk
10
+ [16..0].inner :w0,:w1
11
+ [16..0].output :o
12
+
13
+ seq(clk.posedge) do
14
+ w0 <= x + y
15
+ par do
16
+ w1 <= w0 * x
17
+ top_block.unshift { o <= w1 + y }
18
+ end
19
+ end
20
+ end
21
+
22
+ # Instantiate it for checking.
23
+ with_top_unshift :with_top_unshiftI
24
+
25
+ # Generate the low level representation.
26
+ low = with_top_unshiftI.systemT.to_low
27
+
28
+ # Displays it
29
+ puts low.to_yaml
@@ -0,0 +1,25 @@
1
+ require 'HDLRuby'
2
+
3
+ configure_high
4
+
5
+
6
+ # A example of behavior with some unshifted statements in a block.
7
+ system :with_unshift do
8
+ [15..0].input :x,:y, :clk
9
+ [16..0].inner :w
10
+ [16..0].output :o
11
+
12
+ seq(clk.posedge) do
13
+ w <= x + y
14
+ unshift { o <= w + y }
15
+ end
16
+ end
17
+
18
+ # Instantiate it for checking.
19
+ with_unshift :with_unshiftI
20
+
21
+ # Generate the low level representation.
22
+ low = with_unshiftI.systemT.to_low
23
+
24
+ # Displays it
25
+ puts low.to_yaml
@@ -1187,6 +1187,11 @@ module HDLRuby::High
1187
1187
  end
1188
1188
 
1189
1189
 
1190
+ # Gets the current system.
1191
+ def cur_system
1192
+ return HDLRuby::High.cur_system
1193
+ end
1194
+
1190
1195
  include Hmux
1191
1196
 
1192
1197
  # Fills a low level scope with self's contents.
@@ -2321,6 +2326,41 @@ module HDLRuby::High
2321
2326
  return Cast.new(type.to_type,self.to_expr)
2322
2327
  end
2323
2328
 
2329
+ # Casts to a bit vector type.
2330
+ def to_bit
2331
+ return self.as(bit[self.width])
2332
+ end
2333
+
2334
+ # Casts to an unsigned bit vector type.
2335
+ def to_unsigned
2336
+ return self.as(unsigned[self.width])
2337
+ end
2338
+
2339
+ # Casts to a signed bit vector type.
2340
+ def to_unsigned
2341
+ return self.as(signed[self.width])
2342
+ end
2343
+
2344
+ # Extends on the left to +n+ bits filling with +v+ bit values.
2345
+ def ljust(n,v)
2346
+ return [(v.to_s * (n-self.width)).to_expr, self]
2347
+ end
2348
+
2349
+ # Extends on the right to +n+ bits filling with +v+ bit values.
2350
+ def rjust(n,v)
2351
+ return [self, (v.to_s * (n-self.width)).to_expr]
2352
+ end
2353
+
2354
+ # Extends on the left to +n+ bits filling with 0.
2355
+ def zext(n)
2356
+ return self.ljust(n,0)
2357
+ end
2358
+
2359
+ # Extends on the left to +n+ bits preserving the signe.
2360
+ def sext(n)
2361
+ return self.ljust(self[-1])
2362
+ end
2363
+
2324
2364
  # Gets the origin method for operation +op+.
2325
2365
  def self.orig_operator(op)
2326
2366
  return (op.to_s + "_orig").to_sym
@@ -2342,6 +2382,26 @@ module HDLRuby::High
2342
2382
  define_method(orig_operator(operator),&meth)
2343
2383
  end
2344
2384
 
2385
+ # Left shift of +n+ bits.
2386
+ def ls(n)
2387
+ return self << n
2388
+ end
2389
+
2390
+ # Right shift of +n+ bits.
2391
+ def rs(n)
2392
+ return self >> n
2393
+ end
2394
+
2395
+ # Left rotate of +n+ bits.
2396
+ def lr(n)
2397
+ return [self[-(n+1)..0], self[-1..-(n)]]
2398
+ end
2399
+
2400
+ # Right rotate of +n+ bits.
2401
+ def rr(n)
2402
+ return [self[(n-1)..0], self[-1..n]]
2403
+ end
2404
+
2345
2405
  # Coerce by forcing convertion of obj to expression.
2346
2406
  def coerce(obj)
2347
2407
  if obj.is_a?(HDLRuby::Low::Expression) then
@@ -2806,10 +2866,10 @@ module HDLRuby::High
2806
2866
  return High.cur_behavior
2807
2867
  end
2808
2868
 
2809
- # Gets the enclosing block if any.
2810
- def block
2811
- return High.cur_block
2812
- end
2869
+ # # Gets the enclosing block if any.
2870
+ # def block
2871
+ # return High.cur_block
2872
+ # end
2813
2873
 
2814
2874
  # Converts the this reference to HDLRuby::Low.
2815
2875
  def to_low
@@ -3182,13 +3242,50 @@ module HDLRuby::High
3182
3242
  self.add_block(self.mode,name,&ruby_block)
3183
3243
  end
3184
3244
 
3185
- # Get the current mode of the block.
3186
- #
3187
- # NOTE: for name coherency purpose only.
3188
- def block
3189
- return self.mode
3245
+ # Adds statements at the top of the block.
3246
+ def unshift(&ruby_block)
3247
+ # Create a sub block for the statements.
3248
+ block = High.make_block(self.mode,:"",&ruby_block)
3249
+ # Unshifts it.
3250
+ self.unshift_statement(block)
3251
+ # Use its return value.
3252
+ return block.return_value
3190
3253
  end
3191
3254
 
3255
+ # # Get the current mode of the block.
3256
+ # #
3257
+ # # NOTE: for name coherency purpose only.
3258
+ # def block
3259
+ # return self.mode
3260
+ # end
3261
+
3262
+ # Gets the current block.
3263
+ def cur_block
3264
+ return HDLRuby::High.cur_block
3265
+ end
3266
+
3267
+ # Gets the top block of the current behavior.
3268
+ def top_block
3269
+ return HDLRuby::High.top_block
3270
+ end
3271
+
3272
+ # Gets the current behavior.
3273
+ def cur_behavior
3274
+ return HDLRuby::High.cur_behavior
3275
+ end
3276
+
3277
+ # Gets the current scope.
3278
+ def cur_scope
3279
+ return HDLRuby::High.cur_scope
3280
+ end
3281
+
3282
+ # Gets the current system.
3283
+ def cur_system
3284
+ return HDLRuby::High.cur_system
3285
+ end
3286
+
3287
+
3288
+
3192
3289
  # Need to be able to declare select operators
3193
3290
  include Hmux
3194
3291
 
@@ -3624,7 +3721,6 @@ module HDLRuby::High
3624
3721
  end
3625
3722
  end
3626
3723
 
3627
-
3628
3724
  # Gets the enclosing block if any.
3629
3725
  #
3630
3726
  # NOTE: +level+ allows to get an upper block of the currently enclosing
@@ -3640,6 +3736,20 @@ module HDLRuby::High
3640
3736
  end
3641
3737
  end
3642
3738
 
3739
+ # Gets the top enclosing block if any.
3740
+ def self.top_block(level = 0)
3741
+ blk = cur_block(level)
3742
+ unless blk.is_a?(Block)
3743
+ raise AnyError,
3744
+ "Not within a block: #{blk.user.class}"
3745
+ end
3746
+ if Namespaces[-1-level-1].user.is_a?(Scope) then
3747
+ return blk
3748
+ else
3749
+ return top_block(level+1)
3750
+ end
3751
+ end
3752
+
3643
3753
  # Registers hardware referencing method +name+ to the current namespace.
3644
3754
  def self.space_reg(name,&ruby_block)
3645
3755
  # print "registering #{name} in #{Namespaces[-1]}\n"
@@ -3495,6 +3495,24 @@ module HDLRuby::Low
3495
3495
  statement
3496
3496
  end
3497
3497
 
3498
+ # Adds a +statement+ and the begining of the block
3499
+ #
3500
+ # NOTE: TimeWait is not supported unless for TimeBlock objects.
3501
+ def unshift_statement(statement)
3502
+ unless statement.is_a?(Statement) then
3503
+ raise AnyError,
3504
+ "Invalid class for a statement: #{statement.class}"
3505
+ end
3506
+ if statement.is_a?(TimeWait) then
3507
+ raise AnyError,
3508
+ "Timed statements are not supported in common blocks."
3509
+ end
3510
+ @statements.unshift(statement)
3511
+ # And set its parent.
3512
+ statement.parent = self
3513
+ statement
3514
+ end
3515
+
3498
3516
  # Gets the number of statements.
3499
3517
  def num_statements
3500
3518
  return @statements.size
@@ -3620,6 +3638,20 @@ module HDLRuby::Low
3620
3638
  statement
3621
3639
  end
3622
3640
 
3641
+ # Adds a +statement+ and the begining of the block
3642
+ #
3643
+ # NOTE: TimeWait is not supported unless for TimeBlock objects.
3644
+ def unshift_statement(statement)
3645
+ unless statement.is_a?(Statement) then
3646
+ raise AnyError,
3647
+ "Invalid class for a statement: #{statement.class}"
3648
+ end
3649
+ @statements.unshift(statement)
3650
+ # And set its parent.
3651
+ statement.parent = self
3652
+ statement
3653
+ end
3654
+
3623
3655
  # Comparison for hash: structural comparison.
3624
3656
  def eql?(obj)
3625
3657
  return false unless obj.is_a?(TimeBlock)
@@ -1100,7 +1100,11 @@ module HDLRuby::Low
1100
1100
  # when Numeric
1101
1101
  # return self.content.to_s
1102
1102
  when HDLRuby::BitString
1103
- sign = self.type.signed? ? self.content.to_s[-1] : "0"
1103
+ # Compute the extension: in case of signed type, the extension
1104
+ # is the last bit. Otherwise it is 0 unless the last bit
1105
+ # is not defined (Z or X).
1106
+ sign = self.type.signed? ? self.content.to_s[-1] :
1107
+ /[01]/ =~ self.content[-1] ? "0" : self.content[-1]
1104
1108
  return '"' + self.content.to_s.rjust(width,sign).upcase + '"'
1105
1109
  else
1106
1110
  sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0"
@@ -1796,7 +1796,7 @@ class SystemT
1796
1796
  ref = self.extract_port_assign!(systemI,inout)
1797
1797
  if ref then
1798
1798
  code << "." << name_to_verilog(inout.name) << "("
1799
- code << ref.to_vhdl(level)
1799
+ code << ref.to_verilog
1800
1800
  code << "),"
1801
1801
  end
1802
1802
  end
@@ -18,7 +18,8 @@ module HDLRuby::High::Std
18
18
  @name = name.to_sym
19
19
  # Sets the block for instantiating a channel.
20
20
  @ruby_block = ruby_block
21
- # Sets the instantiation procedure.
21
+ # Sets the instantiation procedure if named.
22
+ return if @name.empty?
22
23
  obj = self
23
24
  HDLRuby::High.space_reg(@name) do |*args|
24
25
  obj.instantiate(*args)
@@ -42,11 +43,12 @@ module HDLRuby::High::Std
42
43
  end
43
44
  end
44
45
  # Generates the channels.
46
+ channelI = nil
45
47
  args.each do |nameI|
46
48
  channelI = ChannelI.new(name,&@ruby_block)
47
49
  HDLRuby::High.space_reg(nameI) { channelI }
48
- channelI
49
50
  end
51
+ channelI
50
52
  end
51
53
 
52
54
  alias_method :call, :instantiate
@@ -55,11 +57,172 @@ module HDLRuby::High::Std
55
57
 
56
58
  ## Creates a new channel type named +name+ whose instances are
57
59
  # creating executing +ruby_block+.
58
- def channel(name,&ruby_block)
60
+ def self.channel(name,&ruby_block)
59
61
  return ChannelT.new(name,&ruby_block)
60
62
  end
61
63
 
64
+ ## Creates a new channel type named +name+ whose instances are
65
+ # creating executing +ruby_block+.
66
+ def channel(name,&ruby_block)
67
+ HDLRuby::High::Std.channel(name,&ruby_block)
68
+ end
69
+
70
+ ## Creates directly an instance of channel named +name+ using
71
+ # +ruby_block+ built with +args+.
72
+ def self.channel_instance(name,*args,&ruby_block)
73
+ return ChannelT.new(:"",&ruby_block).instantiate(name,*args)
74
+ end
75
+
76
+ ## Creates directly an instance of channel named +name+ using
77
+ # +ruby_block+ built with +args+.
78
+ def channel_instance(name,*args,&ruby_block)
79
+ HDLRuby::High::Std.channel_instance(name,*args,&ruby_block)
80
+ end
81
+
82
+
83
+ ##
84
+ # Describes a read port to a channel.
85
+ class ChannelPortR
86
+
87
+ # Creates a new channel reader running in +namespace+ and
88
+ # reading using +reader_proc+ and reseting using +reseter_proc+.
89
+ def initialize(namespace,reader_proc,reseter_proc)
90
+ unless namespace.is_a?(Namespace)
91
+ raise "Invalid class for a namespace: #{namespace.class}"
92
+ end
93
+ @namespace = namespace
94
+ @reader_proc = reader_proc.to_proc
95
+ @rester_proc = reseter_proc.to_proc
96
+ end
97
+
98
+ ## Performs a read on the channel using +args+ and +ruby_block+
99
+ # as arguments.
100
+ def read(*args,&ruby_block)
101
+ # Gain access to the reader as local variable.
102
+ reader_proc = @reader_proc
103
+ # Execute the code generating the accesser in context.
104
+ HDLRuby::High.space_push(@namespace)
105
+ HDLRuby::High.cur_block.open do
106
+ instance_exec(ruby_block,*args,&reader_proc)
107
+ end
108
+ HDLRuby::High.space_pop
109
+ end
110
+
111
+ ## Performs a reset on the channel using +args+ and +ruby_block+
112
+ # as arguments.
113
+ def reset(*args,&ruby_block)
114
+ # Gain access to the accesser as local variable.
115
+ reseter_proc = @reseter_proc
116
+ # Execute the code generating the accesser in context.
117
+ HDLRuby::High.space_push(@namespace)
118
+ HDLRuby::High.cur_block.open do
119
+ instance_exec(ruby_block,*args,&reseter_proc)
120
+ end
121
+ HDLRuby::High.space_pop
122
+ end
123
+ end
124
+
125
+
126
+ ##
127
+ # Describes a writer port to a channel.
128
+ class ChannelPortW
129
+
130
+ # Creates a new channel writer running in +namespace+ and
131
+ # writing using +writer_proc+ and reseting using +reseter_proc+.
132
+ def initialize(namespace,writer_proc,reseter_proc)
133
+ unless namespace.is_a?(Namespace)
134
+ raise "Invalid class for a namespace: #{namespace.class}"
135
+ end
136
+ @namespace = namespace
137
+ @writer_proc = writer_proc.to_proc
138
+ @reseter_proc = reseter_proc.to_proc
139
+ end
140
+
141
+ ## Performs a write on the channel using +args+ and +ruby_block+
142
+ # as arguments.
143
+ def write(*args,&ruby_block)
144
+ # Gain access to the writer as local variable.
145
+ writer_proc = @writer_proc
146
+ # Execute the code generating the accesser in context.
147
+ HDLRuby::High.space_push(@namespace)
148
+ HDLRuby::High.cur_block.open do
149
+ instance_exec(ruby_block,*args,&writer_proc)
150
+ end
151
+ HDLRuby::High.space_pop
152
+ end
153
+
154
+ ## Performs a reset on the channel using +args+ and +ruby_block+
155
+ # as arguments.
156
+ def reset(*args,&ruby_block)
157
+ # Gain access to the accesser as local variable.
158
+ reseter_proc = @reseter_proc
159
+ # Execute the code generating the accesser in context.
160
+ HDLRuby::High.space_push(@namespace)
161
+ HDLRuby::High.cur_block.open do
162
+ instance_exec(ruby_block,*args,&reseter_proc)
163
+ end
164
+ HDLRuby::High.space_pop
165
+ end
166
+ end
167
+
168
+
62
169
 
170
+ ##
171
+ # Describes an access port to a channel.
172
+ class ChannelPortA
173
+
174
+ # Creates a new channel accesser running in +namespace+
175
+ # and reading using +reader_proc+, writing using +writer_proc+,
176
+ # and reseting using +reseter_proc+.
177
+ def initialize(namespace,reader_proc,writer_proc,reseter_proc)
178
+ unless namespace.is_a?(Namespace)
179
+ raise "Invalid class for a namespace: #{namespace.class}"
180
+ end
181
+ @namespace = namespace
182
+ @reader_proc = reader_proc.to_proc
183
+ @writer_proc = writer_proc.to_proc
184
+ @reseter_proc = reseter_proc.to_proc
185
+ end
186
+
187
+ ## Performs a read on the channel using +args+ and +ruby_block+
188
+ # as arguments.
189
+ def read(*args,&ruby_block)
190
+ # Gain access to the accesser as local variable.
191
+ reader_proc = @reader_proc
192
+ # Execute the code generating the accesser in context.
193
+ HDLRuby::High.space_push(@namespace)
194
+ HDLRuby::High.cur_block.open do
195
+ instance_exec(ruby_block,*args,&reader_proc)
196
+ end
197
+ HDLRuby::High.space_pop
198
+ end
199
+
200
+ ## Performs a write on the channel using +args+ and +ruby_block+
201
+ # as arguments.
202
+ def write(*args,&ruby_block)
203
+ # Gain access to the accesser as local variable.
204
+ writer_proc = @writer_proc
205
+ # Execute the code generating the accesser in context.
206
+ HDLRuby::High.space_push(@namespace)
207
+ HDLRuby::High.cur_block.open do
208
+ instance_exec(ruby_block,*args,&writer_proc)
209
+ end
210
+ HDLRuby::High.space_pop
211
+ end
212
+
213
+ ## Performs a reset on the channel using +args+ and +ruby_block+
214
+ # as arguments.
215
+ def reset(*args,&ruby_block)
216
+ # Gain access to the accesser as local variable.
217
+ reseter_proc = @reseter_proc
218
+ # Execute the code generating the accesser in context.
219
+ HDLRuby::High.space_push(@namespace)
220
+ HDLRuby::High.cur_block.open do
221
+ instance_exec(ruby_block,*args,&reseter_proc)
222
+ end
223
+ HDLRuby::High.space_pop
224
+ end
225
+ end
63
226
 
64
227
 
65
228
  ##
@@ -75,16 +238,19 @@ module HDLRuby::High::Std
75
238
  attr_reader :scope
76
239
 
77
240
  # The namespace associated with the current execution when
78
- # building a channel, its reader or its writer.
241
+ # building a channel.
79
242
  attr_reader :namespace
80
243
 
81
244
  ## Creates a new channel instance with +name+ built from +ruby_block+.
82
245
  def initialize(name,&ruby_block)
83
- # Check and set the name
246
+ # Check and set the name of the channel.
84
247
  @name = name.to_sym
248
+ # Generate a name for the scope containing the signals of
249
+ # the channel.
250
+ @scope_name = HDLRuby.uniq_name
85
251
 
86
- # Sets the scope.
87
- @scope = HDLRuby::High.cur_scope
252
+ # # Sets the scope.
253
+ # @scope = HDLRuby::High.cur_scope
88
254
 
89
255
  # Keep access to self.
90
256
  obj = self
@@ -103,58 +269,93 @@ module HDLRuby::High::Std
103
269
  # The writer inout ports by name.
104
270
  @writer_inouts = {}
105
271
 
272
+ # The accesser input ports by name.
273
+ @accesser_inputs = {}
274
+ # The accesser output ports by name.
275
+ @accesser_outputs = {}
276
+ # The accesser inout ports by name.
277
+ @accesser_inouts = {}
278
+
279
+ # The default reset procedures (reseters), by default do nothing.
280
+ @input_reseter_proc = proc {}
281
+ @output_reseter_proc = proc {}
282
+ @inout_reseter_proc = proc {}
283
+
284
+ # The branch channels
285
+ @branches = {}
286
+
106
287
  # Create the namespaces for building the channel, its readers
107
- # and its writers.
288
+ # its writers and its accessers.
108
289
 
109
290
  # Creates the namespace of the channel.
110
- @channel_namespace = Namespace.new(self)
291
+ @namespace = Namespace.new(self)
111
292
  # Make it give access to the internal of the class.
112
- @channel_namespace.add_method(:reader_input, &method(:reader_input))
113
- @channel_namespace.add_method(:reader_output,&method(:reader_output))
114
- @channel_namespace.add_method(:reader_inout, &method(:reader_inout))
115
- @channel_namespace.add_method(:writer_input, &method(:writer_input))
116
- @channel_namespace.add_method(:writer_output,&method(:writer_output))
117
- @channel_namespace.add_method(:writer_inout, &method(:writer_inout))
118
- @channel_namespace.add_method(:reader, &method(:reader))
119
- @channel_namespace.add_method(:writer, &method(:writer))
293
+ @namespace.add_method(:reader_input, &method(:reader_input))
294
+ @namespace.add_method(:reader_output, &method(:reader_output))
295
+ @namespace.add_method(:reader_inout, &method(:reader_inout))
296
+ @namespace.add_method(:writer_input, &method(:writer_input))
297
+ @namespace.add_method(:writer_output, &method(:writer_output))
298
+ @namespace.add_method(:writer_inout, &method(:writer_inout))
299
+ @namespace.add_method(:accesser_input, &method(:accesser_input))
300
+ @namespace.add_method(:accesser_output,&method(:accesser_output))
301
+ @namespace.add_method(:accesser_inout, &method(:accesser_inout))
302
+ @namespace.add_method(:reader, &method(:reader))
303
+ @namespace.add_method(:writer, &method(:writer))
304
+ @namespace.add_method(:brancher, &method(:brancher))
120
305
 
121
306
  # Creates the namespace of the reader.
122
307
  @reader_namespace = Namespace.new(self)
123
308
  # Creates the namespace of the writer.
124
309
  @writer_namespace = Namespace.new(self)
310
+ # Creates the namespace of the accesser.
311
+ @accesser_namespace = Namespace.new(self)
125
312
 
126
- # By default the namespace is the one of the namespace
127
- @namespace = @channel_namespace
128
-
129
- # Builds the channel.
313
+ # Builds the channel within a new scope.
130
314
  HDLRuby::High.space_push(@namespace)
131
315
  # puts "top_user=#{HDLRuby::High.top_user}"
132
- HDLRuby::High.top_user.instance_eval(&ruby_block)
316
+ scope_name = @scope_name
317
+ scope = nil
318
+ HDLRuby::High.top_user.instance_eval do
319
+ sub(scope_name) do
320
+ # Generate the channel code.
321
+ ruby_block.call
322
+ end
323
+ end
133
324
  HDLRuby::High.space_pop
134
325
 
326
+ # Keep access to the scope containing the code of the channel.
327
+ @scope = @namespace.send(scope_name)
328
+ # puts "@scope=#{@scope}"
329
+ # Adds the name space of the scope to the namespace of the
330
+ # channel
331
+ @namespace.concat_namespace(@scope.namespace)
332
+
135
333
  # Gives access to the channel by registering its name.
136
334
  obj = self
137
- HDLRuby::High.space_reg(@name) { self }
335
+ # HDLRuby::High.space_reg(@name) { self }
336
+ HDLRuby::High.space_reg(@name) { obj }
138
337
  end
139
338
 
140
339
  # The methods for defining the channel
141
340
 
142
341
  # For the channel itself
143
342
 
144
- ## Defines new command +name+ to execute +ruby_block+ for the
145
- # channel.
146
- def command(name,&ruby_block)
147
- # Ensures name is a symbol.
148
- name = name.to_sym
149
- # Sets the new command.
150
- self.define_singleton_method(name) do
151
- # Executes the command in the right environment.
152
- HDLRuby::High.space_push(@namespace)
153
- res = HDLRuby::High.top_user.instance_exec(&ruby_block)
154
- HDLRuby::High.space_pop
155
- res
156
- end
157
- end
343
+ # ## Defines new command +name+ to execute +ruby_block+ for the
344
+ # # channel.
345
+ # def command(name,&ruby_block)
346
+ # # Ensures name is a symbol.
347
+ # name = name.to_sym
348
+ # res = nil
349
+ # # Sets the new command.
350
+ # self.define_singleton_method(name) do |*args|
351
+ # HDLRuby::High.space_push(@namespace)
352
+ # HDLRuby::High.cur_block.open do
353
+ # res = instance_exec(*args,&ruby_block)
354
+ # end
355
+ # HDLRuby::High.space_pop
356
+ # res
357
+ # end
358
+ # end
158
359
 
159
360
  # For the reader and the writer
160
361
 
@@ -230,18 +431,74 @@ module HDLRuby::High::Std
230
431
  end
231
432
  end
232
433
 
434
+ ## Sets the signals accessible through +key+ to be accesser input port.
435
+ def accesser_input(*keys)
436
+ # Registers each signal as accesser port
437
+ keys.each do |key|
438
+ # Ensure the key is a symbol.
439
+ key = key.to_sym
440
+ # Register it with the corresponding signal.
441
+ name = HDLRuby.uniq_name # The name of the signal is uniq.
442
+ @accesser_inputs[name] = send(key)
443
+ end
444
+ end
445
+
446
+ ## Sets the signals accessible through +key+ to be accesser output port.
447
+ def accesser_output(*keys)
448
+ # Registers each signal as accesser port
449
+ keys.each do |key|
450
+ # Ensure the key is a symbol.
451
+ key = key.to_sym
452
+ # Register it with the corresponding signal.
453
+ name = HDLRuby.uniq_name # The name of the signal is uniq.
454
+ @accesser_outputs[name] = send(key)
455
+ end
456
+ end
457
+
458
+ ## Sets the signals accessible through +key+ to be accesser inout port.
459
+ def accesser_inout(*keys)
460
+ # Registers each signal as accesser port
461
+ keys.each do |key|
462
+ # Ensure the key is a symbol.
463
+ key = key.to_sym
464
+ # Register it with the corresponding signal.
465
+ name = HDLRuby.uniq_name # The name of the signal is uniq.
466
+ @accesser_inouts[name] = send(key)
467
+ end
468
+ end
469
+
470
+
233
471
  ## Sets the read procedure to be +ruby_block+.
234
472
  def reader(&ruby_block)
235
473
  @reader_proc = ruby_block
236
474
  end
237
475
 
238
- ## Sets the writter procedure to be +ruby_block+.
476
+ ## Sets the writer procedure to be +ruby_block+.
239
477
  def writer(&ruby_block)
240
478
  @writer_proc = ruby_block
241
479
  end
242
480
 
243
- # The methods for accessing the channel
481
+ # ## Sets the accesser procedure to be +ruby_block+.
482
+ # def accesser(&ruby_block)
483
+ # @accesser_proc = ruby_block
484
+ # end
485
+
486
+ ## Sets the input port reset to be +ruby_block+.
487
+ def input_reseter(&ruby_block)
488
+ @input_reseter_proc = ruby_block
489
+ end
490
+
491
+ ## Sets the output port reset to be +ruby_block+.
492
+ def output_reseter(&ruby_block)
493
+ @output_reseter_proc = ruby_block
494
+ end
495
+
496
+ ## Sets the inout port reset to be +ruby_block+.
497
+ def inout_reseter(&ruby_block)
498
+ @inout_reseter_proc = ruby_block
499
+ end
244
500
 
501
+ # The methods for accessing the channel
245
502
  # Channel side.
246
503
 
247
504
  ## Gets the list of the signals of the channel to be connected
@@ -258,22 +515,32 @@ module HDLRuby::High::Std
258
515
  @writer_inouts.values
259
516
  end
260
517
 
261
- # Reader an writer side.
262
-
263
- # ## Declares the ports for the reader.
264
- # def reader_ports
265
- # loc_inputs = @reader_inputs
266
- # loc_outputs = @reader_outputs
267
- # loc_inouts = @reader_inouts
268
- # HDLRuby::High.cur_system.open do
269
- # # The inputs
270
- # loc_inputs.each { |name,sig| sig.type.input name }
271
- # # The outputs
272
- # loc_outputs.each { |name,sig| sig.type.output name }
273
- # # The inouts
274
- # loc_inouts.each { |name,sig| sig.type.inout name }
275
- # end
276
- # end
518
+ # Defines a branch in the channel named +name+ built executing
519
+ # +ruby_block+.
520
+ def brancher(name,*args,&ruby_block)
521
+ # Ensure name is a symbol.
522
+ name = name.to_s unless name.respond_to?(:to_sym)
523
+ name = name.to_sym
524
+ # Create the branch.
525
+ channelI = HDLRuby::High.channel_instance(name,*args,&ruby_block)
526
+ @branches[name] = channelI
527
+ end
528
+
529
+
530
+ # Methods used on the channel outside its definition.
531
+
532
+ # Gets branch channel +name+.
533
+ # NOTE: +name+ can be of any type on purpose.
534
+ def branch(name)
535
+ # Ensure name is a symbol.
536
+ name = name.to_s unless name.respond_to?(:to_sym)
537
+ name = name.to_sym
538
+ # Get the branch.
539
+ return @branches[name]
540
+ end
541
+
542
+
543
+ # Reader, writer and accesser side.
277
544
 
278
545
  ## Declares the ports for the reader and assigned them to +name+.
279
546
  def input(name)
@@ -289,6 +556,7 @@ module HDLRuby::High::Std
289
556
  HDLRuby::High.cur_system.open do
290
557
  # The inputs
291
558
  loc_inputs.each do |name,sig|
559
+ # puts "name=#{name} sig.name=#{sig.name}"
292
560
  port_pairs << [sig, sig.type.input(name)]
293
561
  end
294
562
  # The outputs
@@ -309,28 +577,32 @@ module HDLRuby::High::Std
309
577
  end
310
578
  end
311
579
  end
580
+
581
+ # Fill the reader namespace with the access to the reader signals.
582
+ @reader_inputs.each do |name,sig|
583
+ @reader_namespace.add_method(sig.name) do
584
+ HDLRuby::High.top_user.send(name)
585
+ end
586
+ end
587
+ @reader_outputs.each do |name,sig|
588
+ @reader_namespace.add_method(sig.name) do
589
+ HDLRuby::High.top_user.send(name)
590
+ end
591
+ end
592
+ @reader_inouts.each do |name,sig|
593
+ @reader_namespace.add_method(sig.name) do
594
+ HDLRuby::High.top_user.send(name)
595
+ end
596
+ end
597
+
312
598
  # Give access to the ports through name.
313
599
  # NOTE: for now, simply associate the channel to name.
314
- this = self
315
- HDLRuby::High.space_reg(name) { this }
316
- end
317
-
318
- # ## Declares the ports for the writer.
319
- # def writer_ports
320
- # loc_inputs = @writer_inputs
321
- # loc_outputs = @writer_outputs
322
- # loc_inouts = @writer_inouts
323
- # HDLRuby::High.cur_system.open do
324
- # # The inputs
325
- # loc_inputs.each { |name,sig| sig.type.input name }
326
- # # The outputs
327
- # loc_outputs.each { |name,sig| sig.type.output name }
328
- # # The inouts
329
- # loc_inouts.each { |name,sig| sig.type.inout name }
330
- # end
331
- # end
600
+ chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
601
+ HDLRuby::High.space_reg(name) { chp }
602
+ return chp
603
+ end
332
604
 
333
- ## Declares the ports for the reader and assigned them to +name+.
605
+ ## Declares the ports for the writer and assigned them to +name+.
334
606
  def output(name)
335
607
  # Ensure name is a symbol.
336
608
  name = name.to_sym
@@ -364,77 +636,182 @@ module HDLRuby::High::Std
364
636
  end
365
637
  end
366
638
  end
639
+
640
+ # Fill the writer namespace with the access to the writer signals.
641
+ @writer_inputs.each do |name,sig|
642
+ @writer_namespace.add_method(sig.name) do
643
+ HDLRuby::High.top_user.send(name)
644
+ end
645
+ end
646
+ @writer_outputs.each do |name,sig|
647
+ @writer_namespace.add_method(sig.name) do
648
+ HDLRuby::High.top_user.send(name)
649
+ end
650
+ end
651
+ @writer_inouts.each do |name,sig|
652
+ @writer_namespace.add_method(sig.name) do
653
+ HDLRuby::High.top_user.send(name)
654
+ end
655
+ end
656
+
367
657
  # Give access to the ports through name.
368
658
  # NOTE: for now, simply associate the channel to name.
369
- this = self
370
- HDLRuby::High.space_reg(name) { this }
659
+ chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
660
+ HDLRuby::High.space_reg(name) { chp }
661
+ return chp
371
662
  end
372
663
 
373
-
374
- ## Performs a read on the channel using +args+ and +ruby_block+
375
- # as arguments.
376
- def read(*args,&ruby_block)
377
- # Fill the reader namespace with the access to the reader signals.
378
- @reader_inputs.each do |name,sig|
379
- @reader_namespace.add_method(sig.name) do
664
+ ## Declares the ports for the accesser and assigned them to +name+.
665
+ def inout(name)
666
+ # Ensure name is a symbol.
667
+ name = name.to_sym
668
+ # Access the ports
669
+ loc_inputs = @accesser_inputs
670
+ loc_outputs = @accesser_outputs
671
+ loc_inouts = @accesser_inouts
672
+ # The generated port with corresponding channel port pairs.
673
+ port_pairs = []
674
+ # Add them to the current system.
675
+ HDLRuby::High.cur_system.open do
676
+ # The inputs
677
+ loc_inputs.each do |name,sig|
678
+ port_pairs << [sig, sig.type.input(name)]
679
+ end
680
+ # The outputs
681
+ loc_outputs.each do |name,sig|
682
+ port_pairs << [sig, sig.type.output(name)]
683
+ end
684
+ # The inouts
685
+ loc_inouts.each do |name,sig|
686
+ port_pairs << [sig, sig.type.inout(name)]
687
+ end
688
+ end
689
+ obj = self
690
+ # Make the connection of the instance.
691
+ HDLRuby::High.cur_system.on_instance do |inst|
692
+ obj.scope.open do
693
+ port_pairs.each do |sig, port|
694
+ RefObject.new(inst,port.to_ref) <= sig
695
+ end
696
+ end
697
+ end
698
+
699
+ # Set ups the accesser's namespace
700
+ @accesser_inputs.each do |name,sig|
701
+ @accesser_namespace.add_method(sig.name) do
380
702
  HDLRuby::High.top_user.send(name)
381
703
  end
382
704
  end
383
- @reader_outputs.each do |name,sig|
384
- @reader_namespace.add_method(sig.name) do
705
+ @accesser_outputs.each do |name,sig|
706
+ @accesser_namespace.add_method(sig.name) do
385
707
  HDLRuby::High.top_user.send(name)
386
708
  end
387
709
  end
388
- @reader_inouts.each do |name,sig|
389
- @reader_namespace.add_method(sig.name) do
710
+ @accesser_inouts.each do |name,sig|
711
+ @accesser_namespace.add_method(sig.name) do
390
712
  HDLRuby::High.top_user.send(name)
391
713
  end
392
714
  end
715
+
716
+ # Give access to the ports through name.
717
+ # NOTE: for now, simply associate the channel to name.
718
+ chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
719
+ HDLRuby::High.space_reg(name) { chp }
720
+ return chp
721
+ end
722
+
723
+ ## Declares the ports for accessing the channel as an inner component
724
+ # and assigned them to +name+.
725
+ def inner(name)
726
+ # Ensure name is a symbol.
727
+ name = name.to_sym
728
+ # Access the ports
729
+ loc_inputs = @accesser_inputs.merge(@reader_inputs).
730
+ merge(@writer_inputs)
731
+ loc_outputs = @accesser_outputs.merge(@reader_outputs).
732
+ merge(@writer_outputs)
733
+ loc_inouts = @accesser_inouts.merge(@reader_inouts).
734
+ merge(@writer_inouts)
735
+ locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
736
+ # The generated port with corresponding channel port pairs.
737
+ port_pairs = []
738
+ # Add them to the current system.
739
+ HDLRuby::High.cur_system.open do
740
+ locs.each do |name,sig|
741
+ port_pairs << [sig, sig.type.inner(name)]
742
+ end
743
+ end
744
+ obj = self
745
+ # Make the inner connection
746
+ port_pairs.each do |sig, port|
747
+ port.to_ref <= sig
748
+ end
749
+
750
+ # Set ups the accesser's namespace
751
+ @accesser_inputs.each do |name,sig|
752
+ @accesser_namespace.add_method(sig.name) do
753
+ HDLRuby::High.top_user.send(name)
754
+ end
755
+ end
756
+ @accesser_outputs.each do |name,sig|
757
+ @accesser_namespace.add_method(sig.name) do
758
+ HDLRuby::High.top_user.send(name)
759
+ end
760
+ end
761
+ @accesser_inouts.each do |name,sig|
762
+ @accesser_namespace.add_method(sig.name) do
763
+ HDLRuby::High.top_user.send(name)
764
+ end
765
+ end
766
+
767
+ # Give access to the ports through name.
768
+ # NOTE: for now, simply associate the channel to name.
769
+ chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
770
+ HDLRuby::High.space_reg(name) { chp }
771
+ return chp
772
+ end
773
+
774
+
775
+ ## Performs a read on the channel using +args+ and +ruby_block+
776
+ # as arguments.
777
+ def read(*args,&ruby_block)
393
778
  # Gain access to the reader as local variable.
394
779
  reader_proc = @reader_proc
395
- # The context is the one of the reader.
396
- @namespace = @reader_namespace
780
+ # # The context is the one of the reader.
397
781
  # Execute the code generating the reader in context.
398
782
  HDLRuby::High.space_push(@namespace)
399
783
  HDLRuby::High.cur_block.open do
400
784
  instance_exec(ruby_block,*args,&reader_proc)
401
785
  end
402
786
  HDLRuby::High.space_pop
403
- # Restores the default context.
404
- @namespace = @channel_namespace
405
787
  end
406
788
 
407
789
  ## Performs a write on the channel using +args+ and +ruby_block+
408
790
  # as arguments.
409
791
  def write(*args,&ruby_block)
410
- # Fill the writer namespace with the access to the writer signals.
411
- @writer_inputs.each do |name,sig|
412
- @writer_namespace.add_method(sig.name) do
413
- HDLRuby::High.top_user.send(name)
414
- end
415
- end
416
- @writer_outputs.each do |name,sig|
417
- @writer_namespace.add_method(sig.name) do
418
- HDLRuby::High.top_user.send(name)
419
- end
420
- end
421
- @writer_inouts.each do |name,sig|
422
- @writer_namespace.add_method(sig.name) do
423
- HDLRuby::High.top_user.send(name)
424
- end
425
- end
426
792
  # Gain access to the writer as local variable.
427
793
  writer_proc = @writer_proc
428
- # The context is the one of the writer.
429
- @namespace = @writer_namespace
794
+ # # The context is the one of the writer.
430
795
  # Execute the code generating the writer in context.
431
796
  HDLRuby::High.space_push(@namespace)
432
797
  HDLRuby::High.cur_block.open do
433
798
  instance_exec(ruby_block,*args,&writer_proc)
434
799
  end
435
800
  HDLRuby::High.space_pop
436
- # Restores the default context.
437
- @namespace = @channel_namespace
801
+ end
802
+
803
+ ## Performs a reset on the channel using +args+ and +ruby_block+
804
+ # as arguments.
805
+ def reset(*args,&ruby_block)
806
+ # Gain access to the writer as local variable.
807
+ reseter_proc = @inout_reseter_proc
808
+ # # The context is the one of the writer.
809
+ # Execute the code generating the writer in context.
810
+ HDLRuby::High.space_push(@namespace)
811
+ HDLRuby::High.cur_block.open do
812
+ instance_exec(ruby_block,*args,&reseter_proc)
813
+ end
814
+ HDLRuby::High.space_pop
438
815
  end
439
816
  end
440
817