Class: HDLRuby::Low::Transmit
- Defined in:
- lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.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
Overview
Extends the Transmit class with functionality for converting select expressions to case statements.
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.
-
#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_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(level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code.
-
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#to_verilog(mode = nil) ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(vars, level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
Methods inherited from Statement
#add_blocks_code, #block, #blocks2seq!, #break_types!, #delete_unless!, #extract_declares!, #mix?, #replace_names!, #to_upper_space!, #top_block, #top_scope, #with_boolean!
Methods included from Low2Symbol
Constructor Details
#initialize(left, right) ⇒ Transmit
Creates a new transmission from a +right+ expression to a +left+ reference.
2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 |
# File 'lib/HDLRuby/hruby_low.rb', line 2608 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 @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.
2601 2602 2603 |
# File 'lib/HDLRuby/hruby_low.rb', line 2601 def left @left end |
#right ⇒ Object (readonly)
The right expression.
2604 2605 2606 |
# File 'lib/HDLRuby/hruby_low.rb', line 2604 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.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 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 |
# File 'lib/HDLRuby/hruby_low_without_concat.rb', line 81 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))) else # Multi-bits. # Compute the type of the right value. rtype = TypeVector.new(:"",aux.type.base,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 |
#clone ⇒ Object
Clones the transmit (deeply)
2640 2641 2642 |
# File 'lib/HDLRuby/hruby_low.rb', line 2640 def clone return Transmit.new(@left.clone, @right.clone) end |
#each_block(&ruby_block) ⇒ Object
Iterates over the sub blocks.
2676 2677 2678 2679 2680 2681 |
# File 'lib/HDLRuby/hruby_low.rb', line 2676 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.
2684 2685 2686 2687 2688 2689 |
# File 'lib/HDLRuby/hruby_low.rb', line 2684 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_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the children if any.
2645 2646 2647 2648 2649 2650 2651 |
# File 'lib/HDLRuby/hruby_low.rb', line 2645 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.
2656 2657 2658 2659 2660 2661 2662 2663 2664 |
# File 'lib/HDLRuby/hruby_low.rb', line 2656 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.
2667 2668 2669 2670 2671 2672 2673 |
# File 'lib/HDLRuby/hruby_low.rb', line 2667 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.
2627 2628 2629 2630 2631 2632 |
# File 'lib/HDLRuby/hruby_low.rb', line 2627 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.
130 131 132 133 134 135 |
# File 'lib/HDLRuby/hruby_low_without_select.rb', line 130 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.
2635 2636 2637 |
# File 'lib/HDLRuby/hruby_low.rb', line 2635 def hash return [@left,@right].hash end |
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
549 550 551 552 553 554 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 549 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.
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 562 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.
526 527 528 529 530 531 532 533 534 535 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 526 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.
538 539 540 541 542 543 544 545 546 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 538 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(level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1064 def to_c(level = 0) # Save the state of the value pool. res = (" " * ((level)*3)) res << "{\n" 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(level)},"+ "#{self.left.to_c_signal(level)});\n" else # Assignment inside a signal (RefIndex or RefRange). res << "transmit_to_signal_range#{seq}(#{self.right.to_c(level)},"+ "#{self.left.to_c_signal(level)});\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 |
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
338 339 340 341 342 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 338 def to_high(level = 0) return " " * (level*3) + self.left.to_high(level) + " <= " + self.right.to_high(level) + "\n" end |
#to_verilog(mode = nil) ⇒ Object
Converts the system to Verilog code.
95 96 97 98 99 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 95 def to_verilog(mode = nil) # Determine blocking assignment or nonblocking substitution from mode and return it. code = "#{self.left.to_verilog} #{mode == "seq" ? "=" : "<="} #{self.right.to_verilog};\n" 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.
864 865 866 867 868 869 870 871 872 873 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 864 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 |