udb_helpers 0.1.1
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/LICENSE +26 -0
- data/lib/udb_helpers/backend_helpers.rb +437 -0
- data/lib/udb_helpers/paths.rb +20 -0
- data/lib/udb_helpers/version.rb +11 -0
- metadata +84 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e88952b174696f1600ab5d72a4178b42aa5442a261a376fe66f639b95578183b
|
|
4
|
+
data.tar.gz: bc9f96f7c58e328fca8dabef49b853e2c7113b035961d7bea974a88753696b3a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 91ae8cbd97c75f97129691ec5bde8d8394cd90d840762d2ee3a6816162e88770d83737af4faf3706f11eedea9ecfebd2aaa8981fb23bd3874fa544cb80891057
|
|
7
|
+
data.tar.gz: 0d5385c2fc76483407ae9b80d73fc4685acdafb387b7d16875176cc6c425b9b52299eae2a95406d9d3e62e729a4aa93855aed05fe8f1ef66ccecf29b35b79a22
|
data/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
2
|
+
|
|
3
|
+
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
6
|
+
(subject to the limitations in the disclaimer below) provided that the following conditions are
|
|
7
|
+
met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
10
|
+
and the following disclaimer.
|
|
11
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
12
|
+
conditions and the following disclaimer in the documentation and/or other materials provided
|
|
13
|
+
with the distribution.
|
|
14
|
+
* Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors may be used
|
|
15
|
+
to endorse or promote products derived from this software without specific prior written
|
|
16
|
+
permission.
|
|
17
|
+
|
|
18
|
+
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS
|
|
19
|
+
SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
20
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
21
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|
22
|
+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
24
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
25
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
26
|
+
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
3
|
+
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
4
|
+
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
# Collection of "helper" functions that can be called from backends and/or ERB templates.
|
|
8
|
+
|
|
9
|
+
require "erb"
|
|
10
|
+
require "pathname"
|
|
11
|
+
require "ostruct"
|
|
12
|
+
|
|
13
|
+
# Add to standard String class.
|
|
14
|
+
class String
|
|
15
|
+
# Should be called on all RISC-V extension, instruction, CSR, and CSR field names.
|
|
16
|
+
# Parameters never have periods in their names so they don't need to be sanitized.
|
|
17
|
+
#
|
|
18
|
+
# @param name [String] Some RISC-V name which might have periods in it or ampersand
|
|
19
|
+
# @return [String] New String with periods replaced with underscores and ampersands replaced with "_and_"
|
|
20
|
+
def sanitize = String.new(self).gsub(".", "_").gsub("&", "_and_")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
module Udb
|
|
24
|
+
module Helpers
|
|
25
|
+
module WavedromUtil
|
|
26
|
+
def fix_entities(text)
|
|
27
|
+
text.to_s.gsub("≠", "≠")
|
|
28
|
+
.gsub("±", "±")
|
|
29
|
+
.gsub("-∞", "−∞")
|
|
30
|
+
.gsub("+∞", "+∞")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Custom JSON converter for wavedrom that handles hexadecimal literals
|
|
34
|
+
def json_dump_with_hex_literals(data)
|
|
35
|
+
# First convert to standard JSON
|
|
36
|
+
json_string = JSON.dump(data)
|
|
37
|
+
|
|
38
|
+
# Replace string hex values with actual hex literals
|
|
39
|
+
json_string.gsub(/"0x([0-9a-fA-F]+)"/) do |match|
|
|
40
|
+
# Remove the quotes, leaving just the hex literal
|
|
41
|
+
"0x#{$1}"
|
|
42
|
+
end.gsub(/"name":/, '"name": ') # Add space after colon for name field
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Helper to process wavedrom data
|
|
46
|
+
def process_wavedrom(json_data)
|
|
47
|
+
result = json_data.dup
|
|
48
|
+
|
|
49
|
+
# Process reg array if it exists
|
|
50
|
+
if result["reg"].is_a?(Array)
|
|
51
|
+
result["reg"].each do |item|
|
|
52
|
+
# For fields that are likely opcodes or immediates (type 2)
|
|
53
|
+
if item["type"] == 2
|
|
54
|
+
|
|
55
|
+
# Convert to number first (if it's a string)
|
|
56
|
+
if item["name"].is_a?(String)
|
|
57
|
+
if item["name"].start_with?("0x")
|
|
58
|
+
# Already hexadecimal
|
|
59
|
+
numeric_value = item["name"].to_i(16)
|
|
60
|
+
elsif item["name"] =~ /^[01]+$/
|
|
61
|
+
# Binary string without prefix
|
|
62
|
+
numeric_value = item["name"].to_i(2)
|
|
63
|
+
elsif item["name"] =~ /^\d+$/
|
|
64
|
+
# Decimal
|
|
65
|
+
numeric_value = item["name"].to_i
|
|
66
|
+
else
|
|
67
|
+
# Not a number, leave it alone
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
# Already a number
|
|
72
|
+
numeric_value = item["name"]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Convert to hexadecimal string
|
|
76
|
+
hex_str = numeric_value.to_s(16).downcase
|
|
77
|
+
|
|
78
|
+
# Set the name to a specially formatted string that will be converted
|
|
79
|
+
# to a hex literal in our custom JSON converter
|
|
80
|
+
item["name"] = "0x" + hex_str
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Ensure bits is a number
|
|
84
|
+
if item["bits"].is_a?(String) && item["bits"] =~ /^\d+$/
|
|
85
|
+
item["bits"] = item["bits"].to_i
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
result
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# This module is included in the CfgArch and Design classes so its methods are available to be called directly
|
|
97
|
+
# from them without having to prefix a method with the module name.
|
|
98
|
+
module Udb
|
|
99
|
+
module Helpers
|
|
100
|
+
module TemplateHelpers
|
|
101
|
+
# Include a partial ERB template into a full ERB template.
|
|
102
|
+
#
|
|
103
|
+
# @param template_pname [String] Path to template file relative to "backends" directory.
|
|
104
|
+
# @param inputs [Hash<String, Object>] Input objects to pass into template
|
|
105
|
+
# @return [String] Result of ERB evaluation of the template file
|
|
106
|
+
def partial(template_pname, inputs = {})
|
|
107
|
+
template_path = Pathname.new($root / "backends" / template_pname)
|
|
108
|
+
raise ArgumentError, "Template '#{template_path} not found" unless template_path.exist?
|
|
109
|
+
|
|
110
|
+
erb = ERB.new(template_path.read, trim_mode: "-")
|
|
111
|
+
erb.filename = template_path.realpath.to_s
|
|
112
|
+
|
|
113
|
+
erb.result(OpenStruct.new(inputs).instance_eval { binding })
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#########
|
|
117
|
+
# LINKS #
|
|
118
|
+
#########
|
|
119
|
+
|
|
120
|
+
# Links are created with this proprietary format so that they can be converted
|
|
121
|
+
# later into either AsciiDoc or Antora links (see the two implementations of "resolve_links").
|
|
122
|
+
# %%UDB_DOC_LINK%<type>;<name>;<link_text>%%
|
|
123
|
+
#
|
|
124
|
+
# Documentation:
|
|
125
|
+
# - How to make cross-references: https://docs.asciidoctor.org/asciidoc/latest/macros/xref/
|
|
126
|
+
# - How to create anchors: https://docs.asciidoctor.org/asciidoc/latest/attributes/id/
|
|
127
|
+
# - See https://github.com/riscv/riscv-isa-manual/issues/1397#issuecomment-2515109936 for
|
|
128
|
+
# discussion about using [#anchor] instead of [[anchor]] due to Antora's support.
|
|
129
|
+
|
|
130
|
+
# @return [String] A hyperlink to UDB extension documentation
|
|
131
|
+
# @param ext_name [String] Name of the extension
|
|
132
|
+
def link_to_udb_doc_ext(ext_name)
|
|
133
|
+
"%%UDB_DOC_LINK%ext;#{ext_name.sanitize};#{ext_name}%%"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @return [String] A hyperlink to UDB parameter documentation
|
|
137
|
+
# @param ext_name [String] Name of the extension
|
|
138
|
+
# @param param_name [String] Name of the parameter
|
|
139
|
+
# @param link_text [String] What to put in the link text (don't assume param_name)
|
|
140
|
+
def link_to_udb_doc_ext_param(ext_name, param_name, link_text)
|
|
141
|
+
check_no_periods(param_name)
|
|
142
|
+
"%%UDB_DOC_LINK%ext_param;#{ext_name.sanitize}.#{param_name};#{link_text}%%"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @return [String] A hyperlink to UDB instruction documentation
|
|
146
|
+
# @param inst_name [String] Name of the instruction
|
|
147
|
+
def link_to_udb_doc_inst(inst_name)
|
|
148
|
+
"%%UDB_DOC_LINK%inst;#{inst_name.sanitize};#{inst_name}%%"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @return [String] A hyperlink to UDB CSR documentation
|
|
152
|
+
# @param csr_name [String] Name of the CSR
|
|
153
|
+
def link_to_udb_doc_csr(csr_name)
|
|
154
|
+
"%%UDB_DOC_LINK%csr;#{csr_name.sanitize};#{csr_name}%%"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @return [String] A hyperlink to UDB CSR field documentation
|
|
158
|
+
# @param csr_name [String] Name of the CSR
|
|
159
|
+
# @param field_name [String] Name of the CSR field
|
|
160
|
+
def link_to_udb_doc_csr_field(csr_name, field_name)
|
|
161
|
+
"%%UDB_DOC_LINK%csr_field;#{csr_name}*#{field_name};#{csr_name}.#{field_name}%%"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @return [String] A hyperlink to UDB MMR documentation
|
|
165
|
+
# @param mmr_name [String] Name of the MMR
|
|
166
|
+
def link_to_udb_doc_mmr(mmr_name)
|
|
167
|
+
"%%UDB_DOC_LINK%mmr;#{mmr_name.sanitize};#{mmr_name}%%"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# @return [String] A hyperlink to UDB MMR field documentation
|
|
171
|
+
# @param mmr_name [String] Name of the MMR
|
|
172
|
+
# @param field_name [String] Name of the MMR field
|
|
173
|
+
def link_to_udb_doc_mmr_field(mmr_name, field_name)
|
|
174
|
+
"%%UDB_DOC_LINK%mmr_field;#{mmr_name.sanitize}.#{field_name.sanitize};#{mmr_name}.#{field_name}%%"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# @return [String] A hyperlink to UDB IDL function documentation
|
|
178
|
+
# @param func_name [String] Name of the IDL function
|
|
179
|
+
def link_to_udb_doc_idl_func(func_name)
|
|
180
|
+
"%%UDB_DOC_LINK%func;#{func_name.sanitize};#{func_name}%%"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# @return [String] A hyperlink to a UDB certification normative rule (separate chapters for cov pts and test procs)
|
|
184
|
+
# @param org [String] Organization of normative rules and test procedures (sep=separate chapters, combo=combined chapters, appendix=appendix)
|
|
185
|
+
# @param id [String] ID of the normative rule
|
|
186
|
+
def link_to_udb_doc_cov_pt(org, id)
|
|
187
|
+
raise ArgumentError, "Unknown org value of '#{org}' for ID '#{id}'" unless org == "sep" || org == "combo" || org == "appendix"
|
|
188
|
+
"%%UDB_DOC_COV_PT_LINK%#{org};#{id.sanitize};#{id}%%"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @return [String] A hyperlink into IDL instruction code
|
|
192
|
+
# @param func_name [String] Name of the instruction
|
|
193
|
+
# @param id [String] ID within the instruction code
|
|
194
|
+
def link_into_idl_inst_code(inst_name, id)
|
|
195
|
+
"%%IDL_CODE_LINK%inst;#{inst_name.sanitize}.#{id.sanitize};#{inst_name}.#{id}%%"
|
|
196
|
+
end
|
|
197
|
+
# TODO: Add csr and csr_field support
|
|
198
|
+
|
|
199
|
+
###########
|
|
200
|
+
# ANCHORS #
|
|
201
|
+
###########
|
|
202
|
+
|
|
203
|
+
# @return [String] An anchor for UDB extension documentation
|
|
204
|
+
# @param ext_name [String] Name of the extension
|
|
205
|
+
def anchor_for_udb_doc_ext(ext_name)
|
|
206
|
+
"[#udb:doc:ext:#{ext_name.sanitize}]"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @return [String] An anchor for UDB parameter documentation
|
|
210
|
+
# @param ext_name [String] Name of the extension
|
|
211
|
+
# @param param_name [String] Name of the parameter
|
|
212
|
+
def anchor_for_udb_doc_ext_param(ext_name, param_name)
|
|
213
|
+
check_no_periods(param_name)
|
|
214
|
+
"[#udb:doc:ext_param:#{ext_name.sanitize}:#{param_name}]"
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# @return [String] An anchor for UDB instruction documentation
|
|
218
|
+
# @param name [String] Name of the instruction
|
|
219
|
+
def anchor_for_udb_doc_inst(name)
|
|
220
|
+
"[#udb:doc:inst:#{name.sanitize}]"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @return [String] An anchor for UDB CSR documentation
|
|
224
|
+
# @param name [String] Name of the CSR
|
|
225
|
+
def anchor_for_udb_doc_csr(name)
|
|
226
|
+
"[#udb:doc:csr:#{name.sanitize}]"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# @return [String] An anchor for UDB CSR field documentation
|
|
230
|
+
# @param csr_name [String] Name of the CSR
|
|
231
|
+
# @param field_name [String] Name of the CSR field
|
|
232
|
+
def anchor_for_udb_doc_csr_field(csr_name, field_name)
|
|
233
|
+
"[#udb:doc:csr_field:#{csr_name.sanitize}:#{field_name.sanitize}]"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# @return [String] An anchor for UDB MMR documentation
|
|
237
|
+
# @param name [String] Name of the MMR
|
|
238
|
+
def anchor_for_udb_doc_mmr(name)
|
|
239
|
+
"[#udb:doc:mmr:#{name.sanitize}]"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# @return [String] An anchor for UDB MMR field documentation
|
|
243
|
+
# @param mmr_name [String] Name of the MMR
|
|
244
|
+
# @param field_name [String] Name of the MMR field
|
|
245
|
+
def anchor_for_udb_doc_mmr_field(mmr_name, field_name)
|
|
246
|
+
"[#udb:doc:mmr_field:#{mmr_name.sanitize}:#{field_name.sanitize}]"
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# @return [String] An anchor for an IDL function documentation
|
|
250
|
+
# @param name [String] Name of the function
|
|
251
|
+
def anchor_for_udb_doc_idl_func(name)
|
|
252
|
+
"[#udb:doc:func:#{name.sanitize}]"
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# @return [String] An anchor for a UDB normative rule documentation
|
|
256
|
+
# @param org [String] Document organization of normative rules and test procedures (sep=separate chapters, combo=combined chapters, appendix=appendix)
|
|
257
|
+
# @param id [String] ID of the normative rule
|
|
258
|
+
# Have to use [[anchor]] instead of [#anchor] since only the former works when in a table cell.
|
|
259
|
+
def anchor_for_udb_doc_cov_pt(org, id)
|
|
260
|
+
raise ArgumentError, "Unknown org value of '#{org}' for ID '#{id}'" unless org == "sep" || org == "combo" || org == "appendix"
|
|
261
|
+
"[[udb:doc:cov_pt:#{org}:#{id.sanitize}]]"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# @return [String] An anchor for a UDB non-ISA specification documentation
|
|
265
|
+
# @param name [String] Name of the non-ISA specification
|
|
266
|
+
def anchor_for_non_isa_spec(name)
|
|
267
|
+
"[[udb:doc:non_isa:#{name.sanitize}]]"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# @return [String] An anchor inside IDL instruction code
|
|
271
|
+
# @param func_name [String] Name of the instruction
|
|
272
|
+
# @param id [String] ID within the instruction code
|
|
273
|
+
def anchor_inside_idl_inst_code(inst_name, id)
|
|
274
|
+
"[#idl:code:inst:#{inst_name.sanitize}:#{id.sanitize}]"
|
|
275
|
+
end
|
|
276
|
+
# TODO: Add csr and csr_field support
|
|
277
|
+
|
|
278
|
+
#@ param s [String]
|
|
279
|
+
def check_no_periods(s)
|
|
280
|
+
raise ArgumentError, "Periods are not allowed in '#{s}'" if s.include?(".")
|
|
281
|
+
end
|
|
282
|
+
private :check_no_periods
|
|
283
|
+
|
|
284
|
+
include Udb::Helpers::WavedromUtil
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Utilities for a backend to generate AsciiDoc.
|
|
290
|
+
module Udb
|
|
291
|
+
module Helpers
|
|
292
|
+
module AsciidocUtils
|
|
293
|
+
# The syntax "class << self" causes all methods to be treated as class methods.
|
|
294
|
+
# Convert proprietary link format to legal AsciiDoc links.
|
|
295
|
+
# They are converted to AsciiDoc internal cross references (i.e., <<anchor_name,link_text>>).
|
|
296
|
+
# For example,
|
|
297
|
+
# %%UDB_DOC_LINK%inst;add;add instruction%%
|
|
298
|
+
# is converted to:
|
|
299
|
+
# <<udb:inst:add,add instruction>>
|
|
300
|
+
#
|
|
301
|
+
# @param path_or_str [Pathname or String]
|
|
302
|
+
# @return [String]
|
|
303
|
+
def self.resolve_links(path_or_str)
|
|
304
|
+
str =
|
|
305
|
+
if path_or_str.is_a?(Pathname)
|
|
306
|
+
path_or_str.read
|
|
307
|
+
else
|
|
308
|
+
path_or_str
|
|
309
|
+
end
|
|
310
|
+
str.gsub(/%%UDB_DOC_LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do
|
|
311
|
+
type = Regexp.last_match[1]
|
|
312
|
+
name = Regexp.last_match[2]
|
|
313
|
+
link_text = Regexp.last_match[3]
|
|
314
|
+
|
|
315
|
+
case type
|
|
316
|
+
when "ext"
|
|
317
|
+
"<<udb:doc:ext:#{name},#{link_text}>>"
|
|
318
|
+
when "ext_param"
|
|
319
|
+
ext_name, param_name = name.split(".")
|
|
320
|
+
"<<udb:doc:ext_param:#{ext_name}:#{param_name},#{link_text}>>"
|
|
321
|
+
when "inst"
|
|
322
|
+
"<<udb:doc:inst:#{name},#{link_text}>>"
|
|
323
|
+
when "csr"
|
|
324
|
+
"<<udb:doc:csr:#{name},#{link_text}>>"
|
|
325
|
+
when "csr_field"
|
|
326
|
+
csr_name, field_name = name.split("*")
|
|
327
|
+
"<<udb:doc:csr_field:#{csr_name}:#{field_name},#{link_text}>>"
|
|
328
|
+
when "mmr"
|
|
329
|
+
"<<udb:doc:mmr:#{name},#{link_text}>>"
|
|
330
|
+
when "mmr_field"
|
|
331
|
+
mmr_name, field_name = name.split(".")
|
|
332
|
+
"<<udb:doc:mmr_field:#{mmr_name}:#{field_name},#{link_text}>>"
|
|
333
|
+
when "func"
|
|
334
|
+
"<<udb:doc:func:#{name},#{link_text}>>"
|
|
335
|
+
else
|
|
336
|
+
raise "Unhandled link type of '#{type}' for '#{name}' with link_text '#{link_text}'"
|
|
337
|
+
end
|
|
338
|
+
end.gsub(/%%UDB_DOC_COV_PT_LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do
|
|
339
|
+
org = Regexp.last_match[1] # "sep", "combo", or "appendix"
|
|
340
|
+
id = Regexp.last_match[2]
|
|
341
|
+
link_text = Regexp.last_match[3]
|
|
342
|
+
|
|
343
|
+
raise "Unhandled link org of '#{org}' for ID '#{id}' with link_text '#{link_text}'" unless org == "sep" || org == "combo" || org == "appendix"
|
|
344
|
+
|
|
345
|
+
"<<udb:doc:cov_pt:#{org}:#{id},#{link_text}>>"
|
|
346
|
+
end.gsub(/%%IDL_CODE_LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do
|
|
347
|
+
type = Regexp.last_match[1]
|
|
348
|
+
name = Regexp.last_match[2]
|
|
349
|
+
link_text = Regexp.last_match[3]
|
|
350
|
+
|
|
351
|
+
case type
|
|
352
|
+
when "inst"
|
|
353
|
+
inst_name, id = name.split(".")
|
|
354
|
+
"<<idl:code:inst:#{inst_name}:#{id},#{link_text}>>"
|
|
355
|
+
# TODO: Add csr and csr_field support
|
|
356
|
+
else
|
|
357
|
+
raise "Unhandled link type of '#{type}' for '#{name}' with link_text '#{link_text}'"
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Utilities for a backend to generate an Antora web-site.
|
|
366
|
+
module Udb
|
|
367
|
+
module Helpers
|
|
368
|
+
module AntoraUtils
|
|
369
|
+
# The syntax "class << self" causes all methods to be treated as class methods.
|
|
370
|
+
# Convert proprietary link format to legal AsciiDoc links.
|
|
371
|
+
#
|
|
372
|
+
# They are converted to AsciiDoc external cross references in the form:
|
|
373
|
+
# xref:<module>:<file>.adoc:#<anchor_name>[<link_text>])
|
|
374
|
+
# where <> don't appear in the actual cross reference (just there to indicate variable content).
|
|
375
|
+
#
|
|
376
|
+
# For example,
|
|
377
|
+
# %%UDB_DOC_LINK%inst;add;add instruction%%
|
|
378
|
+
# is converted to:
|
|
379
|
+
# xref:insts:add.adoc#udb:doc:add[add instruction]
|
|
380
|
+
#
|
|
381
|
+
# Antora supports the module name after the "xref:". In the example above, it the module name is "insts"
|
|
382
|
+
# and corresponds to the directory name the add.adoc file is located in. For more details, see:
|
|
383
|
+
# https://docs.antora.org/antora/latest/page/xref/
|
|
384
|
+
# and then
|
|
385
|
+
# https://docs.antora.org/antora/latest/page/resource-id-coordinates/
|
|
386
|
+
#
|
|
387
|
+
# @param path_or_str [Pathname or String]
|
|
388
|
+
# @return [String]
|
|
389
|
+
def self.resolve_links(path_or_str)
|
|
390
|
+
str =
|
|
391
|
+
if path_or_str.is_a?(Pathname)
|
|
392
|
+
path_or_str.read
|
|
393
|
+
else
|
|
394
|
+
path_or_str
|
|
395
|
+
end
|
|
396
|
+
str.gsub(/%%UDB_DOC_LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do
|
|
397
|
+
type = Regexp.last_match[1]
|
|
398
|
+
name = Regexp.last_match[2]
|
|
399
|
+
link_text = Regexp.last_match[3]
|
|
400
|
+
|
|
401
|
+
case type
|
|
402
|
+
when "ext"
|
|
403
|
+
"xref:exts:#{name}.adoc#udb:doc:ext:#{name}[#{link_text}]"
|
|
404
|
+
when "ext_param"
|
|
405
|
+
ext_name, param_name = name.split(".")
|
|
406
|
+
"xref:exts:#{ext_name}.adoc#udb:doc:ext_param:#{ext_name}:#{param_name}[#{link_text}]"
|
|
407
|
+
when "inst"
|
|
408
|
+
"xref:insts:#{name}.adoc#udb:doc:inst:#{name}[#{link_text}]"
|
|
409
|
+
when "csr"
|
|
410
|
+
"xref:csrs:#{name}.adoc#udb:doc:csr:#{name}[#{link_text}]"
|
|
411
|
+
when "csr_field"
|
|
412
|
+
csr_name, field_name = name.split("*")
|
|
413
|
+
"xref:csrs:#{csr_name}.adoc#udb:doc:csr_field:#{csr_name}:#{field_name}[#{link_text}]"
|
|
414
|
+
when "func"
|
|
415
|
+
# All functions are in the same file called "funcs.adoc".
|
|
416
|
+
"xref:funcs:funcs.adoc#udb:doc:func:#{name}[#{link_text.gsub(']', '\]')}]"
|
|
417
|
+
else
|
|
418
|
+
raise "Unhandled link type of '#{type}' for '#{name}' with link_text '#{link_text}'"
|
|
419
|
+
end
|
|
420
|
+
end.gsub(/%%IDL_CODE_LINK%([^;%]+)\s*;\s*([^;%]+)\s*;\s*([^%]+)%%/) do
|
|
421
|
+
type = Regexp.last_match[1]
|
|
422
|
+
name = Regexp.last_match[2]
|
|
423
|
+
link_text = Regexp.last_match[3]
|
|
424
|
+
|
|
425
|
+
case type
|
|
426
|
+
when "inst"
|
|
427
|
+
inst_name, id = name.split(".")
|
|
428
|
+
"xref:insts:#{inst_name}.adoc#idl:code:inst:#{inst_name}:#{id}[#{link_text}]"
|
|
429
|
+
# TODO: Add csr and csr_field support
|
|
430
|
+
else
|
|
431
|
+
raise "Unhandled link type of '#{type}' for '#{name}' with link_text '#{link_text}'"
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
3
|
+
|
|
4
|
+
# typed: true
|
|
5
|
+
# frozen_string_literal: true
|
|
6
|
+
|
|
7
|
+
require "bundler"
|
|
8
|
+
require "sorbet-runtime"
|
|
9
|
+
|
|
10
|
+
module Udb
|
|
11
|
+
module Helpers
|
|
12
|
+
extend T::Sig
|
|
13
|
+
|
|
14
|
+
# Returns installation path for the gem
|
|
15
|
+
sig { returns(Pathname) }
|
|
16
|
+
def self.gem_path
|
|
17
|
+
@gem_path ||= Pathname.new(Bundler.definition.specs.find { |s| s.name == "udb_helpers" }.full_gem_path)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: udb_helpers
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Derek Hower
|
|
8
|
+
- James Ball
|
|
9
|
+
- Afonso Olivera
|
|
10
|
+
autorequire:
|
|
11
|
+
bindir: bin
|
|
12
|
+
cert_chain: []
|
|
13
|
+
date: 2026-03-17 00:00:00.000000000 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: rake
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
|
+
requirements:
|
|
19
|
+
- - ">="
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '0'
|
|
29
|
+
- !ruby/object:Gem::Dependency
|
|
30
|
+
name: yard
|
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
type: :development
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
description: 'Various utilities to help with generating artifacts from UDB.
|
|
44
|
+
|
|
45
|
+
'
|
|
46
|
+
email:
|
|
47
|
+
- dhower@qti.qualcomm.com
|
|
48
|
+
- jamesball@qti.qualcomm.com
|
|
49
|
+
- Afonso.Oliveira@synopsys.com
|
|
50
|
+
executables: []
|
|
51
|
+
extensions: []
|
|
52
|
+
extra_rdoc_files: []
|
|
53
|
+
files:
|
|
54
|
+
- LICENSE
|
|
55
|
+
- lib/udb_helpers/backend_helpers.rb
|
|
56
|
+
- lib/udb_helpers/paths.rb
|
|
57
|
+
- lib/udb_helpers/version.rb
|
|
58
|
+
homepage: https://github.com/riscv/riscv-unified-db
|
|
59
|
+
licenses:
|
|
60
|
+
- BSD-3-Clause-Clear
|
|
61
|
+
metadata:
|
|
62
|
+
homepage_uri: https://github.com/riscv/riscv-unified-db
|
|
63
|
+
mailing_list_uri: https://lists.riscv.org/g/tech-unifieddb
|
|
64
|
+
bug_tracker_uri: https://github.com/riscv/riscv-unified-db/issues
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3.2'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
requirements: []
|
|
80
|
+
rubygems_version: 3.4.19
|
|
81
|
+
signing_key:
|
|
82
|
+
specification_version: 4
|
|
83
|
+
summary: Misc helpers for UDB generators
|
|
84
|
+
test_files: []
|