class HDLRuby::Low::Scope
Extends the scope class with support for C allocation of signals.
Describes scopes of system types.
Extends the Scope
class with generation of C text.
Extends the Scope
class with generation of hdr text.
Add the conversion to high.
Extends the Scope
class with functionality for converting par block to seq.
Extends the Scope
class with conversion to symbol.
Extends the Scope
class with generation of HDLRuby::High
text.
Extends the Scope
class with functionality for converting booleans in assignments to select operators.
Extends the Scope
class with functionality for extracting expressions from cast.
Extends the Scope
class with functionality for cleaning up the structure.
Extends the Scope
class with fixing of types and constants.
Describes scopes of system types.
Extends Scope
with the capability of finding one of its inner object by name.
Extends the Scope
class with retrival conversion to symbol.
Extends the Scope
class with functionality for breaking assingments to concats.
Extends the Scope
class with functionality for moving the declarations to the upper namespace.
Extends the Scope
class with functionality for breaking assingments to concats.
Extends the Scope
class with functionality for converting select expressions to case statements.
Attributes
The name of the scope if any
Public Class Methods
Creates a new scope with a possible name
.
# File lib/HDLRuby/hruby_low.rb, line 437 def initialize(name = :"") # Check and set the name. @name = name.to_sym # Initialize the local types. @types = HashName.new # Initialize the local system types. @systemTs = HashName.new # Initialize the sub scopes. @scopes = [] # Initialize the inner signal instance lists. @inners = HashName.new # Initialize the system instances list. @systemIs = HashName.new # Initialize the non-HDLRuby code chunks list. @codes = [] # Initialize the connections list. @connections = [] # Initialize the behaviors lists. @behaviors = [] end
Public Instance Methods
Adds a behavior
.
# File lib/HDLRuby/hruby_low.rb, line 962 def add_behavior(behavior) unless behavior.is_a?(Behavior) raise AnyError,"Invalid class for a behavior: #{behavior.class}" end # Set its parent behavior.parent = self # And add it @behaviors << behavior behavior end
Adds code chunk code
.
# File lib/HDLRuby/hruby_low.rb, line 730 def add_code(code) # Check and add the code chunk. unless code.is_a?(Code) raise AnyError, "Invalid class for a non-hDLRuby code chunk: #{code.class}" end if @codes.include?(code) then raise AnyError, "Code #{code.name} already present." end # Set the parent of the code chunk. code.parent = self # puts "code = #{code}, parent=#{self}" # Add the code chunk. @codes << code code end
Adds a connection
.
# File lib/HDLRuby/hruby_low.rb, line 907 def add_connection(connection) unless connection.is_a?(Connection) raise AnyError, "Invalid class for a connection: #{connection.class}" end # Set the parent of the connection. connection.parent = self # And add it. @connections << connection connection end
Adds inner signal signal
.
# File lib/HDLRuby/hruby_low.rb, line 771 def add_inner(signal) # Check and add the signal. unless signal.is_a?(SignalI) raise AnyError, "Invalid class for a signal instance: #{signal.class}" end # if @inners.has_key?(signal.name) then if @inners.include?(signal) then raise AnyError, "SignalI #{signal.name} already present." end # @inners[signal.name] = signal # Set the parent of the signal. signal.parent = self # And add the signal. @inners.add(signal) return signal end
Adds a new scope
.
# File lib/HDLRuby/hruby_low.rb, line 623 def add_scope(scope) # Check and add the scope. unless scope.is_a?(Scope) raise AnyError, "Invalid class for a system instance: #{scope.class}" end if @scopes.include?(scope) then raise AnyError, "Scope #{scope} already present." end # Set the parent of the scope scope.parent = self # Add the instance @scopes << scope end
Adds system instance systemI
.
# File lib/HDLRuby/hruby_low.rb, line 678 def add_systemI(systemI) # puts "add_systemI with name #{systemI.name}" # Check and add the systemI. unless systemI.is_a?(SystemI) raise AnyError, "Invalid class for a system instance: #{systemI.class}" end if @systemIs.include?(systemI) then raise AnyError, "SystemI #{systemI.name} already present." end # Set the parent of the instance systemI.parent = self # puts "systemI = #{systemI}, parent=#{self}" # Add the instance @systemIs.add(systemI) end
Adds system instance systemT
.
# File lib/HDLRuby/hruby_low.rb, line 517 def add_systemT(systemT) # puts "add_systemT with name #{systemT.name}" # Check and add the systemT. unless systemT.is_a?(SystemT) raise AnyError, "Invalid class for a system type: #{systemT.class}" end if @systemTs.include?(systemT) then raise AnyError, "SystemT #{systemT.name} already present." end # Set the parent of the instance systemT.parent = self # puts "systemT = #{systemT}, parent=#{self}" # Add the instance @systemTs.add(systemT) end
Adds system instance type
.
# File lib/HDLRuby/hruby_low.rb, line 569 def add_type(type) # puts "add_type with name #{type.name}" # Check and add the type. unless type.is_a?(Type) raise AnyError, "Invalid class for a type: #{type.class}" end if @types.include?(type) then raise AnyError, "Type #{type.name} already present." end # Set the parent of the instance type.parent = self # puts "type = #{type}, parent=#{self}" # Add the instance @types.add(type) end
Converts the par sub blocks to seq.
# File lib/HDLRuby/hruby_low2seq.rb, line 41 def blocks2seq! # Recurse on the behaviors. self.each_behavior { |beh| beh.blocks2seq! } return self end
Converts booleans in assignments to select operators.
# File lib/HDLRuby/hruby_low_bool2select.rb, line 35 def boolean_in_assign2select! # Recurse on the sub scopes. self.each_scope(&:boolean_in_assign2select!) # Apply on the connections. self.each_connection(&:boolean_in_assign2select!) # Apply on the behaviors. self.each_behavior do |behavior| behavior.block.boolean_in_assign2select! end return self end
Breaks the assignments to concats.
# File lib/HDLRuby/hruby_low_without_concat.rb, line 40 def break_concat_assigns! # Recruse on the sub scopes. self.each_scope(&:break_concat_assigns!) # Recurse on the statements. self.each_behavior do |behavior| behavior.block.each_block_deep(&:break_concat_assigns!) end # Work on the connections. self.each_connection.to_a.each do |connection| nconnection = connection.break_concat_assigns if nconnection.is_a?(Block) then # The connection has been broken, remove the former # version and add the generated block as a behavior. # self.remove_connection(connection) self.delete_connection!(connection) self.add_behavior(Behavior.new(nconnection)) end end end
Breaks the hierarchical types into sequences of type definitions. Assumes to_upper_space! has been called before.
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 249 def break_types! # The created types by structure. types = {} # Break the local types. self.each_type {|type| type.break_types!(types)} # Break the types in the inners. # self.each_inner {|inner| inner.type.break_types!(types) } self.each_inner do |inner| inner.set_type!(inner.type.break_types!(types)) end # Break the types in the connections. self.each_connection do |connection| connection.left.break_types!(types) connection.right.break_types!(types) end # Break the types in the behaviors. self.each_behavior do |behavior| behavior.each_event do |event| event.ref.break_types!(types) end behavior.block.break_types!(types) end # Add the resulting types. types.each_value {|type| self.add_type(type) } end
Allocates signals within C code using allocator
.
# File lib/HDLRuby/backend/hruby_c_allocator.rb, line 28 def c_code_allocate(allocator) # Interrate on the sub scopes. self.each_scope { |scope| scope.c_code_allocate(allocator) } # Ally thr allocator on the codes. self.each_code { |code| code.c_code_allocate(allocator) } end
Extracts the expressions from the casts.
# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 36 def casts_without_expression! # Recurse on the sub scopes. self.each_scope(&:casts_without_expression!) # Apply on the connections. self.each_connection(&:casts_without_expression!) # Apply on the behaviors. self.each_behavior do |behavior| behavior.block.casts_without_expression! end return self end
Cleans up. keep
includes the list of names to be kept.
# File lib/HDLRuby/hruby_low_cleanup.rb, line 38 def cleanup!(keep) # Complete the list of signals to keep with the signals parts # of the right values of connections and statements or # instance interface. self.each_scope_deep do |scope| # Connections. scope.each_connection do |connection| connection.right.each_node_deep do |node| # Leaf right value references are to keep. # They are either signal of current system or # system instance names. if node.is_a?(RefName) && !node.ref.is_a?(RefName) then keep << node.name end end end # System instances. scope.each_systemI do |systemI| keep << systemI.name end # Behaviors. scope.each_behavior do |behavior| behavior.block.each_node_deep do |node| # Skip left values. next if node.respond_to?(:leftvalue?) && node.leftvalue? # Leaf right value references are to keep. # They are either signal of current system or # system instance names. if node.is_a?(RefName) && !node.ref.is_a?(RefName) then keep << node.name end end end end # Remove the signals and correspondong assignments that are not # to keep. self.delete_unless!(keep) end
Deletes a behavior.
# File lib/HDLRuby/hruby_low_mutable.rb, line 225 def delete_behavior!(behavior) if @behaviors.include?(behavior) then # The behavior is present, delete it. @behaviors.delete(behavior) # And remove its parent. behavior.parent = nil end end
Deletes a connection.
# File lib/HDLRuby/hruby_low_mutable.rb, line 214 def delete_connection!(connection) if @connections.include?(connection) then # The connection is present, delete it. @connections.delete(connection) # And remove its parent. connection.parent = nil end connection end
Deletes an inner.
# File lib/HDLRuby/hruby_low_mutable.rb, line 192 def delete_inner!(signal) if @inners.key?(signal.name) then # The signal is present, delete it. @inners.delete(signal.name) # And remove its parent. signal.parent = nil end signal end
Deletes a scope.
# File lib/HDLRuby/hruby_low_mutable.rb, line 182 def delete_scope!(scope) # Remove the scope from the list @scopes.delete(scope) # And remove its parent. scope.parent = nil # Return the deleted scope scope end
Deletes a systemI.
# File lib/HDLRuby/hruby_low_mutable.rb, line 203 def delete_systemI!(systemI) if @systemIs.key?(systemI.name) then # The instance is present, do remove it. @systemIs.delete(systemI.name) # And remove its parent. systemI.parent = nil end systemI end
Deletes a systemT.
# File lib/HDLRuby/hruby_low_mutable.rb, line 171 def delete_systemT!(systemT) if @systemTs.key?(systemT.name) then # The systemT is present, delete it. @systemTs.delete(systemT.name) # And remove its parent. systemT.parent = nil end systemT end
Deletes a type.
# File lib/HDLRuby/hruby_low_mutable.rb, line 160 def delete_type!(type) if @types.key?(type.name) then # The type is present, delete it. @types.delete(type.name) # And remove its parent. type.parent = nil end type end
Removes the signals and corresponding assignments whose name is not in keep
.
# File lib/HDLRuby/hruby_low_cleanup.rb, line 80 def delete_unless!(keep) # Recurse on the sub scopes. self.each_scope { |scope| scope.delete_unless!(keep) } # Remove the unessary inner signals. self.each_inner.to_a.each do |inner| unless keep.include?(inner.name) then self.delete_inner!(inner) end end # Remove the unessary connections. self.each_connection.to_a.each do |connection| # puts "connection with left=#{connection.left.name}" unless connection.left.each_node_deep.any? { |node| node.is_a?(RefName) && keep.include?(node.name) } self.delete_connection!(connection) end end # Recurse on the blocks. self.each_behavior do |behavior| behavior.block.delete_unless!(keep) end end
Iterates over the behaviors.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 976 def each_behavior(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_behavior) unless ruby_block # A ruby block? Apply it on each behavior. @behaviors.each(&ruby_block) end
Iterates over all the behaviors of the system type and its system instances.
# File lib/HDLRuby/hruby_low.rb, line 1016 def each_behavior_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_behavior_deep) unless ruby_block # A ruby block? # First recurse on the sub scopes. self.each_scope_deep do |scope| scope.each_behavior(&ruby_block) end # Then iterate over current system type's behavior. self.each_behavior(&ruby_block) end
Iterates over all the blocks of the system type and its system instances.
# File lib/HDLRuby/hruby_low.rb, line 1045 def each_block_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_block_deep) unless ruby_block # A ruby block? # Then apply on each sub scope. self.each_scope do |scope| scope.each_block_deep(&ruby_block) end # And apply it on each behavior's block deeply. self.each_behavior do |behavior| behavior.each_block_deep(&ruby_block) end end
Iterates over the non-HDLRuby code chunks.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 750 def each_code(&ruby_block) # puts "each_code from scope=#{self}" # No ruby block? Return an enumerator. return to_enum(:each_code) unless ruby_block # A ruby block? Apply it on each system instance. @codes.each(&ruby_block) end
Iterates over the connections.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 922 def each_connection(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_connection) unless ruby_block # A ruby block? Apply it on each connection. @connections.each(&ruby_block) end
Iterates over all the connections of the system type and its system instances.
# File lib/HDLRuby/hruby_low.rb, line 947 def each_connection_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_connection_deep) unless ruby_block # A ruby block? # First iterate over current system type's connection. self.each_connection(&ruby_block) # Then recurse on the system instances. self.each_systemI do |systemI| systemI.each_connection_deep(&ruby_block) end end
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 1155 def each_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_deep) unless ruby_block # A ruby block? First apply it to current. ruby_block.call(self) # The apply on each type. self.each_type do |type| type.each_deep(&ruby_block) end # Then apply on each systemT. self.each_systemT do |systemT| systemT.each_deep(&ruby_block) end # Then apply on each scope. self.each_scope do |scope| scope.each_deep(&ruby_block) end # Then apply on each inner signal. self.each_inner do |inner| inner.each_deep(&ruby_block) end # Then apply on each systemI. self.each_systemI do |systemI| systemI.each_deep(&ruby_block) end # Then apply on each code. self.each_code do |code| code.each_deep(&ruby_block) end # Then apply on each connection. self.each_connection do |connection| connection.each_deep(&ruby_block) end # Then apply on each behavior. self.each_behavior do |behavior| behavior.each_deep(&ruby_block) end end
Iterates over the inner signals.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 792 def each_inner(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_inner) unless ruby_block # A ruby block? Apply it on each inner signal instance. # @inners.each_value(&ruby_block) @inners.each(&ruby_block) end
Iterates over all the nodes of the system type and its system instances.
# File lib/HDLRuby/hruby_low.rb, line 1090 def each_node_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_node_deep) unless ruby_block # A ruby block? # Then apply on each sub scope. self.each_scope do |scope| scope.each_node_deep(&ruby_block) end # And apply it on each behavior's block deeply. self.each_behavior do |behavior| behavior.each_node_deep(&ruby_block) end end
Iterates over the sub scopes.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 641 def each_scope(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_scope) unless ruby_block # A ruby block? Apply it on each sub scope. @scopes.each(&ruby_block) end
Iterates over the scopes deeply.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 651 def each_scope_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_scope_deep) unless ruby_block # A ruby block? Apply it on self. ruby_block.call(self) # And recurse each sub scope. @scopes.each {|scope| scope.each_scope_deep(&ruby_block) } end
Iterates over all the signals (Equivalent to each_inner
).
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 803 def each_signal(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_signal) unless ruby_block # A ruby block? Apply it on each signal instance. @inners.each(&ruby_block) end
Iterates over all the signals of the scope, its behaviors', its instances' and its sub scopes'.
# File lib/HDLRuby/hruby_low.rb, line 812 def each_signal_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_signal_deep) unless ruby_block # A ruby block? # First iterate over the current system type's signals. self.each_signal(&ruby_block) # Then apply on the behaviors (since in HDLRuby:High, blocks can # include signals). self.each_behavior do |behavior| behavior.block.each_signal_deep(&ruby_block) end # Then recurse on the system instances. self.each_systemI do |systemI| systemI.each_signal_deep(&ruby_block) end # The recurse on the sub scopes. self.each_scope do |scope| scope.each_signal_deep(&ruby_block) end end
Iterates over all the stamements of the system type and its system instances.
# File lib/HDLRuby/hruby_low.rb, line 1074 def each_statement_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_statement_deep) unless ruby_block # A ruby block? # Then apply on each sub scope. self.each_scope do |scope| scope.each_statement_deep(&ruby_block) end # And apply it on each behavior's block deeply. self.each_behavior do |behavior| behavior.each_statement_deep(&ruby_block) end end
Iterates over the system instances.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 698 def each_systemI(&ruby_block) # puts "each_systemI from scope=#{self}" # No ruby block? Return an enumerator. return to_enum(:each_systemI) unless ruby_block # A ruby block? Apply it on each system instance. @systemIs.each(&ruby_block) end
Iterates over the system instances.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 537 def each_systemT(&ruby_block) # puts "each_systemT from scope=#{self}" # No ruby block? Return an enumerator. return to_enum(:each_systemT) unless ruby_block # A ruby block? Apply it on each system instance. @systemTs.each(&ruby_block) end
Iterates over the system instances.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 589 def each_type(&ruby_block) # puts "each_type from scope=#{self}" # No ruby block? Return an enumerator. return to_enum(:each_type) unless ruby_block # A ruby block? Apply it on each system instance. @types.each(&ruby_block) end
Comparison for hash: structural comparison.
# File lib/HDLRuby/hruby_low.rb, line 462 def eql?(obj) return false unless obj.is_a?(Scope) idx = 0 obj.each_systemT do |systemT| return false unless @systemTs[systemT.name].eql?(systemT) idx += 1 end return false unless idx == @systemTs.size idx = 0 obj.each_type do |type| return false unless @types[type.name].eql?(type) idx += 1 end return false unless idx == @types.size idx = 0 obj.each_scope do |scope| return false unless @scopes[idx].eql?(scope) idx += 1 end return false unless idx == @scopes.size idx = 0 obj.each_inner do |inner| return false unless @inners[inner.name].eql?(inner) idx += 1 end return false unless idx == @inners.size idx = 0 obj.each_systemI do |systemI| return false unless @systemIs[systemI.name].eql?(systemI) idx += 1 end return false unless idx == @systemIs.size idx = 0 obj.each_connection do |connection| return false unless @connections[idx].eql?(connection) idx += 1 end return false unless idx == @connections.size idx = 0 obj.each_behavior do |behavior| return false unless @behaviors[idx].eql?(behavior) idx += 1 end return false unless idx == @behaviors.size return true end
Explicit the types conversions in the scope.
# File lib/HDLRuby/hruby_low_fix_types.rb, line 29 def explicit_types! # Recurse on the sub scopes. self.each_scope(&:explicit_types!) # Fix the types of the declarations. self.each_inner(&:explicit_types!) # Fix the types of the connections. self.each_connection(&:explicit_types!) # Fix the types of the behaviors. self.each_behavior(&:explicit_types!) return self end
Extract the behaviors from the scope and returns them into an array.
NOTE: do not recurse into the sub scopes!
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 130 def extract_behaviors! # Get the behaviors. behs = self.each_behavior.to_a # Remove them from the scope. behs.each { |beh| self.delete_behavior!(beh) } # Return the behaviors. return behs end
Extract the connections from the scope and returns them into an array.
NOTE: do not recurse into the sub scopes!
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 142 def extract_connections! # Get the connections. cnxs = self.each_connection.to_a # Remove them from the scope. cnxs.each { |beh| self.delete_connection!(beh) } # Return the connections. return cnxs end
Extract the declares from the scope and returns them into an array.
NOTE: do not recurse into the sub scopes or behaviors!
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 154 def extract_declares! # Ensure there is a name. self.force_name! # The extracted declares. decls = [] # Extract the types. types = [] self.each_type {|type| types << type } types.each {|type| self.delete_type!(type) } # Renames them with the current level. types.each do |type| former = type.name self.extend_name!(type) self.replace_names_subs!(former,type.name) end # Adds the types decls << types # Extract the systemTs. systemTs = [] self.each_systemT {|systemT| systemTs << systemT } systemTs.each {|systemT| self.delete_systemT!(systemT) } # Renames them with the current level. systemTs.each do |systemT| former = systemT.name self.extend_name!(systemT) self.replace_names_subs!(former,systemT.name) end # Adds the systemTs decls << systemTs # Extract the inners. inners = [] self.each_inner {|inner| inners << inner } inners.each {|inner| self.delete_inner!(inner) } # Renames them with the current level. inners.each do |inner| former = inner.name self.extend_name!(inner) self.replace_names_subs!(former,inner.name) end # Adds the inners decls << inners # Extract the systemIs systemIs = [] self.each_systemI {|systemI| systemIs << systemI } systemIs.each {|systemI| self.delete_systemI!(systemI) } # Renames them with the current level. systemIs.each do |systemI| former = systemI.name self.extend_name!(systemI) self.replace_names_subs!(former,systemI.name) end # Adds the systemIs decls << systemIs # Returns the extracted declares. return decls end
Extracts the assignments to port systemI.signal
and returns the resulting reference to a port wire.
NOTE: assumes to_upper_space! and with_port! has been called.
# File lib/HDLRuby/hruby_low2vhd.rb, line 419 def extract_port_assign!(systemI,signal) # Extract the assignment. assign = nil self.each_connection.to_a.each do |connection| if self.port_assign?(connection.left,systemI,signal) then # The left is the port. # Delete the connection. self.delete_connection!(connection) # And return a copy of the right. return connection.right.clone elsif self.port_assign?(connection.right,systemI,signal) then # The right is the port. # Delete the connection. self.delete_connection!(connection) # And return a copy of the left. return connection.left.clone end end # No port found, nothing to do return nil end
Gets an array containing all the inner signals.
# File lib/HDLRuby/hruby_low.rb, line 844 def get_all_inners return each_inner.to_a end
Find an inner object by name
. NOTE: return nil if not found.
# File lib/HDLRuby/hruby_low_resolve.rb, line 41 def get_by_name(name) # puts "getbyname for name=#{name} with self=#{self}" # Ensure the name is a symbol. name = name.to_sym # Look in the signals. found = self.get_inner(name) return found if found # Look in the instances. found = self.each_systemI.find { |systemI| systemI.name == name } return found if found # Maybe it is a sub scope. return self.each_scope.find { |scope| scope.name == name } end
Gets a code chunk by name
.
# File lib/HDLRuby/hruby_low.rb, line 764 def get_code(name) return @codes[name] end
Gets an inner signal by name
.
# File lib/HDLRuby/hruby_low.rb, line 849 def get_inner(name) return @inners[name.to_sym] end
Gets an inner signal by name
, equivalent to get_inner.
# File lib/HDLRuby/hruby_low.rb, line 889 def get_signal(name) return @inners[name] end
Gets a system instance by name
.
# File lib/HDLRuby/hruby_low.rb, line 712 def get_systemI(name) return @systemIs[name] end
Gets a system instance by name
.
# File lib/HDLRuby/hruby_low.rb, line 551 def get_systemT(name) return @systemTs[name] end
Gets a system instance by name
.
# File lib/HDLRuby/hruby_low.rb, line 603 def get_type(name) return @types[name] end
Tells if there is any inner.
# File lib/HDLRuby/hruby_low.rb, line 1029 def has_behavior? return !@behaviors.empty? end
Tells if there is any non-HDLRuby code chunk.
# File lib/HDLRuby/hruby_low.rb, line 759 def has_code? return !@codes.empty? end
Tells if there is any connection.
# File lib/HDLRuby/hruby_low.rb, line 930 def has_connection? return !@connections.empty? end
Tells if there is any inner.
# File lib/HDLRuby/hruby_low.rb, line 834 def has_inner? return !@inners.empty? end
Tells if there is any sub scope.
# File lib/HDLRuby/hruby_low.rb, line 661 def has_scope? return !@scopes.empty? end
Tells if there is any signal, equivalent to has_inner?
# File lib/HDLRuby/hruby_low.rb, line 839 def has_signal? return self.has_inner? end
Tells if there is any system instance.
# File lib/HDLRuby/hruby_low.rb, line 707 def has_systemI? return !@systemIs.empty? end
Tells if there is any system instance.
# File lib/HDLRuby/hruby_low.rb, line 546 def has_systemT? return !@systemTs.empty? end
Tells if there is any system instance.
# File lib/HDLRuby/hruby_low.rb, line 598 def has_type? return !@types.empty? end
Hash
function.
# File lib/HDLRuby/hruby_low.rb, line 510 def hash return [@systemTs,@types,@scopes,@inners,@systemIs,@connections,@behaviors].hash end
Converts initial array of value of signals to assignment in timed blocks (for making the code compatible with verilog translation).
NOTE: Assumes such array as at the top level.
# File lib/HDLRuby/hruby_low_without_concat.rb, line 65 def initial_concat_to_timed! # Gather the signal with concat as initial values. sigs = [] # For the interface signals of the upper system. self.parent.each_signal do |sig| sigs << sig if sig.value.is_a?(Concat) end # For the inner signals of the scope. self.each_signal do |sig| sigs << sig if sig.value.is_a?(Concat) end # No initial concat? End here. return if sigs.empty? # Create a timed block for moving the concat initialization # to it. initial = TimeBlock.new(:seq) self.add_behavior(TimeBehavior.new(initial)) # Adds to it the initializations. sigs.each do |sig| name = sig.name styp = sig.type btyp = styp.base value = sig.value sig.value.each_expression.with_index do |expr,i| left = RefIndex.new(btyp, RefName.new(styp,RefThis.new,name), i.to_expr) initial.add_statement(Transmit.new(left,expr.clone)) end end # Remove the initial values from the signals. sigs.each do |sig| sig.set_value!(nil) end end
Tells if a node
is a reference to an instance's port.
# File lib/HDLRuby/hruby_low_with_port.rb, line 63 def instance_port?(node) # First the node must be a name reference. return false unless node.is_a?(RefName) # Then its sub ref must be a RefName of an instance. sub = node.ref return false unless sub.is_a?(RefName) # puts "@systemIs.keys=#{@systemIs.keys}" # System instance in current scope? return true if @systemIs.key?(sub.name) # if self.parent.is_a?(Scope) then # # Recurse the search in the parent. # return parent.instance_port?(node) # else # # No parent, failure. # return false # end return false end
Returns the last behavior.
# File lib/HDLRuby/hruby_low.rb, line 994 def last_behavior return @behaviors[-1] end
Generates a port wire from a reference.
# File lib/HDLRuby/hruby_low_with_port.rb, line 55 def make_portw(ref) # First generates the name of the port. name = sym2portw_name(ref.to_sym) # Then generate the port wire. return SignalI.new(name,ref.type) end
Maps on the behaviors.
# File lib/HDLRuby/hruby_low_mutable.rb, line 151 def map_behaviors!(&ruby_block) @behaviors.map! do |behavior| behavior = ruby_block.call(behavior) behavior.parent = self unless behavior.parent behavior end end
Maps on the connections.
# File lib/HDLRuby/hruby_low_mutable.rb, line 142 def map_connections!(&ruby_block) @connections.map! do |connection| connection = ruby_block.call(connection) connection.parent = self unless connection.parent connection end end
Maps on the inners.
# File lib/HDLRuby/hruby_low_mutable.rb, line 124 def map_inners!(&ruby_block) @inners.map! do |inner| inner = ruby_block.call(inner) inner.parent = self unless inner.parent inner end end
Maps on the scopes.
# File lib/HDLRuby/hruby_low_mutable.rb, line 115 def map_scopes!(&ruby_block) @scopes.map! do |scope| scope = ruby_block.call(scope) scope.parent = self unless scope.parent scope end end
Maps on the systemIs.
# File lib/HDLRuby/hruby_low_mutable.rb, line 133 def map_systemIs!(&ruby_block) @systemIs.map! do |systemI| systemI = ruby_block.call(systemI) systemI.parent = self unless systemI.parent systemI end end
Maps on the local systemTs.
# File lib/HDLRuby/hruby_low_mutable.rb, line 110 def map_systemTs!(&ruby_block) @systemTs.map(&ruby_block) end
Maps on the local types.
# File lib/HDLRuby/hruby_low_mutable.rb, line 105 def map_types!(&ruby_block) @types.map(&ruby_block) end
Converts the par sub blocks to seq if they are not full par.
# File lib/HDLRuby/hruby_low2seq.rb, line 48 def mixblocks2seq! # Recurse on the behaviors. self.each_behavior { |beh| beh.mixblocs2seq! } end
Converts par blocks within seq blocks to seq blocks.
# File lib/HDLRuby/hruby_low_without_parinseq.rb, line 30 def par_in_seq2seq! # Recruse on the sub scopes. self.each_scope(&:par_in_seq2seq!) # Recurse on the block. self.each_behavior do |behavior| behavior.block.par_in_seq2seq! end end
Gets the parent system, i.e., the parent of the top scope.
# File lib/HDLRuby/hruby_low.rb, line 1202 def parent_system return self.top_scope.parent end
Tells if an expression is a reference to port systemI.signal
.
# File lib/HDLRuby/hruby_low2vhd.rb, line 410 def port_assign?(expr, systemI, signal) return expr.is_a?(RefName) && expr.name == signal.name && expr.ref.is_a?(RefName) && expr.ref.name == systemI.name end
Converts a port wire to a reference to it.
# File lib/HDLRuby/hruby_low_with_port.rb, line 38 def portw2ref(portw) return RefName.new(portw.type,RefThis.new,portw.name) end
Converts a port wire name
to the symbol giving the corresponding HDLRuby
reference.
# File lib/HDLRuby/hruby_low_with_port.rb, line 50 def portw_name2sym(name) return name[1..-1].to_sym end
Replaces recursively former
name by nname
until it is redeclared.
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 238 def replace_names!(former,nname) # Stop here if the name is redeclared. return if self.each_type.find {|type| type.name == former } return if self.each_systemT.find {|systemT| systemT.name == former } return if self.each_inner.find {|inner| inner.name == former } # Recurse on the internals. replace_names_subs!(former,nname) end
Replaces recursively former
name by nname
until it is redeclared in the internals.
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 213 def replace_names_subs!(former,nname) self.each_type do |type| type.replace_names!(former,nname) end self.each_systemT do |systemT| systemT.replace_names!(former,nname) end self.each_scope do |scope| scope.replace_names!(former,nname) end self.each_inner do |inner| inner.replace_names!(former,nname) end self.each_systemI do |systemI| systemI.replace_names!(former,nname) end self.each_connection do |connection| connection.replace_names!(former,nname) end self.each_behavior do |behavior| behavior.replace_names!(former,nname) end end
Reverse iterates over the behaviors.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 986 def reverse_each_behavior(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:reverse_each_behavior) unless ruby_block # A ruby block? Apply it on each behavior. @behaviors.reverse_each(&ruby_block) end
Converts the Select
expressions to Case
statements.
# File lib/HDLRuby/hruby_low_without_select.rb, line 71 def select2case! # Recruse on the sub scopes. self.each_scope(&:select2case!) # Recurse on the blocks. self.each_behavior do |behavior| behavior.block.each_block_deep(&:select2case!) end # Work on the connections. self.each_connection.to_a.each do |connection| selects = connection.extract_selects! if selects.any? then # Selects have been extract, replace the connection # be y behavior. # Generate the block with cases. blk = LowWithoutSelect.selects2block(selects) # Add a transmit replacing the connection. blk.add_statement( Transmit.new(connection.left.clone, connection.right.clone)) # Remove the connection and add a behavior instead. self.delete_connection!(connection) self.add_behavior(Behavior.new(blk)) end end end
Converts symbol sym
representing an HDLRuby
reference to a instance port to a port wire.
# File lib/HDLRuby/hruby_low_with_port.rb, line 44 def sym2portw_name(sym) return ("^" + sym.to_s).to_sym end
Generates the C text of the equivalent HDLRuby
code. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2c.rb, line 360 def to_c(level = 0) # The resulting string. res = "" # Declare the global variable holding the scope. res << "Scope #{Low2C.obj_name(self)};\n\n" # Generate the code makeing the complex sub components. # Generates the code for making signals if any. self.each_signal { |signal| res << signal.to_c(level) } # Generates the code for making signals if any. self.each_systemI { |systemI| res << systemI.to_c(level) } # Generates the code for making sub scopes if any. self.each_scope { |scope| res << scope.to_c(level) } # Generate the code for making the behaviors. self.each_behavior { |behavior| res << behavior.to_c(level) } # Generate the code for making the non-HDLRuby codes. self.each_code { |code| res << code.to_c(level) } # Generate the code of the scope. # The header of the scope. res << " " * level*3 res << "Scope #{Low2C.make_name(self)}() {\n" res << " " * (level+1)*3 res << "Scope scope = malloc(sizeof(ScopeS));\n" res << " " * (level+1)*3 res << "scope->kind = SCOPE;\n"; # Sets the global variable of the scope. res << "\n" res << " " * (level+1)*3 res << "#{Low2C.obj_name(self)} = scope;\n" # Set the owner if any. if self.parent then res << " " * (level+1)*3 res << "scope->owner = (Object)" + "#{Low2C.obj_name(self.parent)};\n" else res << "scope->owner = NULL;\n" end # The name res << " " * (level+1)*3 res << "scope->name = \"#{self.name}\";\n" # Add the system instances declaration. res << " " * (level+1)*3 res << "scope->num_systemIs = #{self.each_systemI.to_a.size};\n" res << " " * (level+1)*3 res << "scope->systemIs = calloc(sizeof(SystemI)," + "scope->num_systemIs);\n" self.each_systemI.with_index do |systemI,i| res << " " * (level+1)*3 res << "scope->systemIs[#{i}] = " + "#{Low2C.make_name(systemI)}();\n" end # Add the inner signals declaration. res << " " * (level+1)*3 res << "scope->num_inners = #{self.each_inner.to_a.size};\n" res << " " * (level+1)*3 res << "scope->inners = calloc(sizeof(SignalI)," + "scope->num_inners);\n" self.each_inner.with_index do |inner,i| res << " " * (level+1)*3 res << "scope->inners[#{i}] = " + "#{Low2C.make_name(inner)}();\n" end # Add the sub scopes. res << " " * (level+1)*3 res << "scope->num_scopes = #{self.each_scope.to_a.size};\n" res << " " * (level+1)*3 res << "scope->scopes = calloc(sizeof(Scope)," + "scope->num_scopes);\n" self.each_scope.with_index do |scope,i| res << " " * (level+1)*3 res << "scope->scopes[#{i}] = " + "#{Low2C.make_name(scope)}();\n" end # Add the behaviors. res << " " * (level+1)*3 res << "scope->num_behaviors = #{self.each_behavior.to_a.size};\n" res << " " * (level+1)*3 res << "scope->behaviors = calloc(sizeof(Behavior)," + "scope->num_behaviors);\n" self.each_behavior.with_index do |behavior,i| res << " " * (level+1)*3 res << "scope->behaviors[#{i}] = " + "#{Low2C.make_name(behavior)}();\n" end # Add the non-HDLRuby codes. res << " " * (level+1)*3 res << "scope->num_codes = #{self.each_code.to_a.size};\n" res << " " * (level+1)*3 res << "scope->codes = calloc(sizeof(Code)," + "scope->num_codes);\n" self.each_code.with_index do |code,i| res << " " * (level+1)*3 res << "scope->codes[#{i}] = " + "#{Low2C.make_name(code)}();\n" end # Generate the Returns of the result. res << "\n" res << " " * (level+1)*3 res << "return scope;\n" # Close the scope. res << " " * level*3 res << "}\n\n" return res end
Generates the content of the h file.
# File lib/HDLRuby/hruby_low2c.rb, line 480 def to_ch res = "" # Declare the global variable holding the signal. res << "extern Scope #{Low2C.obj_name(self)};\n\n" # Generate the access to the function making the scope. res << "extern Scope #{Low2C.make_name(self)}();\n\n" # Generate the accesses to the system instances. self.each_systemI { |systemI| res << systemI.to_ch } # Generate the accesses to the signals. self.each_inner { |inner| res << inner.to_ch } # Generate the access to the sub scopes. self.each_scope { |scope| res << scope.to_ch } # Generate the access to the behaviors. self.each_behavior { |behavior| res << behavior.to_ch } # Generate the access to the non-HDLRuby code. self.each_behavior { |code| res << code.to_ch } return res; end
Generates the text of the equivalent hdr text. level
is the hierachical level of the object and header
tells if the header is to generate or not.
# File lib/HDLRuby/hruby_low2hdr.rb, line 111 def to_hdr(level = 0,header = true) # The resulting string. res = "" # Generate the header if required. if header then res << (" " * (level*3)) << "sub " unless self.name.empty? then res << ":" << Low2HDR.hdr_decl_name(self.name) << " " end res << "do\n" end level = level + 1 if header # Generate the sub types. # Assume the types are TypeDef. self.each_type do |type| res << " " * (level*3) res << "typedef :#{type.name} do\n" res << " " * ((level+1)*3) << type.def.to_hdr(level) res << " " * (level*3) << "end\n" end # Generaste the sub system types. self.each_systemT { |systemT| res << systemT.to_hdr(level) } # Generate the inners declaration. self.each_inner do |inner| res << " " * (level*3) res << inner.type.to_high(level) res << ".inner :" << Low2HDR.hdr_decl_name(inner.name) << "\n" end # Generate the instances. res << "\n" if self.each_inner.any? self.each_systemI do |systemI| res << " " * (level*3) res << systemI.to_hdr(level) << "\n" end # Generate the sub scopes. self.each_scope do |scope| res << scope.to_hdr(level) end # Generate the connections. res << "\n" if self.each_scope.any? self.each_connection do |connection| res << connection.to_hdr(level) end # Generate the behaviors. res << "\n" if self.each_connection.any? self.each_behavior do |behavior| res << behavior.to_hdr(level) end # Close the scope if required. if header then res << " " * ((level-1)*3) << "end\n" end # Return the result. return res end
Creates a new high scope.
# File lib/HDLRuby/hruby_low2high.rb, line 34 def to_high # Create the high scope. res = new HDLRuby::High::Scope.new(self.name) # Add the local types. self.each_type { |t| res.add_type(t.to_high) } # Add the local system types. self.each_systemT { |s| res.add_systemT(s.to_high) } # Add the sub scopes. self.each_scope { |s| res.add_scope(s.to_high) } # Add the inner signals. self.each_inner { |i| res.add_inner(i.to_high) } # Add the system instances. self.each_systemI { |s| res.add_systemI(s.to_high) } # Add the non-HDLRuby cofe chunks. self.each_code { |c| res.add_code(c.to_high) } # Add the connections. self.each_connection { |c| res.add_connection(c.to_high) } # Add the behaviors. self.each_behavior { |b| res.add_behavior(b.to_high) } return res end
Moves the declarations to the upper namespace.
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 86 def to_upper_space! # First recurse. # On the sub scopes. self.each_scope(&:to_upper_space!) # On the behaviors. self.each_behavior(&:to_upper_space!) # Then extract the declarations from the sub scope. decls = self.each_scope.map(&:extract_declares!) # And do the same with the behaviors'. decls << self.each_behavior.map(&:extract_declares!) # Reinsert the extracted declares to self. decls.flatten.each do |decl| if decl.is_a?(Type) then self.add_type(decl) elsif decl.is_a?(SystemT) then self.add_systemT(decl) elsif decl.is_a?(SignalI) then self.add_inner(decl) elsif decl.is_a?(SystemI) then self.add_systemI(decl) else raise AnyError, "Internal error: invalid class for a declaration: #{decl.class}" end end # Extract the behaviors of the sub scopes. behs = self.each_scope.map(&:extract_behaviors!).flatten # Reinsert them to self. behs.each { |beh| self.add_behavior(beh) } # Extract the connections of the sub scopes. cnxs = self.each_scope.map(&:extract_connections!).flatten # Reinsert them to self. cnxs.each { |beh| self.add_connection(beh) } # Now can delete the sub scopes since they are empty. self.each_scope.to_a.each { |scope| self.delete_scope!(scope) } end
Generates the text of the equivalent HDLRuby::High
code. level
is the hierachical level of the object and
# File lib/HDLRuby/hruby_low2vhd.rb, line 443 def to_vhdl(level = 0) # The resulting string. res = "" # Generate the architecture's header # The instances' headers self.each_systemI do |systemI| systemT = systemI.systemT # Its entity res << (" " * level*3) res << "component #{Low2VHDL.entity_name(systemT.name)}\n" res << (" " * (level+1)*3) # Its ports res << "port(\n" # Inputs systemT.each_input do |input| res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(input.name) << ": in " res << input.type.to_vhdl << ";\n" end # Outputs systemT.each_output do |output| res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(output.name) << ": out " res << output.type.to_vhdl << ";\n" end # Inouts systemT.each_inout do |inout| res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(inout.name) << ": inout " res << inout.type.to_vhdl << ";\n" end # Remove the last ";" for conforming with VHDL syntax. res[-2..-1] = "\n" if res[-2] == ";" res << " " * ((level+1)*3) # Close the port declaration. res << ");\n" # Close the component. res << " " * (level*3) res << "end component;\n\n" end # Generate the architecture's type definition. # It is assumed that these types are all TypeDef. self.each_type do |type| res << (" " * level*3) res << "type #{Low2VHDL.vhdl_name(type.name)} is " res << type.def.to_vhdl(level+1) res << ";\n" end ## Generates the required mux functions. mtps = [] # The mux functions to generate by type. # Gather the mux functions to generate. self.each_scope_deep do |scope| # Checks the connections. scope.each_connection do |connection| connection.right.each_node_deep do |node| if node.is_a?(Select) then mtps << [node.type,node.each_choice.to_a.size] end end end # Checks the statements. scope.each_behavior do |behavior| behavior.block.each_node_deep do |node| if node.is_a?(Select) then mtps << [node.type,node.each_choice.to_a.size] end end end end # Generate the gathered functions (only one per type). mtps.uniq! mtps.each do |type,num| res << Low2VHDL.mux_function(type,num," " * level*3) end # Generate the inner signals declaration. self.each_inner do |inner| res << " " * (level * 3) # General signal or constant signal? res << (inner.is_a?(SignalC) ? "constant " : "signal ") # Signal name. res << Low2VHDL.vhdl_name(inner.name) << ": " # Signal type. res << inner.type.to_vhdl(level) # Signal value. if inner.value then if inner.value.is_a?(Concat) then # Concat are to be given the expected type of the # elements for casting them equally. # res << " := " << inner.value.to_vhdl(inner.type.base,level) res << " := " << inner.value.to_vhdl(level,inner.type.base) else res << " := " << inner.value.to_vhdl(level) end end res << ";\n" end # Generate the architecture's content. res << " " * ((level-1)*3) << "begin\n" # Generate the instances connections. self.each_systemI do |systemI| # Its Declaration. res << " " * (level*3) res << Low2VHDL.vhdl_name(systemI.name) << ": " systemT = systemI.systemT res << Low2VHDL.entity_name(systemT.name).to_s << "\n" res << " " * ((level+1)*3) # Its ports res << "port map(\n" # Inputs systemT.each_input do |input| ref = self.extract_port_assign!(systemI,input) if ref then res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(input.name) << " => " res << ref.to_vhdl(level) res << ",\n" end end # Outputs systemT.each_output do |output| ref = self.extract_port_assign!(systemI,output) if ref then res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(output.name) << " => " res << ref.to_vhdl(level) res << ",\n" end end # Inouts systemT.each_inout do |inout| ref = self.extract_port_assign!(systemI,inout) if ref then res << " " * ((level+2)*3) res << Low2VHDL.vhdl_name(inout.name) << " => " res << ref.to_vhdl(level) res << ",\n" end end # Remove the last ";" for conforming with VHDL syntax. res[-2..-1] = "\n" if res[-2] == "," # Close the port map declaration. res << " " * ((level+1)*3) res << ");\n" end # Generate the connections. res << "\n" if self.each_scope.any? self.each_scope_deep do |scope| scope.each_connection do |connection| res << connection.to_vhdl([],level) end end # Generate the behaviors. # Current scope's res << "\n" if self.each_connection.any? self.each_scope_deep do |scope| scope.each_behavior do |behavior| res << behavior.to_vhdl(level) end end return res end
Gets the top scope, i.e. the first scope of the current system.
# File lib/HDLRuby/hruby_low.rb, line 1197 def top_scope return self.parent.is_a?(SystemT) ? self : self.parent.top_scope end
Converts to a port-compatible system.
NOTE: the result is the same scope.
# File lib/HDLRuby/hruby_low_with_port.rb, line 86 def with_port! # # Recurse on the sub scope. # self.each_scope(&:with_port!) # Gather the references to instance ports. # Also remember if the references were left values or not. refs = [] ref_sym2leftvalue = {} self.each_block_deep do |block| block.each_node_deep do |node| if instance_port?(node) then # puts "port for node: #{node.ref.name}.#{node.name}" refs << node ref_sym2leftvalue[node.to_sym] = node.leftvalue? end end end self.each_connection do |connection| connection.each_node_deep do |node| if instance_port?(node) then # puts "port for node: #{node.ref.name}.#{node.name}" # puts "leftvalue? #{node.leftvalue?}" refs << node ref_sym2leftvalue[node.to_sym] = node.leftvalue? end end end # Generate the port wire from the refs. ref_sym2portw = {} refs.each { |ref| ref_sym2portw[ref.to_sym] = make_portw(ref) } # Declare the port wires. ref_sym2portw.each_value { |portw| self.add_inner(portw.clone) } # Replace the references by their corresponding port wires. self.each_block_deep do |block| block.each_node_deep do |node| node.map_nodes! do |expr| portw = ref_sym2portw[expr.to_sym] portw ? portw2ref(portw) : expr end end end self.each_connection do |connection| connection.each_node_deep do |node| node.map_nodes! do |expr| portw = ref_sym2portw[expr.to_sym] portw ? portw2ref(portw) : expr end end end # Finally adds the connections with the port wires. ref_sym2portw.each do |sym,portw| ref = sym.to_hdr if ref_sym2leftvalue[sym] then # The reference was a left value, assign the port wire # to the ref. self.add_connection( Connection.new(ref.clone,portw2ref(portw)) ) else # The reference was a right value, assign it to the # port wire. self.add_connection( Connection.new(portw2ref(portw),ref.clone) ) end end return self end