Class: HDLRuby::Low::Value

Inherits:
Expression
  • Object
show all
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_bool2select.rb

Overview

Extends the Value class with functionality for converting booleans in assignments to select operators.

Direct Known Subclasses

High::Value

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods inherited from Expression

#boolean?, #break_types!, #each_node, #each_node_deep, #each_ref_deep, #extract_selects_to!, #leftvalue?, #map_nodes!, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #statement, #use_name?

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(type, content) ⇒ Value

Creates a new value typed +type+ and containing +content+.



329
330
331
332
333
334
335
336
337
338
339
# 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

Instance Attribute Details

#contentObject (readonly)

The content of the value.



3898
3899
3900
# File 'lib/HDLRuby/hruby_low.rb', line 3898

def content
  @content
end

Instance Method Details

#<=>(value) ⇒ Object

Compare values.

NOTE: mainly used for being supported by ranges.



3937
3938
3939
3940
# File 'lib/HDLRuby/hruby_low.rb', line 3937

def <=>(value)
    value = value.content if value.respond_to?(:content)
    return self.content <=> value
end

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



161
162
163
164
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 161

def boolean_in_assign2select
    # Simple clones.
    return self.clone
end

#cloneObject

Clones the value (deeply)



3963
3964
3965
# File 'lib/HDLRuby/hruby_low.rb', line 3963

def clone
    return Value.new(@type,@content)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


3919
3920
3921
3922
3923
3924
3925
3926
# File 'lib/HDLRuby/hruby_low.rb', line 3919

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

#even?Boolean

Tells if the value is even.

Returns:

  • (Boolean)


3948
3949
3950
# File 'lib/HDLRuby/hruby_low.rb', line 3948

def even?
    return @content.even?
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the value where +type+ is the expected type of the condition if any.



191
192
193
194
195
196
197
198
199
200
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 191

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

#hashObject

Hash function.



3929
3930
3931
# File 'lib/HDLRuby/hruby_low.rb', line 3929

def hash
    return [super,@content].hash
end

#odd?Boolean

Tells if the value is odd.

Returns:

  • (Boolean)


3953
3954
3955
# File 'lib/HDLRuby/hruby_low.rb', line 3953

def odd?
    return @content.odd?
end

#set_content!(content) ⇒ Object

Sets the content.



1297
1298
1299
1300
1301
1302
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1297

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

#to_arithObject

Generate the text of the equivalent VHDL is case of arithmetic expression.



1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1119

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

#to_c(level = 0) ⇒ Object

Generates the C text for an access to the value. +level+ is the hierachical level of the object.



1420
1421
1422
# File 'lib/HDLRuby/hruby_low2c.rb', line 1420

def to_c(level = 0)
    return "#{Low2C.make_name(self)}()"
end

#to_c_make(level = 0) ⇒ Object

Generates the text of the equivalent c. +level+ is the hierachical level of the object.



1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
# File 'lib/HDLRuby/hruby_low2c.rb', line 1432

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?
    if str =~ /^[01]+$/ 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

#to_chObject

Generates the content of the h file.



1425
1426
1427
1428
# File 'lib/HDLRuby/hruby_low2c.rb', line 1425

def to_ch
    res = ""
    return "extern Value #{Low2C.make_name(self)}();"
end

#to_getrangeObject

How to use when simply obtaining the width



1421
1422
1423
# File 'lib/HDLRuby/hruby_verilog.rb', line 1421

def to_getrange
    return "#{self.content.to_verilog}"
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



553
554
555
556
557
558
559
# File 'lib/HDLRuby/hruby_low2high.rb', line 553

def to_high(level = 0)
    if self.content.is_a?(HDLRuby::BitString) then
        return "_#{self.content}"
    else
        return self.content.to_s
    end
end

#to_iObject

Converts to integer.



3958
3959
3960
# File 'lib/HDLRuby/hruby_low.rb', line 3958

def to_i
    return @content.to_i
end

#to_verilog(unknown = nil) ⇒ Object

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)



1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
# File 'lib/HDLRuby/hruby_verilog.rb', line 1406

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

#to_vhdl(level = 0, std_logic = false, width = nil) ⇒ Object

Generates the text of the equivalent VHDL with +width+ bits. +level+ is the hierachical level of the object.



1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1138

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

#widthObject

Gets the bit width of the value.



3943
3944
3945
# File 'lib/HDLRuby/hruby_low.rb', line 3943

def width
    return @type.width
end