Class: HDLRuby::Low::Code

Inherits:
Base::Code
  • Object
show all
Includes:
Hparent, Low2Symbol
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_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 Hparent

#parent

Instance Method Summary collapse

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #scope

Constructor Details

#initializeCode

Creates a new chunk of code.



2705
2706
2707
2708
2709
2710
# File 'lib/HDLRuby/hruby_low.rb', line 2705

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.



2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
# File 'lib/HDLRuby/hruby_low.rb', line 2716

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.



2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
# File 'lib/HDLRuby/hruby_low.rb', line 2743

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.



2735
2736
2737
2738
2739
2740
# File 'lib/HDLRuby/hruby_low.rb', line 2735

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.



2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
# File 'lib/HDLRuby/hruby_low.rb', line 2780

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.



2757
2758
2759
2760
2761
2762
# File 'lib/HDLRuby/hruby_low.rb', line 2757

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:

  • (Boolean)


2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
# File 'lib/HDLRuby/hruby_low.rb', line 2796

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:

  • (Boolean)


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

def has_event?
    return !@events.empty?
end

#hashObject

Hash function.



2812
2813
2814
# File 'lib/HDLRuby/hruby_low.rb', line 2812

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

#on_edge?Boolean

Tells if there is a positive or negative edge event.

Returns:

  • (Boolean)


2770
2771
2772
2773
2774
2775
# File 'lib/HDLRuby/hruby_low.rb', line 2770

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

#set_content!(content) ⇒ Object

Sets the content.



1285
1286
1287
1288
1289
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1285

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.



1279
1280
1281
1282
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1279

def set_type!(type)
    # Check and set type.
    @type = type.to_sym
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)



1059
1060
1061
1062
1063
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
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
# File 'lib/HDLRuby/hruby_low2c.rb', line 1059

def to_c(res,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)"
        res << 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"
        res << "code->events[#{i}] = "
        event.to_c(res)
        res << ";\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
        sigad = ""
        event.ref.resolve.to_c_signal(sigad)
        # 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"
    res << "code->function = &"
    function.to_c(res)
    res << ";\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_ch(res) ⇒ Object

Generates the content of the h file. def to_ch



1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
# File 'lib/HDLRuby/hruby_low2c.rb', line 1155

def to_ch(res)
    # 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
    self.block.to_ch(res)

    return res;
end

#to_file(path = "") ⇒ Object

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



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# 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.
            # show? "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_hdr(level = 0) ⇒ Object

Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.



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

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

#to_highObject

Creates a new high code.



218
219
220
221
222
223
224
225
# 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

#to_vhdl(level = 0) ⇒ Object

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



1116
1117
1118
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1116

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