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
#hierarchy, #no_parent!, #scope
Constructor Details
#initialize(left, right) ⇒ Transmit
Creates a new transmission from a +right+ expression to a +left+ reference.
3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 |
# File 'lib/HDLRuby/hruby_low.rb', line 3020 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.
3013 3014 3015 |
# File 'lib/HDLRuby/hruby_low.rb', line 3013 def left @left end |
#right ⇒ Object (readonly)
The right expression.
3016 3017 3018 |
# File 'lib/HDLRuby/hruby_low.rb', line 3016 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)
3067 3068 3069 |
# File 'lib/HDLRuby/hruby_low.rb', line 3067 def clone return Transmit.new(@left.clone, @right.clone) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
3103 3104 3105 3106 3107 3108 |
# File 'lib/HDLRuby/hruby_low.rb', line 3103 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.
3111 3112 3113 3114 3115 3116 |
# File 'lib/HDLRuby/hruby_low.rb', line 3111 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.
3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 |
# File 'lib/HDLRuby/hruby_low.rb', line 3042 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.
3072 3073 3074 3075 3076 3077 3078 |
# File 'lib/HDLRuby/hruby_low.rb', line 3072 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.
3083 3084 3085 3086 3087 3088 3089 3090 3091 |
# File 'lib/HDLRuby/hruby_low.rb', line 3083 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.
3094 3095 3096 3097 3098 3099 3100 |
# File 'lib/HDLRuby/hruby_low.rb', line 3094 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.
3054 3055 3056 3057 3058 3059 |
# File 'lib/HDLRuby/hruby_low.rb', line 3054 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.
3062 3063 3064 |
# File 'lib/HDLRuby/hruby_low.rb', line 3062 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)
1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1402 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+.
3119 3120 3121 |
# File 'lib/HDLRuby/hruby_low.rb', line 3119 def use_name?(*names) return @left.use_name?(*names) || @right.use_name?(*names) end |