Sean O'Halpin
4/4/2008 11:54:00 PM
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