Class: HDLRuby::Low::Value
- Inherits:
-
Expression
- Object
- Base::Expression
- Expression
- HDLRuby::Low::Value
- Defined in:
- lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2hdr.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,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Extends the Value class with functionality for extracting expressions from cast.
Direct Known Subclasses
Constant Summary collapse
- @@made_values =
Set.new
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#content ⇒ Object
readonly
The content of the value.
Attributes inherited from Expression
Attributes included from Hparent
Instance Method Summary collapse
-
#<=>(value) ⇒ Object
Compare values.
-
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
-
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
-
#clone ⇒ Object
Clones the value (deeply).
-
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#even? ⇒ Boolean
Tells if the value is even.
-
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the value where +type+ is the expected type of the condition if any.
-
#hash ⇒ Object
Hash function.
-
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.).
-
#initialize(type, content) ⇒ Value
constructor
Creates a new value typed +type+ and containing +content+.
-
#odd? ⇒ Boolean
Tells if the value is odd.
-
#set_content!(content) ⇒ Object
Sets the content.
-
#to_arith ⇒ Object
Generate the text of the equivalent VHDL is case of arithmetic expression.
-
#to_c(res, level = 0) ⇒ Object
Generates the C text for an access to the value.
-
#to_c_expr(res, level = 0) ⇒ Object
Generates the C text for an expression access to the value.
-
#to_c_make(res, level = 0) ⇒ Object
Generates the text of the equivalent c.
-
#to_ch(res) ⇒ Object
Generates the content of the h file.
-
#to_getrange ⇒ Object
How to use when simply obtaining the width.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high value expression.
-
#to_i ⇒ Object
Converts to integer.
-
#to_verilog(unknown = nil) ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(level = 0, std_logic = false, width = nil) ⇒ Object
Generates the text of the equivalent VHDL with +width+ bits.
-
#width ⇒ Object
Gets the bit width of the value.
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
Methods included from Hparent
#hierarchy, #no_parent!, #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
#content ⇒ Object (readonly)
The content of the value.
4697 4698 4699 |
# File 'lib/HDLRuby/hruby_low.rb', line 4697 def content @content end |
Instance Method Details
#<=>(value) ⇒ Object
Compare values.
NOTE: mainly used for being supported by ranges.
4774 4775 4776 4777 |
# File 'lib/HDLRuby/hruby_low.rb', line 4774 def <=>(value) value = value.content if value.respond_to?(:content) return self.content <=> value end |
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
187 188 189 190 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 187 def boolean_in_assign2select # Simple clones. return self.clone end |
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
172 173 174 175 176 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 172 def casts_without_expression! # # Simple clones. # return self.clone return self end |
#clone ⇒ Object
Clones the value (deeply)
4800 4801 4802 |
# File 'lib/HDLRuby/hruby_low.rb', line 4800 def clone return Value.new(@type,@content) end |
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 |
# File 'lib/HDLRuby/hruby_low.rb', line 4742 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 |
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
4756 4757 4758 4759 4760 4761 4762 4763 |
# File 'lib/HDLRuby/hruby_low.rb', line 4756 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.
4785 4786 4787 |
# File 'lib/HDLRuby/hruby_low.rb', line 4785 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.
224 225 226 227 228 229 230 231 232 233 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 224 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 ⇒ Object
Hash function.
4766 4767 4768 |
# File 'lib/HDLRuby/hruby_low.rb', line 4766 def hash return [super,@content].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
4734 4735 4736 4737 |
# File 'lib/HDLRuby/hruby_low.rb', line 4734 def immutable? # Values are always immutable. true end |
#odd? ⇒ Boolean
Tells if the value is odd.
4790 4791 4792 |
# File 'lib/HDLRuby/hruby_low.rb', line 4790 def odd? return @content.odd? end |
#set_content!(content) ⇒ Object
Sets the content.
1379 1380 1381 1382 1383 1384 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1379 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_arith ⇒ Object
Generate the text of the equivalent VHDL is case of arithmetic expression.
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1155 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(res, level = 0) ⇒ Object
Generates the C text for an access to the value. +level+ is the hierachical level of the object.
2097 2098 2099 2100 2101 2102 2103 2104 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2097 def to_c(res,level = 0) # res << Low2C.make_name(self) << "()" # return res res << (" " * (level*3)) # res << "d=" << Low2C.make_name(self) << "();\n" res << "push(" << Low2C.make_name(self) << "());\n" return res end |
#to_c_expr(res, level = 0) ⇒ Object
Generates the C text for an expression access to the value. +level+ is the hierachical level of the object.
2108 2109 2110 2111 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2108 def to_c_expr(res,level = 0) res << Low2C.make_name(self) << "()" return res end |
#to_c_make(res, level = 0) ⇒ Object
Generates the text of the equivalent c. +level+ is the hierachical level of the object. def to_c_make(level = 0)
2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2125 def to_c_make(res,level = 0) # Check is the value maker is already present. maker = Low2C.make_name(self); return res if @@made_values.include?(maker) @@made_values.add(maker) # The header of the value generation. res << " " * level*3 res << "Value " << maker << "() {\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 int data[] = { " # res << str.scan(/.{1,#{Low2C.int_width}}/m).reverse.map do |sub| # sub.to_i(2).to_s # + "ULL" # end.join(",") # res << ", 0" if (str.length <= 32) # 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" # res << "return make_set_value(" # self.type.to_c(res,level+1) # res << ",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" # res << "return make_set_value(" # self.type.to_c(res,level+1) # res << ",0,data);\n" # end # Declares the data. if self.content.is_a?(::Integer) then if self.type.width <= 64 then res << " " * (level+1)*3 res << "Value value = make_value(" self.type.to_c(res,level+1) res << ",1);\n" # res << " " * (level+1)*3 # res << "value->numeric = 1;\n" res << " " * (level+1)*3 res << "value->capacity = 0;\n" res << " " * (level+1)*3 res << "value->data_str = NULL;\n" res << " " * (level+1)*3 if self.content.bit_length <= 63 then res << "value->data_int = #{self.content}LLU;\n" else res << "value->data_int = " res << "#{self.content & 0xFFFFFFFFFFFF}LLU;\n" end # Close the value. res << " " * (level+1)*3 res << "return value;\n" res << " " * level*3 res << "}\n\n" # Return the result. return res else str = self.content.to_s(2) # if str[-1] == "-" then # str[-1] = "1" # elsif str[-1] == "1" then # str = "0" + str # end if self.content < 0 then str = (2**self.type.width + self.content).to_s(2) str = "1" * (self.type.width-str.length) + str else str = self.content.to_s(2) str = "0" * (self.type.width-str.length) + str end str.reverse! end else str = content.to_s.reverse end str = str.ljust(self.type.width,str[-1]) res << " " * (level+1)*3 res << "Value value = make_value(" self.type.to_c(res,level+1) res << ",1);\n" res << " " * (level+1)*3 res << "value->numeric = 0;\n" res << " " * (level+1)*3 res << "value->capacity = #{str.length+1};" res << " " * (level+1)*3 res << "value->data_str = calloc(value->capacity,sizeof(char));\n" res << " " * (level+1)*3 res << "strcpy(value->data_str,\"#{str}\");\n" # Close the value. res << " " * (level+1)*3 res << "return value;\n" res << " " * level*3 res << "}\n\n" # Return the result. return res end |
#to_ch(res) ⇒ Object
Generates the content of the h file. def to_ch
2115 2116 2117 2118 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2115 def to_ch(res) res << "extern Value " << Low2C.make_name(self) << "();" return res end |
#to_getrange ⇒ Object
How to use when simply obtaining the width
1576 1577 1578 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1576 def to_getrange return "#{self.content.to_verilog}" end |
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.
553 554 555 556 557 558 559 |
# 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 |
#to_high ⇒ Object
Creates a new high value expression.
384 385 386 387 388 389 390 391 392 393 394 395 |
# 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 |
#to_i ⇒ Object
Converts to integer.
4795 4796 4797 |
# File 'lib/HDLRuby/hruby_low.rb', line 4795 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)
1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1543 def to_verilog(unknown = nil) # if self.type.base.name.to_s == "bit" # if self.type.unsigned? then # # return "#{self.type.range.first + 1}'b#{self.content.to_verilog}" # return "#{self.type.width}'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}" if self.content.is_a?(Numeric) then if self.content < 0 then # str = (2**self.type.width + self.content).to_s(2) str = self.content.to_s(2) str = "0" * (self.type.width-str.length+1) + str[1..-1] return "-#{self.type.width}'b#{str}" else str = self.content.to_s(2) str = "0" * (self.type.width-str.length) + str return "#{self.type.width}'b#{str}" end # return "#{self.type.width}'b#{str}" else str = self.content.to_verilog return "#{str.length}'b#{str}" end 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.
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1174 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 |
#width ⇒ Object
Gets the bit width of the value.
4780 4781 4782 |
# File 'lib/HDLRuby/hruby_low.rb', line 4780 def width return @type.width end |