Class: HDLRuby::Low::Value
- Inherits:
-
Expression
- Object
- Expression
- HDLRuby::Low::Value
- Defined in:
- lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_viz.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
Describes a value.
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.
-
#to_viz_node(parent) ⇒ Object
Converts the value to a Viz flow node under +parent+.
-
#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!, #fix_scope_refnames!, #leftvalue?, #map_nodes!, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #statement, #to_viz_names, #use_name?
Methods included from Low2Symbol
Methods included from Hparent
#absolute_ref, #hierarchy, #no_parent!, #scope
Constructor Details
#initialize(type, content) ⇒ Value
Creates a new value typed +type+ and containing +content+.
5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 |
# File 'lib/HDLRuby/hruby_low.rb', line 5034 def initialize(type,content) super(type) if content.nil? then # Handle the nil content case. unless type.eql?(Void) then raise AnyError, "A value with nil content must have the Void type." end @content = content elsif content.is_a?(FalseClass) then @content = 0 elsif content.is_a?(TrueClass) then @content = 1 else # Checks and set the content: Ruby Numeric and HDLRuby # BitString are supported. Strings or equivalent are # converted to BitString. unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString) # content = HDLRuby::BitString.new(content.to_s) content = content.to_s if self.type.unsigned? && content[0] != "0" then # content = "0" + content.rjust(self.type.width,content[0]) if content[0] == "1" then # Do not extend the 1, but 0 instead. content = "0" + content.rjust(self.type.width,"0") else # But extend the other. content = "0" + content.rjust(self.type.width,content[0]) end end content = HDLRuby::BitString.new(content) end @content = content if (@content.is_a?(Numeric) && self.type.unsigned?) then # Adjust the bits for unsigned. @content = @content & (2**self.type.width-1) end end end |
Instance Attribute Details
#content ⇒ Object (readonly)
The content of the value.
5031 5032 5033 |
# File 'lib/HDLRuby/hruby_low.rb', line 5031 def content @content end |
Instance Method Details
#<=>(value) ⇒ Object
Compare values.
NOTE: mainly used for being supported by ranges.
5115 5116 5117 5118 |
# File 'lib/HDLRuby/hruby_low.rb', line 5115 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.
192 193 194 195 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 192 def boolean_in_assign2select # Simple clones. return self.clone end |
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
176 177 178 179 180 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 176 def casts_without_expression! # # Simple clones. # return self.clone return self end |
#clone ⇒ Object
Clones the value (deeply)
5141 5142 5143 |
# File 'lib/HDLRuby/hruby_low.rb', line 5141 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.
5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 |
# File 'lib/HDLRuby/hruby_low.rb', line 5083 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.
5097 5098 5099 5100 5101 5102 5103 5104 |
# File 'lib/HDLRuby/hruby_low.rb', line 5097 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.
5126 5127 5128 |
# File 'lib/HDLRuby/hruby_low.rb', line 5126 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.
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 243 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.
5107 5108 5109 |
# File 'lib/HDLRuby/hruby_low.rb', line 5107 def hash return [super,@content].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5075 5076 5077 5078 |
# File 'lib/HDLRuby/hruby_low.rb', line 5075 def immutable? # Values are always immutable. true end |
#odd? ⇒ Boolean
Tells if the value is odd.
5131 5132 5133 |
# File 'lib/HDLRuby/hruby_low.rb', line 5131 def odd? return @content.odd? end |
#set_content!(content) ⇒ Object
Sets the content.
1344 1345 1346 1347 1348 1349 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1344 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.
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1179 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.
2141 2142 2143 2144 2145 2146 2147 2148 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2141 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.
2152 2153 2154 2155 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2152 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)
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 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2169 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 & 0xFFFF_FFFF_FFFF_FFFF}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
2159 2160 2161 2162 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2159 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
1687 1688 1689 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1687 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.
567 568 569 570 571 572 573 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 567 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.
415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 415 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.
5136 5137 5138 |
# File 'lib/HDLRuby/hruby_low.rb', line 5136 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)
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1646 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.type.signed? 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}'sb#{str}" else str = self.content.to_s(2) str = "0" * (self.type.width-str.length) + str return "#{self.type.width}'sb#{str}" end else return "#{self.type.width}'b#{self.content.to_s(2)}" end # return "#{self.type.width}'b#{str}" else str = self.content.to_verilog if self.content.negative? then return "#{str.length}'sb#{str}" else return "#{str.length}'b#{str}" end 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.
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1198 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 |
#to_viz_node(parent) ⇒ Object
Converts the value to a Viz flow node under +parent+.
4891 4892 4893 4894 |
# File 'lib/HDLRuby/hruby_viz.rb', line 4891 def to_viz_node(parent) node = HDLRuby::Viz::Node.new(:value,parent,self.content.to_s) return node end |
#width ⇒ Object
Gets the bit width of the value.
5121 5122 5123 |
# File 'lib/HDLRuby/hruby_low.rb', line 5121 def width return @type.width end |