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