Class: HDLRuby::Low::Code

Inherits:
Base::Code
  • Object
show all
Includes:
Hdecorator, Hparent, Low2Symbol
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2sym.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/backend/hruby_c_allocator.rb,
lib/HDLRuby/hdrcc.rb

Overview

Extend the Code class with generation of file for the content.

Direct Known Subclasses

High::Code

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary

Attributes included from Hdecorator

#hdr_id

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from Low2Symbol

#to_sym

Methods included from Hdecorator

decorate_parent_id, dump, each, each_with_property, get, included, load, #properties

Methods included from Hparent

#scope

Constructor Details

#initializeCode

Creates a new chunk of code.



2658
2659
2660
2661
2662
2663
# File 'lib/HDLRuby/hruby_low.rb', line 2658

def initialize
    # Initialize the set of events.
    @events = []
    # Initialize the content.
    @chunks = HashName.new
end

Instance Method Details

#add_chunk(chunk) ⇒ Object

Adds a +chunk+ to the sensitivity list.



2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
# File 'lib/HDLRuby/hruby_low.rb', line 2669

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

#add_event(event) ⇒ Object

Adds an +event+ to the sensitivity list.



2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
# File 'lib/HDLRuby/hruby_low.rb', line 2696

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

#c_code_allocate(allocator) ⇒ Object

Allocates signals within C code using +allocator+.



68
69
70
71
72
73
# 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

#each_chunk(&ruby_block) ⇒ Object

Iterates over the code chunks.

Returns an enumerator if no ruby block is given.



2688
2689
2690
2691
2692
2693
# File 'lib/HDLRuby/hruby_low.rb', line 2688

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

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
# File 'lib/HDLRuby/hruby_low.rb', line 2733

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

#each_event(&ruby_block) ⇒ Object

Iterates over the events of the sensitivity list.

Returns an enumerator if no ruby block is given.



2710
2711
2712
2713
2714
2715
# File 'lib/HDLRuby/hruby_low.rb', line 2710

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

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:



2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
# File 'lib/HDLRuby/hruby_low.rb', line 2749

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

#has_event?Boolean

Tells if there is any event.

Returns:



2718
2719
2720
# File 'lib/HDLRuby/hruby_low.rb', line 2718

def has_event?
    return !@events.empty?
end

#hashObject

Hash function.



2765
2766
2767
# File 'lib/HDLRuby/hruby_low.rb', line 2765

def hash
    return [@events,@chunk].hash
end

#on_edge?Boolean

Tells if there is a positive or negative edge event.

Returns:



2723
2724
2725
2726
2727
2728
# File 'lib/HDLRuby/hruby_low.rb', line 2723

def on_edge?
    @events.each do |event|
        return true if event.on_edge?
    end
    return false
end

#set_content!(content) ⇒ Object

Sets the content.



1203
1204
1205
1206
1207
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1203

def set_content!(content)
    @content = content
    # Freeze it to avoid dynamic tempering of the hardware.
    content.freeze
end

#set_type!(type) ⇒ Object

Sets the type.



1197
1198
1199
1200
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1197

def set_type!(type)
    # Check and set type.
    @type = type.to_sym
end

#to_c(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
# File 'lib/HDLRuby/hruby_low2c.rb', line 942

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

#to_chObject

Generates the content of the h file.



1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
# File 'lib/HDLRuby/hruby_low2c.rb', line 1029

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

#to_file(path = "") ⇒ Object

Creates a file in +path+ containing the content of the code.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/HDLRuby/hdrcc.rb', line 206

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

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



526
527
528
# File 'lib/HDLRuby/hruby_low2high.rb', line 526

def to_high(level = 0)
    return self.content.to_s
end

#to_vhdl(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



1092
1093
1094
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1092

def to_vhdl(level = 0)
    raise "Code constructs cannot be converted into VHDL."
end