rggen 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +91 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/bin/rggen +6 -0
- data/lib/rggen/base/component.rb +27 -0
- data/lib/rggen/base/component_factory.rb +46 -0
- data/lib/rggen/base/hierarchical_accessors.rb +87 -0
- data/lib/rggen/base/hierarchical_item_accessors.rb +79 -0
- data/lib/rggen/base/item.rb +24 -0
- data/lib/rggen/base/item_factory.rb +20 -0
- data/lib/rggen/builder/builder.rb +69 -0
- data/lib/rggen/builder/category.rb +52 -0
- data/lib/rggen/builder/component_entry.rb +50 -0
- data/lib/rggen/builder/component_store.rb +42 -0
- data/lib/rggen/builder/input_component_store.rb +25 -0
- data/lib/rggen/builder/item_store.rb +89 -0
- data/lib/rggen/builder/list_item_entry.rb +81 -0
- data/lib/rggen/builder/output_component_store.rb +13 -0
- data/lib/rggen/builder/simple_item_entry.rb +33 -0
- data/lib/rggen/builtins/bit_field/bit_assignment.rb +39 -0
- data/lib/rggen/builtins/bit_field/field_model_creation.rb +25 -0
- data/lib/rggen/builtins/bit_field/field_model_declaration.rb +9 -0
- data/lib/rggen/builtins/bit_field/initial_value.rb +36 -0
- data/lib/rggen/builtins/bit_field/name.rb +26 -0
- data/lib/rggen/builtins/bit_field/reference.rb +42 -0
- data/lib/rggen/builtins/bit_field/reserved.rb +9 -0
- data/lib/rggen/builtins/bit_field/ro.rb +19 -0
- data/lib/rggen/builtins/bit_field/rw.erb +13 -0
- data/lib/rggen/builtins/bit_field/rw.rb +25 -0
- data/lib/rggen/builtins/bit_field/type.rb +205 -0
- data/lib/rggen/builtins/bit_field/wo.rb +5 -0
- data/lib/rggen/builtins/global/address_width.rb +17 -0
- data/lib/rggen/builtins/global/data_width.rb +20 -0
- data/lib/rggen/builtins/loaders/configuration/json_loader.rb +7 -0
- data/lib/rggen/builtins/loaders/configuration/yaml_loader.rb +7 -0
- data/lib/rggen/builtins/loaders/register_map/csv_loader.rb +14 -0
- data/lib/rggen/builtins/loaders/register_map/xls_loader.rb +19 -0
- data/lib/rggen/builtins/loaders/register_map/xlsx_ods_loader.rb +24 -0
- data/lib/rggen/builtins/register/accessibility.rb +23 -0
- data/lib/rggen/builtins/register/address_decoder.erb +16 -0
- data/lib/rggen/builtins/register/address_decoder.rb +92 -0
- data/lib/rggen/builtins/register/array.rb +133 -0
- data/lib/rggen/builtins/register/field_model_creator.rb +10 -0
- data/lib/rggen/builtins/register/field_model_declarations.rb +7 -0
- data/lib/rggen/builtins/register/name.rb +26 -0
- data/lib/rggen/builtins/register/offset_address.rb +55 -0
- data/lib/rggen/builtins/register/read_data.rb +36 -0
- data/lib/rggen/builtins/register/reg_model_constructor.rb +17 -0
- data/lib/rggen/builtins/register/reg_model_creation.rb +64 -0
- data/lib/rggen/builtins/register/reg_model_declaration.rb +13 -0
- data/lib/rggen/builtins/register/reg_model_definition.rb +22 -0
- data/lib/rggen/builtins/register/shadow.rb +130 -0
- data/lib/rggen/builtins/register/shadow_index_configurator.rb +53 -0
- data/lib/rggen/builtins/register/uniqueness_validator.rb +48 -0
- data/lib/rggen/builtins/register_block/apb.erb +27 -0
- data/lib/rggen/builtins/register_block/apb.rb +20 -0
- data/lib/rggen/builtins/register_block/base_address.rb +64 -0
- data/lib/rggen/builtins/register_block/block_model_constructor.rb +14 -0
- data/lib/rggen/builtins/register_block/block_model_default_map_creator.rb +39 -0
- data/lib/rggen/builtins/register_block/block_model_definition.rb +18 -0
- data/lib/rggen/builtins/register_block/byte_size.rb +37 -0
- data/lib/rggen/builtins/register_block/clock_reset.rb +8 -0
- data/lib/rggen/builtins/register_block/host_if.rb +46 -0
- data/lib/rggen/builtins/register_block/module_definition.rb +13 -0
- data/lib/rggen/builtins/register_block/name.rb +26 -0
- data/lib/rggen/builtins/register_block/ral_package_definition.rb +19 -0
- data/lib/rggen/builtins/register_block/reg_model_creator.rb +14 -0
- data/lib/rggen/builtins/register_block/reg_model_declarations.rb +7 -0
- data/lib/rggen/builtins/register_block/response_mux.erb +14 -0
- data/lib/rggen/builtins/register_block/response_mux.rb +16 -0
- data/lib/rggen/builtins/register_block/signal_declarations.rb +9 -0
- data/lib/rggen/builtins.rb +52 -0
- data/lib/rggen/commands.rb +23 -0
- data/lib/rggen/core_components/configuration/configuration_factory.rb +23 -0
- data/lib/rggen/core_components/configuration/item_factory.rb +13 -0
- data/lib/rggen/core_components/configuration/raise_error.rb +11 -0
- data/lib/rggen/core_components/configuration/setup.rb +14 -0
- data/lib/rggen/core_components/ral/item.rb +16 -0
- data/lib/rggen/core_components/ral/setup.rb +19 -0
- data/lib/rggen/core_components/register_map/bit_field_factory.rb +11 -0
- data/lib/rggen/core_components/register_map/component.rb +12 -0
- data/lib/rggen/core_components/register_map/generic_map.rb +69 -0
- data/lib/rggen/core_components/register_map/item.rb +22 -0
- data/lib/rggen/core_components/register_map/item_factory.rb +13 -0
- data/lib/rggen/core_components/register_map/loader.rb +13 -0
- data/lib/rggen/core_components/register_map/raise_error.rb +17 -0
- data/lib/rggen/core_components/register_map/register_block_factory.rb +29 -0
- data/lib/rggen/core_components/register_map/register_factory.rb +18 -0
- data/lib/rggen/core_components/register_map/register_map_factory.rb +21 -0
- data/lib/rggen/core_components/register_map/setup.rb +33 -0
- data/lib/rggen/core_components/rtl/component.rb +28 -0
- data/lib/rggen/core_components/rtl/item.rb +83 -0
- data/lib/rggen/core_components/rtl/setup.rb +19 -0
- data/lib/rggen/core_components.rb +23 -0
- data/lib/rggen/core_extensions/facets.rb +17 -0
- data/lib/rggen/core_extensions/forwardable.rb +26 -0
- data/lib/rggen/core_extensions/integer.rb +5 -0
- data/lib/rggen/core_extensions/math.rb +7 -0
- data/lib/rggen/exceptions.rb +22 -0
- data/lib/rggen/generator.rb +185 -0
- data/lib/rggen/input_base/component.rb +19 -0
- data/lib/rggen/input_base/component_factory.rb +58 -0
- data/lib/rggen/input_base/item.rb +170 -0
- data/lib/rggen/input_base/item_factory.rb +13 -0
- data/lib/rggen/input_base/loader.rb +14 -0
- data/lib/rggen/input_base/regexp_patterns.rb +29 -0
- data/lib/rggen/output_base/code_block.rb +72 -0
- data/lib/rggen/output_base/code_utility.rb +44 -0
- data/lib/rggen/output_base/component.rb +88 -0
- data/lib/rggen/output_base/component_factory.rb +32 -0
- data/lib/rggen/output_base/item.rb +175 -0
- data/lib/rggen/output_base/item_factory.rb +6 -0
- data/lib/rggen/output_base/line.rb +28 -0
- data/lib/rggen/output_base/template_utility.rb +29 -0
- data/lib/rggen/output_base/verilog_utility/class_definition.rb +23 -0
- data/lib/rggen/output_base/verilog_utility/declaration.rb +70 -0
- data/lib/rggen/output_base/verilog_utility/identifier.rb +29 -0
- data/lib/rggen/output_base/verilog_utility/module_definition.rb +47 -0
- data/lib/rggen/output_base/verilog_utility/package_definition.rb +67 -0
- data/lib/rggen/output_base/verilog_utility/structure_definition.rb +52 -0
- data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +43 -0
- data/lib/rggen/output_base/verilog_utility.rb +66 -0
- data/lib/rggen/version.rb +6 -0
- data/lib/rggen.rb +65 -0
- data/ral/compile.f +4 -0
- data/ral/rggen_ral_block.svh +84 -0
- data/ral/rggen_ral_field.svh +47 -0
- data/ral/rggen_ral_macros.svh +22 -0
- data/ral/rggen_ral_map.svh +124 -0
- data/ral/rggen_ral_pkg.sv +14 -0
- data/ral/rggen_ral_reg.svh +52 -0
- data/ral/rggen_ral_shadow_reg.svh +188 -0
- data/rggen.gemspec +45 -0
- data/rtl/bit_field/rggen_bit_field_rw.sv +28 -0
- data/rtl/register/rggen_address_decoder.sv +49 -0
- data/rtl/register_block/rggen_host_if_apb.sv +40 -0
- data/rtl/register_block/rggen_response_mux.sv +82 -0
- data/sample/sample.csv +14 -0
- data/sample/sample.json +4 -0
- data/sample/sample.xls +0 -0
- data/sample/sample.xlsx +0 -0
- data/sample/sample.yaml +2 -0
- data/sample/sample_0.sv +285 -0
- data/sample/sample_0_ral_pkg.sv +99 -0
- data/sample/sample_1.sv +172 -0
- data/sample/sample_1_ral_pkg.sv +53 -0
- data/sample/sample_setup.rb +21 -0
- data/setup/default.rb +11 -0
- metadata +296 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
class CodeBlock
|
|
4
|
+
def initialize
|
|
5
|
+
@lines = []
|
|
6
|
+
@indent = 0
|
|
7
|
+
add_newline
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :indent
|
|
11
|
+
|
|
12
|
+
def indent=(value)
|
|
13
|
+
@indent = value
|
|
14
|
+
@lines.last.indent = @indent
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def <<(other)
|
|
18
|
+
case other
|
|
19
|
+
when CodeBlock
|
|
20
|
+
merge_code_block(other)
|
|
21
|
+
when /\n/
|
|
22
|
+
add_multiple_lines_string(other)
|
|
23
|
+
when :newline
|
|
24
|
+
add_newline
|
|
25
|
+
else
|
|
26
|
+
@lines.last << other
|
|
27
|
+
end
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def last_line_empty?
|
|
32
|
+
lines.empty? || lines.last.empty?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
@lines.map(&:to_s).each(&:rstrip!).join("\n")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def add_newline
|
|
42
|
+
line = Line.new
|
|
43
|
+
line.indent = @indent
|
|
44
|
+
@lines << line
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def merge_code_block(other_block)
|
|
48
|
+
other_block.lines.each_with_index do |line, i|
|
|
49
|
+
line.indent += @indent
|
|
50
|
+
if i == 0
|
|
51
|
+
@lines.last.indent = line.indent if last_line_empty?
|
|
52
|
+
@lines.last.words.concat(line.words)
|
|
53
|
+
else
|
|
54
|
+
@lines << line
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
@lines.last.indent = @indent if other_block.last_line_empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def add_multiple_lines_string(other_string)
|
|
61
|
+
other_string.each_line.with_index do |line, i|
|
|
62
|
+
add_newline if i > 0
|
|
63
|
+
@lines.last << line
|
|
64
|
+
end
|
|
65
|
+
add_newline if other_string.end_with?("\n")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
attr_reader :lines
|
|
69
|
+
protected :lines
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module CodeUtility
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def newline
|
|
7
|
+
:newline
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
alias_method :nl, :newline
|
|
11
|
+
|
|
12
|
+
def comma
|
|
13
|
+
','
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def semicolon
|
|
17
|
+
';'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def space(size = 1)
|
|
21
|
+
' ' * size
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def code_block(indent_size = 0, &block)
|
|
25
|
+
CodeBlock.new.tap do |code|
|
|
26
|
+
code.indent = indent_size
|
|
27
|
+
block.call(code) if block_given?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def indent(code_block, indent_size, &indent_block)
|
|
32
|
+
code_block << nl unless code_block.last_line_empty?
|
|
33
|
+
code_block.indent += indent_size
|
|
34
|
+
indent_block.call if block_given?
|
|
35
|
+
code_block << nl unless code_block.last_line_empty?
|
|
36
|
+
code_block.indent -= indent_size
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def loop_index(level)
|
|
40
|
+
level.times.with_object('i') { |_, index| index.next! }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
class Component < Base::Component
|
|
4
|
+
include Base::HierarchicalAccessors
|
|
5
|
+
|
|
6
|
+
def initialize(parent, configuration, register_map)
|
|
7
|
+
super(parent)
|
|
8
|
+
define_hierarchical_accessors
|
|
9
|
+
@configuration = configuration
|
|
10
|
+
@register_map = register_map
|
|
11
|
+
def_delegators(:@register_map, *@register_map.fields)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :configuration
|
|
15
|
+
attr_writer :output_directory
|
|
16
|
+
|
|
17
|
+
def add_item(item)
|
|
18
|
+
super(item)
|
|
19
|
+
def_object_delegators(@items.last, *item.exported_methods)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def build
|
|
23
|
+
items.each(&:build)
|
|
24
|
+
children.each(&:build)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def generate_code(kind, mode, buffer = nil)
|
|
28
|
+
buffer ||= CodeBlock.new
|
|
29
|
+
generate_pre_code(kind, buffer)
|
|
30
|
+
generate_main_code(kind, mode, buffer)
|
|
31
|
+
generate_post_code(kind, buffer)
|
|
32
|
+
buffer
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def write_file(root_directory)
|
|
36
|
+
directory = output_directory(root_directory)
|
|
37
|
+
FileUtils.mkpath(directory) unless Dir.exist?(directory)
|
|
38
|
+
items.each do |item|
|
|
39
|
+
item.write_file(directory)
|
|
40
|
+
end
|
|
41
|
+
children.each do |child|
|
|
42
|
+
child.write_file(directory)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def generate_pre_code(kind, buffer)
|
|
49
|
+
items.each do |item|
|
|
50
|
+
item.generate_pre_code(kind, buffer)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def generate_main_code(kind, mode, buffer)
|
|
55
|
+
case mode
|
|
56
|
+
when :top_down
|
|
57
|
+
generate_item_code(kind, buffer)
|
|
58
|
+
generate_child_code(kind, mode, buffer)
|
|
59
|
+
when :bottom_up
|
|
60
|
+
generate_child_code(kind, mode, buffer)
|
|
61
|
+
generate_item_code(kind, buffer)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def generate_child_code(kind, mode, buffer)
|
|
66
|
+
children.each do |child|
|
|
67
|
+
child.generate_code(kind, mode, buffer)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def generate_item_code(kind, buffer)
|
|
72
|
+
items.each do |item|
|
|
73
|
+
item.generate_code(kind, buffer)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def generate_post_code(kind, buffer)
|
|
78
|
+
items.reverse_each do |item|
|
|
79
|
+
item.generate_post_code(kind, buffer)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def output_directory(root_directory)
|
|
84
|
+
File.join([root_directory, @output_directory.to_s].reject(&:empty?))
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
class ComponentFactory < Base::ComponentFactory
|
|
4
|
+
attr_writer :output_directory
|
|
5
|
+
|
|
6
|
+
def create(*args)
|
|
7
|
+
component = super(*args)
|
|
8
|
+
if @root_factory
|
|
9
|
+
component.build
|
|
10
|
+
component.output_directory = @output_directory
|
|
11
|
+
end
|
|
12
|
+
component
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def create_component(parent, configuration, register_map)
|
|
16
|
+
@target_component.new(parent, configuration, register_map)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create_items(generator, configuration, soruce)
|
|
20
|
+
@item_factories.each_value do |item_factory|
|
|
21
|
+
create_item(item_factory, generator, configuration, soruce)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_children(generator, configuration, source)
|
|
26
|
+
source.children.each do |child_source|
|
|
27
|
+
create_child(generator, configuration, child_source)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
class Item < Base::Item
|
|
4
|
+
include Base::HierarchicalItemAccessors
|
|
5
|
+
include CodeUtility
|
|
6
|
+
include TemplateUtility
|
|
7
|
+
|
|
8
|
+
class CodeGenerator
|
|
9
|
+
def []=(kind, body)
|
|
10
|
+
@bodies ||= {}
|
|
11
|
+
@bodies[kind] = body
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def generate_code(item, kind, buffer)
|
|
15
|
+
return unless @bodies && @bodies.key?(kind)
|
|
16
|
+
if @bodies[kind].arity.zero?
|
|
17
|
+
buffer << item.instance_exec(&@bodies[kind])
|
|
18
|
+
else
|
|
19
|
+
item.instance_exec(buffer, &@bodies[kind])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def copy
|
|
24
|
+
CodeGenerator.new.tap do |g|
|
|
25
|
+
g.instance_variable_set(:@bodies, Hash[@bodies]) if @bodies
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class FileWriter
|
|
31
|
+
def initialize(name_pattern, body)
|
|
32
|
+
@name_pattern = BabyErubis::Text.new.from_str(name_pattern)
|
|
33
|
+
@body = body
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def write_file(item, outptu_directory)
|
|
37
|
+
code = generate_code(item)
|
|
38
|
+
path = file_path(item, outptu_directory)
|
|
39
|
+
File.write(path, code, nil, binmode: true)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def generate_code(item)
|
|
45
|
+
code = CodeBlock.new.tap do |c|
|
|
46
|
+
if @body.arity.zero?
|
|
47
|
+
c << item.instance_exec(&@body)
|
|
48
|
+
else
|
|
49
|
+
item.instance_exec(c, &@body)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
code.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def file_path(item, outptu_directory)
|
|
56
|
+
path = [outptu_directory, file_name(item)].reject(&:empty?)
|
|
57
|
+
File.join(*path)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def file_name(item)
|
|
61
|
+
@name_pattern.render(item)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
define_helpers do
|
|
66
|
+
attr_reader :builders
|
|
67
|
+
attr_reader :pre_code_generator
|
|
68
|
+
attr_reader :code_generator
|
|
69
|
+
attr_reader :post_code_generator
|
|
70
|
+
attr_reader :file_writer
|
|
71
|
+
|
|
72
|
+
def use_verilog_utility
|
|
73
|
+
include VerilogUtility
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def build(&body)
|
|
77
|
+
@builders ||= []
|
|
78
|
+
@builders << body
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def generate_pre_code(kind, &body)
|
|
82
|
+
@pre_code_generator ||= CodeGenerator.new
|
|
83
|
+
@pre_code_generator[kind] = body
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def generate_code(kind, &body)
|
|
87
|
+
@code_generator ||= CodeGenerator.new
|
|
88
|
+
@code_generator[kind] = body
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def generate_code_from_template(kind, path = nil)
|
|
92
|
+
path ||= File.ext(caller.first[/^(.+?):\d/, 1], 'erb')
|
|
93
|
+
generate_code(kind) { process_template(path) }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def generate_post_code(kind, &body)
|
|
97
|
+
@post_code_generator ||= CodeGenerator.new
|
|
98
|
+
@post_code_generator[kind] = body
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def write_file(name_pattern, &body)
|
|
102
|
+
@file_writer ||= FileWriter.new(name_pattern, body)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def export(*exporting_methods)
|
|
106
|
+
exported_methods.concat(
|
|
107
|
+
exporting_methods.reject(&exported_methods.method(:include?))
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def exported_methods
|
|
112
|
+
@exported_methods ||= []
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.inherited(subclass)
|
|
117
|
+
[:@builders, :@exported_methods].each do |v|
|
|
118
|
+
subclass.inherit_class_instance_variable(v, self, &:dup)
|
|
119
|
+
end
|
|
120
|
+
[
|
|
121
|
+
:@pre_code_generator,
|
|
122
|
+
:@code_generator,
|
|
123
|
+
:@post_code_generator
|
|
124
|
+
].each do |v|
|
|
125
|
+
subclass.inherit_class_instance_variable(v, self, &:copy)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def initialize(owner)
|
|
130
|
+
super(owner)
|
|
131
|
+
define_hierarchical_item_accessors
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
class_delegator :builders
|
|
135
|
+
class_delegator :pre_code_generator
|
|
136
|
+
class_delegator :code_generator
|
|
137
|
+
class_delegator :file_writer
|
|
138
|
+
class_delegator :post_code_generator
|
|
139
|
+
class_delegator :exported_methods
|
|
140
|
+
|
|
141
|
+
def build
|
|
142
|
+
return if builders.nil?
|
|
143
|
+
builders.each do |builder|
|
|
144
|
+
instance_exec(&builder)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def generate_pre_code(kind, buffer)
|
|
149
|
+
return if pre_code_generator.nil?
|
|
150
|
+
pre_code_generator.generate_code(self, kind, buffer)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def generate_code(kind, buffer)
|
|
154
|
+
return if code_generator.nil?
|
|
155
|
+
code_generator.generate_code(self, kind, buffer)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def generate_post_code(kind, buffer)
|
|
159
|
+
return if post_code_generator.nil?
|
|
160
|
+
post_code_generator.generate_code(self, kind, buffer)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def write_file(output_directory = '')
|
|
164
|
+
return if file_writer.nil?
|
|
165
|
+
file_writer.write_file(self, output_directory)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
def configuration
|
|
171
|
+
@owner.configuration
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
class Line
|
|
4
|
+
def initialize
|
|
5
|
+
@words = []
|
|
6
|
+
@not_empty = false
|
|
7
|
+
@indent = 0
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :words
|
|
11
|
+
attr_accessor :indent
|
|
12
|
+
|
|
13
|
+
def <<(word)
|
|
14
|
+
@words << word.to_s
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def empty?
|
|
19
|
+
@words.all?(&:empty?)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_s
|
|
23
|
+
return '' if @words.empty?
|
|
24
|
+
@words.join.indent(@indent)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module TemplateUtility
|
|
4
|
+
module Extensions
|
|
5
|
+
def template_engines
|
|
6
|
+
@template_engines ||= Hash.new do |engines, path|
|
|
7
|
+
engines[path] = create_engine(path)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def create_engine(path)
|
|
14
|
+
template = File.read(path)
|
|
15
|
+
BabyErubis::Text.new.from_str(template, path)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.included(klass)
|
|
20
|
+
klass.extend(Extensions)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def process_template(path = nil)
|
|
24
|
+
path ||= File.ext(caller.first[/^(.+?):\d/, 1], 'erb')
|
|
25
|
+
self.class.template_engines[path].render(self)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module VerilogUtility
|
|
4
|
+
class ClassDefinition < StructureDefinition
|
|
5
|
+
attr_setter :base
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def header_code
|
|
10
|
+
code_block do |code|
|
|
11
|
+
code << :class << space << @name
|
|
12
|
+
code << space <<:extends << space << @base unless @base.nil?
|
|
13
|
+
code << semicolon
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def footer_code
|
|
18
|
+
:endclass
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module VerilogUtility
|
|
4
|
+
class Declaration
|
|
5
|
+
def initialize(declation_type, attributes)
|
|
6
|
+
@declation_type = declation_type
|
|
7
|
+
@attributes = attributes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_s
|
|
11
|
+
code_snippets.join(' ')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def code_snippets
|
|
17
|
+
[
|
|
18
|
+
random_or_direction_or_parameter_type,
|
|
19
|
+
data_type,
|
|
20
|
+
width,
|
|
21
|
+
identifier,
|
|
22
|
+
default_value_assignment
|
|
23
|
+
].reject(&:empty?)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def random_or_direction_or_parameter_type
|
|
27
|
+
case @declation_type
|
|
28
|
+
when :variable
|
|
29
|
+
(@attributes[:random] && 'rand') || ''
|
|
30
|
+
when :port
|
|
31
|
+
@attributes[:direction] || ''
|
|
32
|
+
when :parameter
|
|
33
|
+
@attributes[:parameter_type]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def data_type
|
|
38
|
+
@attributes[:data_type] || ''
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def width
|
|
42
|
+
return '' if @attributes[:width].nil?
|
|
43
|
+
return '' if (variable? || port?) && @attributes[:width] == 1
|
|
44
|
+
"[#{@attributes[:width] - 1}:0]"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def identifier
|
|
48
|
+
"#{@attributes[:name]}#{dimensions}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def dimensions
|
|
52
|
+
return '' if @attributes[:dimensions].nil?
|
|
53
|
+
@attributes[:dimensions].map { |dimension| "[#{dimension}]" }.join
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_value_assignment
|
|
57
|
+
(@attributes[:default].nil? && '') || "= #{@attributes[:default]}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def variable?
|
|
61
|
+
@declation_type == :variable
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def port?
|
|
65
|
+
@declation_type == :port
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module VerilogUtility
|
|
4
|
+
class Identifier
|
|
5
|
+
def initialize(name)
|
|
6
|
+
@name = name
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
@name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def [](indexes_or_msb, lsb = indexes_or_msb)
|
|
14
|
+
if indexes_or_msb.nil?
|
|
15
|
+
self
|
|
16
|
+
elsif indexes_or_msb.is_a?(Array)
|
|
17
|
+
indexes_or_msb.inject(self) do |identifer, index|
|
|
18
|
+
identifer[index]
|
|
19
|
+
end
|
|
20
|
+
elsif indexes_or_msb == lsb
|
|
21
|
+
Identifier.new("#{@name}[#{indexes_or_msb}]")
|
|
22
|
+
else
|
|
23
|
+
Identifier.new("#{@name}[#{indexes_or_msb}:#{lsb}]")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module RgGen
|
|
2
|
+
module OutputBase
|
|
3
|
+
module VerilogUtility
|
|
4
|
+
class ModuleDefinition < StructureDefinition
|
|
5
|
+
attr_setter :parameters
|
|
6
|
+
attr_setter :ports
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def header_code
|
|
11
|
+
code_block do |code|
|
|
12
|
+
code << :module << space << @name << space
|
|
13
|
+
parameter_declarations(code)
|
|
14
|
+
port_declarations(code)
|
|
15
|
+
code << semicolon
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def footer_code
|
|
20
|
+
:endmodule
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def parameter_declarations(code)
|
|
24
|
+
return if @parameters.nil? || @parameters.empty?
|
|
25
|
+
code << '#('
|
|
26
|
+
declarations(@parameters, code)
|
|
27
|
+
code << ')'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def port_declarations(code)
|
|
31
|
+
code << '('
|
|
32
|
+
declarations(@ports, code) if @ports && @ports.size > 0
|
|
33
|
+
code << ')'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def declarations(list, code)
|
|
37
|
+
indent(code, 2) do
|
|
38
|
+
list.each_with_index do |d, i|
|
|
39
|
+
code << comma << nl if i > 0
|
|
40
|
+
code << d
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|