Skip to content

Commit 964567b

Browse files
authored
Merge pull request #102 from riscv-software-src/manual_appendices
Add summary of parameters to ISA manual
2 parents 0bbd605 + df19c54 commit 964567b

File tree

15 files changed

+151
-142
lines changed

15 files changed

+151
-142
lines changed

.github/workflows/regress.yml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,5 @@ jobs:
3131
run: ./bin/build_container
3232
- name: Setup project
3333
run: ./bin/setup
34-
- name: Run IDL tests
35-
run: ./do idl_test
36-
- name: Run validator
37-
run: ./do validate
38-
- name: Build html documentation for generic_rv64
39-
run: ./do gen:html[generic_rv64]
40-
- name: Build PDF documentation for MockCRD-1
41-
run: ./do gen:crd_pdf[MockCRD-1]
42-
- name: Build PDF documentation for MC-1
43-
run: ./do gen:crd_pdf[MC-1]
44-
- name: Build PDF documentation for RVA Profile Family
45-
run: ./do gen:profile_pdf[rva]
34+
- name: Run regression
35+
run: ./do regress

Rakefile

Lines changed: 17 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -97,71 +97,6 @@ namespace :validate do
9797

9898
arch_def_64.type_check
9999

100-
# arch_def_64 = arch_def_for("_64")
101-
# arch_def_64.type_check
102-
103-
# puts "Type checking IDL code..."
104-
# progressbar = ProgressBar.create(title: "Instructions", total: arch_def_32.instructions.size + arch_def_64.instructions.size)
105-
# arch_def_32.instructions.each do |inst|
106-
# progressbar.increment
107-
# inst.type_checked_operation_ast(arch_def_32.idl_compiler, arch_def_32.symtab, 32) if inst.rv32?
108-
# end
109-
# arch_def_64.instructions.each do |inst|
110-
# progressbar.increment
111-
# inst.type_checked_operation_ast(arch_def_64.idl_compiler, arch_def_64.symtab, 64) if inst.rv64?
112-
# # also need to check for an RV64 machine running with effective XLEN of 32
113-
# inst.type_checked_operation_ast(arch_def_64.idl_compiler, arch_def_64.symtab, 32) if inst.rv64? && inst.rv32?
114-
# end
115-
116-
# progressbar = ProgressBar.create(title: "CSRs", total: arch_def_32.csrs.size + arch_def_64.csrs.size)
117-
# arch_def_32.csrs.each do |csr|
118-
# progressbar.increment
119-
# profile = RubyProf::Profile.new
120-
# result = profile.profile do
121-
# if csr.has_custom_sw_read?
122-
# csr.type_checked_sw_read_ast(arch_def_32.symtab) if csr.defined_in_base32?
123-
# end
124-
# csr.fields.each do |field|
125-
# unless field.type_ast(arch_def_32.symtab).nil?
126-
# field.type_checked_type_ast(arch_def_32.symtab) if csr.defined_in_base32? && field.defined_in_base32?
127-
# end
128-
# unless field.reset_value_ast(arch_def_32.symtab).nil?
129-
# field.type_checked_reset_value_ast(arch_def_32.symtab) if csr.defined_in_base32? && field.defined_in_base32?
130-
# end
131-
# unless field.sw_write_ast(arch_def_32.symtab).nil?
132-
# field.type_checked_sw_write_ast(arch_def_32.symtab, 32) if csr.defined_in_base32? && field.defined_in_base32?
133-
# end
134-
# end
135-
# end
136-
# RubyProf::GraphHtmlPrinter.new(result).print(File.open("#{csr.name}-prof.html", "w+"), {})
137-
# end
138-
# arch_def_64.csrs.each do |csr|
139-
# progressbar.increment
140-
# if csr.has_custom_sw_read?
141-
# csr.type_checked_sw_read_ast(arch_def_64.symtab) if csr.defined_in_base64?
142-
# end
143-
# csr.fields.each do |field|
144-
# unless field.type_ast(arch_def_64.symtab).nil?
145-
# field.type_checked_type_ast(arch_def_64.symtab) if csr.defined_in_base64? && field.defined_in_base64?
146-
# end
147-
# unless field.reset_value_ast(arch_def_64.symtab).nil?
148-
# field.type_checked_reset_value_ast(arch_def_64.symtab) if csr.defined_in_base64? && field.defined_in_base64?
149-
# end
150-
# unless field.sw_write_ast(arch_def_64.symtab).nil?
151-
# field.type_checked_sw_write_ast(arch_def_64.symtab, 32) if csr.defined_in_base32? && field.defined_in_base32?
152-
# field.type_checked_sw_write_ast(arch_def_64.symtab, 64) if csr.defined_in_base64? && field.defined_in_base64?
153-
# end
154-
# end
155-
# end
156-
# progressbar = ProgressBar.create(title: "Functions", total: arch_def_32.functions.size + arch_def_64.functions.size)
157-
# arch_def_32.functions.each do |func|
158-
# progressbar.increment
159-
# func.type_check(arch_def_32.symtab)
160-
# end
161-
# arch_def_64.functions.each do |func|
162-
# progressbar.increment
163-
# func.type_check(arch_def_64.symtab)
164-
# end
165100
puts "All IDL passed type checking"
166101
end
167102
end
@@ -325,3 +260,20 @@ namespace :gen do
325260
end
326261
end
327262
end
263+
264+
desc <<~DESC
265+
Run the regression tests
266+
267+
These tests must pass before a commit will be allowed in the main branch on GitHub
268+
DESC
269+
task :regress do
270+
Rake::Task["idl_test"].invoke
271+
Rake::Task["validate"].invoke
272+
Rake::Task["gen:html"].invoke("generic_rv64")
273+
Rake::Task["gen:crd_pdf"].invoke("MockCRD-1")
274+
Rake::Task["gen:crd_pdf"].invoke("MC-1")
275+
Rake::Task["gen:profile_pdf"].invoke("rva")
276+
277+
puts
278+
puts "Regression test PASSED"
279+
end

arch/ext/Sm.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,8 @@ Sm:
415415
TODO: GitHub issue 53
416416
schema:
417417
type: integer
418-
# GitHub issue 53
419-
# when:
420-
# version: ">= 1.12.0"
418+
when:
419+
version: ">= 1.12.0"
421420
PMA_GRANULARITY:
422421
description: |
423422
log2 of the smallest supported PMA region.

backends/manual/tasks.rake

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,24 @@ rule %r{#{MANUAL_GEN_DIR}/.*/.*/antora/modules/funcs/pages/funcs.adoc} => [
241241
File.write t.name, AntoraUtils.resolve_links(arch_def.find_replace_links(erb.result(binding)))
242242
end
243243

244+
# rule to create IDL function appendix page
245+
rule %r{#{MANUAL_GEN_DIR}/.*/.*/antora/modules/params/pages/param_list.adoc} => [
246+
__FILE__,
247+
"#{$root}/.stamps/arch-gen-_64.stamp",
248+
($root / "backends" / "manual" / "templates" / "param_list.adoc.erb").to_s
249+
] do |t|
250+
arch_def = arch_def_for("_64")
251+
parts = t.name.sub("#{MANUAL_GEN_DIR}/", "").split("/")
252+
manual_version = arch_def.manual(parts[0])&.version(parts[1])
253+
254+
param_list_template_path = $root / "backends" / "manual" / "templates" / "param_list.adoc.erb"
255+
erb = ERB.new(param_list_template_path.read, trim_mode: "-")
256+
erb.filename = param_list_template_path.to_s
257+
258+
FileUtils.mkdir_p File.dirname(t.name)
259+
File.write t.name, AntoraUtils.resolve_links(arch_def.find_replace_links(erb.result(binding)))
260+
end
261+
244262
rule %r{#{MANUAL_GEN_DIR}/.*/top/.*/antora/landing/antora.yml} => [
245263
__FILE__
246264
] do |t|
@@ -394,6 +412,7 @@ namespace :gen do
394412
version.extensions.each do |ext|
395413
Rake::Task[antora_path / "modules" / "exts" / "pages" / "#{ext.name}.adoc"].invoke
396414
end
415+
Rake::Task[antora_path / "modules" / "params" / "pages" / "param_list.adoc"].invoke
397416
end
398417

399418
landing_page_path = MANUAL_GEN_DIR / ENV["MANUAL_NAME"] / "top" / output_hash / "antora" / "landing" / "modules" / "ROOT" / "pages" / "index.adoc"
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
<%- manual_version.volumes.each do |volume| -%>
2-
.<%= volume.title %>
2+
* <%= volume.title %>
33
<%- volume.chapters.each do |chapter| -%>
4-
* xref:chapters:<%= File.basename(chapter.path) %>[<%= chapter.title %>]
4+
** xref:chapters:<%= File.basename(chapter.path) %>[<%= chapter.title %>]
55
<%- end -%>
66

77
<%- end -%>
88

9-
.Alphabetical list of instrutions
9+
* Alphabetical list of instrutions
1010
<%- manual_version.instructions.sort { |a, b| a.name <=> b.name }.each do |inst| -%>
11-
* xref:insts:<%= inst.name %>.adoc[<%= inst.name %>]
11+
** xref:insts:<%= inst.name %>.adoc[<%= inst.name %>]
1212
<%- end -%>
1313

14-
.Alphabetical list of CSRs
14+
* Alphabetical list of CSRs
1515
<%- manual_version.csrs.sort { |a, b| a.name <=> b.name }.each do |csr| -%>
16-
* xref:csrs:<%= csr.name %>.adoc[<%= csr.name %>]
16+
** xref:csrs:<%= csr.name %>.adoc[<%= csr.name %>]
1717
<%- end -%>
1818

19-
.Alphabetical list of extensions
19+
* Alphabetical list of extensions
2020
<%- manual_version.extensions.sort { |a, b| a.name <=> b.name }.each do |ext| -%>
21-
* xref:exts:<%= ext.name %>.adoc[<%= ext.name %>]
21+
** xref:exts:<%= ext.name %>.adoc[<%= ext.name %>]
2222
<%- end -%>
2323

24-
.Execution functions (IDL)
25-
* xref:funcs:funcs.adoc[Functions]
24+
* xref:params:param_list.adoc[Alphabetical list of parameters]
25+
26+
* xref:funcs:funcs.adoc[Execution functions (IDL)]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
= Architectural Parameters
2+
3+
<%-
4+
params = manual_version.extensions.map{ |e| e.params(arch_def) }.flatten.uniq(&:name).sort_by!(&:name)
5+
-%>
6+
7+
The following <%= params.size %> parameters are defined in this manual:
8+
9+
|===
10+
| Name | Type | Extension(s) | Description
11+
12+
<%- params.each do |param| -%>
13+
| <%= param.name %>
14+
| <%= param.schema.to_pretty_s %>
15+
| <%= param.exts.map { |ext| "`#{ext.name}`"}.join(", ") %>
16+
a| <%= param.desc %>
17+
<%- end -%>
18+
|===

lib/arch_def.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,15 +432,11 @@ def conflicting_ext?(ext_name)
432432
prohibited_extensions.include? { |ext_req| ext_req.name == ext_name }
433433
end
434434

435-
# @return [Array<ExtensionParameter>] List of all parameters defined in the architecture
435+
# @return [Array<ExtensionParameter>] Alphabetical list of all parameters defined in the architecture
436436
def params
437437
return @params unless @params.nil?
438438

439-
@params = []
440-
extensions.each do |ext|
441-
@params += ext.params
442-
end
443-
@params
439+
@params = extensions.map(&:params).flatten.uniq(&:name).sort_by!(&:name)
444440
end
445441

446442
# @return [Hash<String, ExtensionParameter>] Hash of all extension parameters defined in the architecture

lib/arch_obj_models/crd.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def allowed_values
234234
end
235235

236236
# Create a Schema object just using information in the parameter database.
237-
schema_obj = Schema.new(@param_db.schema)
237+
schema_obj = @param_db.schema
238238

239239
# Merge in constraints imposed by the CRD on the parameter.
240240
schema_obj.merge!(@schema_crd)

lib/arch_obj_models/extension.rb

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
# A parameter (AKA option, AKA implementation-defined value) supported by an extension
77
class ExtensionParameter
8+
# @return [ArchDef] The defining Arch def
9+
attr_reader :archdef
10+
811
# @return [String] Parameter name
912
attr_reader :name
1013

1114
# @return [String] Asciidoc description
1215
attr_reader :desc
1316

14-
# @return [Hash] JSON Schema for the parameter value
17+
# @return [Schema] JSON Schema for this param
1518
attr_reader :schema
1619

1720
# @return [String] Ruby code to perform validation above and beyond JSON schema
@@ -25,25 +28,46 @@ class ExtensionParameter
2528
attr_reader :exts
2629

2730
# @returns [Idl::Type] Type of the parameter
28-
attr_reader :type
31+
attr_reader :idl_type
2932

3033
# Pretty convert extension schema to a string.
3134
def schema_type
32-
Schema.new(@schema).to_pretty_s
35+
@schema.to_pretty_s
3336
end
3437

35-
def initialize(name, desc, schema, extra_validation, exts)
38+
def initialize(ext, name, data)
39+
@archdef = ext.arch_def
40+
@data = data
3641
@name = name
37-
@desc = desc
38-
@schema = schema
39-
@extra_validation = extra_validation
40-
@exts = exts
41-
begin
42-
@type = Idl::Type.from_json_schema(@schema).make_const.freeze
43-
rescue
44-
warn "While parsing scheme for ExtensionParameter #{ext.name}.#{name}"
45-
raise
42+
@desc = data["description"]
43+
@schema = Schema.new(data["schema"])
44+
@extra_validation = data["extra_validation"]
45+
also_defined_in = []
46+
unless data["also_defined_in"].nil?
47+
if data["also_defined_in"].is_a?(String)
48+
other_ext = @archdef.extension(data["also_defined_in"])
49+
raise "Definition error in #{ext.name}.#{name}: #{data['also_defined_in']} is not a known extension" if other_ext.nil?
50+
also_defined_in << other_ext
51+
else
52+
unless data["also_defined_in"].is_a?(Array) && data["also_defined_in"].all? { |e| e.is_a?(String) }
53+
raise "schema error: also_defined_in should be a string or array of strings"
54+
end
55+
56+
data["also_defined_in"].each do |other_ext_name|
57+
other_ext = @archdef.extension(other_ext_name)
58+
raise "Definition error in #{ext.name}.#{name}: #{data['also_defined_in']} is not a known extension" if other_ext.nil?
59+
also_defined_in << other_ext
60+
end
61+
end
4662
end
63+
@exts = [ext] + also_defined_in
64+
@idl_type = @schema.to_idl_type.make_const.freeze
65+
end
66+
67+
def defined_in_extension_version?(version)
68+
return true if @data.dig("when", "version").nil?
69+
70+
Gem::Requirement.new(@data["when"]["version"]).satisfied_by?(version)
4771
end
4872

4973
# @return [String]
@@ -147,31 +171,7 @@ def params
147171
@params = []
148172
if @data.key?("params")
149173
@data["params"].each do |param_name, param_data|
150-
also_defined_in = []
151-
unless param_data["also_defined_in"].nil?
152-
if param_data["also_defined_in"].is_a?(String)
153-
other_ext = arch_def.extension(param_data["also_defined_in"])
154-
raise "Definition error in #{name}.#{param_name}: #{param_data['also_defined_in']} is not a known extension" if other_ext.nil?
155-
also_defined_in << other_ext
156-
else
157-
unless param_data["also_defined_in"].is_a?(Array) && param_data["also_defined_in"].all? { |e| e.is_a?(String) }
158-
raise "schema error: also_defined_in should be a string or array of strings"
159-
end
160-
161-
param_data["also_defined_in"].each do |other_ext_name|
162-
other_ext = arch_def.extension(other_ext_name)
163-
raise "Definition error in #{name}.#{param_name}: #{param_data['also_defined_in']} is not a known extension" if other_ext.nil?
164-
also_defined_in << other_ext
165-
end
166-
end
167-
end
168-
@params << ExtensionParameter.new(
169-
param_name,
170-
param_data["description"],
171-
param_data["schema"],
172-
param_data["extra_validation"],
173-
[self] + also_defined_in
174-
)
174+
@params << ExtensionParameter.new(self, param_name, param_data)
175175
end
176176
end
177177
@params
@@ -289,6 +289,11 @@ def ext(arch_def)
289289
arch_def.extension(name)
290290
end
291291

292+
# @return [Array<ExtensionParameter>] The list of parameters for this extension version
293+
def params(arch_def)
294+
ext(arch_def).params.select { |p| p.defined_in_extension_version?(@version) }
295+
end
296+
292297
# @overload ==(other)
293298
# @param other [String] An extension name
294299
# @return [Boolean] whether or not this ExtensionVersion is named 'other'

lib/arch_obj_models/manual.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def volumes
152152

153153
def state = @data["state"]
154154

155+
# @return [Array<ExtensionVersion>] Array of extension versions in this manual version
155156
def extensions
156157
return @extensions unless @extensions.nil?
157158

0 commit comments

Comments
 (0)