lib/HDLRuby/hruby_rcsim.rb in HDLRuby-2.11.11 vs lib/HDLRuby/hruby_rcsim.rb in HDLRuby-2.11.12
- old
+ new
@@ -15,11 +15,10 @@
## Provides tools for converting HDLRuby::High objects to C.
module High2C
## Gives the width of an int in the current computer.
def self.int_width
- # puts "int_width=#{[1.to_i].pack("i").size*8}"
return [1.to_i].pack("i").size*8
end
## Converts string +str+ to a C-compatible string.
def self.c_string(str)
@@ -103,34 +102,22 @@
# Sets the owner if any.
if rcowner then
RCSim.rcsim_set_owner(@rcsystemT,rcowner)
end
# Create and add the interface signals.
- # self.each_input do |sig|
- # rcsig = sig.to_rcsim(@rcsystemT)
- # RCSim.rcsim_add_systemT_input(@rcsystemT,rcsig)
- # end
if self.each_input.any? then
RCSim.rcsim_add_systemT_inputs(@rcsystemT,
self.each_input.map do |sig|
sig.to_rcsim(@rcsystemT)
end)
end
- # self.each_output do |sig|
- # rcsig = sig.to_rcsim(@rcsystemT)
- # RCSim.rcsim_add_systemT_output(@rcsystemT,rcsig)
- # end
if self.each_output.any? then
RCSim.rcsim_add_systemT_outputs(@rcsystemT,
self.each_output.map do |sig|
sig.to_rcsim(@rcsystemT)
end)
end
- # self.each_inout do |sig|
- # rcsig = sig.to_rcsim(@rcsystemT)
- # RCSim.rcsim_add_systemT_inout(@rcsystemT,rcsig)
- # end
if self.each_inout.any? then
RCSim.rcsim_add_systemT_inouts(@rcsystemT,
self.each_inout.map do |sig|
sig.to_rcsim(@rcsystemT)
end)
@@ -172,34 +159,34 @@
# Of the scope is a son of a SystemT, the owner of the sub objects
# will be this systemT. Otherwise, it is the scope.
subowner = self.parent.is_a?(SystemT) ? rcowner : @rcscope
# Create and add the inner signals.
- # self.each_inner do |sig|
- # rcsig = sig.to_rcsim(@rcscope)
- # RCSim.rcsim_add_scope_inner(@rcscope,rcsig)
- # end
if self.each_inner.any? then
RCSim.rcsim_add_scope_inners(@rcscope,self.each_inner.map do|sig|
# sig.to_rcsim(@rcscope)
sig.to_rcsim(subowner)
end)
end
# Create and add the system instances.
- # self.each_systemI do |sys|
- # rcsys = sys.to_rcsim(@rcscope)
- # RCSim.rcsim_add_scope_systemI(@rcscope,rcsys)
- # end
if self.each_systemI.any? then
RCSim.rcsim_add_scope_systemIs(@rcscope,
self.each_systemI.map do |sys|
# sys.to_rcsim(@rcscope)
sys.to_rcsim(subowner)
end)
end
+ # Create and add the sub scopes.
+ if self.each_scope.any? then
+ RCSim.rcsim_add_scope_scopes(@rcscope,self.each_scope.map do|sub|
+ # sub.to_rcsim(@rcscope)
+ sub.to_rcsim(subowner)
+ end)
+ end
+
# # Create and add the behaviors.
# if self.each_behavior.any? then
# RCSim.rcsim_add_scope_behaviors(@rcscope,
# self.each_behavior.map do |beh|
# # beh.to_rcsim(@rcscope)
@@ -222,22 +209,10 @@
end
# Create and add the codes.
# TODO!!
- # Create and add the sub scopes.
- # self.each_scope do |sub|
- # rcsub = sub.to_rcsim(@rcscope)
- # RCSim.rcsim_add_scope_scope(@rcscope,rcsub)
- # end
- if self.each_scope.any? then
- RCSim.rcsim_add_scope_scopes(@rcscope,self.each_scope.map do|sub|
- # sub.to_rcsim(@rcscope)
- sub.to_rcsim(subowner)
- end)
- end
-
return @rcscope
end
end
@@ -320,10 +295,24 @@
## Module for extending the behavior classes for hybrid Ruby-C simulation.
module RCSimBehavior
attr_reader :rcbehavior
+ # Add sub leaf events from +sig+ of +type+.
+ def add_sub_events(type,sig)
+ if sig.each_signal.any? then
+ # The event is hierarchical, recurse.
+ sig.each_signal do |sub|
+ self.add_sub_events(type,sub)
+ end
+ else
+ # Te event is not hierarchical, add it.
+ ref = RefObject.new(this,sig)
+ self.add_event(Event.new(type,ref))
+ end
+ end
+
# Generate the C description of the behavior comming from object
# whose C description is +rcowner+
def to_rcsim(rcowner)
# puts "to_rcsim for behavior=#{self}"
# Process the sensitivity list.
@@ -348,27 +337,33 @@
end
# Generate the event.
events = refs.map {|ref| Event.new(:anyedge,ref.clone) }
# Add them to the behavior for further processing.
events.each {|event| self.add_event(event) }
+ else
+ # Maybe there are event on hierachical signals.
+ events.each do |event|
+ if event.ref.object.each_signal.any? then
+ # This is a hierarchical event, remove it.
+ self.delete_event!(event)
+ # And replace it by event of the subs of the signal.
+ self.add_sub_events(event.type,event.ref)
+ end
+ end
end
# Create the behavior C object.
# puts "make behavior with self.class=#{self.class}"
@rcbehavior = RCSim.rcsim_make_behavior(self.is_a?(TimeBehavior))
# Set the owner.
RCSim.rcsim_set_owner(@rcbehavior,rcowner)
# Create and add the events.
- # self.each_event do |ev|
- # RCSim.rcsim_add_behavior_event(@rcbehavior,ev.to_rcsim)
- # end
if self.each_event.any? then
RCSim.rcsim_add_behavior_events(@rcbehavior,
self.each_event.map do |ev|
- # puts "adding event: #{ev.ref.object.name}(#{ev.type})"
ev.to_rcsim(@rcbehavior)
end)
end
# Create and add the block.
@@ -423,10 +418,16 @@
# puts "to_rcsim for signal=(#{self.name})#{self}, @rcsignalI=#{@rcsignalI}"
# Set the owner.
RCSim.rcsim_set_owner(@rcsignalI,rcowner)
+ # Create and add the sub signals if any.
+ RCSim.rcsim_add_signal_signals(@rcsignalI,
+ self.each_signal.each.map do |sig|
+ sig.to_rcsim(@rcsignalI)
+ end)
+
# Set the initial value if any.
if self.value then
RCSim.rcsim_set_signal_value(@rcsignalI,self.value.to_rcsim)
end
@@ -478,14 +479,10 @@
# Set the owner.
RCSim.rcsim_set_owner(@rcsystemI,rcowner)
# Add the alternate system types.
- # self.each_systemT do |systemT|
- # rcsys = systemT.to_rcsim(@rcsystemI)
- # RCSim.rcsim_add_systemI_systemT(@rcsystemI,rcsys)
- # end
if self.each_systemI.any? then
RCSim.rcsim_add_systemI_systemTs(@rcsystemI,
self.each_systemT.select do|sys|
sys != self.systemT
end.map do |sys|
@@ -545,13 +542,10 @@
def to_rcsim
# Create the print C object.
@rcstatement = RCSim.rcsim_make_print()
# Adds the arguments.
- # self.each_arg do |arg|
- # RCSim.rcsim_add_print_arg(@rcstatement,arg.to_rcsim)
- # end
if self.each_arg.any? then
RCSim.rcsim_add_print_args(@rcstatement,
self.each_arg.map(&:to_rcsim))
end
@@ -590,13 +584,10 @@
@rcstatement = RCSim.rcsim_make_hif(self.condition.to_rcsim,
self.yes.to_rcsim,
self.no ? self.no.to_rcsim : nil)
# Add the alternate ifs if any.
- # self.each_noif do |cond,stmnt|
- # RCSim.rcsim_add_hif_noif(@rcstatement,cond.to_rcsim,stmnt.to_rcsim)
- # end
rcsim_conds = self.each_noif.map {|cond,stmnt| cond.to_rcsim }
rcsim_stmnts = self.each_noif.map {|cond,stmnt| stmnt.to_rcsim }
if rcsim_conds.any? then
RCSim.rcsim_add_hif_noifs(@rcstatement,rcsim_conds,rcsim_stmnts)
end
@@ -620,14 +611,10 @@
# Create the hardware case C object.
@rcstatement = RCSim.rcsim_make_hcase(self.value.to_rcsim,
self.default ? self.default.to_rcsim : nil)
# Add the hardware whens.
- # self.each_when do |wh|
- # RCSim.rcsim_add_hcase_when(@rcstatement,
- # wh.match.to_rcsim,wh.statement.to_rcsim)
- # end
rcsim_matches = self.each_when.map {|wh| wh.match.to_rcsim }
rcsim_stmnts = self.each_when.map {|wh| wh.statement.to_rcsim }
if rcsim_matches.any? then
RCSim.rcsim_add_hcase_whens(@rcstatement,rcsim_matches,
rcsim_stmnts)
@@ -693,24 +680,18 @@
if owner then
RCSim.rcsim_set_owner(@rcstatement,owner)
end
# Add the inner signals.
- # self.each_inner do |inner|
- # RCSim.rcsim_add_block_inner(@rcstatement,inner.to_rcsim(@rcstatement))
- # end
if self.each_inner.any? then
RCSim.rcsim_add_block_inners(@rcstatement,
self.each_inner.map do |sig|
sig.to_rcsim(@rcstatement)
end)
end
# Add the statements.
- # self.each_statement do |stmnt|
- # RCSim.rcsim_add_block_statement(@rcstatement,stmnt.to_rcsim)
- # end
if self.each_statement.any? then
RCSim.rcsim_add_block_statements(@rcstatement,
self.each_statement.map do |stmnt|
stmnt.to_rcsim
end)
@@ -733,10 +714,24 @@
## Extends the Connection class for hybrid Ruby-C simulation.
class Connection
attr_reader :rcbehavior
+ # Add recursively any event to +rcevs+ for activativing the
+ # connection from signal +sig+ attached to +rcbehavior+
+ def self.add_rcevents(sig,rcevs,rcbehavior)
+ # Recurse on sub signals if any.
+ sig.each_signal do |sub|
+ Connection.add_rcevents(sub,rcevs,rcbehavior)
+ end
+ # Apply on the current node.
+ rcsig = sig.is_a?(SignalI) ? sig.rcsignalI : sig.rcsignalC
+ ev = RCSim.rcsim_make_event(:anyedge,rcsig)
+ RCSim.rcsim_set_owner(ev,rcbehavior)
+ rcevs << ev
+ end
+
# Generate the C description of the connection.
# +rcowner+ is a link to the C description of the owner scope.
def to_rcsim(rcowner)
# puts "make behavior with self.class=#{self.class}"
# Create the connection C object, actually it is a behavior.
@@ -747,13 +742,14 @@
# Create and add the events.
rcevs = []
self.right.each_node_deep do |node|
if node.is_a?(RefObject) && !node.parent.is_a?(RefObject) then
- ev = RCSim.rcsim_make_event(:anyedge,node.to_rcsim)
- RCSim.rcsim_set_owner(ev,@rcbehavior)
- rcevs << ev
+ Connection.add_rcevents(node.object,rcevs,@rcbehavior)
+ # ev = RCSim.rcsim_make_event(:anyedge,node.to_rcsim)
+ # RCSim.rcsim_set_owner(ev,@rcbehavior)
+ # rcevs << ev
end
end
if rcevs.any? then
RCSim.rcsim_add_behavior_events(@rcbehavior,rcevs)
end
@@ -890,13 +886,10 @@
# Create the select C object.
rcexpression = RCSim.rcsim_make_select(self.type.to_rcsim,
self.select.to_rcsim)
# Add the choice expressions. */
- # self.each_choice do |choice|
- # rcsim_add_select_choice(rcexpression,choice.to_rcsim)
- # end
if self.each_choice.any? then
RCSim.rcsim_add_select_choices(rcexpression,
self.each_choice.map(&:to_rcsim))
end
@@ -914,13 +907,10 @@
# Create the concat C object.
rcexpression = RCSim.rcsim_make_concat(self.type.to_rcsim,
self.type.direction)
# Add the concatenated expressions. */
- # self.each_expression do |expr|
- # RCSim.rcsim_add_concat_expression(rcexpression,expr.to_rcsim)
- # end
if self.each_expression.any? then
RCSim.rcsim_add_concat_expressions(rcexpression,
self.each_expression.map(&:to_rcsim))
end
@@ -952,13 +942,10 @@
# Create the reference concat C object.
rcref = RCSim.rcsim_make_refConcat(self.type.to_rcsim,
self.type.direction)
# Add the concatenated expressions. */
- # self.each_ref do |ref|
- # RCSim.rcsim_add_refConcat_ref(rcref,ref.to_rcsim)
- # end
if self.each_ref.any? then
RCSim.rcsim_add_refConcat_refs(rcref,self.each_ref.map(&:to_rcsim))
end
return rcref
@@ -1016,17 +1003,39 @@
## Extends the RefObject class for hybrid Ruby-C simulation.
class RefObject
# attr_reader :rcref
# alias_method :rcexpression, :rcref
+
+ # Generate the C description of the reference object with sub signals.
+ def to_rcsim_subs
+ # Create the reference concat C object.
+ # The reference is always big endian, it is the sequence
+ # of element which is reversed if necessary.
+ rcref = RCSim.rcsim_make_refConcat(self.type.to_rcsim,:big)
+ # self.type.direction)
+ # Add the concatenated expressions. */
+ if self.object.each_signal.any? then
+ iter = self.object.each_signal
+ iter = iter.reverse_each if self.type.direction == :big
+ RCSim.rcsim_add_refConcat_refs(rcref, iter.map do|sig|
+ sig.is_a?(SignalI) ? sig.rcsignalI : sig.rcsignalC
+ end)
+ end
+
+ return rcref
+ end
+
# Generate the C description of the reference object.
def to_rcsim
# puts "object=#{self.object.name}(#{self.object})"
if self.object.is_a?(SignalI)
- return self.object.rcsignalI
+ return self.object.each_signal.any? ? self.to_rcsim_subs :
+ self.object.rcsignalI
elsif self.object.is_a?(SignalC)
- return self.object.rcsignalC
+ return self.object.each_signal.any? ? self.to_rcsim_subs :
+ self.object.rcsignalC
else
raise "Invalid object: #{self.object}"
end
end
end