From 9d7921dd2cb33d8c0538cb8f5b07a9a10eecbefb Mon Sep 17 00:00:00 2001 From: james-ball-qualcomm Date: Tue, 3 Dec 2024 21:54:35 +0000 Subject: [PATCH 01/10] Switching to desktop workspace from Codespace. --- Rakefile | 44 +++++++++----- arch/profile_release/MockProfileRelease.yaml | 3 + backends/profile_doc/tasks.rake | 2 +- .../profile_doc/templates/profile.adoc.erb | 59 +++++++++++++------ lib/arch_obj_models/extension.rb | 35 ++++++++++- lib/arch_obj_models/portfolio.rb | 47 +++++++++------ lib/arch_obj_models/profile.rb | 21 +++++++ 7 files changed, 157 insertions(+), 54 deletions(-) diff --git a/Rakefile b/Rakefile index b1b3feb28..51a15e183 100644 --- a/Rakefile +++ b/Rakefile @@ -302,42 +302,56 @@ task :regress do end desc <<~DESC - Generate all certificates and profile PDFs. + Generate all portfolio-based PDFs (certificates and profiles). DESC -task :cert_profile_pdfs do +task :portfolio_pdfs do + puts "" puts "===================================" - puts "cert_profile_pdfs: Generating MC100" - puts " 1st target" + puts "Generating MC100" puts "===================================" + puts "" Rake::Task["#{$root}/gen/certificate_doc/pdf/MC100.pdf"].invoke + puts "" puts "==================================================" - puts "cert_profile_pdfs: Generating MockCertificateModel" - puts " 2nd target" + puts "Generating MockCertificateModel" puts "==================================================" + puts "" Rake::Task["#{$root}/gen/certificate_doc/pdf/MockCertificateModel.pdf"].invoke + puts "" puts "===================================" - puts "cert_profile_pdfs: Generating RVA20" - puts " 3rd target" + puts "Generating RVA20" puts "===================================" + puts "" Rake::Task["#{$root}/gen/profile_doc/pdf/RVA20.pdf"].invoke + puts "" puts "===================================" - puts "cert_profile_pdfs: Generating RVA22" - puts " 4th target" + puts "Generating RVA22" puts "===================================" + puts "" Rake::Task["#{$root}/gen/profile_doc/pdf/RVA22.pdf"].invoke + puts "" puts "===================================" - puts "cert_profile_pdfs: Generating RVI20" - puts " 5th target" + puts "Generating RVI20" puts "===================================" + puts "" Rake::Task["#{$root}/gen/profile_doc/pdf/RVI20.pdf"].invoke + puts "" puts "===================================" - puts "cert_profile_pdfs: Generating MockProfileRelease" - puts " 6th target" + puts "Generating MockProfileRelease" puts "===================================" + puts "" Rake::Task["#{$root}/gen/profile_doc/pdf/MockProfileRelease.pdf"].invoke -end \ No newline at end of file +end + +# Shortcut targets for building profiles and certificates. +task MC100: "#{$root}/gen/certificate_doc/pdf/MC100.pdf" +task MockCertificateModel: "#{$root}/gen/certificate_doc/pdf/MockCertificateModel.pdf" +task RVI20: "#{$root}/gen/profile_doc/pdf/RVI20.pdf" +task RVA20: "#{$root}/gen/profile_doc/pdf/RVA20.pdf" +task RVA22: "#{$root}/gen/profile_doc/pdf/RVA22.pdf" +task MockProfileRelease: "#{$root}/gen/profile_doc/pdf/MockProfileRelease.pdf" \ No newline at end of file diff --git a/arch/profile_release/MockProfileRelease.yaml b/arch/profile_release/MockProfileRelease.yaml index 45104cdec..ca4a0f10c 100644 --- a/arch/profile_release/MockProfileRelease.yaml +++ b/arch/profile_release/MockProfileRelease.yaml @@ -68,6 +68,9 @@ MockProfileRelease: optional: transitory version: "~> 1.11" note: Made this a transitory option + MockExt: + presence: mandatory + version: "~> 0.9.9" extra_notes: - presence: mandatory text: | diff --git a/backends/profile_doc/tasks.rake b/backends/profile_doc/tasks.rake index 167ba087e..489cfd9aa 100644 --- a/backends/profile_doc/tasks.rake +++ b/backends/profile_doc/tasks.rake @@ -4,7 +4,7 @@ rule %r{#{$root}/gen/profile_doc/adoc/.*\.adoc} => proc { |tname| profile_release_name = Pathname.new(tname).basename(".adoc") [ - "#{$root}/.stamps/arch-gen.stamp", + "#{$root}/.stamps/arch-gen-_64.stamp", __FILE__, "#{$root}/lib/arch_obj_models/profile.rb", "#{$root}/backends/profile_doc/templates/profile.adoc.erb" diff --git a/backends/profile_doc/templates/profile.adoc.erb b/backends/profile_doc/templates/profile.adoc.erb index 166ec08b7..cee0ec4b2 100644 --- a/backends/profile_doc/templates/profile.adoc.erb +++ b/backends/profile_doc/templates/profile.adoc.erb @@ -2,7 +2,7 @@ :description: <%= profile_release.marketing_name %> Profile :revdate: <%= profile_release.ratification_date.nil? ? Date.today : profile_release.ratification_date %> -// XXX - Figure out what we really want here - Change percent hash to percent equals. +// TODO - Figure out what we really want here - Change percent hash to percent equals. // :revnumber: <%# profile_release.map(&:version).sort.last %> :revmark: "TODO: revmark" @@ -311,6 +311,7 @@ optional profile extensions for a new profile might be prototyped as non-profile extensions on an earlier profile. // XXX - Need to create render() Ruby function. +// See https://github.com/riscv-software-src/riscv-unified-db/issues/59 // <%# render("#{$root}/backends/portfolio_doc/templates/family_intro.erb", portfolio_class: profile_class) %> == <%= profile_class.name %> Profile Class @@ -344,21 +345,6 @@ Ratification date:: <%= profile_release.ratification_date %> -- <% end # each profile_release -%> -=== Extension Presence - -The <%= profile_class.marketing_name %> Profile Class references -<%= profile_class.referenced_extensions.size %> extensions. - -.Status -|=== -| Extension | <%= profile_class.profiles.map(&:marketing_name).join(" | ") -%> - -<% profile_class.referenced_extensions.sort_by(&:name).each do |ext| -%> -| <%= ext.name %> | <%= profile_class.profiles.map { |profile| profile.extension_presence(ext.name) }.join(" | ") -%> -<% end -%> - -|=== - == <%= profile_release.name %> Profile Release <%= profile_release.introduction %> @@ -370,8 +356,8 @@ associated implementation-defined parameters across all its defined profiles. === <%= profile_release.name %> Description <%= profile_release.description %> - <% end # unless -%> + <% profile_release.profiles.each do |profile| -%> === <%= profile.marketing_name %> Profile @@ -411,6 +397,41 @@ associated implementation-defined parameters. <% end # each profile -%> +<<< +[appendix] +== Profile Comparisons + +=== Release Comparison + +The <%= profile_class.marketing_name %> Profile Class has <%= profile_class.profile_releases.size %> releases that +reference a total of <%= profile_class.referenced_extensions.size %> extensions. + +.Extension Presence +|=== +| Extension | <%= profile_class.profile_releases.map(&:marketing_name).join(" | ") %> + +<% profile_class.referenced_extensions.sort_by(&:name).each do |ext| -%> +| <%= ext.name %> | <%= profile_class.profile_releases.map { |profile_release| profile_release.extension_presence(ext.name) }.join(" | ") %> +<% end -%> +|=== + +=== Profile Comparison + +The <%= profile_release.marketing_name %> Profile Release has <%= profile_release.profiles.size %> profiles that +reference a total of <%= profile_release.referenced_extensions.size %> extensions. + +[NOTE] +Extensions present in a profile are also present in higher-privileged profiles in the same profile release. + +.Extension Presence +|=== +| Extension | <%= profile_release.profiles.map(&:marketing_name).join(" | ") %> + +<% profile_release.referenced_extensions.sort_by(&:name).each do |ext| -%> +| <%= ext.name %> | <%= profile_release.profiles.map { |profile| profile.extension_presence(ext.name) }.join(" | ") %> +<% end -%> +|=== + <<< [appendix] == Extension Details @@ -420,12 +441,12 @@ associated implementation-defined parameters. === <%= ext.name %> Extension <%= ext.long_name %> -.Status +.Presence |=== | Profile | v<%= ext.versions.map { |v| v.version }.join(" | v") %> <% profile_release.profiles.each do |profile| -%> -| <%= profile.marketing_name %> | <%= profile.version_strongest_presence(ext.name, ext.versions).join(" | ") -%> +| <%= profile.marketing_name %> | <%= profile.version_greatest_presence(ext.name, ext.versions).join(" | ") -%> <% end -%> |=== diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index b40aff3c5..97671b44a 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -476,8 +476,8 @@ def initialize(data) end end - def mandatory? = (@presence == mandatory) - def optional? = (@presence == optional) + def mandatory? = (@presence == "mandatory") + def optional? = (@presence == "optional") # Class methods def self.mandatory = "mandatory" @@ -522,6 +522,17 @@ def to_s @optional_type.nil? ? "#{presence}" : "#{presence} (#{optional_type})" end + def to_s_concise + "#{presence}" + end + + # + # Overloaded comparison operators following these rules: + # - "mandatory" is greater than "optional" + # - optional_types all have same rank + # - equals compares presence and then optional_type + # + # @overload ==(other) # @param other [String] A presence string # @return [Boolean] whether or not this ExtensionPresence has the same presence (ignores optional_type) @@ -539,6 +550,26 @@ def ==(other) end end + # @overload >(other) + # @param other [ExtensionPresence] An extension presence object + # @return [Boolean] Whether or not this ExtensionPresence is greater-than the other + def >(other) = (self.mandatory? && other.optional?) + + # @overload >=(other) + # @param other [ExtensionPresence] An extension presence object + # @return [Boolean] Whether or not this ExtensionPresence is greater-than or equal to the other + def >=(other) = (self > other) || (self == other) + + # @overload <(other) + # @param other [ExtensionPresence] An extension presence object + # @return [Boolean] Whether or not this ExtensionPresence is less-than the other + def <(other) = (self.optional? && other.mandatory?) + + # @overload <=(other) + # @param other [ExtensionPresence] An extension presence object + # @return [Boolean] Whether or not this ExtensionPresence is less-than or equal to the other + def <=(other) = (self < other) || (self == other) + # Sorts by presence, then by optional_type def <=>(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index e378cdc01..7a2ad3a8b 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -61,35 +61,48 @@ def description = @data["description"] # @return [Gem::Version] Semantic version of the PortfolioInstance def version = Gem::Version.new(@data["version"]) + # @return [ExtensionPresence] Given an extension +ext_name+, return the presence. + # If the extension name isn't found in the portfolio, return nil. + def extension_presence_obj(ext_name) + # Get extension information from YAML for passed in extension name. + ext_data = @data["extensions"][ext_name] + + ext_data.nil? ? nil : ExtensionPresence.new(ext_data["presence"]) + end + # @return [String] Given an extension +ext_name+, return the presence as a string. # If the extension name isn't found in the portfolio, return "-". def extension_presence(ext_name) - # Get extension information from YAML for passed in extension name. - ext_data = @data["extensions"][ext_name] + ext_presence_obj = extension_presence_obj(ext_name) - ext_data.nil? ? "-" : ExtensionPresence.new(ext_data["presence"]).to_s + ext_presence_obj.nil? ? "-" : ext_presence_obj.to_s end - # Returns the strongest presence string for each of the specified versions. + # Returns the greatest presence string for each of the specified versions. # @param ext_name [String] # @param ext_versions [Array] # @return [Array] - def version_strongest_presence(ext_name, ext_versions) + def version_greatest_presence(ext_name, ext_versions) presences = [] - # See if any extension requirement in this profile lists this version as either mandatory or optional. ext_versions.map do |v| - mandatory = mandatory_ext_reqs.any? { |ext_req| ext_req.satisfied_by?(ext_name, v.version) } - optional = optional_ext_reqs.any? { |ext_req| ext_req.satisfied_by?(ext_name, v.version) } - - # Just show strongest presence (mandatory stronger than optional). - if mandatory - presences << ExtensionPresence.mandatory - elsif optional - presences << ExtensionPresence.optional - else - presences << "-" + greatest_presence = nil + + in_scope_ext_reqs.each do |ext_req| + if ext_req.satisfied_by?(ext_name, v.version) + presence = extension_presence_obj(ext_name) + + unless presence.nil? + if greatest_presence.nil? + greatest_presence = presence + elsif presence > greatest_presence + greatest_presence = presence + end + end + end end + + presences << (greatest_presence.nil? ? "-" : greatest_presence.to_s_concise) end presences @@ -194,7 +207,7 @@ def to_arch_def end arch_def_data["params"] = all_in_scope_ext_params.select(&:single_value?).map { |p| [p.name, p.value] }.to_h - # XXX Add list of prohibited_extensions + # TODO: Add list of prohibited_extensions file = Tempfile.new("archdef") file.write(YAML.safe_dump(arch_def_data, permitted_classes: [Date])) diff --git a/lib/arch_obj_models/profile.rb b/lib/arch_obj_models/profile.rb index 44d63f3b4..497a62317 100644 --- a/lib/arch_obj_models/profile.rb +++ b/lib/arch_obj_models/profile.rb @@ -126,6 +126,27 @@ def referenced_extensions @referenced_extensions end + + # @return [String] Given an extension +ext_name+, return the presence as a string. + # Returns the greatest presence string across all profiles in the release. + # If the extension name isn't found in the release, return "-". + def extension_presence(ext_name) + greatest_presence = nil + + profiles.each do |profile| + presence = profile.extension_presence_obj(ext_name) + + unless presence.nil? + if greatest_presence.nil? + greatest_presence = presence + elsif presence > greatest_presence + greatest_presence = presence + end + end + end + + greatest_presence.nil? ? "-" : greatest_presence.to_s_concise + end end # Representation of a specific profile in a profile release. From 4acf3adf2289b651e0a0241cb3fa3b0e9aecceef Mon Sep 17 00:00:00 2001 From: james-ball-qualcomm Date: Tue, 3 Dec 2024 21:54:50 +0000 Subject: [PATCH 02/10] Forgot this one. --- lib/arch_obj_models/extension.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 97671b44a..9cb10debd 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -448,6 +448,7 @@ def implemented_instructions(archdef) # Example => presence: # optional: development class ExtensionPresence + include Comparable # Creates <, >, <=, >= automatically since <=> is provided attr_reader :presence attr_reader :optional_type From db874da7ef48e91831a7eb6bcce9996923e69bdf Mon Sep 17 00:00:00 2001 From: James Ball Date: Tue, 3 Dec 2024 22:00:31 -0800 Subject: [PATCH 03/10] Many cleanups to get better quality profiles. Also changed ratification_date from null to unknown to be consistent. --- arch/ext/Smcdeleg.yaml | 2 +- arch/ext/Ssccfg.yaml | 2 +- arch/ext/Ssccptr.yaml | 2 +- arch/ext/Sstc.yaml | 9 ++- arch/ext/Sstvala.yaml | 2 +- arch/ext/Sstvecd.yaml | 2 +- arch/ext/Ssu64xl.yaml | 15 ++++ arch/ext/Svbare.yaml | 2 +- arch/ext/Svpbmt.yaml | 2 +- arch/ext/U.yaml | 8 ++- arch/ext/V.yaml | 2 +- arch/ext/Za128rs.yaml | 2 +- arch/ext/Zic64b.yaml | 2 +- arch/ext/Ziccamoa.yaml | 2 +- arch/ext/Ziccif.yaml | 2 +- arch/ext/Zicclsm.yaml | 2 +- arch/ext/Ziccrse.yaml | 2 +- arch/ext/Zicsr.yaml | 2 +- arch/ext/Zifencei.yaml | 2 +- arch/ext/Zihintpause.yaml | 2 +- arch/ext/Zkt.yaml | 2 +- arch/profile_release/RVA20.yaml | 14 ++-- .../profile_doc/templates/profile.adoc.erb | 26 ++++--- .../arch_overlay/ext/Xcustom.yaml | 2 +- lib/arch_obj_models/certificate.rb | 4 +- lib/arch_obj_models/extension.rb | 70 ++++++++++++------- lib/arch_obj_models/portfolio.rb | 46 +++++++----- lib/arch_obj_models/schema.rb | 2 +- 28 files changed, 141 insertions(+), 91 deletions(-) create mode 100644 arch/ext/Ssu64xl.yaml diff --git a/arch/ext/Smcdeleg.yaml b/arch/ext/Smcdeleg.yaml index cf03c5253..6687479e0 100644 --- a/arch/ext/Smcdeleg.yaml +++ b/arch/ext/Smcdeleg.yaml @@ -16,7 +16,7 @@ doc_license: versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown repositories: - url: https://github.com/riscvarchive/riscv-smcdeleg-ssccfg url: https://github.com/riscvarchive/riscv-smcdeleg-ssccfg/releases/download/v1.0.0/riscv-smcdeleg-ssccfg-v1.0.0.pdf diff --git a/arch/ext/Ssccfg.yaml b/arch/ext/Ssccfg.yaml index b19973dbc..67b94f42f 100644 --- a/arch/ext/Ssccfg.yaml +++ b/arch/ext/Ssccfg.yaml @@ -9,5 +9,5 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown url: https://docs.google.com/document/d/1s-GeH5XpHBLzbQZucA8DPA7vvF7Xvf_nrPbrU2YLBcE/edit#heading=h.yyrgtolcaczx diff --git a/arch/ext/Ssccptr.yaml b/arch/ext/Ssccptr.yaml index 247dc2b07..dcfc0aedc 100644 --- a/arch/ext/Ssccptr.yaml +++ b/arch/ext/Ssccptr.yaml @@ -13,7 +13,7 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown url: https://github.com/riscv/riscv-profiles/releases/tag/v1.0 repositories: - url: https://github.com/riscv/riscv-profiles diff --git a/arch/ext/Sstc.yaml b/arch/ext/Sstc.yaml index 435287d68..f55c454c8 100644 --- a/arch/ext/Sstc.yaml +++ b/arch/ext/Sstc.yaml @@ -3,11 +3,10 @@ $schema: "ext_schema.json#" kind: extension name: Sstc -long_name: Superivisor mode timer interrupts -description: Superivisor mode timer interrupts +long_name: Supervisor-mode timer interrupts +description: Supervisor-mode timer interrupts type: privileged versions: -- version: "0.9.0" +- version: "1.0.0" state: ratified - ratification_date: null - url: https://drive.google.com/file/d/1m84Re2yK8m_vbW7TspvevCDR82MOBaSX/view?usp=drive_link + ratification_date: unknown \ No newline at end of file diff --git a/arch/ext/Sstvala.yaml b/arch/ext/Sstvala.yaml index 118b7811d..46987c66a 100644 --- a/arch/ext/Sstvala.yaml +++ b/arch/ext/Sstvala.yaml @@ -19,7 +19,7 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown url: https://github.com/riscv/riscv-profiles/releases/tag/v1.0 repositories: - url: https://github.com/riscv/riscv-profiles diff --git a/arch/ext/Sstvecd.yaml b/arch/ext/Sstvecd.yaml index cbe35c0c1..e6e4f0f55 100644 --- a/arch/ext/Sstvecd.yaml +++ b/arch/ext/Sstvecd.yaml @@ -12,7 +12,7 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown url: https://github.com/riscv/riscv-profiles/releases/tag/v1.0 repositories: - url: https://github.com/riscv/riscv-profiles diff --git a/arch/ext/Ssu64xl.yaml b/arch/ext/Ssu64xl.yaml new file mode 100644 index 000000000..8f456c28b --- /dev/null +++ b/arch/ext/Ssu64xl.yaml @@ -0,0 +1,15 @@ +# yaml-language-server: $schema=../../schemas/ext_schema.json + +$schema: "ext_schema.json#" +kind: extension +name: Ssu64xl +long_name: UXLEN=64 must be supported +description: | + `sstatus.UXL` must be capable of holding the value 2 (i.e., UXLEN=64 must be supported). + + [NOTE] + This extension was ratified as part of the RVA20 profile. +versions: +- version: "1.0.0" + state: ratified + ratification_date: unknown \ No newline at end of file diff --git a/arch/ext/Svbare.yaml b/arch/ext/Svbare.yaml index afc684ac2..2bc7d6f80 100644 --- a/arch/ext/Svbare.yaml +++ b/arch/ext/Svbare.yaml @@ -13,7 +13,7 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown requires: name: S param_constraints: diff --git a/arch/ext/Svpbmt.yaml b/arch/ext/Svpbmt.yaml index 43db85e29..7b6719fd7 100644 --- a/arch/ext/Svpbmt.yaml +++ b/arch/ext/Svpbmt.yaml @@ -14,7 +14,7 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown requires: name: Sv39 param_constraints: diff --git a/arch/ext/U.yaml b/arch/ext/U.yaml index c7c4fc253..bd2cbcbd7 100644 --- a/arch/ext/U.yaml +++ b/arch/ext/U.yaml @@ -3,11 +3,13 @@ $schema: "ext_schema.json#" kind: extension name: U -long_name: User-level privilege mode -description: User-level privilege mode +long_name: User-mode privilege level +description: | + User-mode privilege level is supported by an implementation if the U extension is present. + Note that the RISC-V ISA doens't formally define a U extension and it is only discussed in the Privileged ISA manual. type: privileged versions: -- version: "1.12.0" +- version: "1.0.0" state: ratified ratification_date: 2019-12 params: diff --git a/arch/ext/V.yaml b/arch/ext/V.yaml index e40290605..c8e69a2aa 100644 --- a/arch/ext/V.yaml +++ b/arch/ext/V.yaml @@ -8,7 +8,7 @@ long_name: Variable-length vector versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown description: | TODO params: diff --git a/arch/ext/Za128rs.yaml b/arch/ext/Za128rs.yaml index e78da5e68..dc0a059b8 100644 --- a/arch/ext/Za128rs.yaml +++ b/arch/ext/Za128rs.yaml @@ -16,7 +16,7 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown param_constraints: LRSC_RESERVATION_STRATEGY: schema: diff --git a/arch/ext/Zic64b.yaml b/arch/ext/Zic64b.yaml index 15395d5ec..9506f16bc 100644 --- a/arch/ext/Zic64b.yaml +++ b/arch/ext/Zic64b.yaml @@ -13,7 +13,7 @@ type: privileged versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown url: https://github.com/riscv/riscv-profiles/releases/tag/v1.0 repositories: - url: https://github.com/riscv/riscv-profiles diff --git a/arch/ext/Ziccamoa.yaml b/arch/ext/Ziccamoa.yaml index 838438db1..a24f265d4 100644 --- a/arch/ext/Ziccamoa.yaml +++ b/arch/ext/Ziccamoa.yaml @@ -12,4 +12,4 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Ziccif.yaml b/arch/ext/Ziccif.yaml index 4a35d7b00..70d5f10c4 100644 --- a/arch/ext/Ziccif.yaml +++ b/arch/ext/Ziccif.yaml @@ -14,4 +14,4 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Zicclsm.yaml b/arch/ext/Zicclsm.yaml index 835e91223..c95bace89 100644 --- a/arch/ext/Zicclsm.yaml +++ b/arch/ext/Zicclsm.yaml @@ -20,7 +20,7 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown param_constraints: MISALIGNED_LDST: schema: diff --git a/arch/ext/Ziccrse.yaml b/arch/ext/Ziccrse.yaml index 93e7539b8..c03ff9bc6 100644 --- a/arch/ext/Ziccrse.yaml +++ b/arch/ext/Ziccrse.yaml @@ -12,4 +12,4 @@ description: | versions: - version: "1.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Zicsr.yaml b/arch/ext/Zicsr.yaml index 92689331a..e28539c64 100644 --- a/arch/ext/Zicsr.yaml +++ b/arch/ext/Zicsr.yaml @@ -9,4 +9,4 @@ type: unprivileged versions: - version: "2.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Zifencei.yaml b/arch/ext/Zifencei.yaml index 7b661769b..d9b7dc433 100644 --- a/arch/ext/Zifencei.yaml +++ b/arch/ext/Zifencei.yaml @@ -69,4 +69,4 @@ type: unprivileged versions: - version: "2.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Zihintpause.yaml b/arch/ext/Zihintpause.yaml index 06db29627..8c7c7c27d 100644 --- a/arch/ext/Zihintpause.yaml +++ b/arch/ext/Zihintpause.yaml @@ -70,4 +70,4 @@ type: unprivileged versions: - version: "2.0.0" state: ratified - ratification_date: null + ratification_date: unknown diff --git a/arch/ext/Zkt.yaml b/arch/ext/Zkt.yaml index df11a4e36..304e7b69e 100644 --- a/arch/ext/Zkt.yaml +++ b/arch/ext/Zkt.yaml @@ -354,7 +354,7 @@ versions: - name: Claire Wolf - version: 1.0.1 state: ratified - ratification_date: null + ratification_date: unknown changes: - Fix typos to show that `c.srli`, `c.srai`, and `c.slli` are Zkt instructions in RV64. company: diff --git a/arch/profile_release/RVA20.yaml b/arch/profile_release/RVA20.yaml index 279024c2c..28f37d993 100644 --- a/arch/profile_release/RVA20.yaml +++ b/arch/profile_release/RVA20.yaml @@ -55,13 +55,6 @@ RVA20: presence: mandatory M: presence: mandatory - U: - presence: mandatory - version: "~> 2.0" - param_constraints: - U_MODE_ENDIANESS: - schema: - const: little Zicntr: presence: mandatory Ziccif: @@ -138,6 +131,13 @@ RVA20: supervisor-mode execution environment in 64-bit applications processors. RVA20S64 is based on privileged architecture version 1.11. extensions: + U: + presence: mandatory + version: "~> 1.0" + param_constraints: + U_MODE_ENDIANESS: + schema: + const: little S: presence: mandatory version: "~> 1.11" diff --git a/backends/profile_doc/templates/profile.adoc.erb b/backends/profile_doc/templates/profile.adoc.erb index cee0ec4b2..74fa8f4ec 100644 --- a/backends/profile_doc/templates/profile.adoc.erb +++ b/backends/profile_doc/templates/profile.adoc.erb @@ -441,7 +441,7 @@ Extensions present in a profile are also present in higher-privileged profiles i === <%= ext.name %> Extension <%= ext.long_name %> -.Presence +.<%= ext.name %> Extension Presence |=== | Profile | v<%= ext.versions.map { |v| v.version }.join(" | v") %> @@ -453,8 +453,12 @@ Extensions present in a profile are also present in higher-privileged profiles i <% ext.versions.each do |v| -%> <%= v.version %>:: + State::: + <%= v.state %> + <% if v.state == "ratified" -%> Ratification date::: <%= v.ratification_date %> + <% end # if %> <% unless v.changes.empty? -%> Changes::: @@ -462,18 +466,18 @@ Extensions present in a profile are also present in higher-privileged profiles i * <%= c %> <% end -%> - <%- end -%> - <%- unless v.url.nil? -%> + <% end -%> + <% unless v.url.nil? -%> Ratification document::: <%= v.url %> - <%- end -%> - <%- unless v.implications -%> + <% end -%> + <% unless v.implications -%> Implies::: - <%- v.implications.each do |i| -%> + <% v.implications.each do |i| -%> * `<%= i.name %>` version <%= i.version %> - <%- end -%> - <%- end -%> -<%- end -%> + <% end -%> + <% end -%> +<% end -%> ==== Synopsis @@ -484,8 +488,8 @@ Extensions present in a profile are also present in higher-privileged profiles i :leveloffset: -3 // TODO: GitHub issue 92: Use version specified by each profile and add version info to inst table below. -<%- insts = arch_def.instructions.select { |i| i.defined_by?(ext.min_version) } -%> -<%- unless insts.empty? -%> +<% insts = arch_def.instructions.select { |i| i.defined_by?(ext.min_version) } -%> +<% unless insts.empty? -%> ==== Instructions The following instructions are added by this extension: diff --git a/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml b/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml index 80aa49d40..ca6771f9a 100644 --- a/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml +++ b/cfgs/generic_rv64/arch_overlay/ext/Xcustom.yaml @@ -6,7 +6,7 @@ long_name: A new custom extension! type: unprivileged versions: - version: "0.1.0" - ratification_date: null + ratification_date: unknown state: development description: | A new custom extension! diff --git a/lib/arch_obj_models/certificate.rb b/lib/arch_obj_models/certificate.rb index 5b8f0552a..1a326fb6b 100644 --- a/lib/arch_obj_models/certificate.rb +++ b/lib/arch_obj_models/certificate.rb @@ -79,7 +79,7 @@ def when_pretty "Parameter #{param_name} == #{param_value}" end else - raise "TODO: when type #{key} not implemented" + raise "Type #{key} not implemented" end end.flatten.join(" and ") end @@ -111,7 +111,7 @@ def when_pretty "Parameter #{param_name} == #{param_value}" end else - raise "TODO: when type #{key} not implemented" + raise "Type #{key} not implemented" end end.flatten.join(" and ") end diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 9cb10debd..8f652766a 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -448,7 +448,6 @@ def implemented_instructions(archdef) # Example => presence: # optional: development class ExtensionPresence - include Comparable # Creates <, >, <=, >= automatically since <=> is provided attr_reader :presence attr_reader :optional_type @@ -527,13 +526,6 @@ def to_s_concise "#{presence}" end - # - # Overloaded comparison operators following these rules: - # - "mandatory" is greater than "optional" - # - optional_types all have same rank - # - equals compares presence and then optional_type - # - # @overload ==(other) # @param other [String] A presence string # @return [Boolean] whether or not this ExtensionPresence has the same presence (ignores optional_type) @@ -551,35 +543,56 @@ def ==(other) end end + # @overload <=>(other) + # @param other [String] A presence string + # @return [Integer] Sort alphabetically by presence, then alphabetically by optional_type + def <=>(other) + raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) + + if @presence != other.presence + @presence <=> other.presence + else + @optional_type <=> other.optional_type + end + end + + ###################################################### + # Following comparison operators follow these rules: + # - "mandatory" is greater than "optional" + # - optional_types all have same rank + # - equals compares presence and then optional_type + ###################################################### + # @overload >(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is greater-than the other - def >(other) = (self.mandatory? && other.optional?) + def >(other) + raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) + (self.mandatory? && other.optional?) + end # @overload >=(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is greater-than or equal to the other - def >=(other) = (self > other) || (self == other) + def >=(other) + raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) + (self > other) || (self == other) + end # @overload <(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is less-than the other - def <(other) = (self.optional? && other.mandatory?) + def <(other) + raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) + (self.optional? && other.mandatory?) + end # @overload <=(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is less-than or equal to the other - def <=(other) = (self < other) || (self == other) - - # Sorts by presence, then by optional_type - def <=>(other) + def <=(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) - - if @presence != other.presence - @presence <=> other.presence - else - @optional_type <=> other.optional_type - end + (self < other) || (self == other) end end @@ -624,6 +637,14 @@ def satisfying_versions(archdef) ext.versions.select { |v| @requirement.satisfied_by?(v.version) } end + # @return [Boolean] True if any extension version satifies this requirement + # @param [Extension] The extension object that contains one or more versions + def satisfied_by_ext?(ext) + return false if ext.nil? + + ext.versions.any? { |v| @requirement.satisfied_by?(v.version) } + end + # @overload # @param extension_version [ExtensionVersion] A specific extension version # @return [Boolean] whether or not the extension_version meets this requirement @@ -644,14 +665,13 @@ def satisfied_by?(*args) satified_by?(ext_ver) end else - raise ArgumentError, "Single argument must be an ExtensionVersion or ExtensionRquirement" + raise ArgumentError, "Single argument must be an ExtensionVersion or ExtensionRequirement" end elsif args.size == 2 raise ArgumentError, "First parameter must be an extension name" unless args[0].respond_to?(:to_s) raise ArgumentError, "First parameter must be an extension version" unless args[1].respond_to?(:to_s) - args[0] == @name && - @requirement.satisfied_by?(Gem::Version.new(args[1])) + (args[0] == @name) && @requirement.satisfied_by?(Gem::Version.new(args[1])) else raise ArgumentError, "Wrong number of args (expecting 1 or 2)" end @@ -674,4 +694,4 @@ def <=>(other) @name <=> other.name end -end +end \ No newline at end of file diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index 7a2ad3a8b..701c57f4d 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -82,6 +82,7 @@ def extension_presence(ext_name) # @param ext_name [String] # @param ext_versions [Array] # @return [Array] + # JamesBall def version_greatest_presence(ext_name, ext_versions) presences = [] @@ -132,26 +133,41 @@ def in_scope_ext_reqs(desired_presence = nil) desired_presence.is_a?(ExtensionPresence) ? desired_presence : ExtensionPresence.new(desired_presence) + missing_ext = false + @data["extensions"]&.each do |ext_name, ext_data| actual_presence = ext_data["presence"] # Could be a String or Hash raise "Missing extension presence for extension #{ext_name}" if actual_presence.nil? - # Convert String or Hash to object. + # Convert presence String or Hash to object. actual_presence_obj = ExtensionPresence.new(actual_presence) - match = - if desired_presence.nil? - true # Always match + if desired_presence.nil? || (actual_presence_obj == desired_presence_converted) + version_data = ext_data["version"] + + ext_req = + ExtensionRequirement.new(ext_name, version_data, presence: actual_presence_obj, + note: ext_data["note"], req_id: "REQ-EXT-" + ext_name) + + # Does extension even exist? + # If not, don't raise an error right away so we can find all of the missing extensions and report them all. + ext = arch_def.extension(ext_name) + if ext.nil? + puts "Extension #{ext_name} for #{name} not found in database" + missing_ext = true else - actual_presence_obj == desired_presence_converted + # Okay, so extension exists. Can the extension requirement be met? + raise "No version of extension #{ext_name} in #{name} satifies the extension requirement #{version_data}" unless ext_req.satisfied_by_ext?(ext) end - if match - in_scope_ext_reqs << - ExtensionRequirement.new(ext_name, ext_data["version"], presence: actual_presence_obj, - note: ext_data["note"], req_id: "REQ-EXT-" + ext_name) + in_scope_ext_reqs << ext_req end end + + # TODO: Change to "raise" when missing extensions added to database so we can make progress until then. + # See https://github.com/riscv-software-src/riscv-unified-db/issues/320 + puts "One or more extensions referenced by #{name} missing in database" if missing_ext + in_scope_ext_reqs end @@ -163,15 +179,9 @@ def optional_type_ext_reqs = in_scope_ext_reqs(ExtensionPresence.optional) def in_scope_extensions return @in_scope_extensions unless @in_scope_extensions.nil? - @in_scope_extensions = in_scope_ext_reqs.map do |er| - obj = arch_def.extension(er.name) - - # @todo: change this to raise once all the profile extensions - # are defined - warn "Extension #{er.name} is not defined" if obj.nil? - - obj - end.reject(&:nil?) + @in_scope_extensions = in_scope_ext_reqs.map do |ext_req| + arch_def.extension(ext_req.name) + end.reject(&:nil?) # Filter out extensions that don't exist yet. @in_scope_extensions end diff --git a/lib/arch_obj_models/schema.rb b/lib/arch_obj_models/schema.rb index c5cbbc998..758c3251a 100644 --- a/lib/arch_obj_models/schema.rb +++ b/lib/arch_obj_models/schema.rb @@ -107,7 +107,7 @@ def to_pretty_s(schema_hash = @schema_hash) raise "to_pretty_s unknown type #{schema_hash["type"]} in #{schema_hash}" end else - raise "TODO: to_pretty_s schema for #{schema_hash}" + raise "Unsupported schema for #{schema_hash}" end end From c59841dc49fdd33ade4d5302cd1784df7fe4d36e Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 4 Dec 2024 10:21:06 -0800 Subject: [PATCH 04/10] Back out code to attempt to ensure required extension versions are in the DB. --- arch/csr/menvcfg.yaml | 3 ++- arch/csr/senvcfg.yaml | 7 ++++--- arch/ext/S.yaml | 8 +++++++- arch/ext/Sm.yaml | 1 + lib/arch_obj_models/extension.rb | 8 -------- lib/arch_obj_models/portfolio.rb | 26 +++++++++----------------- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/arch/csr/menvcfg.yaml b/arch/csr/menvcfg.yaml index 31b2d7e99..e1732fe2a 100644 --- a/arch/csr/menvcfg.yaml +++ b/arch/csr/menvcfg.yaml @@ -6,7 +6,8 @@ name: menvcfg address: 0x30A long_name: Machine Environment Configuration description: | - Contains bits to enable/disable extensions + Contains fields that control certain characteristics of the execution environment + for modes less privileged than M-mode. The `menvcfg` CSR controls certain characteristics of the execution environment for modes less diff --git a/arch/csr/senvcfg.yaml b/arch/csr/senvcfg.yaml index e804e5aae..025095bbb 100644 --- a/arch/csr/senvcfg.yaml +++ b/arch/csr/senvcfg.yaml @@ -5,14 +5,15 @@ kind: csr name: senvcfg address: 0x10A long_name: Supervisor Environment Configuration -description: Contains bits to enable/disable extensions +description: | + Contains fields that control certain characteristics of the U-mode execution environment. priv_mode: S length: 64 definedBy: allOf: - - name: Sm - version: ">=1.12" - name: S + version: ">=1.12" + - name: U fields: CBZE: location: 7 diff --git a/arch/ext/S.yaml b/arch/ext/S.yaml index 34e33bc92..1b6a3ec96 100644 --- a/arch/ext/S.yaml +++ b/arch/ext/S.yaml @@ -6,12 +6,18 @@ name: S type: privileged long_name: Supervisor mode versions: +- version: "1.11.0" + state: ratified + ratification_date: 2019-06 + requires: + name: U + version: ">= 1.0.0" - version: "1.12.0" state: ratified ratification_date: 2021-12 requires: name: U - version: "= 1.12.0" + version: ">= 1.0.0" description: | This chapter describes the RISC-V supervisor-level architecture, which contains a common core that is used with various supervisor-level diff --git a/arch/ext/Sm.yaml b/arch/ext/Sm.yaml index 47b5a40a6..1686c9922 100644 --- a/arch/ext/Sm.yaml +++ b/arch/ext/Sm.yaml @@ -460,6 +460,7 @@ params: schema: type: string enum: [little, big, dynamic] + # TODO: Only little available in Sm 1.11 MISA_CSR_IMPLEMENTED: description: | Whether or not the `misa` CSR returns zero or a non-zero value. diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 8f652766a..443480360 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -637,14 +637,6 @@ def satisfying_versions(archdef) ext.versions.select { |v| @requirement.satisfied_by?(v.version) } end - # @return [Boolean] True if any extension version satifies this requirement - # @param [Extension] The extension object that contains one or more versions - def satisfied_by_ext?(ext) - return false if ext.nil? - - ext.versions.any? { |v| @requirement.satisfied_by?(v.version) } - end - # @overload # @param extension_version [ExtensionVersion] A specific extension version # @return [Boolean] whether or not the extension_version meets this requirement diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index 701c57f4d..002d3dd94 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -136,6 +136,14 @@ def in_scope_ext_reqs(desired_presence = nil) missing_ext = false @data["extensions"]&.each do |ext_name, ext_data| + # Does extension even exist? + # If not, don't raise an error right away so we can find all of the missing extensions and report them all. + ext = arch_def.extension(ext_name) + if ext.nil? + puts "Extension #{ext_name} for #{name} not found in database" + missing_ext = true + end + actual_presence = ext_data["presence"] # Could be a String or Hash raise "Missing extension presence for extension #{ext_name}" if actual_presence.nil? @@ -143,24 +151,8 @@ def in_scope_ext_reqs(desired_presence = nil) actual_presence_obj = ExtensionPresence.new(actual_presence) if desired_presence.nil? || (actual_presence_obj == desired_presence_converted) - version_data = ext_data["version"] - - ext_req = - ExtensionRequirement.new(ext_name, version_data, presence: actual_presence_obj, + in_scope_ext_reqs << ExtensionRequirement.new(ext_name, ext_data["version"], presence: actual_presence_obj, note: ext_data["note"], req_id: "REQ-EXT-" + ext_name) - - # Does extension even exist? - # If not, don't raise an error right away so we can find all of the missing extensions and report them all. - ext = arch_def.extension(ext_name) - if ext.nil? - puts "Extension #{ext_name} for #{name} not found in database" - missing_ext = true - else - # Okay, so extension exists. Can the extension requirement be met? - raise "No version of extension #{ext_name} in #{name} satifies the extension requirement #{version_data}" unless ext_req.satisfied_by_ext?(ext) - end - - in_scope_ext_reqs << ext_req end end From b1ff611631f5cbdd2485e9bf8f102b0d24ca7e1e Mon Sep 17 00:00:00 2001 From: James Ball Date: Tue, 17 Dec 2024 18:09:47 -0800 Subject: [PATCH 05/10] Merging after Derek's big patch merge into main --- arch/ext/Sv32.yaml | 2 +- arch/ext/Sv39.yaml | 2 +- arch/ext/Sv48.yaml | 2 +- arch/ext/Sv57.yaml | 2 +- arch/ext/Zihpm.yaml | 2 +- arch/profile/MP-S-64.yaml | 3 +++ arch/profile/RVA20S64.yaml | 7 +++++++ 7 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/ext/Sv32.yaml b/arch/ext/Sv32.yaml index e638dc938..6ac42cabe 100644 --- a/arch/ext/Sv32.yaml +++ b/arch/ext/Sv32.yaml @@ -9,5 +9,5 @@ type: privileged versions: - version: "1.12.0" state: ratified - ratification_date: unknown + ratification_date: null url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf diff --git a/arch/ext/Sv39.yaml b/arch/ext/Sv39.yaml index bd54871df..646c0380e 100644 --- a/arch/ext/Sv39.yaml +++ b/arch/ext/Sv39.yaml @@ -9,5 +9,5 @@ type: privileged versions: - version: "1.12.0" state: ratified - ratification_date: unknown + ratification_date: null url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf diff --git a/arch/ext/Sv48.yaml b/arch/ext/Sv48.yaml index 40b6416f6..ef7f970e5 100644 --- a/arch/ext/Sv48.yaml +++ b/arch/ext/Sv48.yaml @@ -9,7 +9,7 @@ type: privileged versions: - version: "1.12.0" state: ratified - ratification_date: unknown + ratification_date: null url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf requires: name: Sv39 diff --git a/arch/ext/Sv57.yaml b/arch/ext/Sv57.yaml index 62f1d82a1..18bdd3d15 100644 --- a/arch/ext/Sv57.yaml +++ b/arch/ext/Sv57.yaml @@ -9,7 +9,7 @@ type: privileged versions: - version: "1.12.0" state: ratified - ratification_date: unknown + ratification_date: null url: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf requires: name: Sv48 diff --git a/arch/ext/Zihpm.yaml b/arch/ext/Zihpm.yaml index c5922e781..f5f798b9d 100644 --- a/arch/ext/Zihpm.yaml +++ b/arch/ext/Zihpm.yaml @@ -9,6 +9,6 @@ type: unprivileged versions: - version: "2.0.0" state: ratified - ratification_date: unknown + ratification_date: null requires: name: Smhpm diff --git a/arch/profile/MP-S-64.yaml b/arch/profile/MP-S-64.yaml index cd34a233c..3b21e5f29 100644 --- a/arch/profile/MP-S-64.yaml +++ b/arch/profile/MP-S-64.yaml @@ -36,6 +36,9 @@ extensions: optional: transitory version: "= 1.11" note: Made this a transitory option + MockExt: + presence: mandatory + version: "~> 0.9.9" extra_notes: - presence: mandatory text: | diff --git a/arch/profile/RVA20S64.yaml b/arch/profile/RVA20S64.yaml index 7af25aa36..939b820f0 100644 --- a/arch/profile/RVA20S64.yaml +++ b/arch/profile/RVA20S64.yaml @@ -11,6 +11,13 @@ introduction: | processors. RVA20S64 is based on privileged architecture version 1.11. extensions: $inherits: "profile/RVI20U64.yaml#/extensions" + U: + presence: mandatory + version: "~> 1.0" + param_constraints: + U_MODE_ENDIANESS: + schema: + const: little`` S: presence: mandatory version: "= 1.11" From bc97374582ac8498e9992779c07ca9c59f6e13c1 Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 18 Dec 2024 11:57:56 -0800 Subject: [PATCH 06/10] Fixes to portfolio after merge of big ugly patch and "do" file bugs when running in a container or avoiding using a container for clean. --- do | 14 ++++++-------- lib/arch_obj_models/portfolio.rb | 10 +++++----- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/do b/do index 57ae6f102..92ed0e671 100755 --- a/do +++ b/do @@ -1,15 +1,13 @@ #!/bin/bash ROOT=$(dirname $(realpath $BASH_SOURCE[0])) -if [ -v DEVCONTAINER_ENV ]; then - BUNDLE=bundle -else - source $ROOT/bin/setup -fi if [ "$1" == "clean" ]; then ${ROOT}/bin/clean -else - # really long way of invoking rake, but renamed to 'do' - $BUNDLE exec --gemfile $ROOT/Gemfile ruby -r rake -e "Rake.application.init('do');Rake.application.load_rakefile;Rake.application.top_level" -- $@ + exit $? fi + +source $ROOT/bin/setup + +# really long way of invoking rake, but renamed to 'do' +$BUNDLE exec --gemfile $ROOT/Gemfile ruby -r rake -e "Rake.application.init('do');Rake.application.load_rakefile;Rake.application.top_level" -- $@ diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index 1b9ca4aaf..3e1d1442a 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -79,10 +79,10 @@ def version_greatest_presence(ext_name, ext_versions) greatest_presence = nil in_scope_ext_reqs.each do |ext_req| - if ext_req.satisfied_by?(ext_name, v.version) + if ext_req.satisfied_by?(v) presence = extension_presence_obj(ext_name) - unless presence.nil? + unless presence.nil? if greatest_presence.nil? greatest_presence = presence elsif presence > greatest_presence @@ -127,11 +127,11 @@ def in_scope_ext_reqs(desired_presence = nil) @data["extensions"]&.each do |ext_name, ext_data| next if ext_name[0] == "$" - # Does extension even exist? + # Does extension even exist? # If not, don't raise an error right away so we can find all of the missing extensions and report them all. - ext = arch_def.extension(ext_name) + ext = cfg_arch.extension(ext_name) if ext.nil? - puts "Extension #{ext_name} for #{name} not found in database" + puts "Extension #{ext_name} for #{name} not found in database" missing_ext = true end From 442cfeca3ee0cf0bbec707c5249a542ef583d63e Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 18 Dec 2024 12:34:48 -0800 Subject: [PATCH 07/10] Manually fixing linter failures --- arch/csr/menvcfg.yaml | 2 +- lib/arch_obj_models/extension.rb | 12 ++++++------ lib/arch_obj_models/profile.rb | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/csr/menvcfg.yaml b/arch/csr/menvcfg.yaml index ae41ca1a2..8feafff95 100644 --- a/arch/csr/menvcfg.yaml +++ b/arch/csr/menvcfg.yaml @@ -6,7 +6,7 @@ name: menvcfg address: 0x30A long_name: Machine Environment Configuration description: | - Contains fields that control certain characteristics of the execution environment + Contains fields that control certain characteristics of the execution environment for modes less privileged than M-mode. The `menvcfg` CSR controls diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 742a08ad6..358bfea08 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -558,7 +558,7 @@ def initialize(data) end end - def mandatory? = (@presence == "mandatory") + def mandatory? = (@presence == "mandatory") def optional? = (@presence == "optional") # Class methods @@ -648,7 +648,7 @@ def <=>(other) # @overload >(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is greater-than the other - def >(other) + def >(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) (self.mandatory? && other.optional?) end @@ -659,12 +659,12 @@ def >(other) def >=(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) (self > other) || (self == other) - end + end # @overload <(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is less-than the other - def <(other) + def <(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) (self.optional? && other.mandatory?) end @@ -672,7 +672,7 @@ def <(other) # @overload <=(other) # @param other [ExtensionPresence] An extension presence object # @return [Boolean] Whether or not this ExtensionPresence is less-than or equal to the other - def <=(other) + def <=(other) raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) (self < other) || (self == other) end @@ -795,4 +795,4 @@ def <=>(other) @name <=> other.name end -end \ No newline at end of file +end diff --git a/lib/arch_obj_models/profile.rb b/lib/arch_obj_models/profile.rb index 2ad406e06..9a6ed4652 100644 --- a/lib/arch_obj_models/profile.rb +++ b/lib/arch_obj_models/profile.rb @@ -121,7 +121,7 @@ def extension_presence(ext_name) profiles.each do |profile| presence = profile.extension_presence_obj(ext_name) - unless presence.nil? + unless presence.nil? if greatest_presence.nil? greatest_presence = presence elsif presence > greatest_presence From a1a2195e56994db8e886a84432a7ebb88a48435f Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 18 Dec 2024 17:32:34 -0800 Subject: [PATCH 08/10] Looks like MockExt was renamed to XMockExt. --- arch/profile/MP-S-64.yaml | 2 +- backends/certificate_doc/tasks.rake | 1 - .../certificate_doc/templates/certificate.adoc.erb | 14 ++------------ cfgs/generic_rv64/cfg.yaml | 2 +- lib/arch_obj_models/extension.rb | 10 +++++----- lib/arch_obj_models/portfolio.rb | 11 ++++++++++- lib/idl/tests/helpers.rb | 10 +++++----- 7 files changed, 24 insertions(+), 26 deletions(-) diff --git a/arch/profile/MP-S-64.yaml b/arch/profile/MP-S-64.yaml index 3b21e5f29..de2718e08 100644 --- a/arch/profile/MP-S-64.yaml +++ b/arch/profile/MP-S-64.yaml @@ -36,7 +36,7 @@ extensions: optional: transitory version: "= 1.11" note: Made this a transitory option - MockExt: + Xmock: presence: mandatory version: "~> 0.9.9" extra_notes: diff --git a/backends/certificate_doc/tasks.rake b/backends/certificate_doc/tasks.rake index 3972b31f3..98da6684f 100644 --- a/backends/certificate_doc/tasks.rake +++ b/backends/certificate_doc/tasks.rake @@ -29,7 +29,6 @@ Dir.glob("#{$root}/arch/certificate_model/*.yaml") do |f| cert_model = cfg_arch.cert_model(cert_model_name) raise "No certificate model defined for #{cert_model_name}" if cert_model.nil? - # Switch to the generated certificate arch def # XXX - Add this to profile releases cfg_arch = cert_model.to_cfg_arch cert_model = cfg_arch.cert_model(cert_model_name) diff --git a/backends/certificate_doc/templates/certificate.adoc.erb b/backends/certificate_doc/templates/certificate.adoc.erb index 41e9fb32f..b37cf7f18 100644 --- a/backends/certificate_doc/templates/certificate.adoc.erb +++ b/backends/certificate_doc/templates/certificate.adoc.erb @@ -201,16 +201,11 @@ None == Instruction Summary -<% - insts = cert_model.in_scope_extensions.map { |ext_cert_model| ext_cert_model.instructions }.flatten.uniq - insts.sort_by!(&:name) --%> - [%autowidth] |=== | Name | Long Name -<% insts.each do |inst| -%> +<% portfolio.in_scope_instructions.each do |inst| -%> | <%= link_to_inst(inst.name) %> | <%= inst.long_name %> <% end # do -%> @@ -387,12 +382,7 @@ The following instructions are added by this extension: [appendix] == Instruction Details -<%= - insts = cert_model.in_scope_extensions.map { |ext_cert_model| ext_cert_model.instructions }.flatten.uniq - insts.sort_by!(&:name) --%> - -<% insts.each do |inst| -%> +<% portfolio.in_scope_instructions.each do |inst| -%> <<< <%= anchor_for_inst(inst.name) %> === <%= inst.name %> diff --git a/cfgs/generic_rv64/cfg.yaml b/cfgs/generic_rv64/cfg.yaml index c15ff4800..7577c8bd3 100644 --- a/cfgs/generic_rv64/cfg.yaml +++ b/cfgs/generic_rv64/cfg.yaml @@ -16,7 +16,7 @@ implemented_extensions: - [Sm, "1.12.0"] - [Smhpm, "1.12.0"] - [Smpmp, "1.12.0"] - - [U, "1.12.0"] + - [U, "1.0.0"] - [V, "1.0.0"] - [Zicntr, "2.0.0"] - [Zicsr, "2.0.0"] diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index 358bfea08..ad0dd85cb 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -6,7 +6,7 @@ # A parameter (AKA option, AKA implementation-defined value) supported by an extension class ExtensionParameter - # @return [ConfiguredArchitecture] The defining Arch def + # @return [ConfiguredArchitecture] The defining configured architecture attr_reader :cfg_arch # @return [String] Parameter name @@ -293,14 +293,14 @@ def initialize(name, version_str, cfg_arch, fail_if_version_does_not_exist: fals @cfg_arch = cfg_arch @ext = @cfg_arch.extension(@name) - raise "Extension #{name} not found in arch def" if @ext.nil? + raise "Extension #{name} not found in configured architecture #{cfg_arch.name}" if @ext.nil? @data = @ext.data["versions"].find { |v| VersionSpec.new(v["version"]) == @version_spec } if fail_if_version_does_not_exist && @data.nil? - raise ArgumentError, "#{@name}, Version #{version_str} is not defined" + raise ArgumentError, "Version #{version_str} of #{@name} extension in #{cfg_arch.name} is not defined" elsif @data.nil? - warn "#{@name}, Version #{version_str} is not defined" + warn "Version #{version_str} of #{@name} extension in #{cfg_arch.name} is not defined" end end @@ -718,7 +718,7 @@ def initialize(name, *requirements, cfg_arch: nil, note: nil, req_id: nil, prese @cfg_arch = cfg_arch @ext = @cfg_arch.extension(@name) - raise ArgumentError, "Could not find extension named '#{@name}'" if @ext.nil? + raise ArgumentError, "Could not find extension named '#{@name}' in #{@cfg_arch.name}" if @ext.nil? requirements = if requirements.empty? diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index 3e1d1442a..10fc7fcec 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -70,7 +70,6 @@ def extension_presence(ext_name) # @param ext_name [String] # @param ext_versions [Array] # @return [Array] - # JamesBall def version_greatest_presence(ext_name, ext_versions) presences = [] @@ -184,6 +183,13 @@ def in_scope_extensions @in_scope_extensions end + # @return [Array] Sorted list of all instructions associated with extensions listed as + # mandatory or optional in portfolio. Uses minimum version of + # extension version that meets extension requirement specified in portfolio. + def in_scope_instructions + in_scope_ext_reqs.map { |ext_req| ext_req.implemented_instructions }.flatten.uniq.sort + end + # @return [Boolean] Does the profile differentiate between different types of optional. def uses_optional_types? return @uses_optional_types unless @uses_optional_types.nil? @@ -201,6 +207,9 @@ def uses_optional_types? @uses_optional_types end + # Called by rakefile when generating a particular portfolio instance. + # Creates an in-memory data structure used by all portfolio routines that access a cfg_arch. + # # @return [ConfiguredArchitecture] A partially-configured architecture definition corresponding to this portfolio. def to_cfg_arch return @generated_cfg_arch unless @generated_cfg_arch.nil? diff --git a/lib/idl/tests/helpers.rb b/lib/idl/tests/helpers.rb index 3b3132d5d..2d694e5b3 100644 --- a/lib/idl/tests/helpers.rb +++ b/lib/idl/tests/helpers.rb @@ -3,23 +3,23 @@ require "ostruct" # Extension mock that returns an extension name -class MockExtension +class Xmockension attr_reader :name def initialize(name) @name = name end end -MockExtensionParameter = Struct.new(:name, :desc, :schema, :extra_validation, :exts, :type) -MockExtensionParameterWithValue = Struct.new(:name, :desc, :schema, :extra_validation, :exts, :value) +XmockensionParameter = Struct.new(:name, :desc, :schema, :extra_validation, :exts, :type) +XmockensionParameterWithValue = Struct.new(:name, :desc, :schema, :extra_validation, :exts, :value) # ConfiguredArchitecture mock that knows about XLEN and extensions class MockConfiguredArchitecture def param_values = { "XLEN" => 32 } - def params_with_value = [MockExtensionParameterWithValue.new("XLEN", "mxlen", {"type" => "integer", "enum" => [32, 64]}, nil, nil, 32)] + def params_with_value = [XmockensionParameterWithValue.new("XLEN", "mxlen", {"type" => "integer", "enum" => [32, 64]}, nil, nil, 32)] def params_without_value = [] def params = [] - def extensions = [MockExtension.new("I")] + def extensions = [Xmockension.new("I")] def mxlen = 64 def exception_codes = [OpenStruct.new(var: "ACode", num: 0), OpenStruct.new(var: "BCode", num: 1)] def interrupt_codes = [OpenStruct.new(var: "CoolInterrupt", num: 1)] From 3b848261b2bb9b5e2fec8b4b752539ef77586a80 Mon Sep 17 00:00:00 2001 From: James Ball Date: Wed, 18 Dec 2024 18:20:22 -0800 Subject: [PATCH 09/10] Merge fixes --- backends/certificate_doc/tasks.rake | 12 ++++++++---- backends/profile_doc/tasks.rake | 4 +++- lib/arch_obj_models/portfolio.rb | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/backends/certificate_doc/tasks.rake b/backends/certificate_doc/tasks.rake index 98da6684f..df4c6562c 100644 --- a/backends/certificate_doc/tasks.rake +++ b/backends/certificate_doc/tasks.rake @@ -25,14 +25,18 @@ Dir.glob("#{$root}/arch/certificate_model/*.yaml") do |f| __FILE__ ] do |t| # TODO: schema validation - cfg_arch = cfg_arch_for("rv#{base}") - cert_model = cfg_arch.cert_model(cert_model_name) - raise "No certificate model defined for #{cert_model_name}" if cert_model.nil? + base_cert_model = cfg_arch_for("rv#{base}").cert_model(cert_model_name) + raise "No certificate model named '#{cert_model_name}'" if base_cert_model.nil? + # Ask base certification model to create an in-memory config arch for this model. # XXX - Add this to profile releases - cfg_arch = cert_model.to_cfg_arch + cfg_arch = base_cert_model.to_cfg_arch + + # Set globals for ERB template. cert_model = cfg_arch.cert_model(cert_model_name) cert_class = cert_model.cert_class + portfolio = cert_model + portfolio_class = cert_class version = File.basename(t.name, '.adoc').split('-')[1..].join('-') diff --git a/backends/profile_doc/tasks.rake b/backends/profile_doc/tasks.rake index 8b68ba048..26f1fb869 100644 --- a/backends/profile_doc/tasks.rake +++ b/backends/profile_doc/tasks.rake @@ -7,11 +7,13 @@ rule %r{#{$root}/gen/profile_doc/adoc/.*\.adoc} => [ Dir.glob("#{$root}/arch/profile_release/**/*.yaml") ].flatten do |t| profile_release_name = Pathname.new(t.name).basename(".adoc").to_s - profile_release = cfg_arch_for("_").profile_release(profile_release_name) raise ArgumentError, "No profile release named '#{profile_release_name}'" if profile_release.nil? + # Set globals for ERB template. profile_class = profile_release.profile_class + portfolio_class = profile_class + portfolio = profile_release template_path = Pathname.new "#{$root}/backends/profile_doc/templates/profile.adoc.erb" erb = ERB.new(template_path.read, trim_mode: "-") diff --git a/lib/arch_obj_models/portfolio.rb b/lib/arch_obj_models/portfolio.rb index 10fc7fcec..2ee8f2169 100644 --- a/lib/arch_obj_models/portfolio.rb +++ b/lib/arch_obj_models/portfolio.rb @@ -187,7 +187,7 @@ def in_scope_extensions # mandatory or optional in portfolio. Uses minimum version of # extension version that meets extension requirement specified in portfolio. def in_scope_instructions - in_scope_ext_reqs.map { |ext_req| ext_req.implemented_instructions }.flatten.uniq.sort + in_scope_extensions.map { |ext| ext.instructions }.flatten.uniq.sort end # @return [Boolean] Does the profile differentiate between different types of optional. From afcc7f8e5c01d908dc49e402ffa2d58d7f614f49 Mon Sep 17 00:00:00 2001 From: James Ball Date: Thu, 19 Dec 2024 07:50:50 -0800 Subject: [PATCH 10/10] Removed <=> operator on ExtensionPresence. Doesn't seem to be needed anyways (looked at code to see if using it and looked at output artifacts). --- lib/arch_obj_models/extension.rb | 19 +++++-------------- lib/arch_obj_models/profile.rb | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/lib/arch_obj_models/extension.rb b/lib/arch_obj_models/extension.rb index ad0dd85cb..d1f97c6b8 100644 --- a/lib/arch_obj_models/extension.rb +++ b/lib/arch_obj_models/extension.rb @@ -625,19 +625,6 @@ def ==(other) end end - # @overload <=>(other) - # @param other [String] A presence string - # @return [Integer] Sort alphabetically by presence, then alphabetically by optional_type - def <=>(other) - raise ArgumentError, "ExtensionPresence is only comparable to other ExtensionPresence classes" unless other.is_a?(ExtensionPresence) - - if @presence != other.presence - @presence <=> other.presence - else - @optional_type <=> other.optional_type - end - end - ###################################################### # Following comparison operators follow these rules: # - "mandatory" is greater than "optional" @@ -695,8 +682,12 @@ class ExtensionRequirement # @return [Array] Set of requirement specifications def requirement_specs = @requirements + def requirement_specs_to_s + "#{@requirements.map(&:to_s).join(', ')}" + end + def to_s - "#{name} #{@requirements.map(&:to_s).join(', ')}" + "#{name} " + requirement_specs_to_s end # @return [Extension] The extension that this requirement is for diff --git a/lib/arch_obj_models/profile.rb b/lib/arch_obj_models/profile.rb index 9a6ed4652..4e7e4910e 100644 --- a/lib/arch_obj_models/profile.rb +++ b/lib/arch_obj_models/profile.rb @@ -225,7 +225,7 @@ def ext_req_to_adoc(ext_req) ext = cfg_arch.extension(ext_req.name) ret << "* *#{ext_req.name}* " + (ext.nil? ? "" : ext.long_name) ret << "+" - ret << "Version #{ext_req.requirement_specs}" + ret << "Version #{ext_req.requirement_specs_to_s}" ret end