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_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
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.
-
#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
Constructor Details
#initialize(left, right) ⇒ Transmit
Creates a new transmission from a +right+ expression to a +left+ reference.
2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 |
# File 'lib/HDLRuby/hruby_low.rb', line 2986 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.
2979 2980 2981 |
# File 'lib/HDLRuby/hruby_low.rb', line 2979 def left @left end |
#right ⇒ Object (readonly)
The right expression.
2982 2983 2984 |
# File 'lib/HDLRuby/hruby_low.rb', line 2982 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.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 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 |
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 133 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) ) # puts "new signal: #{aux.name}" aux = RefName.new(aux.type,RefThis.new,aux.name) # Is a default value required to avoid latch generation? unless top_block.parent.each_event. find {|ev| ev.type!=:change} 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 # puts "Resulting block=#{block.to_vhdl}" # Return the resulting 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)
3033 3034 3035 |
# File 'lib/HDLRuby/hruby_low.rb', line 3033 def clone return Transmit.new(@left.clone, @right.clone) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
3069 3070 3071 3072 3073 3074 |
# File 'lib/HDLRuby/hruby_low.rb', line 3069 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.
3077 3078 3079 3080 3081 3082 |
# File 'lib/HDLRuby/hruby_low.rb', line 3077 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.
3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 |
# File 'lib/HDLRuby/hruby_low.rb', line 3008 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.
3038 3039 3040 3041 3042 3043 3044 |
# File 'lib/HDLRuby/hruby_low.rb', line 3038 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.
3049 3050 3051 3052 3053 3054 3055 3056 3057 |
# File 'lib/HDLRuby/hruby_low.rb', line 3049 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.
3060 3061 3062 3063 3064 3065 3066 |
# File 'lib/HDLRuby/hruby_low.rb', line 3060 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.
3020 3021 3022 3023 3024 3025 |
# File 'lib/HDLRuby/hruby_low.rb', line 3020 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.
3028 3029 3030 |
# File 'lib/HDLRuby/hruby_low.rb', line 3028 def hash return [@left,@right].hash end |
#map_nodes!(&ruby_block) ⇒ Object
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.
609 610 611 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 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 609 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 |
#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)
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1360 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.
903 904 905 906 907 908 909 910 911 912 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 903 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+.
3085 3086 3087 |
# File 'lib/HDLRuby/hruby_low.rb', line 3085 def use_name?(*names) return @left.use_name?(*names) || @right.use_name?(*names) end |