Class: HDLRuby::Low::Transmit
- 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_without_concat.rb,
lib/HDLRuby/hruby_low_without_select.rb,
lib/HDLRuby/hruby_low_without_namespace.rb,
lib/HDLRuby/hruby_low_without_subsignals.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Decribes a transmission statement.
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.
-
#fix_scope_refnames!(scopes) ⇒ Object
Fix the references names using scopes given in +scopes + list (they are marked to be deleted).
-
#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.
-
#to_viz_node(parent) ⇒ Object
Converts the transmit to a Viz flow node under +parent+.
-
#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
#absolute_ref, #hierarchy, #no_parent!, #scope
Constructor Details
#initialize(left, right) ⇒ Transmit
Creates a new transmission from a +right+ expression to a +left+ reference.
3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 |
# File 'lib/HDLRuby/hruby_low.rb', line 3354 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.
3347 3348 3349 |
# File 'lib/HDLRuby/hruby_low.rb', line 3347 def left @left end |
#right ⇒ Object (readonly)
The right expression.
3350 3351 3352 |
# File 'lib/HDLRuby/hruby_low.rb', line 3350 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.
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 235 236 237 238 239 |
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 157 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)
3401 3402 3403 |
# File 'lib/HDLRuby/hruby_low.rb', line 3401 def clone return Transmit.new(@left.clone, @right.clone) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
3437 3438 3439 3440 3441 3442 |
# File 'lib/HDLRuby/hruby_low.rb', line 3437 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.
3445 3446 3447 3448 3449 3450 |
# File 'lib/HDLRuby/hruby_low.rb', line 3445 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.
3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 |
# File 'lib/HDLRuby/hruby_low.rb', line 3376 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.
3406 3407 3408 3409 3410 3411 3412 |
# File 'lib/HDLRuby/hruby_low.rb', line 3406 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.
3417 3418 3419 3420 3421 3422 3423 3424 3425 |
# File 'lib/HDLRuby/hruby_low.rb', line 3417 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.
3428 3429 3430 3431 3432 3433 3434 |
# File 'lib/HDLRuby/hruby_low.rb', line 3428 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.
3388 3389 3390 3391 3392 3393 |
# File 'lib/HDLRuby/hruby_low.rb', line 3388 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.
88 89 90 91 92 93 94 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 88 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.
163 164 165 166 167 168 |
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 163 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 |
#fix_scope_refnames!(scopes) ⇒ Object
Fix the references names using scopes given in +scopes + list (they are marked to be deleted).
531 532 533 534 535 |
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 531 def fix_scope_refnames!(scopes) self.set_left!(self.left.fix_scope_refnames!(scopes)) self.set_right!(self.right.fix_scope_refnames!(scopes)) return self end |
#hash ⇒ Object
Hash function.
3396 3397 3398 |
# File 'lib/HDLRuby/hruby_low.rb', line 3396 def hash return [@left,@right].hash end |
#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!
Maps on the children.
570 571 572 573 574 575 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 570 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.
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 586 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.
547 548 549 550 551 552 553 554 555 556 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 547 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.
559 560 561 562 563 564 565 566 567 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 559 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.
137 138 139 140 141 142 |
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 137 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)
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 1464 1465 1466 1467 1468 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1439 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.
344 345 346 347 348 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 344 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.
261 262 263 264 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 261 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.
226 227 228 229 230 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 226 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.
914 915 916 917 918 919 920 921 922 923 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 914 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 |
#to_viz_node(parent) ⇒ Object
Converts the transmit to a Viz flow node under +parent+.
4623 4624 4625 4626 4627 4628 4629 |
# File 'lib/HDLRuby/hruby_viz.rb', line 4623 def to_viz_node(parent) node = HDLRuby::Viz::Node.new(:assign,parent) # And generate the left and right children. self.left.to_viz_node(node) self.right.to_viz_node(node) return node end |
#use_name?(*names) ⇒ Boolean
Tell if the statement includes a signal whose name is one of +names+.
3453 3454 3455 |
# File 'lib/HDLRuby/hruby_low.rb', line 3453 def use_name?(*names) return @left.use_name?(*names) || @right.use_name?(*names) end |