lib/rggen/builtins/register/reg_model.rb
simple_item :register, :reg_model do
ral do
export :model_creation
delegate [:byte_width] => :configuration
delegate [:local_address_width] => :register_block
delegate [:name, :dimensions, :array?, :type?] => :register
available? { !type?(:external) }
build do
variable :block_model, :reg_model,
data_type: model_name,
name: name,
dimensions: dimensions,
random: true
end
generate_code :package_item do
class_definition model_name do |c|
c.base base_model
c.variables register.variable_declarations(:reg_model)
c.body { |code| body_code(code) }
end
end
def model_creation(code)
foreach_header(code) if array?
code << subroutine_call('`rggen_ral_create_reg_model', arguments) << nl
foreach_footer(code) if array?
end
def foreach_header(code)
code << "foreach (#{name}[#{loop_varibles.join(', ')}]) begin" << nl
code.indent += 2
end
def foreach_footer(code)
code.indent -= 2
code << :end << nl
end
def arguments
[handle, instance_name, array_index, offset_address, rights, unmapped, hdl_path]
end
def handle
create_identifier(name)[loop_varibles]
end
def instance_name
return string(name) unless array?
subroutine_call '$sformatf', [
string(name + '[%0d]' * loop_varibles.size),
*loop_varibles
]
end
def array_index
array((array? && loop_varibles) || [])
end
def offset_address
base = hex(register.start_address, local_address_width)
if !array? || type?(:indirect)
base
else
"#{base} + #{byte_width} * #{loop_varibles.first}"
end
end
def rights
return string(:RO) if register.read_only?
return string(:WO) if register.write_only?
string(:RW)
end
def unmapped
(type?(:indirect) && 1) || 0
end
def hdl_path
return string("g_#{name}") unless array?
subroutine_call '$sformatf', [
string("g_#{name}" + '.g[%0d]' * loop_varibles.size),
*loop_varibles
]
end
def loop_varibles
return nil unless array?
@loop_varibles ||= Array.new(dimensions.size, &method(:loop_index))
end
def model_name
"#{name}_reg_model"
end
def base_model
(type?(:indirect) && :rggen_ral_indirect_reg) || :rggen_ral_reg
end
def body_code(code)
register.generate_code(:reg_model_item, :top_down, code)
end
end
end