class HDLRuby::Low::Connection
Describes a connection.
NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.
Describes a connection.
NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.
Extends the Connection
class with generation of C text.
Extends the Connection
class with generation of hdr text.
Add the conversion to high.
Extends the Connection
class with generation of HDLRuby::High
text.
Extends the Connection
class with fixing of types and constants.
Describes a connection.
NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.
Extends the Connection
class with functionality for breaking assingments to concats.
Translate expression of combination circuit. Enhance Connection
with generation of verilog code.
Public Instance Methods
Method used for array.
# File lib/HDLRuby/hruby_verilog.rb, line 1566 def array_connection(left,right) expression = right.each_expression.to_a result = "" expression[0..-2].each do |expression| result << " assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n" end result << " assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n" return result end
Break the assignments to concats.
NOTE: when breaking generates a new Block
containing the broken
assignments.
# File lib/HDLRuby/hruby_low_without_concat.rb, line 225 def break_concat_assigns # puts "break_concat_assigns with self=#{self}" # Is the left value a RefConcat? self.left.each_node_deep do |node| if node.is_a?(RefConcat) then # Yes, must break. Create the resulting sequential # block that will contain the new assignements. block = Block.new(:seq) # Create an intermediate signal for storing the # right value. Put it in the top scope. top_scope = self.top_scope aux = top_scope.add_inner( SignalI.new(HDLRuby.uniq_name,self.right.type) ) # puts "new signal: #{aux.name}" aux = RefName.new(aux.type,RefThis.new,aux.name) # Set a default value to avoid latch generation. block.insert_statement!(0, Transmit.new(aux.clone,Value.new(aux.type,0))) # Replace the concat in the copy of the left value. if left.eql?(node) then # node was the top of left, replace here. nleft = aux else # node was inside left, replace within left. nleft = self.left.clone nleft.each_node_deep do |ref| ref.map_nodes! do |sub| sub.eql?(node) ? aux.clone : sub end end end # Recreate the transmit and add it to the block. block.add_statement( Transmit.new(nleft,self.right.clone) ) # And assign its part to each reference of the # concat. pos = 0 node.each_ref.reverse_each do |ref| # Compute the range to assign. range = ref.type.width-1+pos .. pos # Single or multi-bit range? sbit = range.first == range.last # Convert the range to an HDLRuby range for # using is the resulting statement. # Create and add the statement. if sbit then # Single bit. # Generate the index. idx = Value.new(Integer,range.first) # Generate the assignment. block.add_statement( Transmit.new(ref.clone, # RefIndex.new(aux.type.base, aux.clone, idx))) RefIndex.new(bit, aux.clone, idx))) else # Multi-bits. # Compute the type of the right value. # rtype = TypeVector.new(:"",aux.type.base,range) rtype = TypeVector.new(:"",bit,range) # Generate the range. range = Value.new(Integer,range.first) .. Value.new(Integer,range.last) # Generate the assignment. block.add_statement( Transmit.new(ref.clone, RefRange.new(rtype, aux.clone, range))) end pos += ref.type.width end # puts "Resulting block=#{block.to_vhdl}" # Return the resulting block return block end end # No, nothing to do. return self end
Comparison for hash: structural comparison.
# File lib/HDLRuby/hruby_low.rb, line 4282 def eql?(obj) return false unless obj.is_a?(Connection) return super(obj) end
Hash
function.
# File lib/HDLRuby/hruby_low.rb, line 4288 def hash return super end
Gets the parent system, i.e., the parent of the top scope.
# File lib/HDLRuby/hruby_low.rb, line 4303 def parent_system return self.top_scope.parent end
Replace node by corresponding replacement from node2reassign
that is a table whose entries are: node
the node to replace rep
the replacement of the node ref
the reference where to reassign the node.
# File lib/HDLRuby/hruby_low_mutable.rb, line 1294 def reassign_expressions!(node2reassign) # Build the replacement table. node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h # Performs the replacements. node2rep_done = {} # The performed replacements. # Replace on the sons of the left. node2rep_done.merge!(self.left.replace_expressions!(node2rep)) # Replace on the sons of the left. node2rep_done.merge!(self.right.replace_expressions!(node2rep)) # Shall we replace the right? rep = node2rep[self.right] if rep then # Yes, do it. rep = rep.clone node = self.right # node.set_parent!(nil) self.set_right!(rep) node2rep_done[node] = rep end # Assign the replaced nodes. node2rep_done.each do |node,rep| reassign = node2reassign[node][1].clone self.parent.add_connection( Connection.new(reassign,node.clone)) end end
Creates a new high connection.
# File lib/HDLRuby/hruby_low2high.rb, line 364 def to_high return HDLRuby::High::Connection.new(self.left.to_high, self.right.to_high) end
# File lib/HDLRuby/hruby_verilog.rb, line 1576 def to_verilog # Decide whether to assign to array by if. # NOTICE: Now array assignment is done trough constant initialization, will be treated later. # if self.right.respond_to? (:each_expression) # array_connection(self.left,self.right); # else cnt = 0 # Use count. bit = -2 # Used to determine the bit width. Since there are 0 and default, -2. # Measure the number of choices on the right side (case statement if it is 3 or more). if self.right.respond_to? (:each_choice) choice = self.right.each_choice.to_a choice.each do |choice| bit += 1 end end # Three or more choices. if (bit > 2) # The bit width is obtained by converting the bit into a binary number and obtaining the size. bit = bit.to_s(2).size # Create a case statement. result = " begin\n" result << " case(#{self.right.select.to_verilog})\n" # Output other than the last one in order. choice[0..-2].each do |choice| result << " #{bit}'#{cnt}: #{self.left.to_verilog} = #{choice.to_verilog}\n" cnt += 1 end # At the end, it becomes default because it needs default. result << " default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n" result << " endcase\n" result << " end\n" return result end # It is not a case so call it normally. return " assign #{self.left.to_verilog} = #{self.right.to_verilog};\n" # end end
Gets the top block, i.e. the first block of the current behavior.
# File lib/HDLRuby/hruby_low.rb, line 4293 def top_block raise AnyError, "Connections are not within blocks." end
Gets the top scope, i.e. the first scope of the current system.
# File lib/HDLRuby/hruby_low.rb, line 4298 def top_scope return self.parent.is_a?(Scope) ? self.parent : self.parent.top_scope end