class HDLRuby::High::Std::DecoderT
Describes a high-level decoder type.
Attributes
default_code[R]
The default code if any.
name[R]
The name of the decoder type.
namespace[R]
The namespace associated with the decoder
Public Class Methods
new(name)
click to toggle source
Creates a new decoder type with name
.
# 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
Public Instance Methods
build(expr,&ruby_block)
click to toggle source
builds the decoder on expression expr
by executing ruby_block
.
# 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)
click to toggle source
Declares the default code to execute when no format maches.
# File lib/HDLRuby/std/decoder.rb, line 179 def default(&ruby_block) @default_code = ruby_block end
entry(format, &ruby_block)
click to toggle source
Declares a new entry with format
and executing ruby_block
.
# 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