HDLRuby 2.10.5 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/HDLRuby.gemspec +1 -0
- data/README.md +8 -4
- data/Rakefile +8 -0
- data/{lib/HDLRuby/sim/Makefile → ext/hruby_sim/Makefile_csim} +0 -0
- data/ext/hruby_sim/extconf.rb +13 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +1188 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim.h +255 -16
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_calc.c +310 -181
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_core.c +34 -17
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_list.c +0 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c +4 -1
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c.sav +0 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +375 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vcd.c +5 -5
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vizualize.c +2 -2
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_value_pool.c +4 -1
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +0 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +46 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/print_bench.rb +62 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +5 -3
- data/lib/HDLRuby/hdr_samples/simple_counter_bench.rb +43 -0
- data/lib/HDLRuby/hdrcc.rb +54 -8
- data/lib/HDLRuby/hruby_bstr.rb +1175 -917
- data/lib/HDLRuby/hruby_high.rb +200 -90
- data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
- data/lib/HDLRuby/hruby_low.rb +41 -23
- data/lib/HDLRuby/hruby_low2c.rb +7 -0
- data/lib/HDLRuby/hruby_rcsim.rb +978 -0
- data/lib/HDLRuby/hruby_rsim.rb +1134 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +322 -0
- data/lib/HDLRuby/hruby_values.rb +362 -18
- data/lib/HDLRuby/hruby_verilog.rb +21 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +24 -13
@@ -0,0 +1,1134 @@
|
|
1
|
+
require "HDLRuby/hruby_high"
|
2
|
+
# require "HDLRuby/hruby_low_resolve"
|
3
|
+
require "HDLRuby/hruby_bstr"
|
4
|
+
require "HDLRuby/hruby_values"
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
module HDLRuby::High
|
9
|
+
|
10
|
+
##
|
11
|
+
# Library for describing the Ruby simulator of HDLRuby
|
12
|
+
#
|
13
|
+
########################################################################
|
14
|
+
|
15
|
+
##
|
16
|
+
# Enhance a system type with Ruby simulation.
|
17
|
+
class SystemT
|
18
|
+
|
19
|
+
## Add timed behavior +beh+.
|
20
|
+
# Returns the id of the timed behavior.
|
21
|
+
def add_timed_behavior(beh)
|
22
|
+
@timed_behaviors << beh
|
23
|
+
@total_timed_behaviors += 1
|
24
|
+
return @total_timed_behaviors - 1
|
25
|
+
end
|
26
|
+
|
27
|
+
## Remove timed beahvior +beh+
|
28
|
+
def remove_timed_behavior(beh)
|
29
|
+
# puts "remove_timed_behavior"
|
30
|
+
@timed_behaviors.delete(beh)
|
31
|
+
end
|
32
|
+
|
33
|
+
## Add +sig+ to the list of active signals.
|
34
|
+
def add_sig_active(sig)
|
35
|
+
# puts "Adding activated signal=#{sig.fullname}"
|
36
|
+
@sig_active << sig
|
37
|
+
end
|
38
|
+
|
39
|
+
## Run the simulation from the current systemT and outputs the resuts
|
40
|
+
# on simout.
|
41
|
+
def sim(simout)
|
42
|
+
HDLRuby.show "Initializing Ruby-level simulator..."
|
43
|
+
HDLRuby.show "#{Time.now}#{show_mem}"
|
44
|
+
# Merge the included.
|
45
|
+
self.merge_included!
|
46
|
+
# Initializes the run mutex and the conditions.
|
47
|
+
@mutex = Mutex.new
|
48
|
+
@master = ConditionVariable.new
|
49
|
+
@master_flag = 0
|
50
|
+
@slave = ConditionVariable.new
|
51
|
+
@slave_flags_not = 0
|
52
|
+
@num_done = 0
|
53
|
+
# @lock = 0
|
54
|
+
# @runs = 0
|
55
|
+
# Initializes the time.
|
56
|
+
@time = 0
|
57
|
+
# Initializes the time and signals execution buffers.
|
58
|
+
@tim_exec = []
|
59
|
+
@sig_exec = []
|
60
|
+
# Initialize the list of currently exisiting timed behavior.
|
61
|
+
@timed_behaviors = []
|
62
|
+
# Initialize the list of activated signals.
|
63
|
+
@sig_active = []
|
64
|
+
# Initializes the total number of timed behaviors (currently
|
65
|
+
# existing or not: used for generating the id of the behaviors).
|
66
|
+
@total_timed_behaviors = 0
|
67
|
+
# Initilizes the simulation.
|
68
|
+
self.init_sim(self)
|
69
|
+
# Initialize the displayer.
|
70
|
+
self.show_init(simout)
|
71
|
+
# exit
|
72
|
+
# First all the timed behaviors are to be executed.
|
73
|
+
@timed_behaviors.each {|beh| @tim_exec << beh }
|
74
|
+
# But starts locked.
|
75
|
+
@slave_flags_not = 2**@timed_behaviors.size - 1
|
76
|
+
# Starts the threads.
|
77
|
+
@timed_behaviors.each {|beh| beh.make_thread }
|
78
|
+
|
79
|
+
HDLRuby.show "Starting Ruby-level simulator..."
|
80
|
+
HDLRuby.show "#{Time.now}#{show_mem}"
|
81
|
+
# Run the simulation.
|
82
|
+
self.run_init do
|
83
|
+
# # Wake the behaviors.
|
84
|
+
# @timed_behaviors.each {|beh| beh.run }
|
85
|
+
until @tim_exec.empty? do
|
86
|
+
# Display the time
|
87
|
+
self.show_time
|
88
|
+
# Execute the time behaviors that are ready.
|
89
|
+
self.run_ack
|
90
|
+
self.run_wait
|
91
|
+
shown_values = {}
|
92
|
+
# Get the behaviors waiting on activated signals.
|
93
|
+
until @sig_active.empty? do
|
94
|
+
# # Update the signals.
|
95
|
+
# @sig_active.each { |sig| sig.c_value = sig.f_value }
|
96
|
+
# puts "sig_active.size=#{@sig_active.size}"
|
97
|
+
# Look for the behavior sensitive to the signals.
|
98
|
+
@sig_active.each do |sig|
|
99
|
+
sig.each_anyedge { |beh| @sig_exec << beh }
|
100
|
+
if (sig.c_value.zero? && !sig.f_value.zero?) then
|
101
|
+
# puts "sig.c_value=#{sig.c_value.content}"
|
102
|
+
sig.each_posedge { |beh| @sig_exec << beh }
|
103
|
+
elsif (!sig.c_value.zero? && sig.f_value.zero?) then
|
104
|
+
sig.each_negedge { |beh| @sig_exec << beh }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
# Update the signals.
|
108
|
+
@sig_active.each { |sig| sig.c_value = sig.f_value }
|
109
|
+
# puts "first @sig_exec.size=#{@sig_exec.size}"
|
110
|
+
@sig_exec.uniq! {|beh| beh.object_id }
|
111
|
+
# Display the activated signals.
|
112
|
+
@sig_active.each do |sig|
|
113
|
+
if !shown_values[sig].eql?(sig.f_value) then
|
114
|
+
self.show_signal(sig)
|
115
|
+
shown_values[sig] = sig.f_value
|
116
|
+
end
|
117
|
+
end
|
118
|
+
# Clear the list of active signals.
|
119
|
+
@sig_active.clear
|
120
|
+
# puts "sig_exec.size=#{@sig_exec.size}"
|
121
|
+
# Execute the relevant behaviors and connections.
|
122
|
+
@sig_exec.each { |obj| obj.execute(:par) }
|
123
|
+
@sig_exec.clear
|
124
|
+
@sig_active.uniq! {|sig| sig.object_id }
|
125
|
+
# puts "@sig_active.size=#{@sig_active.size}"
|
126
|
+
end
|
127
|
+
break if @timed_behaviors.empty?
|
128
|
+
# Advance time.
|
129
|
+
@time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
|
130
|
+
# Schedule the next timed behavior to execute.
|
131
|
+
@tim_exec = []
|
132
|
+
@timed_behaviors.each do |beh|
|
133
|
+
@tim_exec << beh if beh.time == @time
|
134
|
+
end
|
135
|
+
# puts "@tim_exec.size=#{@tim_exec.size}"
|
136
|
+
# puts "@timed_bevaviors.size=#{@timed_behaviors.size}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
## Initialize the simulation for system +systemT+.
|
142
|
+
def init_sim(systemT)
|
143
|
+
# puts "init_sim for #{self} (#{self.name})"
|
144
|
+
# Recurse on the signals.
|
145
|
+
self.each_signal { |sig| sig.init_sim(systemT) }
|
146
|
+
# Recure on the scope.
|
147
|
+
self.scope.init_sim(systemT)
|
148
|
+
end
|
149
|
+
|
150
|
+
## Initialize run for executing +ruby_block+
|
151
|
+
def run_init(&ruby_block)
|
152
|
+
@mutex.synchronize(&ruby_block)
|
153
|
+
end
|
154
|
+
|
155
|
+
## Request for running for timed behavior +id+
|
156
|
+
def run_req(id)
|
157
|
+
# puts "run_req with id=#{id} and @slave_flags_not=#{@slave_flags_not}"
|
158
|
+
@slave.wait(@mutex) while @slave_flags_not[id] == 1
|
159
|
+
end
|
160
|
+
|
161
|
+
## Tell running part done for timed behavior +id+.
|
162
|
+
def run_done(id)
|
163
|
+
# puts "run_done with id=#{id}"
|
164
|
+
@num_done += 1
|
165
|
+
@slave_flags_not |= 2**id
|
166
|
+
if @num_done == @tim_exec.size
|
167
|
+
# puts "All done."
|
168
|
+
@master_flag = 1
|
169
|
+
@master.signal
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
## Wait for all the run to complete.
|
174
|
+
def run_wait
|
175
|
+
# puts "run_wait"
|
176
|
+
@master.wait(@mutex) unless @master_flag == 1
|
177
|
+
@num_done = 0
|
178
|
+
@master_flag = 0
|
179
|
+
end
|
180
|
+
|
181
|
+
## Acknowledge the run request the executable timed behavior.
|
182
|
+
def run_ack
|
183
|
+
# puts "run_ack"
|
184
|
+
mask = 0
|
185
|
+
@tim_exec.each { |beh| mask |= 2**beh.id }
|
186
|
+
mask = 2**@total_timed_behaviors - 1 - mask
|
187
|
+
@slave_flags_not &= mask
|
188
|
+
@slave.broadcast
|
189
|
+
end
|
190
|
+
|
191
|
+
## Initializes the displayer
|
192
|
+
def show_init(simout)
|
193
|
+
# Sets the simulation output.
|
194
|
+
@simout = simout
|
195
|
+
end
|
196
|
+
|
197
|
+
## Displays the time.
|
198
|
+
def show_time
|
199
|
+
@simout.puts("# #{@time}ps")
|
200
|
+
end
|
201
|
+
|
202
|
+
## Displays the value of signal +sig+.
|
203
|
+
def show_signal(sig)
|
204
|
+
@simout.puts("#{sig.fullname}: #{sig.f_value.to_vstr}")
|
205
|
+
end
|
206
|
+
|
207
|
+
## Displays value +val+.
|
208
|
+
def show_value(val)
|
209
|
+
@simout.print(val.to_vstr)
|
210
|
+
end
|
211
|
+
|
212
|
+
## Displays string +str+.
|
213
|
+
def show_string(str)
|
214
|
+
@simout.print(str)
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
## Returns the name of the signal with its hierarchy.
|
219
|
+
def fullname
|
220
|
+
@fullname ||= (self.parent ? self.parent.fullname + ":" : "") +
|
221
|
+
self.name.to_s
|
222
|
+
return @fullname
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
##
|
228
|
+
# Describes scopes of system types.
|
229
|
+
class Scope
|
230
|
+
|
231
|
+
## Initialize the simulation for system +systemT+.
|
232
|
+
def init_sim(systemT)
|
233
|
+
# Recurse on the inner signals.
|
234
|
+
self.each_inner { |sig| sig.init_sim(systemT) }
|
235
|
+
# Recurse on the behaviors.
|
236
|
+
self.each_behavior { |beh| beh.init_sim(systemT) }
|
237
|
+
# Recurse on the systemI.
|
238
|
+
self.each_systemI { |sys| sys.init_sim(systemT) }
|
239
|
+
# Recurse on the connections.
|
240
|
+
self.each_connection { |cnx| cnx.init_sim(systemT) }
|
241
|
+
# Recurse on the sub scopes.
|
242
|
+
self.each_scope { |sco| sco.init_sim(systemT) }
|
243
|
+
end
|
244
|
+
|
245
|
+
## Returns the name of the signal with its hierarchy.
|
246
|
+
def fullname
|
247
|
+
@fullname ||= self.parent.fullname + ":" + self.name.to_s
|
248
|
+
return @fullname
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
## Extends the TypeTuple class for Ruby simulation.
|
254
|
+
class TypeTuple
|
255
|
+
# Add the possibility to change the direction.
|
256
|
+
def direction=(dir)
|
257
|
+
@direction = dir == :little ? :little : :big
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
## Extends the TypeStruct class for Ruby simulation.
|
262
|
+
class TypeStruct
|
263
|
+
# Add the possibility to change the direction.
|
264
|
+
def direction=(dir)
|
265
|
+
@direction = dir == :little ? :little : :big
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
##
|
271
|
+
# Describes a behavior.
|
272
|
+
class Behavior
|
273
|
+
|
274
|
+
## Execute the expression.
|
275
|
+
def execute(mode)
|
276
|
+
return self.block.execute(mode)
|
277
|
+
end
|
278
|
+
|
279
|
+
## Initialize the simulation for system +systemT+.
|
280
|
+
def init_sim(systemT)
|
281
|
+
# Process the sensitivity list.
|
282
|
+
# Is it a clocked behavior?
|
283
|
+
events = self.each_event.to_a
|
284
|
+
if events.empty? then
|
285
|
+
# No events, this is not a clock behavior.
|
286
|
+
# And it is not a time behavior neigther.
|
287
|
+
# Generate the events list from the right values.
|
288
|
+
# First get the references.
|
289
|
+
refs = self.block.each_node_deep.select do |node|
|
290
|
+
node.is_a?(RefObject) && !node.leftvalue? &&
|
291
|
+
!node.parent.is_a?(RefObject)
|
292
|
+
end.to_a
|
293
|
+
# Keep only one ref per signal.
|
294
|
+
refs.uniq! { |node| node.fullname }
|
295
|
+
# Remove the inner signals from the list.
|
296
|
+
self.block.each_inner do |inner|
|
297
|
+
refs.delete_if {|r| r.name == inner.name }
|
298
|
+
end
|
299
|
+
# Generate the event.
|
300
|
+
events = refs.map {|ref| Event.new(:anyedge,ref.clone) }
|
301
|
+
# Add them to the behavior for further processing.
|
302
|
+
events.each {|event| self.add_event(event) }
|
303
|
+
end
|
304
|
+
# Now process the events: add the behavior to the corresponding
|
305
|
+
# activation list of the signals of the events.
|
306
|
+
self.each_event do |event|
|
307
|
+
sig = event.ref.object
|
308
|
+
case event.type
|
309
|
+
when :posedge
|
310
|
+
sig.add_posedge(self)
|
311
|
+
when :negedge
|
312
|
+
sig.add_negedge(self)
|
313
|
+
else
|
314
|
+
sig.add_anyedge(self)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
# Now process the block.
|
318
|
+
self.block.init_sim(systemT)
|
319
|
+
end
|
320
|
+
|
321
|
+
## Returns the name of the signal with its hierarchy.
|
322
|
+
def fullname
|
323
|
+
return self.parent.fullname
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
##
|
329
|
+
# Describes a timed behavior.
|
330
|
+
#
|
331
|
+
# NOTE:
|
332
|
+
# * this is the only kind of behavior that can include time statements.
|
333
|
+
# * this kind of behavior is not synthesizable!
|
334
|
+
class TimeBehavior
|
335
|
+
## Get the current time of the behavior.
|
336
|
+
attr_accessor :time
|
337
|
+
## Get the id of the timed behavior.
|
338
|
+
attr_reader :id
|
339
|
+
|
340
|
+
## Initialize the simulation for system +systemT+.
|
341
|
+
def init_sim(systemT)
|
342
|
+
@sim = systemT
|
343
|
+
# Add the behavior to the list of timed behavior.
|
344
|
+
@id = systemT.add_timed_behavior(self)
|
345
|
+
# Initialize the time to 0.
|
346
|
+
@time = 0
|
347
|
+
# Initialize the statements.
|
348
|
+
self.block.init_sim(systemT)
|
349
|
+
end
|
350
|
+
|
351
|
+
# Create the execution thread
|
352
|
+
def make_thread
|
353
|
+
systemT = @sim
|
354
|
+
@thread = Thread.new do
|
355
|
+
# puts "In thread."
|
356
|
+
# sleep
|
357
|
+
systemT.run_init do
|
358
|
+
begin
|
359
|
+
# puts "Starting thread"
|
360
|
+
systemT.run_req(@id)
|
361
|
+
self.block.execute(:par)
|
362
|
+
# puts "Ending thread"
|
363
|
+
rescue => e
|
364
|
+
puts "Got exception: #{e.full_message}"
|
365
|
+
end
|
366
|
+
systemT.remove_timed_behavior(self)
|
367
|
+
systemT.run_done(@id)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
## (Re)start execution of the thread.
|
373
|
+
def run
|
374
|
+
# Run.
|
375
|
+
@thread.run
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
##
|
381
|
+
# Describes an event.
|
382
|
+
class Event
|
383
|
+
# Nothing to do.
|
384
|
+
end
|
385
|
+
|
386
|
+
|
387
|
+
##
|
388
|
+
# Module for extending signal classes with Ruby-level simulation.
|
389
|
+
module SimSignal
|
390
|
+
# Access the current and future value.
|
391
|
+
attr_accessor :c_value, :f_value
|
392
|
+
|
393
|
+
## Initialize the simulation for +systemT+
|
394
|
+
def init_sim(systemT)
|
395
|
+
if self.value then
|
396
|
+
@c_value = self.value.execute(:par).to_value
|
397
|
+
@f_value = @c_value.to_value
|
398
|
+
# puts "init signal value at=#{@c_value.to_bstr}"
|
399
|
+
# The signal is considered active.
|
400
|
+
systemT.add_sig_active(self)
|
401
|
+
else
|
402
|
+
# @c_value = Value.new(self.type,"x" * self.type.width)
|
403
|
+
# @f_value = Value.new(self.type,"x" * self.type.width)
|
404
|
+
@c_value = Value.new(self.type,"x")
|
405
|
+
@f_value = Value.new(self.type,"x")
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
## Adds behavior +beh+ activated on a positive edge of the signal.
|
410
|
+
def add_posedge(beh)
|
411
|
+
@posedge_behaviors ||= []
|
412
|
+
@posedge_behaviors << beh
|
413
|
+
end
|
414
|
+
|
415
|
+
## Adds behavior +beh+ activated on a negative edge of the signal.
|
416
|
+
def add_negedge(beh)
|
417
|
+
@negedge_behaviors ||= []
|
418
|
+
@negedge_behaviors << beh
|
419
|
+
end
|
420
|
+
|
421
|
+
## Adds behavior +beh+ activated on a any edge of the signal.
|
422
|
+
def add_anyedge(beh)
|
423
|
+
@anyedge_behaviors ||= []
|
424
|
+
@anyedge_behaviors << beh
|
425
|
+
end
|
426
|
+
|
427
|
+
## Iterates over the behaviors activated on a positive edge.
|
428
|
+
def each_posedge(&ruby_block)
|
429
|
+
@posedge_behaviors ||= []
|
430
|
+
@posedge_behaviors.each(&ruby_block)
|
431
|
+
end
|
432
|
+
|
433
|
+
## Iterates over the behaviors activated on a negative edge.
|
434
|
+
def each_negedge(&ruby_block)
|
435
|
+
@negedge_behaviors ||= []
|
436
|
+
@negedge_behaviors.each(&ruby_block)
|
437
|
+
end
|
438
|
+
|
439
|
+
## Iterates over the behaviors activated on any edge.
|
440
|
+
def each_anyedge(&ruby_block)
|
441
|
+
@anyedge_behaviors ||= []
|
442
|
+
@anyedge_behaviors.each(&ruby_block)
|
443
|
+
end
|
444
|
+
|
445
|
+
|
446
|
+
## Execute the expression.
|
447
|
+
def execute(mode)
|
448
|
+
# puts "Executing signal=#{self.fullname}"
|
449
|
+
# return mode == :par ? self.c_value : self.f_value
|
450
|
+
return @mode == :seq ? self.f_value : self.c_value
|
451
|
+
end
|
452
|
+
|
453
|
+
## Assigns +value+ the the reference.
|
454
|
+
def assign(mode,value)
|
455
|
+
# Set the next value.
|
456
|
+
@f_value = value
|
457
|
+
# Set the mode.
|
458
|
+
@mode = mode
|
459
|
+
# puts "assign #{value.content} (#{value.content.class}) with self.type.width=#{self.type.width} while value.type.width=#{value.type.width}" if self.name.to_s.include?("idx")
|
460
|
+
# @f_value = value.cast(self.type) # Cast inserted by HDLRuby normally
|
461
|
+
end
|
462
|
+
|
463
|
+
## Assigns +value+ at +index+ (integer or range).
|
464
|
+
def assign_at(mode,value,index)
|
465
|
+
# @f_value = @f_value.assign_at(mode,value,index)
|
466
|
+
# Sets the next value.
|
467
|
+
if (@f_value.equal?(@c_value)) then
|
468
|
+
# Need to duplicate @f_value to avoid side effect.
|
469
|
+
@f_value = Value.new(@f_value.type,@f_value.content.clone)
|
470
|
+
end
|
471
|
+
@f_value[index] = value
|
472
|
+
# Sets the mode
|
473
|
+
@mode = mode
|
474
|
+
end
|
475
|
+
|
476
|
+
|
477
|
+
|
478
|
+
## Returns the name of the signal with its hierarchy.
|
479
|
+
def fullname
|
480
|
+
@fullname ||= self.parent.fullname + ":" + self.name.to_s
|
481
|
+
return @fullname
|
482
|
+
end
|
483
|
+
|
484
|
+
end
|
485
|
+
|
486
|
+
##
|
487
|
+
# Describes a signal.
|
488
|
+
class SignalI
|
489
|
+
include SimSignal
|
490
|
+
end
|
491
|
+
|
492
|
+
##
|
493
|
+
# Describes a constant signal.
|
494
|
+
class SignalC
|
495
|
+
include SimSignal
|
496
|
+
end
|
497
|
+
|
498
|
+
|
499
|
+
##
|
500
|
+
# Describes a system instance.
|
501
|
+
#
|
502
|
+
# NOTE: an instance can actually represented muliple layers
|
503
|
+
# of systems, the first one being the one actually instantiated
|
504
|
+
# in the final RTL code.
|
505
|
+
# This layering can be used for describing software or partial
|
506
|
+
# (re)configuration.
|
507
|
+
class SystemI
|
508
|
+
## Initialize the simulation for system +systemT+.
|
509
|
+
def init_sim(systemT)
|
510
|
+
# Recurse on the Eigen system.
|
511
|
+
self.systemT.init_sim(systemT)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
|
516
|
+
##
|
517
|
+
# Describes a non-HDLRuby code chunk.
|
518
|
+
class Chunk
|
519
|
+
# TODO
|
520
|
+
end
|
521
|
+
|
522
|
+
|
523
|
+
##
|
524
|
+
# Decribes a set of non-HDLRuby code chunks.
|
525
|
+
class Code
|
526
|
+
# TODO
|
527
|
+
end
|
528
|
+
|
529
|
+
|
530
|
+
##
|
531
|
+
# Describes a statement.
|
532
|
+
#
|
533
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
534
|
+
class Statement
|
535
|
+
## Initialize the simulation for system +systemT+.
|
536
|
+
def init_sim(systemT)
|
537
|
+
raise "init_sim must be implemented in class #{self.class}"
|
538
|
+
end
|
539
|
+
|
540
|
+
## Executes the statement in +mode+ (:blocking or :nonblocking)
|
541
|
+
# NOTE: to be overrided.
|
542
|
+
def execute(mode)
|
543
|
+
raise "execute must be implemented in class #{self.class}"
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
|
548
|
+
##
|
549
|
+
# Decribes a transmission statement.
|
550
|
+
class Transmit
|
551
|
+
## Initialize the simulation for system +systemT+.
|
552
|
+
def init_sim(systemT)
|
553
|
+
self.left.init_sim(systemT)
|
554
|
+
end
|
555
|
+
|
556
|
+
## Executes the statement.
|
557
|
+
def execute(mode)
|
558
|
+
self.left.assign(mode,self.right.execute(mode))
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
|
563
|
+
##
|
564
|
+
# Describes an if statement.
|
565
|
+
class If
|
566
|
+
## Initialize the simulation for system +systemT+.
|
567
|
+
def init_sim(systemT)
|
568
|
+
self.yes.init_sim(systemT)
|
569
|
+
self.each_noif { |cond,stmnt| stmnt.init_sim(systemT) }
|
570
|
+
self.no.init_sim(systemT) if self.no
|
571
|
+
end
|
572
|
+
|
573
|
+
## Executes the statement.
|
574
|
+
def execute(mode)
|
575
|
+
# Check the main condition.
|
576
|
+
if !(self.condition.execute(mode).zero?) then
|
577
|
+
self.yes.execute(mode)
|
578
|
+
else
|
579
|
+
# Check the other conditions (elsif)
|
580
|
+
success = false
|
581
|
+
self.each_noif do |cond,stmnt|
|
582
|
+
if !(cond.execute(mode).zero?) then
|
583
|
+
stmnt.execute(mode)
|
584
|
+
success = true
|
585
|
+
break
|
586
|
+
end
|
587
|
+
end
|
588
|
+
self.no.execute(mode) if self.no && !success
|
589
|
+
end
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
|
594
|
+
##
|
595
|
+
# Describes a when for a case statement.
|
596
|
+
class When
|
597
|
+
## Initialize the simulation for system +systemT+.
|
598
|
+
def init_sim(systemT)
|
599
|
+
self.statement.init_sim(systemT)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
|
604
|
+
##
|
605
|
+
# Describes a case statement.
|
606
|
+
class Case
|
607
|
+
## Initialize the simulation for system +systemT+.
|
608
|
+
def init_sim(systemT)
|
609
|
+
self.each_when { |wh| wh.init_sim(systemT) }
|
610
|
+
self.default.init_sim(systemT)
|
611
|
+
end
|
612
|
+
|
613
|
+
## Executes the statement.
|
614
|
+
def execute(mode)
|
615
|
+
unless self.each_when.find do |wh|
|
616
|
+
if wh.match.eql?(self.value.execute(mode)) then
|
617
|
+
wh.statement.execute(mode)
|
618
|
+
return
|
619
|
+
end
|
620
|
+
end
|
621
|
+
self.default.execute(mode)
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
|
627
|
+
##
|
628
|
+
# Describes a delay: not synthesizable.
|
629
|
+
class Delay
|
630
|
+
## Get the time of the delay in pico seconds.
|
631
|
+
def time_ps
|
632
|
+
case self.unit
|
633
|
+
when :ps
|
634
|
+
return self.value.to_i
|
635
|
+
when :ns
|
636
|
+
return self.value.to_i * 1000
|
637
|
+
when :us
|
638
|
+
return self.value.to_i * 1000000
|
639
|
+
when :ms
|
640
|
+
return self.value.to_i * 1000000000
|
641
|
+
when :s
|
642
|
+
return self.value.to_i * 1000000000000
|
643
|
+
end
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
|
648
|
+
##
|
649
|
+
# Describes a print statement: not synthesizable!
|
650
|
+
class Print
|
651
|
+
## Initialize the simulation for system +systemT+.
|
652
|
+
def init_sim(systemT)
|
653
|
+
@sim = systemT
|
654
|
+
end
|
655
|
+
|
656
|
+
## Executes the statement.
|
657
|
+
def execute(mode)
|
658
|
+
self.each_arg.map do |arg|
|
659
|
+
case arg
|
660
|
+
when StringE
|
661
|
+
@sim.show_string(arg.content)
|
662
|
+
when SignalI
|
663
|
+
@sim.show_signal(arg)
|
664
|
+
when SignalC
|
665
|
+
@sim.show_signal(arg)
|
666
|
+
else
|
667
|
+
@sim.show_value(arg.execute(mode))
|
668
|
+
end
|
669
|
+
end
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
|
674
|
+
##
|
675
|
+
# Describes a system instance (re)configuration statement: not synthesizable!
|
676
|
+
class Configure
|
677
|
+
## TODO
|
678
|
+
end
|
679
|
+
|
680
|
+
|
681
|
+
##
|
682
|
+
# Describes a wait statement: not synthesizable!
|
683
|
+
class TimeWait
|
684
|
+
## Initialize the simulation for system +systemT+.
|
685
|
+
def init_sim(systemT)
|
686
|
+
@sim = systemT
|
687
|
+
end
|
688
|
+
|
689
|
+
## Executes the statement.
|
690
|
+
def execute(mode)
|
691
|
+
@behavior ||= self.behavior
|
692
|
+
@behavior.time += self.delay.time_ps
|
693
|
+
# puts "Stopping #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
|
694
|
+
@sim.run_done(@behavior.id)
|
695
|
+
# puts "Rerunning #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
|
696
|
+
@sim.run_req(@behavior.id)
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
|
701
|
+
##
|
702
|
+
# Describes a timed loop statement: not synthesizable!
|
703
|
+
class TimeRepeat
|
704
|
+
## Deprecated
|
705
|
+
end
|
706
|
+
|
707
|
+
|
708
|
+
##
|
709
|
+
# Describes a timed terminate statement: not synthesizable!
|
710
|
+
class TimeTerminate
|
711
|
+
## Initialize the simulation for system +systemT+.
|
712
|
+
def init_sim(systemT)
|
713
|
+
@sim = systemT
|
714
|
+
end
|
715
|
+
|
716
|
+
## Executes the statement.
|
717
|
+
def execute(mode)
|
718
|
+
# @behavior ||= self.get_behavior
|
719
|
+
# @behavior.terminate
|
720
|
+
exit
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
724
|
+
|
725
|
+
##
|
726
|
+
# Describes a block.
|
727
|
+
class Block
|
728
|
+
## Initialize the simulation for system +systemT+.
|
729
|
+
def init_sim(systemT)
|
730
|
+
# Recurse on the inner signals.
|
731
|
+
self.each_inner { |sig| sig.init_sim(systemT) }
|
732
|
+
# Recurde on the statements.
|
733
|
+
self.each_statement { |stmnt| stmnt.init_sim(systemT) }
|
734
|
+
end
|
735
|
+
|
736
|
+
## Executes the statement.
|
737
|
+
def execute(mode)
|
738
|
+
self.each_statement { |stmnt| stmnt.execute(self.mode) }
|
739
|
+
end
|
740
|
+
|
741
|
+
## Returns the name of the signal with its hierarchy.
|
742
|
+
def fullname
|
743
|
+
@fullname ||= self.parent.fullname + ":" + self.name.to_s
|
744
|
+
return @fullname
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
# Describes a timed block.
|
749
|
+
#
|
750
|
+
# NOTE:
|
751
|
+
# * this is the only kind of block that can include time statements.
|
752
|
+
# * this kind of block is not synthesizable!
|
753
|
+
class TimeBlock
|
754
|
+
## Initialize the simulation for system +systemT+.
|
755
|
+
def init_sim(systemT)
|
756
|
+
self.each_statement { |stmnt| stmnt.init_sim(systemT) }
|
757
|
+
end
|
758
|
+
|
759
|
+
## Executes the statement.
|
760
|
+
def execute(mode)
|
761
|
+
# puts "TimeBlock"
|
762
|
+
self.each_statement do |stmnt|
|
763
|
+
# puts "Going to execute statement: #{stmnt}"
|
764
|
+
stmnt.execute(self.mode)
|
765
|
+
end
|
766
|
+
# puts "End TimeBlock"
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
|
771
|
+
##
|
772
|
+
# Describes a connection.
|
773
|
+
class Connection
|
774
|
+
|
775
|
+
## Initialize the simulation for system +systemT+.
|
776
|
+
def init_sim(systemT)
|
777
|
+
# Recurse on the left.
|
778
|
+
self.left.init_sim(systemT)
|
779
|
+
# Process the sensitivity list.
|
780
|
+
# Is it a clocked behavior?
|
781
|
+
events = []
|
782
|
+
# Generate the events list from the right values.
|
783
|
+
# First get the references.
|
784
|
+
refs = self.right.each_node_deep.select do |node|
|
785
|
+
node.is_a?(RefObject) && !node.parent.is_a?(RefObject)
|
786
|
+
end.to_a
|
787
|
+
# Keep only one ref per signal.
|
788
|
+
refs.uniq! { |node| node.fullname }
|
789
|
+
# # Generate the event.
|
790
|
+
# events = refs.map {|ref| Event.new(:anyedge,ref) }
|
791
|
+
# # Add them to the behavior for further processing.
|
792
|
+
# events.each {|event| self.add_event(event) }
|
793
|
+
# Now process the events: add the connection to the corresponding
|
794
|
+
# activation list of the signals of the events.
|
795
|
+
refs.each {|ref| ref.object.add_anyedge(self) }
|
796
|
+
end
|
797
|
+
|
798
|
+
## Executes the statement.
|
799
|
+
def execute(mode)
|
800
|
+
# puts "connection = #{self}"
|
801
|
+
self.left.assign(mode,self.right.execute(mode))
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
|
806
|
+
|
807
|
+
##
|
808
|
+
# Describes an expression.
|
809
|
+
#
|
810
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
811
|
+
class Expression
|
812
|
+
## Executes the expression in +mode+ (:blocking or :nonblocking)
|
813
|
+
# NOTE: to be overrided.
|
814
|
+
def execute(mode)
|
815
|
+
raise "execute must be implemented in class #{self.class}"
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
|
820
|
+
##
|
821
|
+
# Describes a value.
|
822
|
+
class Value
|
823
|
+
# include Vprocess
|
824
|
+
|
825
|
+
## Executes the expression.
|
826
|
+
def execute(mode)
|
827
|
+
return self
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
|
832
|
+
##
|
833
|
+
# Describes a cast.
|
834
|
+
class Cast
|
835
|
+
## Executes the expression.
|
836
|
+
def execute(mode)
|
837
|
+
# Recurse on the child.
|
838
|
+
# res = tocast.execute(mode)
|
839
|
+
# Shall we reverse the content of a concat.
|
840
|
+
if self.child.is_a?(Concat) &&
|
841
|
+
self.type.direction != self.child.type.direction then
|
842
|
+
# Yes, do it.
|
843
|
+
res = self.child.execute(mode,:reverse)
|
844
|
+
else
|
845
|
+
res = self.child.execute(mode)
|
846
|
+
end
|
847
|
+
# Cast it.
|
848
|
+
res = res.cast(self.type,true)
|
849
|
+
# Returns the result.
|
850
|
+
return res
|
851
|
+
end
|
852
|
+
end
|
853
|
+
|
854
|
+
|
855
|
+
##
|
856
|
+
# Describes an operation.
|
857
|
+
#
|
858
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
859
|
+
class Operation
|
860
|
+
## Left to the children.
|
861
|
+
end
|
862
|
+
|
863
|
+
|
864
|
+
##
|
865
|
+
# Describes an unary operation.
|
866
|
+
class Unary
|
867
|
+
## Execute the expression.
|
868
|
+
def execute(mode)
|
869
|
+
# puts "Unary with operator=#{self.operator}"
|
870
|
+
# Recurse on the child.
|
871
|
+
tmp = self.child.execute(mode)
|
872
|
+
# puts "tmp=#{tmp}"
|
873
|
+
# Apply the operator.
|
874
|
+
return tmp.send(self.operator)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
|
879
|
+
##
|
880
|
+
# Describes an binary operation.
|
881
|
+
class Binary
|
882
|
+
## Execute the expression.
|
883
|
+
def execute(mode)
|
884
|
+
# Recurse on the children.
|
885
|
+
tmpl = self.left.execute(mode)
|
886
|
+
tmpr = self.right.execute(mode)
|
887
|
+
# Apply the operator.
|
888
|
+
return tmpl.send(self.operator,tmpr)
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
|
893
|
+
##
|
894
|
+
# Describes a selection operation (generalization of the ternary operator).
|
895
|
+
#
|
896
|
+
# NOTE: choice is using the value of +select+ as an index.
|
897
|
+
class Select
|
898
|
+
## Execute the expression.
|
899
|
+
def execute(mode)
|
900
|
+
# Recurse on the select.
|
901
|
+
tmps = self.select.execute(mode)
|
902
|
+
# Recurse on the selection result.
|
903
|
+
return @choices[tmps.to_i].execute(mode)
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
|
908
|
+
##
|
909
|
+
# Describes a concatenation expression.
|
910
|
+
class Concat
|
911
|
+
## Execute the expression.
|
912
|
+
def execute(mode, reverse=false)
|
913
|
+
# Recurse on the children.
|
914
|
+
tmpe = self.each_expression.map { |expr| expr.execute(mode) }
|
915
|
+
# Ensure the order of the elements matches the type.
|
916
|
+
if (self.type.direction == :little && !reverse) ||
|
917
|
+
(self.type.direction == :big && reverse) then
|
918
|
+
tmpe.reverse!
|
919
|
+
end
|
920
|
+
# puts "concat result=#{Vprocess.concat(*tmpe).to_bstr}"
|
921
|
+
# Concatenate the result.
|
922
|
+
return Vprocess.concat(*tmpe)
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
|
927
|
+
##
|
928
|
+
# Describes a reference expression.
|
929
|
+
#
|
930
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
931
|
+
class Ref
|
932
|
+
## Initialize the simulation for system +systemT+.
|
933
|
+
def init_sim(systemT)
|
934
|
+
raise "assign must be implemented in class #{self.class}"
|
935
|
+
end
|
936
|
+
|
937
|
+
## Assigns +value+ to the reference.
|
938
|
+
# Must be overriden.
|
939
|
+
def assign(mode,value)
|
940
|
+
raise "assign must be implemented in class #{self.class}"
|
941
|
+
end
|
942
|
+
|
943
|
+
## Assigns +value+ at +index+ (integer or range).
|
944
|
+
def assign_at(mode,value,index)
|
945
|
+
raise "assign_at must be implemented in class #{self.class}"
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
|
950
|
+
##
|
951
|
+
# Describes concatenation reference.
|
952
|
+
class RefConcat
|
953
|
+
## Initialize the simulation for system +systemT+.
|
954
|
+
def init_sim(systemT)
|
955
|
+
self.each_ref { |ref| ref.init_sim(systemT) }
|
956
|
+
end
|
957
|
+
|
958
|
+
## Execute the expression.
|
959
|
+
def execute(mode)
|
960
|
+
# Recurse on the children.
|
961
|
+
tmpe = self.each_ref.map { |ref| ref.execute(mode) }
|
962
|
+
# Concatenate the result.
|
963
|
+
return tmpe.reduce(:concat)
|
964
|
+
end
|
965
|
+
|
966
|
+
## Assigns +value+ the the reference.
|
967
|
+
def assign(mode,value)
|
968
|
+
# puts "self.type=#{self.type}"
|
969
|
+
# Flatten the value type.
|
970
|
+
value.type = [value.type.width].to_type
|
971
|
+
pos = 0
|
972
|
+
width = 0
|
973
|
+
# Recurse on the children.
|
974
|
+
@refs.reverse_each do |ref|
|
975
|
+
# puts "ref.type=#{ref.type}"
|
976
|
+
width = ref.type.width
|
977
|
+
# puts "pos=#{pos} width=#{width}, pos+width-1=#{pos+width-1}"
|
978
|
+
# puts "value.content=#{value.content}"
|
979
|
+
# puts "value[(pos+width-1).to_expr..pos.to_expr].content=#{value[(pos+width-1).to_expr..pos.to_expr].content}"
|
980
|
+
ref.assign(mode,value[(pos+width-1).to_expr..pos.to_expr])
|
981
|
+
# Prepare for the next reference.
|
982
|
+
pos += width
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
## Assigns +value+ at +index+ (integer or range).
|
987
|
+
def assign_at(mode,value,index)
|
988
|
+
# Get the refered value.
|
989
|
+
refv = self.execute(mode,value)
|
990
|
+
# Assign to it.
|
991
|
+
refv.assign_at(mode,value,index)
|
992
|
+
# Update the reference.
|
993
|
+
self.assign(mode,refv)
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
|
998
|
+
##
|
999
|
+
# Describes a index reference.
|
1000
|
+
class RefIndex
|
1001
|
+
## Initialize the simulation for system +systemT+.
|
1002
|
+
def init_sim(systemT)
|
1003
|
+
self.ref.init_sim(systemT)
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
## Execute the expression.
|
1007
|
+
def execute(mode)
|
1008
|
+
# Recurse on the children.
|
1009
|
+
tmpr = self.ref.execute(mode)
|
1010
|
+
idx = self.index.execute(mode)
|
1011
|
+
# puts "tmpr=#{tmpr} idx=#{idx} tmpr[idx]=#{tmpr[idx]}"
|
1012
|
+
return tmpr[idx]
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
## Assigns +value+ the the reference.
|
1016
|
+
def assign(mode,value)
|
1017
|
+
# Compute the index.
|
1018
|
+
idx = self.index.execute(mode).to_i
|
1019
|
+
# Assigns.
|
1020
|
+
self.ref.assign_at(mode,value,idx)
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
## Assigns +value+ at +index+ (integer or range).
|
1024
|
+
def assign_at(mode,value,index)
|
1025
|
+
# Get the refered value.
|
1026
|
+
refv = self.execute(mode)
|
1027
|
+
# Assign to it.
|
1028
|
+
refv = refv.assign_at(mode,value,index)
|
1029
|
+
# Update the refered value.
|
1030
|
+
self.assign(mode,refv)
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
|
1036
|
+
##
|
1037
|
+
# Describes a range reference.
|
1038
|
+
class RefRange
|
1039
|
+
## Initialize the simulation for system +systemT+.
|
1040
|
+
def init_sim(systemT)
|
1041
|
+
self.ref.init_sim(systemT)
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
## Execute the expression.
|
1045
|
+
def execute(mode)
|
1046
|
+
# Recurse on the children.
|
1047
|
+
tmpr = self.ref.execute(mode)
|
1048
|
+
rng = (self.range.first.execute(mode))..
|
1049
|
+
(self.range.last.execute(mode))
|
1050
|
+
# puts "tmpr=#{tmpr} rng=#{rng} tmpr[rng]=#{tmpr[rng]}"
|
1051
|
+
return tmpr[rng]
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
## Assigns +value+ the the reference.
|
1055
|
+
def assign(mode,value)
|
1056
|
+
# Compute the index range.
|
1057
|
+
rng = (self.range.first.execute(mode).to_i)..
|
1058
|
+
(self.range.last.execute(mode).to_i)
|
1059
|
+
# Assigns.
|
1060
|
+
self.ref.assign_at(mode,value,rng)
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
## Assigns +value+ at +index+ (integer or range).
|
1064
|
+
def assign_at(mode,value,index)
|
1065
|
+
# Get the refered value.
|
1066
|
+
refv = self.execute(mode)
|
1067
|
+
# Assign to it.
|
1068
|
+
refv = refv.assign_at(mode,value,index)
|
1069
|
+
# Update the refered value.
|
1070
|
+
self.assign(mode,refv)
|
1071
|
+
end
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
|
1075
|
+
##
|
1076
|
+
# Describes a name reference.
|
1077
|
+
class RefName
|
1078
|
+
# Not used?
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
|
1082
|
+
##
|
1083
|
+
# Describe a this reference.
|
1084
|
+
#
|
1085
|
+
# This is the current system.
|
1086
|
+
class RefThis
|
1087
|
+
# Not used.
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
|
1091
|
+
##
|
1092
|
+
# Describes a high-level object reference: no low-level equivalent!
|
1093
|
+
class RefObject
|
1094
|
+
## Initialize the simulation for system +systemT+.
|
1095
|
+
def init_sim(systemT)
|
1096
|
+
@sim = systemT
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
## Execute the expression.
|
1100
|
+
def execute(mode)
|
1101
|
+
return self.object.execute(mode)
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
## Assigns +value+ the the reference.
|
1105
|
+
def assign(mode,value)
|
1106
|
+
self.object.assign(mode,value)
|
1107
|
+
# puts "name=#{self.object.name} value=#{value.to_vstr}"
|
1108
|
+
# puts "c_value=#{self.object.c_value.content}" if self.object.c_value
|
1109
|
+
# puts "f_value=#{self.object.f_value.content}" if self.object.f_value
|
1110
|
+
if !(self.object.c_value.eql?(self.object.f_value)) then
|
1111
|
+
@sim.add_sig_active(self.object)
|
1112
|
+
end
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
## Assigns +value+ at +index+ (integer or range).
|
1116
|
+
def assign_at(mode,value,index)
|
1117
|
+
# puts "name=#{self.object.name} value=#{value.to_vstr}"
|
1118
|
+
self.object.assign_at(mode,value,index)
|
1119
|
+
# puts "c_value=#{self.object.c_value.content}" if self.object.c_value
|
1120
|
+
# puts "f_value=#{self.object.f_value.content}" if self.object.f_value
|
1121
|
+
if !(self.object.c_value.eql?(self.object.f_value)) then
|
1122
|
+
@sim.add_sig_active(self.object)
|
1123
|
+
end
|
1124
|
+
end
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
|
1128
|
+
##
|
1129
|
+
# Describes a string.
|
1130
|
+
#
|
1131
|
+
# NOTE: This is not synthesizable!
|
1132
|
+
class StringE
|
1133
|
+
end
|
1134
|
+
end
|