Class: HDLRuby::Low::Transmit
- 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_without_concat.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/hruby_low_without_subsignals.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Extends the Transmit class with functionality for extracting expressions from cast.
Direct Known Subclasses
Constant Summary
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#left ⇒ Object
readonly
The left reference.
-
#right ⇒ Object
readonly
The right expression.
Attributes included from Hparent
Instance Method Summary collapse
-
#boolean_in_assign2select! ⇒ Object
Converts booleans in assignments to select operators.
-
#break_concat_assigns ⇒ Object
Break the assignments to concats.
-
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
-
#clone ⇒ Object
Clones the transmit (deeply).
-
#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_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
-
#each_node(&ruby_block) ⇒ Object
(also: #each_expression)
Iterates over the children if any.
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#each_statement_deep(&ruby_block) ⇒ Object
Iterates over all the stamements of the block and its sub blocks.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types! ⇒ Object
Explicit the types conversions in the statement.
-
#extract_selects! ⇒ Object
Extract the Select expressions.
-
#hash ⇒ Object
Hash function.
-
#initialize(left, right) ⇒ Transmit
constructor
Creates a new transmission from a +right+ expression to a +left+ reference.
-
#map_nodes!(&ruby_block) ⇒ Object
(also: #map_expressions!)
Maps on the children.
-
#replace_expressions!(node2rep) ⇒ Object
Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement.
-
#set_left!(left) ⇒ Object
Sets the left.
-
#set_right!(right) ⇒ Object
Sets the right.
-
#signal2subs! ⇒ Object
Decompose the hierarchical signals in the statements.
-
#to_c(res, level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby code.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high transmit statement.
-
#to_verilog(spc = 3) ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(vars, level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#use_name?(*names) ⇒ Boolean
Tell if the statement includes a signal whose name is one of +names+.
Methods inherited from Statement
#add_blocks_code, #add_make_block, #behavior, #block, #blocks2seq!, #break_types!, #delete_related!, #delete_unless!, #each_statement, #extract_declares!, #mix?, #par_in_seq2seq!, #parent_system, #replace_names!, #scope, #to_ch, #to_seq!, #to_upper_space!, #top_block, #top_scope, #with_boolean!
Methods included from Low2Symbol
Methods included from Hparent
#hierarchy, #no_parent!, #scope
Constructor Details
#initialize(left, right) ⇒ Transmit
Creates a new transmission from a +right+ expression to a +left+ reference.
3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 |
# File 'lib/HDLRuby/hruby_low.rb', line 3184 def initialize(left,right) # Check and set the left reference. unless left.is_a?(Ref) raise AnyError, "Invalid class for a reference (left value): #{left.class}" end super() @left = left # and set its parent. left.parent = self # Check and set the right expression. unless right.is_a?(Expression) raise AnyError, "Invalid class for an expression (right value): #{right.class}" end @right = right # and set its parent. right.parent = self end |
Instance Attribute Details
#left ⇒ Object (readonly)
The left reference.
3177 3178 3179 |
# File 'lib/HDLRuby/hruby_low.rb', line 3177 def left @left end |
#right ⇒ Object (readonly)
The right expression.
3180 3181 3182 |
# File 'lib/HDLRuby/hruby_low.rb', line 3180 def right @right end |
Instance Method Details
#boolean_in_assign2select! ⇒ Object
Converts booleans in assignments to select operators.
56 57 58 59 60 61 62 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 56 def boolean_in_assign2select! # Apply on the left value. self.set_left!(self.left.boolean_in_assign2select) # Apply on the right value. self.set_right!(self.right.boolean_in_assign2select) return self end |
#break_concat_assigns ⇒ Object
Break the assignments to concats.
NOTE: when breaking generates a new Block containing the broken assignments.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 152 def break_concat_assigns # puts "break_concat_assigns with self=#{self}" # Is the left value a RefConcat? self.left.each_node_deep do |node| if node.is_a?(RefConcat) then # Yes, must break. Create the resulting sequential # block that will contain the new assignements. block = Block.new(:seq) # Create an intermediate signal for storing the # right value. Put it in the top scope. top_block = self.top_block top_scope = top_block.top_scope aux = top_scope.add_inner( SignalI.new(HDLRuby.uniq_name,self.right.type) ) aux = RefName.new(aux.type,RefThis.new,aux.name) # Is a default value required to avoid latch generation? unless top_block.is_a?(TimeBlock) || top_block.parent.each_event. # find {|ev| ev.type!=:change} then find {|ev| ev.type!=:anyedge} then # Yes, generate it. top_block.insert_statement!(0, Transmit.new(aux.clone,Value.new(aux.type,0))) end # Replace the concat in the copy of the left value. if left.eql?(node) then # node was the top of left, replace here. nleft = aux else # node was inside left, replace within left. nleft = self.left.clone nleft.each_node_deep do |ref| ref.map_nodes! do |sub| sub.eql?(node) ? aux.clone : sub end end end # Recreate the transmit and add it to the block. block.add_statement( Transmit.new(nleft,self.right.clone) ) # And assign its part to each reference of the # concat. pos = 0 node.each_ref.reverse_each do |ref| # Compute the range to assign. range = ref.type.width-1+pos .. pos # Single or multi-bit range? sbit = range.first == range.last # Convert the range to an HDLRuby range for # using is the resulting statement. # Create and add the statement. if sbit then # Single bit. # Generate the index. idx = Value.new(Integer,range.first) # Generate the assignment. block.add_statement( Transmit.new(ref.clone, # RefIndex.new(aux.type.base, aux.clone, idx))) RefIndex.new(bit, aux.clone, idx))) else # Multi-bits. # Compute the type of the right value. # rtype = TypeVector.new(:"",aux.type.base,range) rtype = TypeVector.new(:"",bit,range) # Generate the range. range = Value.new(Integer,range.first) .. Value.new(Integer,range.last) # Generate the assignment. block.add_statement( Transmit.new(ref.clone, RefRange.new(rtype, aux.clone, range))) end pos += ref.type.width end # Return the resulting block # puts "new block=#{block}" return block end end # No, nothing to do. return self end |
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
57 58 59 60 61 62 63 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 57 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 |
#clone ⇒ Object
Clones the transmit (deeply)
3231 3232 3233 |
# File 'lib/HDLRuby/hruby_low.rb', line 3231 def clone return Transmit.new(@left.clone, @right.clone) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
3267 3268 3269 3270 3271 3272 |
# File 'lib/HDLRuby/hruby_low.rb', line 3267 def each_block(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_block) unless ruby_block # A ruby block? # Nothing to do. end |
#each_block_deep(&ruby_block) ⇒ Object
Iterates over all the blocks contained in the current block.
3275 3276 3277 3278 3279 3280 |
# File 'lib/HDLRuby/hruby_low.rb', line 3275 def each_block_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_block_deep) unless ruby_block # A ruby block? # Nothing to do. end |
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 |
# File 'lib/HDLRuby/hruby_low.rb', line 3206 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 left. self.left.each_deep(&ruby_block) # Then apply on the right. self.right.each_deep(&ruby_block) end |
#each_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the children if any.
3236 3237 3238 3239 3240 3241 3242 |
# File 'lib/HDLRuby/hruby_low.rb', line 3236 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 the children. ruby_block.call(@left) ruby_block.call(@right) end |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
3247 3248 3249 3250 3251 3252 3253 3254 3255 |
# File 'lib/HDLRuby/hruby_low.rb', line 3247 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 @left.each_node_deep(&ruby_block) @right.each_node_deep(&ruby_block) end |
#each_statement_deep(&ruby_block) ⇒ Object
Iterates over all the stamements of the block and its sub blocks.
3258 3259 3260 3261 3262 3263 3264 |
# File 'lib/HDLRuby/hruby_low.rb', line 3258 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) end |
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
3218 3219 3220 3221 3222 3223 |
# File 'lib/HDLRuby/hruby_low.rb', line 3218 def eql?(obj) return false unless obj.is_a?(Transmit) return false unless @left.eql?(obj.left) return false unless @right.eql?(obj.right) return true end |
#explicit_types! ⇒ Object
Explicit the types conversions in the statement.
82 83 84 85 86 87 88 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 82 def explicit_types! # Recurse on the left and the right. self.set_left!(self.left.explicit_types) # The right have to match the left type. self.set_right!(self.right.explicit_types(self.left.type)) return self end |
#extract_selects! ⇒ Object
Extract the Select expressions.
158 159 160 161 162 163 |
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 158 def extract_selects! selects = [] self.set_left!(self.left.extract_selects_to!(selects)) self.set_right!(self.right.extract_selects_to!(selects)) return selects end |
#hash ⇒ Object
Hash function.
3226 3227 3228 |
# File 'lib/HDLRuby/hruby_low.rb', line 3226 def hash return [@left,@right].hash end |
#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!
Maps on the children.
596 597 598 599 600 601 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 596 def map_nodes!(&ruby_block) @left = ruby_block.call(@left) left.parent = self unless left.parent @right = ruby_block.call(@right) right.parent = self unless right.parent 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.
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 612 def replace_expressions!(node2rep) # First recurse on the children. res = self.left.replace_expressions!(node2rep) res.merge!(self.right.replace_expressions!(node2rep)) # Is there a replacement to do on the left? rep = node2rep[self.left] if rep then # Yes, do it. rep = rep.clone node = self.left # node.set_parent!(nil) self.set_left!(rep) # And register the replacement. res[node] = rep end # Is there a replacement to do on the right? rep = node2rep[self.right] if rep then # Yes, do it. rep = rep.clone node = self.right # node.set_parent!(nil) self.set_right!(rep) # And register the replacement. res[node] = rep end return res end |
#set_left!(left) ⇒ Object
Sets the left.
573 574 575 576 577 578 579 580 581 582 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 573 def set_left!(left) # Check and set the left reference. unless left.is_a?(Ref) raise AnyError, "Invalid class for a reference (left value): #{left.class}" end @left = left # and set its parent. left.parent = self end |
#set_right!(right) ⇒ Object
Sets the right.
585 586 587 588 589 590 591 592 593 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 585 def set_right!(right) # Check and set the right expression. unless right.is_a?(Expression) raise AnyError, "Invalid class for an expression (right value): #{right.class}" end @right = right # and set its parent. right.parent = self end |
#signal2subs! ⇒ Object
Decompose the hierarchical signals in the statements.
122 123 124 125 126 127 |
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 122 def signal2subs! # Recurse on the left and right. self.set_left!(self.left.signal2subs!) self.set_right!(self.right.signal2subs!) return self end |
#to_c(res, level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby code.
+level+ is the hierachical level of the object.
def to_c(level = 0)
def to_c(res,level = 0) # Save the state of the value pool. # res = (" " * ((level)*3)) res << (" " * ((level)*3)) res << " res << (" " * ((level+1)*3)) res << "unsigned int pool_state = get_value_pos();\n" # Perform the copy and the touching only if the new content # is different. # res << (" " * ((level+1)*3)) # Is it a sequential execution model? seq = self.block.mode == :seq ? "_seq" : "" # # Generate the assignment. # if (self.left.is_a?(RefName)) then # # Direct assignment to a signal, simple transmission. # res << "transmit_to_signal#{seq(" # self.right.to_c(res,level) # res << "," # self.left.to_c_signal(res,level) # res << ");\n" # else # # Assignment inside a signal (RefIndex or RefRange). # res << "transmit_to_signal_range#seq(" # self.right.to_c(res,level) # res << "," # self.left.to_c_signal(res,level) # res << ");\n" # ### Why twice ??? # res << "transmit_to_signal_range#seq(" # self.right.to_c(res,level) # res << "," # self.left.to_c_signal(res,level) # res << ");\n" # end # Generate the assignment. if (self.left.is_a?(RefName)) then # Generate the right value. self.right.to_c(res,level+1) # Direct assignment to a signal, simple transmission. res << (" " * ((level+1)*3)) res << "transmit_to_signal#seq(d," # Generate the left value (target signal). self.left.to_c_signal(res,level+1) res << ");\n" else # Generate the right value. self.right.to_c(res,level+1) # Assignment inside a signal (RefIndex or RefRange). res << "transmit_to_signal_range#seq(d," # Generate the left value (target signal). self.left.to_c_signal(res,level+1) res << ");\n" end # Restore the value pool state. res << (" " * ((level+1)*3)) res << "set_value_pos(pool_state);\n" res << (" " * ((level)*3)) res << "}\n" return res end Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object. def to_c(level = 0)
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1434 def to_c(res,level = 0) # Save the value pool state. res << (" " * (level*3)) << "SV;\n" # Perform the copy and the touching only if the new content # is different. # Is it a sequential execution model? seq = self.block.mode == :seq ? "_seq" : "" # Generate the assignment. if (self.left.is_a?(RefName)) then # Generate the right value. self.right.to_c(res,level) # Direct assignment to a signal, simple transmission. res << (" " * (level*3)) res << "transmit#{seq}(" # Generate the left value (target signal). self.left.to_c_signal(res,level+1) res << ");\n" else # Generate the right value. self.right.to_c(res,level) # Assignment inside a signal (RefIndex or RefRange). res << "transmitR#{seq}(" # Generate the left value (target signal). self.left.to_c_signal(res,level+1) res << ");\n" end # Restore the value pool state. res << (" " * (level*3)) << "RV;\n" return res end |
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.
338 339 340 341 342 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 338 def to_hdr(level = 0) return " " * (level*3) + self.left.to_hdr(level) + " <= " + self.right.to_hdr(level) + "\n" end |
#to_high ⇒ Object
Creates a new high transmit statement.
242 243 244 245 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 242 def to_high return HDLRuby::High::Transmit.new(self.left.to_high, self.right.to_high) end |
#to_verilog(spc = 3) ⇒ Object
Converts the system to Verilog code.
165 166 167 168 169 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 165 def to_verilog(spc = 3) # Determine blocking assignment or nonblocking substitution from mode and return it. code = "#{" " * spc}#{self.left.to_verilog} #{self.block.mode == :seq ? "=" : "<="} #{self.right.to_verilog};" return code 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.
904 905 906 907 908 909 910 911 912 913 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 904 def to_vhdl(vars,level = 0) # Generate the assign operator. assign = vars.any? do |var| self.left.respond_to?(:name) && var.name == self.left.name end ? " := " : " <= " # Generate the assignment. return " " * (level*3) + self.left.to_vhdl(level) + assign + Low2VHDL.to_type(self.left.type,self.right) + ";\n" end |
#use_name?(*names) ⇒ Boolean
Tell if the statement includes a signal whose name is one of +names+.
3283 3284 3285 |
# File 'lib/HDLRuby/hruby_low.rb', line 3283 def use_name?(*names) return @left.use_name?(*names) || @right.use_name?(*names) end |