require 'HDLRuby' require 'HDLRuby/hruby_tools' require 'HDLRuby/hruby_low_mutable' require 'HDLRuby/hruby_low_with_bool' module HDLRuby::Low ## # Replace expressions in cast operators with variables. # Use for generating Verilog code generation since bit extension cannot # be performed on expression but only on signals. # ######################################################################## ## Extends the SystemT class with functionality for extracting # expressions from cast. class SystemT # Extracts the expressions from the casts. def casts_without_expression! self.scope.casts_without_expression! return self end end ## Extends the Scope class with functionality for extracting # expressions from cast. class Scope # Extracts the expressions from the casts. def casts_without_expression! # Recurse on the sub scopes. self.each_scope(&:casts_without_expression!) # Apply on the connections. self.each_connection(&:casts_without_expression!) # Apply on the behaviors. self.each_behavior do |behavior| behavior.block.casts_without_expression! end return self end end ## Extends the Transmit class with functionality for extracting # expressions from cast. class Transmit # Extracts the expressions from the casts. def casts_without_expression! # Apply on the left value. self.set_left!(self.left.casts_without_expression) # Apply on the right value. self.set_right!(self.right.casts_without_expression) return self end end ## Extends the Print class with functionality for extracting # expressions from cast. class Print # Extracts the expressions from the casts. def casts_without_expression! # Apply on the arguments. self.map_args!(&:casts_without_expression) return self end end ## Extends the If class with functionality for extracting # expressions from cast. class If # Extracts the expressions from the casts. def casts_without_expression! # Apply on the condition. self.set_condition!(self.condition.casts_without_expression) # Apply on the yes. self.yes.casts_without_expression! # Apply on the noifs. @noifs.map! do |cond,stmnt| [cond.casts_without_expression,stmnt.casts_without_expression!] end # Apply on the no if any. self.no.casts_without_expression! if self.no return self end end ## Extends the When class with functionality for extracting # expressions from cast. class When # Extracts the expressions from the casts. def casts_without_expression! # Apply on the match. self.set_match!(self.match.casts_without_expression) # Apply on the statement. self.statement.casts_without_expression! return self end end ## Extends the Case class with functionality for extracting # expressions from cast. class Case # Extracts the expressions from the casts. 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 end ## Extends the TimeWait class with functionality for extracting # expressions from cast. class TimeWait # Extracts the expressions from the casts. def casts_without_expression! # Nothing to do. return self end end ## Extends the TimeRepeat class with functionality for extracting # expressions from cast. class TimeRepeat # Extracts the expressions from the casts. def casts_without_expression! # Simply recurse on the stamtement. self.statement.casts_without_expression! return self end end ## Extends the Block class with functionality for extracting # expressions from cast. class Block # Extracts the expressions from the casts. def casts_without_expression! # Apply on each statement. self.each_statement(&:casts_without_expression!) return self end end ## Extends the Value class with functionality for extracting # expressions from cast. class Value # Extracts the expressions from the casts. def casts_without_expression # Simple clones. return self.clone end end ## Extends the Cast class with functionality for extracting # expressions from cast. class Cast # Extracts the expressions from the casts. def casts_without_expression # Recurse on the child. nchild = self.child.casts_without_expression # Process the cast. unless (nchild.is_a?(Ref)) then # Need to extract the child. # Create signal holding the child. stmnt = self.statement if (stmnt.is_a?(Connection)) then # Specific case of connections: need to build # a new block. scop = stmnt.parent scop.delete_connection!(stmnt) stmnt = Transmit.new(stmnt.left.clone, stmnt.right.clone) blk = Block.new(:seq) scop.add_behavior(Behavior.new(blk)) blk.add_statement(stmnt) else blk = stmnt.block end name = HDLRuby.uniq_name typ = nchild.type sig = blk.add_inner(SignalI.new(name,typ)) # Add a statement assigning the child to the new signal. nref = RefName.new(typ,RefThis.new,name) nstmnt = Transmit.new(nref,nchild) idx = blk.each_statement.find_index(stmnt) blk.insert_statement!(idx,nstmnt) # Replace the child by a reference to the created # signal. nchild = nref.clone end return Cast.new(self.type,nchild) end end ## Extends the Unary class with functionality for extracting # expressions from cast. class Unary # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub node. return Unary.new(self.type,self.operator, self.child.casts_without_expression) return self end end ## Extends the Binary class with functionality for extracting # expressions from cast. class Binary # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub nodes. return Binary.new(self.type,self.operator, self.left.casts_without_expression, self.right.casts_without_expression) end end ## Extends the Select class with functionality for extracting # expressions from cast. class Select # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub node. return Select.new(self.type,"?", self.select.casts_without_expression, *self.each_choice.map do |choice| choice.casts_without_expression end ) return self end end ## Extends the Concat class with functionality for converting booleans # in assignments to select operators. class Concat # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub expressions. return Concat.new(self.type,self.each_expression.map do |expr| expr.casts_without_expression end ) end end ## Extends the RefConcat class with functionality for converting booleans # in assignments to select operators. class RefConcat # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub references. return RefConcat.new(self.type,self.each_expression.map do |expr| expr.casts_without_expression end ) end end ## Extends the RefIndex class with functionality for converting booleans # in assignments to select operators. class RefIndex # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub references. return RefIndex.new(self.type, self.ref.casts_without_expression, self.index.casts_without_expression) end end ## Extends the RefRange class with functionality for converting booleans # in assignments to select operators. class RefRange # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub references. return RefRange.new(self.type, self.ref.casts_without_expression, self.range.first.casts_without_expression .. self.range.last.casts_without_expression) end end ## Extends the RefName class with functionality for converting booleans # in assignments to select operators. class RefName # Extracts the expressions from the casts. def casts_without_expression # Recurse on the sub references. return RefName.new(self.type, self.ref.casts_without_expression, self.name) end end ## Extends the RefThis class with functionality for converting booleans # in assignments to select operators. class RefThis # Extracts the expressions from the casts. def casts_without_expression # Simply clone. return self.clone end end ## Extends the StringE class with functionality for extracting # expressions from cast. class StringE # Extracts the expressions from the casts. def casts_without_expression return StringE.new(self.content, *self.each_arg.map(&:cast_without_expression)) return self end end end