On Fri, Apr 4, 2008 at 4:49 AM, tender flake <tenderflake / mailinator.com> wrote:
> Hello,
>
>  I'm trying to write a simple DSL to define memory maps of hardware
>  devices.
>  Something like:
>
>  cfg_block "top_device", :depth => 16 do
>   reg "ctrl_reg", :offset => 0, :mode => "RW"
>   reg "status_reg", :offset => 1, :mode => "R"
>  end
>
>  I've implemented something but I am not satisfied with it.

Hi,

I wrote Doodle to do this kind of thing (gem install doodle):

require 'doodle'
require 'pp'

class Register < Doodle::Base
  has :name
  has :offset
  has :mode
end

class ConfigBlock < Doodle::Base
  has :name
  has :depth
  has :registers, :init => [], :collect => { :reg => Register }
end

def cfg_block(*args, &block)
  ConfigBlock(*args, &block)
end

modules = cfg_block "top_device", :depth => 16 do
 reg "ctrl_reg", :offset => 0, :mode => "RW"
 reg "status_reg", :offset => 1, :mode => "R"
end

pp modules

Output:

#<ConfigBlock:0xb7b9b5c4
 @depth=16,
 @name="top_device",
 @registers=
  [#<Register:0xb7b9582c @mode="RW", @name="ctrl_reg", @offset=0>,
   #<Register:0xb7b8ecfc @mode="R", @name="status_reg", @offset=1>]>

If you wanted validation on the parameters, you could do something like:

require 'doodle'

class Named < Doodle::Base
  has :name, :kind => String do
    from Symbol do |sym|
      sym.to_s
    end
  end
end

class Register < Named
  has :offset, :kind => Integer do
    must "be in range 0-15" do |offset|
      (0..15).include?(offset)
    end
  end
  has :mode, :kind => String do |mode|
    valid_modes = %w[R W RW]
    must "be one of #{valid_modes.join(', ')}" do |mode|
      valid_modes.include?(mode)
    end
  end
end

class ConfigBlock < Named
  has :depth, :kind => Integer
  has :registers, :init => [], :collect => { :reg => Register }
end

def cfg_block(*args, &block)
  ConfigBlock(*args, &block)
end

modules = cfg_block :top_device, :depth => 16 do
 reg :ctrl_reg, :offset => 0, :mode => "RW"
 reg :status_reg, :offset => 1, :mode => "WR"
end

#=> memory-map2.rb:35: mode must be one of R, W, RW - got String("WR")
(Doodle::ValidationError)

Regards,
Sean