Class: HDLRuby::High::Std::DecoderT

Inherits:
Object
  • Object
show all
Includes:
HScope_missing
Defined in:
lib/HDLRuby/std/decoder.rb

Overview

Describes a high-level decoder type.

Defined Under Namespace

Classes: Entry, Field

Constant Summary

Constants included from Hmissing

Hmissing::High, Hmissing::NAMES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HScope_missing

#h_missing, #method_missing

Methods included from Hmissing

#method_missing

Constructor Details

#initialize(name) ⇒ DecoderT

Creates a new decoder type with +name+.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/HDLRuby/std/decoder.rb', line 37

def initialize(name)
    # Check and set the name
    @name = name.to_sym

    # Initialize the internals of the decoder.


    # Initialize the environment for building the decoder.

    # The main entries.
    @entries = []

    # The default code to execute when no entry match.
    @default_code = nil

    # Creates the namespace to execute the fsm block in.
    @namespace = Namespace.new(self)

    # Generates the function for setting up the decoder
    # provided there is a name.
    obj = self # For using the right self within the proc
    HDLRuby::High.space_reg(@name) do |expr,&ruby_block|
        if ruby_block then
            # Builds the decoder.
            obj.build(expr,&ruby_block)
        else
            # Return the fsm as is.
            return obj
        end
    end unless name.empty?

end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class HDLRuby::High::HScope_missing

Instance Attribute Details

#default_codeObject (readonly)

The default code if any.



33
34
35
# File 'lib/HDLRuby/std/decoder.rb', line 33

def default_code
  @default_code
end

#nameObject (readonly)

The name of the decoder type.



27
28
29
# File 'lib/HDLRuby/std/decoder.rb', line 27

def name
  @name
end

#namespaceObject (readonly)

The namespace associated with the decoder



30
31
32
# File 'lib/HDLRuby/std/decoder.rb', line 30

def namespace
  @namespace
end

Instance Method Details

#build(expr, &ruby_block) ⇒ Object

builds the decoder on expression +expr+ by executing +ruby_block+.



71
72
73
74
75
76
77
78
79
80
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
# File 'lib/HDLRuby/std/decoder.rb', line 71

def build(expr,&ruby_block)
    # Use local variable for accessing the attribute since they will
    # be hidden when opening the sytem.
    entries = @entries
    namespace = @namespace
    this   = self
    return_value = nil

    HDLRuby::High.space_push(namespace)
    # Execute the instantiation block
    return_value =HDLRuby::High.top_user.instance_exec(&ruby_block)

    # Create the decoder code

    # The process
    par do
        # Depending on the type of entry.
        test = :hif # Which command to use for testing
        # (first: hif, then heslif)
        entries.each do |entry|
            # Build the predicate for checking the entry.
            entry_predicate = entry.id_fields.map do |field|
                expr[field.range] == field.content
            end.reduce(:&)

            send(test,entry_predicate) do
                # Sets the local variables.
                entry.var_fields.each do |field|
                    this.
                        define_singleton_method(field.content) do
                        expr[field.range]
                    end
                end
                # Generate the content of the entry.
                entry.code.call
            end
            test = :helsif # Now use helsif for the alternative.
        end
        # Adds the default code if any.
        if default_code then
            helse(&default_code)
        end
    end

    HDLRuby::High.space_pop

    return return_value
end

#default(&ruby_block) ⇒ Object

Declares the default code to execute when no format maches.



179
180
181
# File 'lib/HDLRuby/std/decoder.rb', line 179

def default(&ruby_block)
    @default_code = ruby_block
end

#entry(format, &ruby_block) ⇒ Object

Declares a new entry with +format+ and executing +ruby_block+.



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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/HDLRuby/std/decoder.rb', line 125

def entry(format, &ruby_block)
    # puts "entry with format=#{format}"
    # Create the resulting entry
    result = Entry.new
    result.code = ruby_block
    # Process the format.
    format = format.to_s
    width = format.size
    # For that purpose create the regular expression used to process it.
    prs = "([0-1]+)|(a+)|(b+)|(c+)|(d+)|(e+)|(g+)|(h+)|(i+)|(j+)|(k+)|(l+)|(m+)|(n+)|(o+)|(p+)|(q+)|(r+)|(s+)|(t+)|(u+)|(v+)|(w+)|(x+)|(y+)|(z+)"
    # Check if the format is compatible with it.
    unless format =~ Regexp.new("^(#{prs})+$") then
        raise AnyError("Invalid format for a field: #{format}")
    end
    # Split the format in fields.
    format = format.split(Regexp.new(prs)).select {|str| !str.empty?}
    # puts "format=#{format}"
    # Fills the entry with each field of the format.
    result.id_fields = []
    result.var_fields = []
    pos = width-1
    format.each do |str|
        # puts "str=#{str}"
        # Create a new field and compute its range.
        field = Field.new
        field.range = pos..(pos-str.size+1)
        # Build its content, and add the field.
        # Depends on wether it is an id or a variable field?
        if str =~ /[0-1]+/ then
            # Id field.
            # Build its type.
            type = TypeVector.new(:"",bit,
                                  field.range.first-field.range.last..0)
            # Build the content as a value.
            field.content = Value.new(type,str)
            # Add the field.
            result.id_fields << field
        else
            # Variable field.
            # Build the content as a single-character symbol.
            field.content = str[0].to_sym
            # Add the field.
            result.var_fields << field
        end
        # Update the position.
        pos = pos-str.size
    end
    # Add it to the list of entries.
    @entries << result
    # Return it.
    return result
end