class HDLRuby::Low::Code
Extends the code class with support for C allocation of signals.
Extend the Code
class with generation of file for the content.
Decribes a piece of software code.
Decribes a set of non-HDLRuby code chunks.
Extends the SystemI
class with generation of C text.
Extends the Code
class with generation of hdr text.
Add the conversion to high.
Extends the Code
class with conversion to symbol.
Extends the Code
class with generation of HDLRuby::High
text.
Decribes a piece of software code.
Public Class Methods
Creates a new chunk of code.
# File lib/HDLRuby/hruby_low.rb, line 2694 def initialize # Initialize the set of events. @events = [] # Initialize the content. @chunks = HashName.new end
Public Instance Methods
Adds a chunk
to the sensitivity list.
# File lib/HDLRuby/hruby_low.rb, line 2705 def add_chunk(chunk) # Check and add the chunk. unless chunk.is_a?(Chunk) raise AnyError, "Invalid class for a code chunk: #{chunk.class}" end # if @chunks.has_key?(chunk.name) then if @chunks.include?(chunk) then raise AnyError, "Code chunk #{chunk.name} already present." end # Set its parent. chunk.parent = self # And add it @chunks.add(chunk) end
Adds an event
to the sensitivity list.
# File lib/HDLRuby/hruby_low.rb, line 2732 def add_event(event) unless event.is_a?(Event) raise AnyError, "Invalid class for a event: #{event.class}" end # Set the event's parent. event.parent = self # And add the event. @events << event event end
Allocates signals within C code using allocator
.
# File lib/HDLRuby/backend/hruby_c_allocator.rb, line 68 def c_code_allocate(allocator) # Apply the allocator on each C chunk. self.each_chunk do |chunk| chunk.c_code_allocate!(allocator) if chunk.name == :c end end
Iterates over the code chunks.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 2724 def each_chunk(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_chunk) unless ruby_block # A ruby block? Apply it on each chunk. @chunks.each(&ruby_block) end
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 2769 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 each chunk. self.each_chunk do |chunk| chunk.each_deep(&ruby_block) end # Then apply on each event. self.each_event do |event| event.each_deep(&ruby_block) end end
Iterates over the events of the sensitivity list.
Returns an enumerator if no ruby block is given.
# File lib/HDLRuby/hruby_low.rb, line 2746 def each_event(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_event) unless ruby_block # A ruby block? Apply it on each event. @events.each(&ruby_block) end
Comparison for hash: structural comparison.
# File lib/HDLRuby/hruby_low.rb, line 2785 def eql?(obj) return false unless obj.is_a?(Code) idx = 0 obj.each_event do |event| return false unless @events[idx].eql?(event) idx += 1 end idx = 0 obj.each_chunk do |chunk| return false unless @chunks[idx].eql?(chunk) idx += 1 end return true end
Tells if there is any event.
# File lib/HDLRuby/hruby_low.rb, line 2754 def has_event? return !@events.empty? end
Hash
function.
# File lib/HDLRuby/hruby_low.rb, line 2801 def hash return [@events,@chunk].hash end
Tells if there is a positive or negative edge event.
# File lib/HDLRuby/hruby_low.rb, line 2759 def on_edge? @events.each do |event| return true if event.on_edge? end return false end
Sets the content.
# File lib/HDLRuby/hruby_low_mutable.rb, line 1273 def set_content!(content) @content = content # Freeze it to avoid dynamic tempering of the hardware. content.freeze end
Sets the type.
# File lib/HDLRuby/hruby_low_mutable.rb, line 1267 def set_type!(type) # Check and set type. @type = type.to_sym end
Generates the C text of the equivalent HDLRuby
code. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2c.rb, line 949 def to_c(level = 0) # puts "For behavior: #{self}" # The resulting string. res = "" # Declare the global variable holding the behavior. res << "Code #{Low2C.obj_name(self)};\n\n" # Generate the code of the behavior. # The header of the behavior. res << " " * level*3 res << "Code #{Low2C.make_name(self)}() {\n" res << " " * (level+1)*3 # Allocate the code. res << "Code code = malloc(sizeof(CodeS));\n" res << " " * (level+1)*3 res << "code->kind = CODE;\n"; # Sets the global variable of the code. res << "\n" res << " " * (level+1)*3 res << "#{Low2C.obj_name(self)} = code;\n" # Set the owner if any. if self.parent then res << " " * (level+1)*3 res << "code->owner = (Object)" + "#{Low2C.obj_name(self.parent)};\n" else res << "code->owner = NULL;\n" end # Set the code as inactive. */ res << " " * (level+1)*3 res << "code->activated = 0;\n" # Add the events and register the code as activable # on them. res << " " * (level+1)*3 res << "code->num_events = #{self.each_event.to_a.size};\n" res << " " * (level+1)*3 res << "code->events = calloc(sizeof(Event)," + "code->num_events);\n" # Process the events. events = self.each_event.to_a events.each_with_index do |event,i| # puts "for event=#{event}" # Add the event. res << " " * (level+1)*3 res << "code->events[#{i}] = #{event.to_c};\n" # Register the behavior as activable on this event. # Select the active field. field = "any" field = "pos" if event.type == :posedge field = "neg" if event.type == :negedge # Get the target signal access sigad = event.ref.resolve.to_c_signal # Add the code to the relevant field. res << " " * (level+1)*3 res << "#{sigad}->num_#{field} += 1;\n" res << " " * (level+1)*3 res << "#{sigad}->#{field} = realloc(#{sigad}->#{field}," + "#{sigad}->num_#{field}*sizeof(Object));\n" res << "#{sigad}->#{field}[#{sigad}->num_#{field}-1] = " + "(Object)code;\n" end # Adds the function to execute. function = self.each_chunk.find { |chunk| chunk.name == :sim } res << " " * (level+1)*3 res << "code->function = &#{function.to_c};\n" # Generate the Returns of the result. res << "\n" res << " " * (level+1)*3 res << "return code;\n" # Close the behavior makeing. res << " " * level*3 res << "}\n\n" return res end
Generates the content of the h file.
# File lib/HDLRuby/hruby_low2c.rb, line 1036 def to_ch res = "" # Declare the global variable holding the signal. res << "extern Behavior #{Low2C.obj_name(self)};\n\n" # Generate the access to the function making the behavior. res << "extern Behavior #{Low2C.make_name(self)}();\n\n" # Generate the accesses to the block of the behavior. res << self.block.to_ch return res; end
Creates a file in path
containing the content of the code.
# File lib/HDLRuby/hdrcc.rb, line 233 def to_file(path = "") self.each_chunk do |chunk| # Process the lumps of the chunk. # NOTE: for now use the C code generation of Low2C content = chunk.to_c # Dump to a file. if chunk.name != :sim then # The chunk is to be dumbed to a file. # puts "Outputing chunk:#{HDLRuby::Low::Low2C.obj_name(chunk)}" outfile = File.open(path + "/" + HDLRuby::Low::Low2C.obj_name(chunk) + "." + chunk.name.to_s,"w") outfile << content outfile.close end end end
Generates the text of the equivalent hdr text. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2hdr.rb, line 526 def to_hdr(level = 0) return self.content.to_s end
Creates a new high code.
# File lib/HDLRuby/hruby_low2high.rb, line 218 def to_high # Create the new code. res = HDLRuby::High::Code.new # Add the events. self.each_event { |ev| res.add_event(ev.to_high) } # Add the code chunks. self.each_chunk { |ch| res.add_chunk(ch.to_high) } end
Generates the text of the equivalent HDLRuby::High
code. level
is the hierachical level of the object.
# File lib/HDLRuby/hruby_low2vhd.rb, line 1116 def to_vhdl(level = 0) raise "Code constructs cannot be converted into VHDL." end