class HDLRuby::Low::Value
Describes a value.
Describes a value.
Extends the Value
class with generation of C text.
Extends the Value
class with generation of hdr text.
Add the conversion to high.
Extends the Value
class with generation of HDLRuby::High
text.
Extends the Value
class with functionality for converting booleans in assignments to select operators.
Extends the Value
class with functionality for extracting expressions from cast.
Extends the Value
class with fixing of types and constants.
Describes a value.
Used to output numbers. Enhance Value
with generation of verilog code.
Attributes
The content of the value.
Public Class Methods
Creates a new value typed as type
and containing numeric content
.
# File lib/HDLRuby/hruby_db.rb, line 329 def initialize(type,content) # Ensures type is from Low::Type type = Type.get(type) # # Ensures the content is valid for low-level hardware. # unless content.is_a?(Numeric) or # content.is_a?(HDLRuby::BitString) then # raise "Invalid type for a value content: #{content.class}." # end # NOW CHECKED BY BASE # Initialize the value structure. super(type,content) end
Public Instance Methods
Compare values.
NOTE: mainly used for being supported by ranges.
# File lib/HDLRuby/hruby_low.rb, line 4499 def <=>(value) value = value.content if value.respond_to?(:content) return self.content <=> value end
Converts booleans in assignments to select operators.
# File lib/HDLRuby/hruby_low_bool2select.rb, line 175 def boolean_in_assign2select # Simple clones. return self.clone end
Extracts the expressions from the casts.
# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 172 def casts_without_expression # Simple clones. return self.clone end
Clones the value (deeply)
# File lib/HDLRuby/hruby_low.rb, line 4525 def clone return Value.new(@type,@content) end
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 4467 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) # Then apply on the type. self.type.each_deep(&ruby_block) # Then apply on the content if possible. if self.content.respond_to?(:each_deep) then self.content.each_deep(&ruby_block) end end
Comparison for hash: structural comparison.
# File lib/HDLRuby/hruby_low.rb, line 4481 def eql?(obj) # General comparison. return false unless super(obj) # Specific comparison. return false unless obj.is_a?(Value) return false unless @content.eql?(obj.content) return true end
Tells if the value is even.
# File lib/HDLRuby/hruby_low.rb, line 4510 def even? return @content.even? end
Explicit the types conversions in the value where type
is the expected type of the condition if any.
# File lib/HDLRuby/hruby_low_fix_types.rb, line 205 def explicit_types(type = nil) # Does the type match the value? if type && !self.type.eql?(type) then # No, update the type of the value. return Value.new(type,self.content) else # yes, return the value as is. return self.clone end end
Hash
function.
# File lib/HDLRuby/hruby_low.rb, line 4491 def hash return [super,@content].hash end
Tells if the expression is immutable (cannot be written.)
# File lib/HDLRuby/hruby_low.rb, line 4459 def immutable? # Values are always immutable. true end
Tells if the value is odd.
# File lib/HDLRuby/hruby_low.rb, line 4515 def odd? return @content.odd? end
Sets the content.
# File lib/HDLRuby/hruby_low_mutable.rb, line 1367 def set_content!(content) unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString) content = HDLRuby::BitString.new(content.to_s) end @content = content end
Generate the text of the equivalent VHDL is case of arithmetic expression.
# File lib/HDLRuby/hruby_low2vhd.rb, line 1143 def to_arith case self.content when HDLRuby::BitString if self.content.specified? then sign = self.type.signed? && self.content.to_s[-1] == "0" ? -1 : 1 return (sign * self.content.to_s.to_i(2)).to_s else return self.content.to_s.upcase end else # NOTE: in VHDL, "z" and "x" must be upcase. return self.content.to_s.upcase end end
Generates the C text for an access to the value. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2c.rb, line 1531 def to_c(level = 0) return "#{Low2C.make_name(self)}()" end
Generates the text of the equivalent c. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2c.rb, line 1543 def to_c_make(level = 0) # The resulting string. res = "" # The header of the value generation. res << " " * level*3 res << "Value #{Low2C.make_name(self)}() {\n" # Declares the data. # Create the bit string. # str = self.content.is_a?(BitString) ? # self.content.to_s : self.content.to_s(2).rjust(32,"0") if self.content.is_a?(BitString) then str = self.content.is_a?(BitString) ? self.content.to_s : self.content.to_s(2).rjust(32,"0") else # sign = self.content>=0 ? "0" : "1" # str = self.content.abs.to_s(2).rjust(width,sign).upcase if self.content >= 0 then str = self.content.to_s(2).rjust(width,"0").upcase else # Compute the extension to the next multiple # of int_width ext_width = (((width-1) / Low2C.int_width)+1)*Low2C.int_width # Convert the string. str = (2**ext_width+self.content).to_s(2).upcase end # puts "content=#{self.content} str=#{str}" end # Is it a fully defined number? # NOTE: bignum values are not supported by the simulation engine # yet, therefore numeric values are limited to 64 max. if str =~ /^[01]+$/ && str.length <= 64 then # Yes, generate a numeral value. res << " " * (level+1)*3 res << "static unsigned long long data[] = { " res << str.scan(/.{1,#{Low2C.int_width}}/m).map do |sub| sub.to_i(2).to_s + "ULL" end.join(",") res << " };\n" # Create the value. res << " " * (level+1)*3 # puts "str=#{str} type width=#{self.type.width} signed? #{type.signed?}" res << "return make_set_value(#{self.type.to_c(level+1)},1," + "data);\n" else # No, generate a bit string value. res << " " * (level+1)*3 # res << "static unsigned char data[] = \"#{str}\";\n" res << "static unsigned char data[] = \"#{str.reverse}\";\n" # Create the value. res << " " * (level+1)*3 res << "return make_set_value(#{self.type.to_c(level+1)},0," + "data);\n" end # Close the value. res << " " * level*3 res << "}\n\n" # Return the result. return res end
Generates the content of the h file.
# File lib/HDLRuby/hruby_low2c.rb, line 1536 def to_ch res = "" return "extern Value #{Low2C.make_name(self)}();" end
How to use when simply obtaining the width
# File lib/HDLRuby/hruby_verilog.rb, line 1477 def to_getrange return "#{self.content.to_verilog}" end
Generates the text of the equivalent hdr text. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2hdr.rb, line 553 def to_hdr(level = 0) if self.content.is_a?(HDLRuby::BitString) then return "_#{self.content}" else return self.content.to_s end end
Creates a new high value expression.
# File lib/HDLRuby/hruby_low2high.rb, line 384 def to_high # Is there a content? if (self.content) then # Yes, use it for creating the new value. return HDLRuby::High::Value.new(self.type.to_high, self.content.to_high) else # puts "Self.type.name=#{self.type.name}" # No (this should be a void value). return HDLRuby::High::Value.new(self.type.to_high,nil) end end
Converts to integer.
# File lib/HDLRuby/hruby_low.rb, line 4520 def to_i return @content.to_i end
Converts the system to Verilog
code. If
it is bit, it is b, and if it is int, it is represented by d. (Example: 4'b0000, 32'd1)
# File lib/HDLRuby/hruby_verilog.rb, line 1462 def to_verilog(unknown = nil) if self.type.base.name.to_s == "bit" return "#{self.type.range.first + 1}'b#{self.content.to_verilog}" elsif self.type.name.to_s == "integer" str = self.content.to_verilog if str[0] == "-" then # Negative value. return "-#{self.type.range.first + 1}'d#{str[1..-1]}" else return "#{self.type.range.first + 1}'d#{str}" end end return "#{self.type.range.first + 1}'b#{self.content.to_verilog}" end
Generates the text of the equivalent VHDL with width
bits. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2vhd.rb, line 1162 def to_vhdl(level = 0, std_logic = false, width = nil) raise "Invalid std_logic argument: #{std_logic}." unless std_logic == true || std_logic == false if self.type.boolean? then # Boolean case if self.content.is_a?(HDLRuby::BitString) return self.zero? ? "false" : "true" else return self.to_i == 0 ? "false" : "true" end end # Other cases # Maybe the value is used as a range or an index. if self.parent.is_a?(RefIndex) or self.parent.is_a?(RefRange) then # Yes, convert to a simple integer. return self.to_i.to_s.upcase end # No, generates as a bit string. width = self.type.width unless width # puts "self.type=#{self.type} width=#{width}" case self.content # when Numeric # return self.content.to_s when HDLRuby::BitString # Compute the extension: in case of signed type, the extension # is the last bit. Otherwise it is 0 unless the last bit # is not defined (Z or X). sign = self.type.signed? ? self.content.to_s[-1] : /[01]/ =~ self.content[-1] ? "0" : self.content[-1] return '"' + self.content.to_s.rjust(width,sign).upcase + '"' else # sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0" sign = self.content>=0 ? "0" : "1" return '"' + self.content.abs.to_s(2).rjust(width,sign).upcase + '"' end end
Gets the bit width of the value.
# File lib/HDLRuby/hruby_low.rb, line 4505 def width return @type.width end