Skip to content

Commit 786dc9f

Browse files
Finished adding support for profile processor kinds and now RVB23 is compared with the RVA profiles as desired.
1 parent 0632dbb commit 786dc9f

File tree

8 files changed

+157
-75
lines changed

8 files changed

+157
-75
lines changed

backends/profile_doc/tasks.rake

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,28 @@ rule %r{#{$root}/gen/profile_doc/adoc/.*\.adoc} => [
77
Dir.glob("#{$root}/arch/profile_release/**/*.yaml")
88
].flatten do |t|
99
profile_release_name = Pathname.new(t.name).basename(".adoc").to_s
10-
11-
# Switch to the generated profile certificate cfg arch and set some variables available to ERB template.
12-
# XXX - Copy what certificate tasks.rake file does here (i.e. switching to generated profile cfg arch).
1310
profile_release = cfg_arch_for("_").profile_release(profile_release_name)
14-
portfolio = profile_release
1511
raise ArgumentError, "No profile release named '#{profile_release_name}'" if profile_release.nil?
1612

17-
# Set globals for ERB template.
18-
profile_class = profile_release.profile_class
19-
portfolio_class = profile_class
20-
portfolio = profile_release
21-
2213
template_path = Pathname.new "#{$root}/backends/profile_doc/templates/profile.adoc.erb"
2314
erb = ERB.new(template_path.read, trim_mode: "-")
2415
erb.filename = template_path.to_s
2516

17+
# Switch to the generated profile certificate cfg arch and set some variables available to ERB template.
2618
cfg_arch = cfg_arch_for("_")
2719

28-
# XXX - Add call to to_cfg_arch() in portfolio instance class.
29-
# But somehow have to merge the multiple portofolios in one profile release to one since
30-
# to_cfg_arch used to provide coloring of fields in CSRs in appendices that apply to all profiles in a release.
20+
# Create empty binding and then specify explicitly which variables the ERB template can access.
21+
def create_empty_binding
22+
binding
23+
end
24+
erb_binding = create_empty_binding
25+
erb_binding.local_variable_set(:cfg_arch, cfg_arch)
26+
erb_binding.local_variable_set(:profile_class, profile_release.profile_class)
27+
erb_binding.local_variable_set(:profile_release, profile_release)
28+
erb_binding.local_variable_set(:portfolio_class, profile_release.profile_class)
3129

3230
FileUtils.mkdir_p File.dirname(t.name)
33-
File.write t.name, AsciidocUtils.resolve_links(cfg_arch.find_replace_links(erb.result(binding)))
31+
File.write t.name, AsciidocUtils.resolve_links(cfg_arch.find_replace_links(erb.result(erb_binding)))
3432
puts "Generated adoc source at #{t.name}"
3533
end
3634

backends/profile_doc/templates/profile.adoc.erb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,21 +403,21 @@ associated implementation-defined parameters.
403403
[appendix]
404404
== Profile Comparisons
405405
406-
=== Processor Kind Comparison
406+
=== <%= profile_class.processor_kind %> Profile Releases
407407
408-
The <%= profile_class.processor_kind %> processor kind has <%= profile_class.profile_releases.filter_processor_kind.size %> processor
409-
profile releases that reference a total of <%= profile_class.filter_processor_kind.referenced_extensions.size %> extensions.
408+
The <%= profile_class.processor_kind %> processor kind has <%= profile_class.profile_releases_matching_processor_kind.size %> processor
409+
profile releases that reference a total of <%= profile_class.referenced_extensions_matching_processor_kind.size %> extensions.
410410
411411
.Extension Presence
412412
|===
413-
| Extension | <%= profile_class.profile_releases.filter_processor_kind.map(&:marketing_name).join(" | ") %>
413+
| Extension | <%= profile_class.profile_releases_matching_processor_kind.map(&:marketing_name).join(" | ") %>
414414
415-
<% profile_class.filter_processor_kind.referenced_extensions.sort_by(&:name).each do |ext| -%>
416-
| <%= ext.name %> | <%= profile_class.profile_releases.filter_processor_kind.map { |profile_release| profile_release.extension_presence(ext.name) }.join(" | ") %>
415+
<% profile_class.referenced_extensions_matching_processor_kind.sort_by(&:name).each do |ext| -%>
416+
| <%= ext.name %> | <%= profile_class.profile_releases_matching_processor_kind.map { |profile_release| profile_release.extension_presence(ext.name) }.join(" | ") %>
417417
<% end -%>
418418
|===
419419
420-
=== Release Comparison
420+
=== <%= profile_class.marketing_name %> Profile Releases
421421
422422
The <%= profile_class.marketing_name %> Profile Class has <%= profile_class.profile_releases.size %> releases that
423423
reference a total of <%= profile_class.referenced_extensions.size %> extensions.
@@ -431,7 +431,7 @@ reference a total of <%= profile_class.referenced_extensions.size %> extensions.
431431
<% end -%>
432432
|===
433433
434-
=== Profile Comparison
434+
=== <%= profile_release.marketing_name %> Profiles
435435
436436
The <%= profile_release.marketing_name %> Profile Release has <%= profile_release.profiles.size %> profiles that
437437
reference a total of <%= profile_release.referenced_extensions.size %> extensions.

lib/arch_obj_models/certificate.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def mandatory_priv_modes = @data["mandatory_priv_modes"]
1919

2020
# Holds information about a certificate model YAML file.
2121
# The inherited "data" member is the database of extensions, instructions, CSRs, etc.
22-
class CertModel < PortfolioInstance
22+
class CertModel < Portfolio
2323
def unpriv_isa_manual_revision = @data["unpriv_isa_manual_revision"]
2424
def priv_isa_manual_revision = @data["priv_isa_manual_revision"]
2525
def debug_manual_revision = @data["debug_manual_revision"]

lib/arch_obj_models/portfolio.rb

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# Classes for Porfolios which form a common base class for profiles and certificates.
1+
# Classes for Portfolios which form a common base class for profiles and certificates.
22
# A "Portfolio" is a named & versioned grouping of extensions (each with a name and version).
3-
# Each Portfolio Instance is a member of a Portfolio Class:
4-
# RVA20U64 and MC100 are examples of portfolio instances
3+
# Each Portfolio is a member of a Portfolio Class:
4+
# RVA20U64 and MC100 are examples of portfolios
55
# RVA and MC are examples of portfolio classes
66
#
77
# Many classes inherit from the DatabaseObject class. This provides facilities for accessing the contents of a
88
# Portfolio Class YAML or Portfolio Model YAML file via the "data" member (hash holding releated YAML file contents).
99
#
10-
# A variable name with a "_data" suffix indicates it is the raw hash data from the porfolio YAML file.
10+
# A variable name with a "_data" suffix indicates it is the raw hash data from the portfolio YAML file.
1111

1212
require "tmpdir"
1313

@@ -37,15 +37,21 @@ def description = @data["description"]
3737
def eql?(other)
3838
other.instance_of?(self.class) && other.name == name
3939
end
40+
41+
# @return [Array<PortfolioClass] All portfolio classes that have the same portfolio kind and same processor kind.
42+
def portfolio_classes_matching_portfolio_kind_and_processor_kind
43+
cfg_arch.portfolio_classes.select {|portfolio_class|
44+
(portfolio_class.kind == kind) && (portfolio_class.processor_kind == processor_kind)}
45+
end
4046
end
4147

42-
#####################
43-
# PortfolioInstance #
44-
#####################
48+
#############
49+
# Portfolio #
50+
#############
4551

46-
# Holds information about a PortfolioInstance YAML file (certificate or profile).
52+
# Holds information about a Portfolio (certificate or profile).
4753
# The inherited "data" member is the database of extensions, instructions, CSRs, etc.
48-
class PortfolioInstance < DatabaseObject
54+
class Portfolio < DatabaseObject
4955
# @return [ConfiguredArchitecture] The defining ConfiguredArchitecture
5056
attr_reader :cfg_arch
5157

@@ -55,7 +61,7 @@ def introduction = @data["introduction"]
5561
# @return [String] Large enough to need its own heading (generally one level deeper than the "introduction").
5662
def description = @data["description"]
5763

58-
# @return [Gem::Version] Semantic version of the PortfolioInstance
64+
# @return [Gem::Version] Semantic version of the Portfolio
5965
def version = Gem::Version.new(@data["version"])
6066

6167
# @return [ExtensionPresence] Given an extension +ext_name+, return the presence.
@@ -283,7 +289,7 @@ def value
283289
# @return [String] - # What parameter values are allowed by the portfolio.
284290
def allowed_values
285291
if (@schema_portfolio.empty?)
286-
# PortfolioInstance doesn't add any constraints on parameter's value.
292+
# Portfolio doesn't add any constraints on parameter's value.
287293
return "Any"
288294
end
289295

lib/arch_obj_models/profile.rb

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,33 @@ def profile_releases
3232

3333
# @return [Array<ProfileRelease>] Defined profile releases of this processor class
3434
def profile_releases_matching_processor_kind
35+
return @profile_releases_matching_processor_kind unless @profile_releases_matching_processor_kind.nil?
3536

37+
matching_classes = portfolio_classes_matching_portfolio_kind_and_processor_kind
38+
39+
# Look for all profile releases that are from any of the matching classes.
40+
@profile_releases_matching_processor_kind = @cfg_arch.profile_releases.select { |pr|
41+
matching_classes.any? { |matching_class| matching_class.name == pr.profile_class.name }
42+
}
43+
44+
@profile_releases_matching_processor_kind
3645
end
3746

3847
# @return [Array<Profile>] All profiles in this profile class (for all releases).
3948
def profiles
4049
return @profiles unless @profiles.nil?
4150

42-
@profiles = []
43-
@cfg_arch.profiles.each do |profile|
44-
if profile.profile_class.name == name
45-
@profiles << profile
46-
end
47-
end
51+
@profiles = @cfg_arch.profiles.select {|profile| profile.profile_class.name == name}
52+
end
4853

49-
@profiles
54+
# @return [Array<Profile>] All profiles in database matching my processor kind
55+
def profiles_matching_processor_kind
56+
return @profiles_matching_processor_kind unless @profiles_matching_processor_kind.nil?
57+
58+
@profiles_matching_processor_kind = @cfg_arch.profiles.select {|profile| profile.profile_class.processor_kind == processor_kind}
5059
end
5160

52-
# @return [Array<Extension>] List of all extensions referenced by the class
61+
# @return [Array<Extension>] List of all extensions referenced by the profile class
5362
def referenced_extensions
5463
return @referenced_extensions unless @referenced_extensions.nil?
5564

@@ -63,6 +72,19 @@ def referenced_extensions
6372
@referenced_extensions
6473
end
6574

75+
# @return [Array<Extension>] List of all extensions referenced by any profile class in the database with my processor kind
76+
def referenced_extensions_matching_processor_kind
77+
return @reference_extensions_matching_processor_kind unless @reference_extensions_matching_processor_kind.nil?
78+
79+
@reference_extensions_matching_processor_kind = []
80+
profiles_matching_processor_kind.each do |profile|
81+
@reference_extensions_matching_processor_kind += profile.in_scope_extensions
82+
end
83+
84+
@reference_extensions_matching_processor_kind.uniq!(&:name)
85+
86+
@reference_extensions_matching_processor_kind
87+
end
6688
end
6789

6890
# A profile release consists of a number of releases each with one or more profiles.
@@ -148,7 +170,7 @@ def extension_presence(ext_name)
148170
end
149171

150172
# Representation of a specific profile in a profile release.
151-
class Profile < PortfolioInstance
173+
class Profile < Portfolio
152174
# @return [String] The marketing name of the Profile
153175
def marketing_name = @data["marketing_name"]
154176

lib/architecture.rb

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
# frozen_string_literal: true
22

3+
# Contains the "database" of RISC-V standards including extensions, instructions,
4+
# CSRs, Profiles, and Certificates. Could be either the standard spec (defined by RISC-V International)
5+
# of a custom spec (defined as an arch_overlay in cfgs/).
6+
#
7+
# Creates Ruby functions at runtime (see generate_obj_methods() and OBJS array).
8+
# 1) Function to return Array<klass> (every klass in database)
9+
# 2) Function to return Hash<String name, klass> (hash entry is nil if name doesn't exist)
10+
# 3) Function to return Klass given name (nil if name doesn't exist)
11+
#
12+
# klass Array<klass> Hash<String name,klass> Klass func(String name)
13+
# =============== ================== ======================= =========================
14+
# Extension extensions() extension_hash() extension(name)
15+
# Instruction instructions() instruction_hash() instruction(name)
16+
# Csr csrs() csr_hash() csr(name)
17+
# CertClass cert_classes() cert_class_hash() cert_class(name)
18+
# CertModel cert_models() cert_model_hash() cert_model(name)
19+
# ProfileClass profile_classes() profile_class_hash() profile_class(name)
20+
# ProfileRelease profile_releases() profile_release_hash() profile_release(name)
21+
# Profile profiles() profile_hash() profile(name)
22+
# Manual manuals() manual_hash() manual(name)
23+
# ManualVersion manual_versions() manual_version_hash() manual_version(name)
24+
#
25+
# Statically created Ruby functions:
26+
#
27+
# klass Array<klass> Hash<String name,klass> Klass func(String name)
28+
# ================== ================== ======================= =========================
29+
# ExtensionParameter params() param_hash() param(name)
30+
# PortfolioClass portfolio_classes() portfolio_class_hash() portfolio_class(name)
31+
# Portfolio portfolios() portfolio_hash() portfolio(name)
32+
# ExceptionCodes exception_codes()
33+
# InterruptCodes interrupt_codes()
34+
335
require "active_support/inflector/methods"
436

537
require "json"
@@ -19,10 +51,6 @@
1951
require_relative "arch_obj_models/portfolio"
2052
require_relative "arch_obj_models/profile"
2153

22-
# Represents the entire RISC-V Architecture.
23-
#
24-
# Could be either the standard spec (defined by RISC-V International)
25-
# of a custom spec (defined as an arch_overlay in cfgs/)
2654
class Architecture
2755
# @return [Pathname] Path to the directory with the standard YAML files
2856
attr_reader :path
@@ -169,20 +197,66 @@ def params
169197
end
170198

171199
# @return [Hash<String, ExtensionParameter>] Hash of all extension parameters defined in the architecture
172-
def params_hash
173-
return @params_hash unless @params_hash.nil?
200+
def param_hash
201+
return @param_hash unless @param_hash.nil?
174202

175-
@params_hash = {}
203+
@param_hash = {}
176204
params.each do |param|
177-
@params_hash[param.name] = param
205+
@param_hash[param.name] = param
178206
end
179207
@param_hash
180208
end
181209

182210
# @return [ExtensionParameter] Parameter named +name+
183211
# @return [nil] if there is no parameter named +name+
184212
def param(name)
185-
params_hash[name]
213+
param_hash[name]
214+
end
215+
216+
# @return [Array<PortfolioClass>] Alphabetical list of all portfolio classes defined in the architecture
217+
def portfolio_classes
218+
return @portfolio_classes unless @portfolio_classes.nil?
219+
220+
@portfolio_classes = profile_classes.concat(cert_classes).sort_by!(&:name)
221+
end
222+
223+
# @return [Hash<String, PortfolioClass>] Hash of all portfolio classes defined in the architecture
224+
def portfolio_class_hash
225+
return @portfolio_class_hash unless @portfolio_class_hash.nil?
226+
227+
@portfolio_class_hash = {}
228+
portfolio_classes.each do |portfolio_class|
229+
@portfolio_class_hash[portfolio_class.name] = portfolio_class
230+
end
231+
@portfolio_class_hash
232+
end
233+
234+
# @return [PortfolioClass] Portfolio class named +name+
235+
# @return [nil] if there is no Portfolio class named +name+
236+
def portfolio_class(name) = portfolio_class_hash[name]
237+
238+
# @return [Array<Portfolio>] Alphabetical list of all portfolios defined in the architecture
239+
def portfolios
240+
return @portfolios unless @portfolios.nil?
241+
242+
@portfolios = @profiles.concat(@certificates).sort_by!(&:name)
243+
end
244+
245+
# @return [Hash<String, Portfolio>] Hash of all portfolios defined in the architecture
246+
def portfolio_hash
247+
return @portfolio_hash unless @portfolio_hash.nil?
248+
249+
@portfolio_hash = {}
250+
portfolios.each do |portfolio|
251+
@portfolio_hash[portfolio.name] = portfolio
252+
end
253+
@portfolio_hash
254+
end
255+
256+
# @return [PortfolioClass] Portfolio named +name+
257+
# @return [nil] if there is no Portfolio named +name+
258+
def portfolio(name)
259+
portfolio_hash[name]
186260
end
187261

188262
# @return [Array<ExceptionCode>] All exception codes defined by the spec

lib/cfg_arch.rb

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,9 @@
11
# frozen_string_literal: true
22

3-
# Many classes have an "cfg_arch" member which is an ConfiguredArchitecture (not DatabaseObject) class.
4-
# The "cfg_arch" member contains the "database" of RISC-V standards including extensions, instructions,
5-
# CSRs, Profiles, and Certificates.
6-
#
7-
# The cfg_arch member has methods such as:
8-
# extensions() Array<Extension> of all extensions known to the database (even if not implemented).
9-
# extension(name) Extension object for "name" and nil if none.
10-
# parameters() Array<ExtensionParameter> of all parameters defined in the architecture
11-
# param(name) ExtensionParameter object for "name" and nil if none.
12-
# csrs() Array<Csr> of all CSRs defined by RISC-V, whether or not they are implemented
13-
# csr(name) Csr object for "name" and nil if none.
14-
# instructions() Array<Instruction> of all instructions, whether or not they are implemented
15-
# inst(name) Instruction object for "name" and nil if none.
16-
# profile_classes Array<ProfileClass> of all known profile classes.
17-
# profile_class(class_name) ProfileClass object for "class_name" and nil if none.
18-
# profile_releases Array<ProfileRelease> of all profile releases for all profile classes
19-
# profile_release(release_name) ProfileRelease object for "release_name" and nil if none.
20-
# profiles Array<Profile> of all profiles in all releases in all classes
21-
# profile(name) Profile object for profile "name" and nil if none.
22-
# cert_classes Array<CertClass> of all known certificate classes
23-
# cert_class(name) CertClass object for "name" and nil if none.
24-
# cert_models Array<CertModel> of all known certificate models across all classes.
25-
# cert_model(name) CertModel object for "name" and nil if none.
3+
# Many classes have an "cfg_arch" member which is an ConfiguredArchitecture class.
4+
# It combines knowledge of the RISC-V Architecture with a particular configuration.
5+
# A configuration is an instance of the Config object either located in the /cfg directory
6+
# or created at runtime for things like profiles and certificate models.
267

278
require "forwardable"
289
require "ruby-prof"

lib/config.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
require "pathname"
44

5-
# this class represents a configuration file (e.g., cfgs/*/cfg.yaml), independent of the Architecture
5+
# This class represents a configuration file (e.g., cfgs/*/cfg.yaml), independent of the Architecture.
6+
# Can either be in the /cfg directory or created at runtime in memory by the certificate tasks.rake file.
67
class Config
78
# @return [Hash<String, Object>] A hash mapping parameter name to value for any parameter that has
89
# been configured with a value. May be empty.

0 commit comments

Comments
 (0)