udb-gen 0.1.6 → 0.1.12
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 +4 -4
- data/lib/udb-gen/cfg_header_base.rb +206 -0
- data/lib/udb-gen/common_opts.rb +15 -1
- data/lib/udb-gen/generators/cfg_c_header/generator.rb +87 -0
- data/lib/udb-gen/generators/cfg_svh_header/generator.rb +87 -0
- data/lib/udb-gen/generators/ext_doc/generator.rb +2 -2
- data/lib/udb-gen/generators/ext_doc/helpers.rb +3 -3
- data/lib/udb-gen/generators/isa_explorer/table_builder.rb +3 -2
- data/lib/udb-gen/generators/manual/tasks.rake +1 -1
- data/lib/udb-gen/template_helpers.rb +10 -8
- data/lib/udb-gen/version.rb +1 -1
- data/templates/common/csr.adoc.erb +1 -1
- data/templates/manual/playbook.yml.erb +2 -2
- metadata +10 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 185afac7b8a6c8e7bdc766345c0963b3507e5196c3b0bf5afc50df2763607617
|
|
4
|
+
data.tar.gz: 3176d980ea6d9792b86f27f2b3ed0f3a1ee3a952cbdd4c495a68a7a1e7a7d6df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9af5bcc545ef8820a6bcde727b1db168a9b60d5a3185b94846fbb9b212a53aeb9b92e2faba7d55a77643004bf2295e36822be9000dbb97c586342db4859796d0
|
|
7
|
+
data.tar.gz: 29ed9637c8140810e849db5f00632090bba16690064cd9694381843114b09871fb55016954ebd2883b9a107fed527ff40e11042ce750cce7406825d0df8da9b3
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Copyright (c) Jordan Carlin, Harvey Mudd College.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
3
|
+
|
|
4
|
+
# typed: true
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require "fileutils"
|
|
8
|
+
require "pathname"
|
|
9
|
+
require "sorbet-runtime"
|
|
10
|
+
require "tty-exit"
|
|
11
|
+
require "udb/cfg_arch"
|
|
12
|
+
|
|
13
|
+
module UdbGen
|
|
14
|
+
# Shared logic for generating config header files across languages (C, SystemVerilog, etc.).
|
|
15
|
+
# Including classes must include TTY::Exit, inherit from SubcommandWithCommonOptions,
|
|
16
|
+
# and include this module; SubcommandWithCommonOptions provides cfg_arch, params,
|
|
17
|
+
# parse, help, and exit_with.
|
|
18
|
+
module CfgHeaderBase
|
|
19
|
+
extend T::Sig
|
|
20
|
+
extend T::Helpers
|
|
21
|
+
|
|
22
|
+
abstract!
|
|
23
|
+
|
|
24
|
+
sig { abstract.returns(Udb::ConfiguredArchitecture) }
|
|
25
|
+
def cfg_arch; end
|
|
26
|
+
|
|
27
|
+
sig { abstract.returns(T.untyped) }
|
|
28
|
+
def params; end
|
|
29
|
+
|
|
30
|
+
sig { abstract.params(argv: T::Array[String]).returns(T.untyped) }
|
|
31
|
+
def parse(argv); end
|
|
32
|
+
|
|
33
|
+
sig { abstract.returns(String) }
|
|
34
|
+
def help; end
|
|
35
|
+
|
|
36
|
+
sig { abstract.params(exit_code: Symbol, message: T.nilable(String)).returns(T.noreturn) }
|
|
37
|
+
def exit_with(exit_code, message = nil); end
|
|
38
|
+
|
|
39
|
+
sig { abstract.returns(String) }
|
|
40
|
+
def command_name; end
|
|
41
|
+
|
|
42
|
+
# The preprocessor define directive, e.g. "#define" or "`define"
|
|
43
|
+
sig { abstract.returns(String) }
|
|
44
|
+
def define_directive; end
|
|
45
|
+
|
|
46
|
+
# The begin-guard line, e.g. "#ifndef NAME" or "`ifndef NAME"
|
|
47
|
+
sig { abstract.params(guard_name: String).returns(String) }
|
|
48
|
+
def guard_begin(guard_name); end
|
|
49
|
+
|
|
50
|
+
# The end-guard line, e.g. "#endif /* NAME */" or "`endif // NAME"
|
|
51
|
+
sig { abstract.params(guard_name: String).returns(String) }
|
|
52
|
+
def guard_end(guard_name); end
|
|
53
|
+
|
|
54
|
+
# Guard name suffix, e.g. "_H" or "_SVH"
|
|
55
|
+
sig { abstract.returns(String) }
|
|
56
|
+
def guard_suffix; end
|
|
57
|
+
|
|
58
|
+
# A section comment line, e.g. "/* text */" or "// text"
|
|
59
|
+
sig { abstract.params(text: String).returns(String) }
|
|
60
|
+
def section_comment(text); end
|
|
61
|
+
|
|
62
|
+
# Multi-line file header comment block
|
|
63
|
+
sig { abstract.params(text_lines: T::Array[String]).returns(T::Array[String]) }
|
|
64
|
+
def header_comment(text_lines); end
|
|
65
|
+
|
|
66
|
+
# Human-readable file type for log messages, e.g. "C header" or "SystemVerilog header"
|
|
67
|
+
sig { abstract.returns(String) }
|
|
68
|
+
def file_type_name; end
|
|
69
|
+
|
|
70
|
+
# Format an integer value as a language-appropriate literal
|
|
71
|
+
sig { abstract.params(value: Integer).returns(String) }
|
|
72
|
+
def format_integer(value); end
|
|
73
|
+
|
|
74
|
+
sig { returns(String) }
|
|
75
|
+
def generate_header
|
|
76
|
+
unless cfg_arch.fully_configured?
|
|
77
|
+
exit_with(:data_err, "Config '#{cfg_arch.name}' is not fully configured. Only fully configured configs are supported.\n")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
lines = []
|
|
81
|
+
guard_name = "UDB_CFG_#{cfg_arch.name.upcase.gsub(/[^A-Z0-9]/, "_")}#{guard_suffix}"
|
|
82
|
+
|
|
83
|
+
convention_lines = [
|
|
84
|
+
"SPDX-License-Identifier: BSD-3-Clause-Clear",
|
|
85
|
+
"",
|
|
86
|
+
"Auto-generated by riscv-unified-db (udb-gen #{command_name})",
|
|
87
|
+
"Config: #{cfg_arch.name}",
|
|
88
|
+
"",
|
|
89
|
+
"Define conventions:",
|
|
90
|
+
" Extensions: #{define_directive} NAME_SUPPORTED and #{define_directive} NAMEverPver_SUPPORTED",
|
|
91
|
+
" Boolean params: #{define_directive} UDB_NAME (present when true, absent when false)",
|
|
92
|
+
" Integer params: #{define_directive} UDB_NAME value and #{define_directive} UDB_NAME_<value>",
|
|
93
|
+
" Enum (string) params: #{define_directive} UDB_NAME_VALUE (value sanitized to uppercase identifier)",
|
|
94
|
+
" Boolean arrays: #{define_directive} UDB_NAME_<index> (one per true element)",
|
|
95
|
+
" Integer arrays: #{define_directive} UDB_NAME_<value> (one per unique element, sorted)",
|
|
96
|
+
" String arrays: #{define_directive} UDB_NAME_<VALUE> (one per unique element, sanitized)"
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
lines.concat(header_comment(convention_lines))
|
|
100
|
+
lines << ""
|
|
101
|
+
lines << guard_begin(guard_name)
|
|
102
|
+
lines << "#{define_directive} #{guard_name}"
|
|
103
|
+
|
|
104
|
+
lines << ""
|
|
105
|
+
lines << section_comment("Implemented extensions")
|
|
106
|
+
emit_extension_defines(lines)
|
|
107
|
+
|
|
108
|
+
lines << ""
|
|
109
|
+
lines << section_comment("Configuration parameters")
|
|
110
|
+
emit_param_defines(lines)
|
|
111
|
+
|
|
112
|
+
lines << ""
|
|
113
|
+
lines << guard_end(guard_name)
|
|
114
|
+
lines << ""
|
|
115
|
+
|
|
116
|
+
lines.join("\n")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
sig { params(argv: T::Array[String]).returns(T.noreturn) }
|
|
120
|
+
def run_generator(argv)
|
|
121
|
+
parse(argv)
|
|
122
|
+
|
|
123
|
+
if params[:help]
|
|
124
|
+
Kernel.print help
|
|
125
|
+
exit_with(:success)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if params.errors.any?
|
|
129
|
+
exit_with(:usage_error, "#{params.errors.summary}\n\n#{help}")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
unless params.remaining.empty?
|
|
133
|
+
exit_with(:usage_error, "Unknown arguments: #{params.remaining}\n")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
header = generate_header
|
|
137
|
+
|
|
138
|
+
if params[:output].nil?
|
|
139
|
+
$stdout.write(header)
|
|
140
|
+
else
|
|
141
|
+
FileUtils.mkdir_p(params[:output].dirname)
|
|
142
|
+
File.write(params[:output], header)
|
|
143
|
+
Udb.logger.info "Generated #{file_type_name}: #{params[:output]}"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
exit_with(:success)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
sig { params(str: String).returns(String) }
|
|
152
|
+
def sanitize_to_identifier(str)
|
|
153
|
+
str.upcase.gsub(/[^A-Z0-9]/, "_").gsub(/_+/, "_").gsub(/\A_|_\z/, "")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
sig { params(lines: T::Array[String]).void }
|
|
157
|
+
def emit_extension_defines(lines)
|
|
158
|
+
ext_versions = cfg_arch.implemented_extension_versions.sort_by { |ev| ev.name.upcase }
|
|
159
|
+
ext_versions.each do |ext_ver|
|
|
160
|
+
lines << "#{define_directive} #{ext_ver.name.upcase}_SUPPORTED"
|
|
161
|
+
versioned_name = "#{ext_ver.name.upcase}#{ext_ver.version_spec.to_rvi_s.upcase}"
|
|
162
|
+
lines << "#{define_directive} #{versioned_name}_SUPPORTED"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
sig { params(lines: T::Array[String]).void }
|
|
167
|
+
def emit_param_defines(lines)
|
|
168
|
+
pv = cfg_arch.param_values
|
|
169
|
+
return if pv.empty?
|
|
170
|
+
|
|
171
|
+
pv.sort_by { |k, _| k }.each do |name, value|
|
|
172
|
+
prefixed = "UDB_#{name}"
|
|
173
|
+
case value
|
|
174
|
+
when true
|
|
175
|
+
lines << "#{define_directive} #{prefixed}"
|
|
176
|
+
when false
|
|
177
|
+
next
|
|
178
|
+
when Integer
|
|
179
|
+
lines << "#{define_directive} #{prefixed} #{format_integer(value)}"
|
|
180
|
+
lines << "#{define_directive} #{prefixed}_#{value}"
|
|
181
|
+
when String
|
|
182
|
+
lines << "#{define_directive} #{prefixed}_#{sanitize_to_identifier(value)}"
|
|
183
|
+
when Array
|
|
184
|
+
emit_array_param(lines, prefixed, value)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
sig { params(lines: T::Array[String], name: String, value: T::Array[T.untyped]).void }
|
|
190
|
+
def emit_array_param(lines, name, value)
|
|
191
|
+
if value.all? { |v| v == true || v == false }
|
|
192
|
+
value.each_with_index do |v, i|
|
|
193
|
+
lines << "#{define_directive} #{name}_#{i}" if v
|
|
194
|
+
end
|
|
195
|
+
elsif value.all? { |v| v.is_a?(Integer) }
|
|
196
|
+
value.uniq.sort.each do |v|
|
|
197
|
+
lines << "#{define_directive} #{name}_#{v}"
|
|
198
|
+
end
|
|
199
|
+
elsif value.all? { |v| v.is_a?(String) }
|
|
200
|
+
value.map { |v| sanitize_to_identifier(v) }.uniq.sort.each do |sanitized|
|
|
201
|
+
lines << "#{define_directive} #{name}_#{sanitized}"
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
data/lib/udb-gen/common_opts.rb
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# typed: true
|
|
5
5
|
# frozen_string_literal: true
|
|
6
6
|
|
|
7
|
+
require "pathname"
|
|
7
8
|
require "sorbet-runtime"
|
|
8
9
|
|
|
9
10
|
require_relative "subcommand"
|
|
@@ -40,7 +41,20 @@ module UdbGen
|
|
|
40
41
|
sig { returns(Udb::ConfiguredArchitecture) }
|
|
41
42
|
def cfg_arch
|
|
42
43
|
@cfg_arch ||=
|
|
43
|
-
resolver.cfg_arch_for(params[:cfg])
|
|
44
|
+
resolver.cfg_arch_for(resolve_cfg_arg(params[:cfg]))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Accept either a known config name (looked up under @cfgs_path) or a
|
|
48
|
+
# filesystem path to a config YAML. Path-like arguments (containing a
|
|
49
|
+
# path separator or ending in .yaml/.yml, or actually existing on disk)
|
|
50
|
+
# are converted to Pathname so the resolver treats them as paths.
|
|
51
|
+
sig { params(arg: String).returns(T.any(String, Pathname)) }
|
|
52
|
+
def resolve_cfg_arg(arg)
|
|
53
|
+
return Pathname.new(arg) if arg.include?(File::SEPARATOR) ||
|
|
54
|
+
arg.end_with?(".yaml", ".yml") ||
|
|
55
|
+
File.file?(arg)
|
|
56
|
+
|
|
57
|
+
arg
|
|
44
58
|
end
|
|
45
59
|
|
|
46
60
|
sig { override.params(argv: T::Array[String]).returns(T.noreturn) }
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Copyright (c) Jordan Carlin, Harvey Mudd College.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
3
|
+
|
|
4
|
+
# typed: true
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require "sorbet-runtime"
|
|
8
|
+
require "tty-exit"
|
|
9
|
+
|
|
10
|
+
require_relative "../../common_opts"
|
|
11
|
+
require_relative "../../defines"
|
|
12
|
+
require_relative "../../cfg_header_base"
|
|
13
|
+
|
|
14
|
+
module UdbGen
|
|
15
|
+
class GenCfgCHeaderOptions < SubcommandWithCommonOptions
|
|
16
|
+
include TTY::Exit
|
|
17
|
+
include CfgHeaderBase
|
|
18
|
+
|
|
19
|
+
NAME = "cfg-c-header"
|
|
20
|
+
|
|
21
|
+
sig { void }
|
|
22
|
+
def initialize
|
|
23
|
+
super(name: NAME, desc: "Generate a C header with #defines from a fully configured UDB config")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
usage \
|
|
27
|
+
command: NAME,
|
|
28
|
+
desc: "Generate a C header file with #define directives derived from a fully configured UDB YAML config",
|
|
29
|
+
example: <<~EXAMPLE
|
|
30
|
+
Generate a C header for the rv64 config, printed to stdout
|
|
31
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c rv64
|
|
32
|
+
|
|
33
|
+
Generate a C header for the rv64 config, written to a file
|
|
34
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c rv64 -o config.h
|
|
35
|
+
|
|
36
|
+
Generate a C header for a custom config file
|
|
37
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c /path/to/my_config.yaml
|
|
38
|
+
EXAMPLE
|
|
39
|
+
|
|
40
|
+
option :output do
|
|
41
|
+
T.bind(self, TTY::Option::Parameter::Option)
|
|
42
|
+
short "-o"
|
|
43
|
+
long "--output=file"
|
|
44
|
+
desc "Output file path (default: stdout)"
|
|
45
|
+
convert :path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
sig { override.returns(String) }
|
|
49
|
+
def define_directive = "#define"
|
|
50
|
+
|
|
51
|
+
sig { override.returns(String) }
|
|
52
|
+
def command_name = NAME
|
|
53
|
+
|
|
54
|
+
sig { override.params(guard_name: String).returns(String) }
|
|
55
|
+
def guard_begin(guard_name) = "#ifndef #{guard_name}"
|
|
56
|
+
|
|
57
|
+
sig { override.params(guard_name: String).returns(String) }
|
|
58
|
+
def guard_end(guard_name) = "#endif /* #{guard_name} */"
|
|
59
|
+
|
|
60
|
+
sig { override.returns(String) }
|
|
61
|
+
def guard_suffix = "_H"
|
|
62
|
+
|
|
63
|
+
sig { override.params(text: String).returns(String) }
|
|
64
|
+
def section_comment(text) = "/* #{text} */"
|
|
65
|
+
|
|
66
|
+
sig { override.params(text_lines: T::Array[String]).returns(T::Array[String]) }
|
|
67
|
+
def header_comment(text_lines)
|
|
68
|
+
lines = ["/*"]
|
|
69
|
+
text_lines.each do |line|
|
|
70
|
+
lines << (line.empty? ? " *" : " * #{line}")
|
|
71
|
+
end
|
|
72
|
+
lines << " */"
|
|
73
|
+
lines
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
sig { override.returns(String) }
|
|
77
|
+
def file_type_name = "C header"
|
|
78
|
+
|
|
79
|
+
sig { override.params(value: Integer).returns(String) }
|
|
80
|
+
def format_integer(value) = value.to_s
|
|
81
|
+
|
|
82
|
+
sig { override.params(argv: T::Array[String]).returns(T.noreturn) }
|
|
83
|
+
def run(argv)
|
|
84
|
+
run_generator(argv)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Copyright (c) Jordan Carlin, Harvey Mudd College.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
3
|
+
|
|
4
|
+
# typed: true
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require "sorbet-runtime"
|
|
8
|
+
require "tty-exit"
|
|
9
|
+
|
|
10
|
+
require_relative "../../common_opts"
|
|
11
|
+
require_relative "../../defines"
|
|
12
|
+
require_relative "../../cfg_header_base"
|
|
13
|
+
|
|
14
|
+
module UdbGen
|
|
15
|
+
class GenCfgSvhHeaderOptions < SubcommandWithCommonOptions
|
|
16
|
+
include TTY::Exit
|
|
17
|
+
include CfgHeaderBase
|
|
18
|
+
|
|
19
|
+
NAME = "cfg-svh-header"
|
|
20
|
+
|
|
21
|
+
sig { void }
|
|
22
|
+
def initialize
|
|
23
|
+
super(name: NAME, desc: "Generate a SystemVerilog header with `define directives from a fully configured UDB config")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
usage \
|
|
27
|
+
command: NAME,
|
|
28
|
+
desc: "Generate a SystemVerilog header file with `define directives derived from a fully configured UDB YAML config",
|
|
29
|
+
example: <<~EXAMPLE
|
|
30
|
+
Generate a SystemVerilog header for the rv64 config, printed to stdout
|
|
31
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c rv64
|
|
32
|
+
|
|
33
|
+
Generate a SystemVerilog header for the rv64 config, written to a file
|
|
34
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c rv64 -o config.svh
|
|
35
|
+
|
|
36
|
+
Generate a SystemVerilog header for a custom config file
|
|
37
|
+
$ #{File.basename($PROGRAM_NAME)} #{NAME} -c /path/to/my_config.yaml
|
|
38
|
+
EXAMPLE
|
|
39
|
+
|
|
40
|
+
option :output do
|
|
41
|
+
T.bind(self, TTY::Option::Parameter::Option)
|
|
42
|
+
short "-o"
|
|
43
|
+
long "--output=file"
|
|
44
|
+
desc "Output file path (default: stdout)"
|
|
45
|
+
convert :path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
sig { override.returns(String) }
|
|
49
|
+
def define_directive = "`define"
|
|
50
|
+
|
|
51
|
+
sig { override.returns(String) }
|
|
52
|
+
def command_name = NAME
|
|
53
|
+
|
|
54
|
+
sig { override.params(guard_name: String).returns(String) }
|
|
55
|
+
def guard_begin(guard_name) = "`ifndef #{guard_name}"
|
|
56
|
+
|
|
57
|
+
sig { override.params(guard_name: String).returns(String) }
|
|
58
|
+
def guard_end(guard_name) = "`endif // #{guard_name}"
|
|
59
|
+
|
|
60
|
+
sig { override.returns(String) }
|
|
61
|
+
def guard_suffix = "_SVH"
|
|
62
|
+
|
|
63
|
+
sig { override.params(text: String).returns(String) }
|
|
64
|
+
def section_comment(text) = "// #{text}"
|
|
65
|
+
|
|
66
|
+
sig { override.params(text_lines: T::Array[String]).returns(T::Array[String]) }
|
|
67
|
+
def header_comment(text_lines)
|
|
68
|
+
text_lines.map { |line| line.empty? ? "//" : "// #{line}" }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
sig { override.returns(String) }
|
|
72
|
+
def file_type_name = "SystemVerilog header"
|
|
73
|
+
|
|
74
|
+
# Emit sized hex literals so large unsigned values are not misinterpreted
|
|
75
|
+
sig { override.params(value: Integer).returns(String) }
|
|
76
|
+
def format_integer(value)
|
|
77
|
+
bits = [32, value.bit_length].max
|
|
78
|
+
width = ((bits + 31) / 32) * 32
|
|
79
|
+
"#{width}'h#{value.to_s(16).upcase}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
sig { override.params(argv: T::Array[String]).returns(T.noreturn) }
|
|
83
|
+
def run(argv)
|
|
84
|
+
run_generator(argv)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -142,7 +142,7 @@ module UdbGen
|
|
|
142
142
|
when nil
|
|
143
143
|
">=0"
|
|
144
144
|
when "latest"
|
|
145
|
-
"=#{ext.versions.max}"
|
|
145
|
+
"=#{T.must(ext).versions.max}"
|
|
146
146
|
else
|
|
147
147
|
"=#{req}"
|
|
148
148
|
end
|
|
@@ -181,7 +181,7 @@ module UdbGen
|
|
|
181
181
|
"-a imagesdir=#{params[:images]}",
|
|
182
182
|
"-r asciidoctor-diagram",
|
|
183
183
|
"-r idl_highlighter",
|
|
184
|
-
"-a wavedrom
|
|
184
|
+
"-a wavedrom=#{Udb.repo_root}/node_modules/.bin/wavedrom-cli",
|
|
185
185
|
"-o #{pdf_filename}",
|
|
186
186
|
adoc_filename
|
|
187
187
|
].join(" ")
|
|
@@ -15,7 +15,7 @@ module UdbGen
|
|
|
15
15
|
# Uses ratification_date year if available, otherwise current year.
|
|
16
16
|
sig { params(version: Udb::ExtensionVersion).returns(String) }
|
|
17
17
|
def copyright_year(version)
|
|
18
|
-
version.ratification_date.nil? ? Date.today.year.to_s : T.must(version.ratification_date).split("-")[0]
|
|
18
|
+
version.ratification_date.nil? ? Date.today.year.to_s : T.must(T.must(version.ratification_date).split("-")[0])
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# Returns the revdate for a version: release date (for nonstandard-released),
|
|
@@ -23,9 +23,9 @@ module UdbGen
|
|
|
23
23
|
sig { params(version: Udb::ExtensionVersion).returns(T.any(String, Date)) }
|
|
24
24
|
def revdate(version)
|
|
25
25
|
if version.state == "nonstandard-released"
|
|
26
|
-
version.release_date.nil? ? Date.today : version.release_date
|
|
26
|
+
version.release_date.nil? ? Date.today : T.must(version.release_date)
|
|
27
27
|
elsif version.state == "ratified"
|
|
28
|
-
version.ratification_date.nil? ? Date.today : version.ratification_date
|
|
28
|
+
version.ratification_date.nil? ? Date.today : T.must(version.ratification_date)
|
|
29
29
|
else
|
|
30
30
|
Date.today
|
|
31
31
|
end
|
|
@@ -82,10 +82,11 @@ module UdbGen
|
|
|
82
82
|
ext.conflicting_extensions.map(&:name),
|
|
83
83
|
ext.ratified,
|
|
84
84
|
if ext.ratified
|
|
85
|
-
|
|
85
|
+
rat_date = T.must(ext.min_ratified_version).ratification_date
|
|
86
|
+
if rat_date.nil? || rat_date.empty?
|
|
86
87
|
"UDB MISSING"
|
|
87
88
|
else
|
|
88
|
-
|
|
89
|
+
rat_date
|
|
89
90
|
end
|
|
90
91
|
else
|
|
91
92
|
""
|
|
@@ -27,7 +27,7 @@ module UdbGen
|
|
|
27
27
|
erb.result(context.instance_eval { binding })
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
LinkableObj = T.type_alias { T.any(Udb::Instruction, Udb::Csr, Udb::CsrField, Udb::Extension, Idl::FunctionDefAst) }
|
|
30
|
+
LinkableObj = T.type_alias { T.any(Udb::Instruction, Udb::Csr, Udb::CsrField, Udb::Extension, Udb::Parameter, Idl::FunctionDefAst) }
|
|
31
31
|
|
|
32
32
|
# return an asciidoc link to obj, with text "text"
|
|
33
33
|
sig { params(obj: LinkableObj, text: String).returns(String) }
|
|
@@ -56,6 +56,8 @@ module UdbGen
|
|
|
56
56
|
"udb-extension-#{obj.name.gsub(".", "_")}"
|
|
57
57
|
when Udb::Instruction
|
|
58
58
|
"udb-insn-#{obj.name.gsub(".", "_")}"
|
|
59
|
+
when Udb::Parameter
|
|
60
|
+
"udb-param-#{obj.name.gsub(".", "_")}"
|
|
59
61
|
else
|
|
60
62
|
T.absurd(obj)
|
|
61
63
|
end
|
|
@@ -64,17 +66,17 @@ module UdbGen
|
|
|
64
66
|
sig { params(cfg_arch: Udb::ConfiguredArchitecture, adoc: String).returns(String) }
|
|
65
67
|
def convert_monospace_to_links(cfg_arch, adoc)
|
|
66
68
|
adoc.gsub(/`([\w.]+)`/) do |match|
|
|
67
|
-
name = Regexp.last_match(1)
|
|
68
|
-
csr_name, field_name =
|
|
69
|
+
name = T.must(Regexp.last_match(1))
|
|
70
|
+
csr_name, field_name = name.split(".")
|
|
69
71
|
csr = cfg_arch.not_prohibited_csrs.find { |c| c.name == csr_name }
|
|
70
72
|
if !field_name.nil? && !csr.nil? && csr.field?(field_name)
|
|
71
73
|
link_to(csr.field(field_name), match)
|
|
72
74
|
elsif !csr.nil?
|
|
73
75
|
link_to(csr, match)
|
|
74
76
|
elsif cfg_arch.not_prohibited_instructions.any? { |inst| inst.name == name }
|
|
75
|
-
link_to(cfg_arch.instruction(name), match)
|
|
77
|
+
link_to(T.must(cfg_arch.instruction(name)), match)
|
|
76
78
|
elsif cfg_arch.not_prohibited_extensions.any? { |ext| ext.name == name }
|
|
77
|
-
link_to(cfg_arch.extension(name), match)
|
|
79
|
+
link_to(T.must(cfg_arch.extension(name)), match)
|
|
78
80
|
else
|
|
79
81
|
match
|
|
80
82
|
end
|
|
@@ -92,7 +94,7 @@ module UdbGen
|
|
|
92
94
|
when "ext"
|
|
93
95
|
ext = cfg_arch.extension(name)
|
|
94
96
|
if ext
|
|
95
|
-
link_to(
|
|
97
|
+
link_to(ext, link_text)
|
|
96
98
|
else
|
|
97
99
|
Udb.logger.warn "Attempted link to undefined extension: #{name}"
|
|
98
100
|
match
|
|
@@ -116,14 +118,14 @@ module UdbGen
|
|
|
116
118
|
when "csr"
|
|
117
119
|
csr = cfg_arch.csr(name)
|
|
118
120
|
if csr
|
|
119
|
-
link_to(
|
|
121
|
+
link_to(csr, link_text)
|
|
120
122
|
else
|
|
121
123
|
Udb.logger.warn "Attempted link to undefined CSR: #{name}"
|
|
122
124
|
match
|
|
123
125
|
end
|
|
124
126
|
when "csr_field"
|
|
125
127
|
csr_name, field_name = name.split("*")
|
|
126
|
-
csr = cfg_arch.csr(csr_name)
|
|
128
|
+
csr = cfg_arch.csr(T.must(csr_name))
|
|
127
129
|
if csr
|
|
128
130
|
csr_field = csr.field(field_name)
|
|
129
131
|
if csr_field
|
data/lib/udb-gen/version.rb
CHANGED
|
@@ -36,7 +36,7 @@ h^ Privilege Mode ^ <%= csr.priv_mode %>
|
|
|
36
36
|
.<%= csr.name %> format
|
|
37
37
|
[wavedrom, ,svg,subs='attributes',width="100%"]
|
|
38
38
|
....
|
|
39
|
-
<%= JSON.dump csr.wavedrom_desc(cfg_arch, 64) %>
|
|
39
|
+
<%= JSON.dump csr.wavedrom_desc(cfg_arch, csr.base || 64) %>
|
|
40
40
|
....
|
|
41
41
|
<%- else -%>
|
|
42
42
|
<%# CSR has a dynamic length, or a field has a dynamic location,
|
|
@@ -29,9 +29,9 @@ ui:
|
|
|
29
29
|
snapshot: true
|
|
30
30
|
supplemental_files:
|
|
31
31
|
- path: css/vendor/tabs.css
|
|
32
|
-
contents:
|
|
32
|
+
contents: <%= Udb.repo_root %>/node_modules/@asciidoctor/tabs/dist/css/tabs.css
|
|
33
33
|
- path: js/vendor/tabs.js
|
|
34
|
-
contents:
|
|
34
|
+
contents: <%= Udb.repo_root %>/node_modules/@asciidoctor/tabs/dist/js/tabs.js
|
|
35
35
|
- path: partials/footer-scripts.hbs
|
|
36
36
|
contents: |
|
|
37
37
|
<script id="site-script" src="{{{uiRootPath}}}/js/site.js" data-ui-root-path="{{{uiRootPath}}}"></script>
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: udb-gen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Derek Hower
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
10
|
+
date: 2026-05-19 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: asciidoctor
|
|
@@ -140,16 +139,16 @@ dependencies:
|
|
|
140
139
|
name: udb
|
|
141
140
|
requirement: !ruby/object:Gem::Requirement
|
|
142
141
|
requirements:
|
|
143
|
-
- -
|
|
142
|
+
- - '='
|
|
144
143
|
- !ruby/object:Gem::Version
|
|
145
|
-
version:
|
|
144
|
+
version: 0.1.13
|
|
146
145
|
type: :runtime
|
|
147
146
|
prerelease: false
|
|
148
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
148
|
requirements:
|
|
150
|
-
- -
|
|
149
|
+
- - '='
|
|
151
150
|
- !ruby/object:Gem::Version
|
|
152
|
-
version:
|
|
151
|
+
version: 0.1.13
|
|
153
152
|
- !ruby/object:Gem::Dependency
|
|
154
153
|
name: write_xlsx
|
|
155
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -206,8 +205,11 @@ files:
|
|
|
206
205
|
- bin/udb-gen
|
|
207
206
|
- lib/udb-gen.rb
|
|
208
207
|
- lib/udb-gen/adoc_helpers.rb
|
|
208
|
+
- lib/udb-gen/cfg_header_base.rb
|
|
209
209
|
- lib/udb-gen/common_opts.rb
|
|
210
210
|
- lib/udb-gen/defines.rb
|
|
211
|
+
- lib/udb-gen/generators/cfg_c_header/generator.rb
|
|
212
|
+
- lib/udb-gen/generators/cfg_svh_header/generator.rb
|
|
211
213
|
- lib/udb-gen/generators/ext_doc/generator.rb
|
|
212
214
|
- lib/udb-gen/generators/ext_doc/helpers.rb
|
|
213
215
|
- lib/udb-gen/generators/isa_explorer/generator.rb
|
|
@@ -248,7 +250,6 @@ metadata:
|
|
|
248
250
|
homepage_uri: https://github.com/riscv/riscv-unified-db
|
|
249
251
|
mailing_list_uri: https://lists.riscv.org/g/tech-unifieddb
|
|
250
252
|
bug_tracker_uri: https://github.com/riscv/riscv-unified-db/issues
|
|
251
|
-
post_install_message:
|
|
252
253
|
rdoc_options: []
|
|
253
254
|
require_paths:
|
|
254
255
|
- lib
|
|
@@ -263,8 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
263
264
|
- !ruby/object:Gem::Version
|
|
264
265
|
version: '0'
|
|
265
266
|
requirements: []
|
|
266
|
-
rubygems_version: 3.
|
|
267
|
-
signing_key:
|
|
267
|
+
rubygems_version: 3.6.9
|
|
268
268
|
specification_version: 4
|
|
269
269
|
summary: Command line interface for UDB-based generators
|
|
270
270
|
test_files: []
|