class HDLRuby::Low::Case
Describes a case statement.
Describes a case statement.
Extends the Case
class with generation of C text.
Extends the Case
class with generation of hdr text.
Add the conversion to high.
Extends the When
class with functionality for converting par block to seq.
Extends the Case
class with generation of HDLRuby::High
text.
Extends the Case
class with functionality for converting booleans in assignments to select operators.
Extends the Case
class with functionality for extracting expressions from cast.
Extends the Case
class with functionality for breaking assingments to concats.
Extends the Case
class with fixing of types and constants.
Describes a case statement.
Extends the Case
class with separation between signals and variables.
Extends the When
class with functionality for moving the declarations to the upper namespace.
Extends the Case
class with functionality for breaking assingments to concats.
Extends the If
class with functionality for converting select expressions to case statements.
Used to translate case
Attributes
The default block.
The tested value
Public Class Methods
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)
# File lib/HDLRuby/hruby_low.rb, line 3421 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 super() @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
Public Instance Methods
Adds possible when case w
.
# File lib/HDLRuby/hruby_low.rb, line 3474 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
Converts the par sub blocks to seq.
# 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
Converts booleans in assignments to select operators.
# File lib/HDLRuby/hruby_low_bool2select.rb, line 123 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
Extracts the expressions from the casts.
# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 120 def casts_without_expression! # No need to apply on the value! # Apply on the value. self.set_value!(self.value.casts_without_expression) # Apply on the whens. self.each_when(&:casts_without_expression!) # Apply on the default if any. self.default.casts_without_expression! if self.default return self end
Clones the Case
(deeply)
# File lib/HDLRuby/hruby_low.rb, line 3591 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
Sets the default block.
No can only be set once.
# File lib/HDLRuby/hruby_low.rb, line 3488 def default=(default) if @default != nil then raise AnyError, "Default already set in if statement." end # Check and set the yes statement. unless default.is_a?(Statement) raise AnyError,"Invalid class for a statement: #{default.class}" end @default = default # And set its parent. default.parent = self @default end
Removes the signals and corresponding assignments whose name is not in keep
.
# 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 a when.
# File lib/HDLRuby/hruby_low_mutable.rb, line 912 def delete_when!(w) @whens.delete(w) end
Iterates over the sub blocks.
# File lib/HDLRuby/hruby_low.rb, line 3550 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
Iterates over all the blocks contained in the current block.
# File lib/HDLRuby/hruby_low.rb, line 3561 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
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 3440 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 value. self.value.each_deep(&ruby_block) # Then apply on the whens. self.each_when do |w| w.each_deep(&ruby_block) end end
Iterates over the children (including the value).
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 3528 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
Iterates over the nodes deeply if any.
# File lib/HDLRuby/hruby_low.rb, line 3538 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
Iterates over each sub statement if any.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 3505 def each_statement(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_statement) unless ruby_block # A ruby block? # Apply on each when. @whens.each { |w| w.each_statement(&ruby_block) } # And on the default if any. ruby_block.call(@default) if @default end
Iterates over all the statements contained in the current statement.
# File lib/HDLRuby/hruby_low.rb, line 3572 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
Iterates over the match cases.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 3518 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
Comparison for hash: structural comparison.
# File lib/HDLRuby/hruby_low.rb, line 3454 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 the types conversions in the case.
# File lib/HDLRuby/hruby_low_fix_types.rb, line 143 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 the declares from the scope and returns them into an array.
NOTE: do not recurse into the sub scopes or behaviors!
# 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 res = self.each_when.map(&:extract_declares!) res += self.default.extract_declares! if self.default return res end
Extract the Select
expressions.
Note: the default is not treated.
# File lib/HDLRuby/hruby_low_without_select.rb, line 214 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
function.
# File lib/HDLRuby/hruby_low.rb, line 3469 def hash return [@value,@whens,@default].hash end
Maps on the children (including the value).
# File lib/HDLRuby/hruby_low_mutable.rb, line 917 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
Maps on the whens.
# File lib/HDLRuby/hruby_low_mutable.rb, line 903 def map_whens!(&ruby_block) @whens.map! do |w| w = ruby_block.call(w) w.parent = self unless w.parent w end end
Tell if there is a mix block. mode
is the mode of the upper block.
# 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
Converts par blocks within seq blocks to seq blocks.
# File lib/HDLRuby/hruby_low_without_parinseq.rb, line 85 def par_in_seq2seq! self.each_when do |w| w.statement.par_in_seq2seq! end self.default.par_in_seq2seq! if self.default end
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.
# File lib/HDLRuby/hruby_low_mutable.rb, line 933 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
Replaces recursively former
name by nname
until it is redeclared.
# File lib/HDLRuby/hruby_low_without_namespace.rb, line 630 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
Sets the default.
# File lib/HDLRuby/hruby_low_mutable.rb, line 897 def set_default!(default) # Checks and set the default case if any. self.default = default end
Sets the value.
# File lib/HDLRuby/hruby_low_mutable.rb, line 886 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
Generates the text of the equivalent HDLRuby
code. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2c.rb, line 1263 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
Generates the content of the h file.
# File lib/HDLRuby/hruby_low2c.rb, line 1305 def to_ch res = "" # Recurse on the whens. self.each_when {|w| res << w.to_ch } # Recurse on the default statement. res << self.default.to_ch if self.default return res end
Generates the text of the equivalent hdr text. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2hdr.rb, line 400 def to_hdr(level = 0) # The result string. res = " " * (level*3) # Generate the test. res << "hcase " << self.value.to_hdr(level) << "\n" # Generate the whens. self.each_when do |w| res << w.to_hdr(level) end # Generatethe default. if self.default then res << " " * (level*3) res << "helse do\n" res << self.default.to_hdr(level+1) res << " " * (level*3) res << "end\n" end # Return the resulting string. return res end
Creates a new high case statement.
# File lib/HDLRuby/hruby_low2high.rb, line 285 def to_high # Is there a default? if self.default then # Yes, create the new case statement with it. return HDLRuby::High::Case.new(self.value.to_high, self.default.to_high, self.each_when.map { |w| w.to_high }) end end
Convert the block to seq.
# File lib/HDLRuby/hruby_low_without_parinseq.rb, line 93 def to_seq! self.each_when do |w| w.statement.to_seq! end self.default.to_seq! if self.default end
Moves the declarations to the upper namespace.
# 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
def to_verilog
(mode = nil)
Converts to Verilog
code, checking if variables are register or wire adding 'spc' spaces at the begining of each line.
# File lib/HDLRuby/hruby_verilog.rb, line 1527 def to_verilog(spc = 3) result = " " * spc # Indented based on space_count. 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 << " " * (spc+3) + "#{whens.match.to_verilog}: " if whens.statement.each_statement.count >= 1 then result << whens.statement.to_verilog(spc+3) else result << "\n" end end if self.default then if self.default.each_statement.count >= 1 then result << self.default.each_statement.map do |stmnt| stmnt.to_verilog(spc+3) end.join("\n") else result << "\n" end end result << " " * spc + "endcase\n" # Conclusion. return result # Return case after translation. end
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.
# File lib/HDLRuby/hruby_low2vhd.rb, line 987 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
Tell if the statement includes a signal whose name is one of names
. NOTE: for the case check only the value.
# File lib/HDLRuby/hruby_low.rb, line 3586 def use_name?(*names) return @value.use_name?(*name) end
Converts to a variable-compatible case where upper
is the upper block if any.
NOTE: the result is a new case.
# 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