Class: HDLRuby::Low::Case
- Defined in:
- lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2seq.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_cleanup.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_with_var.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/hruby_low_without_namespace.rb
Overview
Extends the When class with functionality for moving the declarations to the upper namespace.
Direct Known Subclasses
Constant Summary
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#default ⇒ Object
The default block.
-
#value ⇒ Object
readonly
The tested value.
Attributes included from Hparent
Instance Method Summary collapse
-
#add_when(w) ⇒ Object
Adds possible when case +w+.
-
#blocks2seq! ⇒ Object
Converts the par sub blocks to seq.
-
#boolean_in_assign2select! ⇒ Object
Converts booleans in assignments to select operators.
-
#clone ⇒ Object
Clones the Case (deeply).
-
#delete_unless!(keep) ⇒ Object
Removes the signals and corresponding assignments whose name is not in +keep+.
-
#delete_when!(w) ⇒ Object
Delete a when.
-
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
-
#each_block_deep(&ruby_block) ⇒ Object
Iterates over all the blocks contained in the current block.
-
#each_node(&ruby_block) ⇒ Object
Iterates over the children (including the value).
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#each_statement_deep(&ruby_block) ⇒ Object
Iterates over all the statements contained in the current statement.
-
#each_when(&ruby_block) ⇒ Object
Iterates over the match cases.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types! ⇒ Object
Explicit the types conversions in the case.
-
#extract_declares! ⇒ Object
Extract the declares from the scope and returns them into an array.
-
#extract_selects! ⇒ Object
Extract the Select expressions.
-
#hash ⇒ Object
Hash function.
-
#initialize(value, default = nil, whens = []) ⇒ Case
constructor
Creates a new case statement whose excution flow is decided from +value+ with a possible cases given in +whens+ and +default + (can be set later).
-
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children (including the value).
-
#map_whens!(&ruby_block) ⇒ Object
Maps on the whens.
-
#mix?(mode = nil) ⇒ Boolean
Tell if there is a mix block.
-
#replace_expressions!(node2rep) ⇒ Object
Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement.
-
#replace_names!(former, nname) ⇒ Object
Replaces recursively +former+ name by +nname+ until it is redeclared.
-
#set_default!(default) ⇒ Object
Sets the default.
-
#set_value!(value) ⇒ Object
Sets the value.
-
#to_c(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#to_upper_space! ⇒ Object
Moves the declarations to the upper namespace.
- #to_verilog(mode = nil) ⇒ Object
-
#to_vhdl(vars, level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#with_var(upper = nil) ⇒ Object
Converts to a variable-compatible case where +upper+ is the upper block if any.
Methods inherited from Statement
#add_blocks_code, #block, #break_types!, #parent_system, #scope, #top_block, #top_scope, #with_boolean!
Methods included from Low2Symbol
Methods included from Hparent
Constructor Details
#initialize(value, default = nil, whens = []) ⇒ Case
Creates a new case statement whose excution flow is decided from +value+ with a possible cases given in +whens+ and +default
- (can be set later)
3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 |
# File 'lib/HDLRuby/hruby_low.rb', line 3056 def initialize(value, default = nil, whens = []) # Check and set the value. unless value.is_a?(Expression) raise AnyError, "Invalid class for a value: #{value.class}" end @value = value # And set its parent. value.parent = self # Checks and set the default case if any. self.default = default if default # Check and add the whens. @whens = [] whens.each { |w| self.add_when(w) } end |
Instance Attribute Details
#default ⇒ Object
The default block.
3051 3052 3053 |
# File 'lib/HDLRuby/hruby_low.rb', line 3051 def default @default end |
#value ⇒ Object (readonly)
The tested value
3048 3049 3050 |
# File 'lib/HDLRuby/hruby_low.rb', line 3048 def value @value end |
Instance Method Details
#add_when(w) ⇒ Object
Adds possible when case +w+.
3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 |
# File 'lib/HDLRuby/hruby_low.rb', line 3092 def add_when(w) # Check +w+. unless w.is_a?(When) raise AnyError, "Invalid class for a when: #{w.class}" end # Add it. @whens << w # And set the parent of +w+. w.parent = self end |
#blocks2seq! ⇒ Object
Converts the par sub blocks to seq.
154 155 156 157 158 159 160 |
# File 'lib/HDLRuby/hruby_low2seq.rb', line 154 def blocks2seq! # Recurse on the whens. self.each_when(&:blocks2seq!) # Converts the default if any. self.default.blocks2seq! if self.default return self end |
#boolean_in_assign2select! ⇒ Object
Converts booleans in assignments to select operators.
109 110 111 112 113 114 115 116 117 118 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 109 def boolean_in_assign2select! # No need to apply on the value! # # Apply on the value. # self.set_value!(self.value.boolean_in_assign2select) # Apply on the whens. self.each_when(&:boolean_in_assign2select!) # Apply on the default if any. self.default.boolean_in_assign2select! if self.default return self end |
#clone ⇒ Object
Clones the Case (deeply)
3190 3191 3192 3193 3194 3195 3196 3197 |
# File 'lib/HDLRuby/hruby_low.rb', line 3190 def clone # Clone the default if any. default = @default ? @default.clone : nil # Clone the case. return Case.new(@value.clone,default,(@whens.map do |w| w.clone end) ) end |
#delete_unless!(keep) ⇒ Object
Removes the signals and corresponding assignments whose name is not in +keep+.
157 158 159 160 161 162 |
# File 'lib/HDLRuby/hruby_low_cleanup.rb', line 157 def delete_unless!(keep) # Recurse on the whens. self.each_when {|w| w.delete_unless!(keep) } # Recurse on the default if any. self.default.delete_unless!(keep) if self.default end |
#delete_when!(w) ⇒ Object
Delete a when.
795 796 797 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 795 def delete_when!(w) @whens.delete(w) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
3155 3156 3157 3158 3159 3160 3161 3162 3163 |
# File 'lib/HDLRuby/hruby_low.rb', line 3155 def each_block(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_block) unless ruby_block # A ruby block? # Apply it on each when's block. self.each_when { |w| w.each_block(&ruby_block) } # And apply it on the default if any. ruby_block.call(@default) if @default end |
#each_block_deep(&ruby_block) ⇒ Object
Iterates over all the blocks contained in the current block.
3166 3167 3168 3169 3170 3171 3172 3173 3174 |
# File 'lib/HDLRuby/hruby_low.rb', line 3166 def each_block_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_block_deep) unless ruby_block # A ruby block? # Apply it on each when's block. self.each_when { |w| w.each_block_deep(&ruby_block) } # And apply it on the default if any. @default.each_block_deep(&ruby_block) if @default end |
#each_node(&ruby_block) ⇒ Object
Iterates over the children (including the value).
Returns an enumerator if no ruby block is given.
3133 3134 3135 3136 3137 3138 3139 3140 |
# File 'lib/HDLRuby/hruby_low.rb', line 3133 def each_node(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_node) unless ruby_block # A ruby block? Apply it on each child. ruby_block.call(@value) @whens.each(&ruby_block) ruby_block.call(@default) if @default end |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 |
# File 'lib/HDLRuby/hruby_low.rb', line 3143 def each_node_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_node_deep) unless ruby_block # A ruby block? First apply it to current. ruby_block.call(self) # And recurse on the children @value.each_node_deep(&ruby_block) @whens.each { |w| w.each_node_deep(&ruby_block) } @default.each_node_deep(&ruby_block) if @default end |
#each_statement_deep(&ruby_block) ⇒ Object
Iterates over all the statements contained in the current statement.
3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 |
# File 'lib/HDLRuby/hruby_low.rb', line 3177 def each_statement_deep(&ruby_block) # No ruby statement? Return an enumerator. return to_enum(:each_statement_deep) unless ruby_block # A ruby block? # Apply it on self. ruby_block.call(self) # And apply it on each when's statement. self.each_when { |w| w.each_statement_deep(&ruby_block) } # And apply it on the default if any. @default.each_statement_deep(&ruby_block) if @default end |
#each_when(&ruby_block) ⇒ Object
Iterates over the match cases.
Returns an enumerator if no ruby block is given.
3123 3124 3125 3126 3127 3128 |
# File 'lib/HDLRuby/hruby_low.rb', line 3123 def each_when(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_when) unless ruby_block # A ruby block? Apply it on each when case. @whens.each(&ruby_block) end |
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 |
# File 'lib/HDLRuby/hruby_low.rb', line 3072 def eql?(obj) return false unless obj.is_a?(Case) return false unless @value.eql?(obj.value) return false unless @whens.eql?(obj.instance_variable_get(:@whens)) idx = 0 obj.each_when do |w| return false unless @whens[idx].eql?(w) idx += 1 end return false unless idx == @whens.size return false unless @default.eql?(obj.default) return true end |
#explicit_types! ⇒ Object
Explicit the types conversions in the case.
129 130 131 132 133 134 135 136 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 129 def explicit_types! # Recurse on the value. self.set_value!(self.value.explicit_types) # Recurse on the whens, the match of each when must be of the # type of the value. self.each_when { |w| w.explicit_types!(self.value.type) } return self end |
#extract_declares! ⇒ Object
Extract the declares from the scope and returns them into an array.
NOTE: do not recurse into the sub scopes or behaviors!
619 620 621 622 623 624 |
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 619 def extract_declares! # Recurse on the whens. return self.each_when.map(&:extract_declares!) # Recurse on the default if any. self.default.extract_declares! if self.default end |
#extract_selects! ⇒ Object
Extract the Select expressions.
Note: the default is not treated.
201 202 203 204 205 206 207 208 |
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 201 def extract_selects! selects = [] # Work on the value. self.set_value!(self.value.extract_selects_to!(selects)) # Work on the whens. selects += self.each_when.map(&:extract_selects!).reduce(:+) return selects end |
#hash ⇒ Object
Hash function.
3087 3088 3089 |
# File 'lib/HDLRuby/hruby_low.rb', line 3087 def hash return [@value,@whens,@default].hash end |
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children (including the value).
800 801 802 803 804 805 806 807 808 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 800 def map_nodes!(&ruby_block) # A block? Apply it on each child. @value = ruby_block.call(@value) map_whens!(&ruby_block) if @default then @default = ruby_block.call(@default) @default.parent = self unless @default.parent end end |
#map_whens!(&ruby_block) ⇒ Object
Maps on the whens.
786 787 788 789 790 791 792 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 786 def map_whens!(&ruby_block) @whens.map! do |w| w = ruby_block.call(w) w.parent = self unless w.parent w end end |
#mix?(mode = nil) ⇒ Boolean
Tell if there is a mix block. +mode+ is the mode of the upper block.
164 165 166 167 168 169 |
# File 'lib/HDLRuby/hruby_low2seq.rb', line 164 def mix?(mode = nil) # Recuse on the whens. return true if self.each_when.any? { |w| w.mix?(mode) } # Check the default if any. return self.default.mix?(mode) end |
#replace_expressions!(node2rep) ⇒ Object
Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.
NOTE: the replacement is duplicated.
816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 816 def replace_expressions!(node2rep) # First recurse on the children. res = {} self.each_node do |node| res.merge!(node.replace_expressions!(node2rep)) end # Is there a replacement to do on the value? rep = node2rep[self.value] if rep then # Yes, do it. rep = rep.clone node = self.value # node.set_parent!(nil) self.set_value!(rep) # And register the replacement. res[node] = rep end return res end |
#replace_names!(former, nname) ⇒ Object
Replaces recursively +former+ name by +nname+ until it is redeclared.
627 628 629 630 631 632 633 634 |
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 627 def replace_names!(former,nname) # Recurse on the value. self.value.replace_names!(former,nname) # Recurse on the whens. self.each_when {|w| w.replace_names!(former,nname) } # Recurse on the default. self.default.replace_names!(former,nname) if self.default end |
#set_default!(default) ⇒ Object
Sets the default.
780 781 782 783 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 780 def set_default!(default) # Checks and set the default case if any. self.default = default end |
#set_value!(value) ⇒ Object
Sets the value.
769 770 771 772 773 774 775 776 777 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 769 def set_value!(value) # Check and set the value. unless value.is_a?(Expression) raise AnyError, "Invalid class for a value: #{value.class}" end @value = value # And set its parent. value.parent = self end |
#to_c(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
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 1209 1210 1211 1212 1213 1214 1215 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1176 def to_c(level = 0) res = "" # Compute the selection value. res << "{\n" res << " " * (level+1)*3 res << "Value value = " << self.value.to_c(level+1) << ";\n" # Ensure the selection value is testable. res << " " * (level+1)*3 res << "if (is_defined_value(value)) {\n" # The condition is testable. # Generate the case as a succession of if statements. first = true self.each_when do |w| res << " " * (level+2)*3 if first then first = false else res << "else " end res << "if (value2integer(value) == " res << "value2integer(" << w.match.to_c(level+2) << ")) {\n" res << w.statement.to_c(level+3) res << " " * (level+2)*3 res << "}\n" end if self.default then res << " " * (level+2)*3 res << "else {\n" res << self.default.to_c(level+3) res << " " * (level+2)*3 res << "}\n" end # Close the case. res << " " * (level+1)*3 res << "}\n" res << " " * (level)*3 res << "}\n" # Return the resulting string. return res end |
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 400 def to_high(level = 0) # The result string. res = " " * (level*3) # Generate the test. res << "hcase " << self.value.to_high(level) << "\n" # Generate the whens. self.each_when do |w| res << w.to_high(level) end # Generatethe default. if self.default then res << " " * (level*3) res << "helse do\n" res << self.default.to_high(level+1) res << " " * (level*3) res << "end\n" end # Return the resulting string. return res end |
#to_upper_space! ⇒ Object
Moves the declarations to the upper namespace.
609 610 611 612 613 614 |
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 609 def to_upper_space! # Recurse on the whens. self.each_when(&:to_upper_space!) # Recurse on the default if any. self.default.to_upper_space! if self.default end |
#to_verilog(mode = nil) ⇒ Object
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1478 def to_verilog(mode = nil) if ($space_count == 0) then result = " " * ($space_count) # Indented based on space_count. else result = "" end $space_count += 1 # Add count to be used for indentation. result = "" result << "case(#{self.value.to_verilog})\n" # n the case statement, each branch is partitioned by when. Process each time when. self.each_when do |whens| # Reads and stores the numbers and expressions stored in when. result << " " + " " *$space_count + "#{whens.match.to_verilog}: " if whens.statement.each_statement.count > 1 then result << "begin\n" whens.statement.each_statement do |statement| result << " "+ " " *$space_count +"#{statement.to_verilog}" end result << " " + " " *$space_count + "end\n" elsif whens.statement.each_statement.count == 1 then whens.statement.each_statement do |statement| result << "#{statement.to_verilog}" end else # Empty statement case. result << "\n" end end # The default part is stored in default instead of when. Reads and processes in the same way as when. if self.default then if self.default.each_statement.count > 1 then result << " " + " " *$space_count + "default: begin\n" self.default.each_statement do |statement| result << " " + " " *$space_count + "#{statement.to_verilog}" end result << " end\n" elsif self.default.each_statement.count == 1 then result << " " + " " *$space_count + "default: " self.default.each_statement do |statement| result << "#{statement.to_verilog}" end end end result << " " + " " *$space_count + "endcase\n" # Conclusion. $space_count -= 1 # Since the output ends, reduce the count. return result # Return case after translation. end |
#to_vhdl(vars, level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +vars+ is the list of the variables and +level+ is the hierachical level of the object.
963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 963 def to_vhdl(vars,level = 0) # The result string. res = " " * (level*3) # Generate the test. res << "case " << self.value.to_vhdl(level) << " is\n" # Generate the whens. self.each_when do |w| res << w.to_vhdl(vars,self.value.type,level) end # Generate teh default if any. if self.default then res << " " * (level*3) res << "when others =>\n" res << self.default.to_vhdl(vars,level+1) else # NOTE: some VHDL parsers are very picky about others, # even though all the cases have been treated through # "when" statements. res << " " * (level*3) res << "when others =>\n" end # Close the case. res << " " * (level*3) res << "end case;\n" # Return the resulting string. return res end |
#with_var(upper = nil) ⇒ Object
Converts to a variable-compatible case where +upper+ is the upper block if any.
NOTE: the result is a new case.
311 312 313 314 315 |
# File 'lib/HDLRuby/hruby_low_with_var.rb', line 311 def with_var(upper = nil) ndefault = self.default ? self.default.clone : nil return Case.new(self.value.clone,ndefault, self.each_when.map {|w| w.with_var(upper) }) end |