Skip to content

Commit

Permalink
Change ext_pdf generator to be optionally version-specific
Browse files Browse the repository at this point in the history
  • Loading branch information
dhower-qc committed Nov 21, 2024
1 parent 21882db commit 154904f
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 70 deletions.
2 changes: 1 addition & 1 deletion backends/crd_doc/templates/crd.adoc.erb
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ Requirement <%= req.name %> only apply when <%= req.when_pretty %>.
<% end -%>
// TODO: GitHub issue 92: Use version specified by each profile.
<% insts = arch_def.instructions.select { |i| i.defined_by?(ext_db.name,ext_db.min_version) } -%>
<% insts = arch_def.instructions.select { |i| i.defined_by?(ext_db.min_version) } -%>
<% unless insts.empty? -%>
==== Instructions
Expand Down
52 changes: 34 additions & 18 deletions backends/ext_pdf_doc/tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,18 @@ rule %r{#{$root}/gen/ext_pdf_doc/.*/adoc/.*_extension\.adoc} => proc { |tname|
erb.filename = template_path.to_s

ext = arch_def.extension(ext_name)
version_num =
if ENV.key?("EXT_VERSION")
ENV["EXT_VERSION"]
version_strs = ENV["VERSION"].split(",")
versions =
if version_strs.include?("all")
ext.versions
else
ext.versions.max { |a, b| a.version <=> b.version }.version
vs = ext.versions.select do |ext_ver|
version_strs.include?(ext_ver.version.to_s)
end
vs << ext.max_version if version_strs.include?("latest")
vs.uniq
end
ext_version = ext.versions.find { |v| v.version == version_num }
max_version = versions.max { |a, b| a.version <=> b.version }
FileUtils.mkdir_p File.dirname(t.name)
File.write t.name, AsciidocUtils.resolve_links(arch_def.find_replace_links(erb.result(binding)))
end
Expand All @@ -161,25 +166,36 @@ namespace :gen do
Generate PDF documentation for :extension
If the extension is custom (from an arch_overlay), also give the config name
DESC
task :ext_pdf, [:extension] do |_t, args|
extension = args[:extension]
Rake::Task[$root / "gen" / "ext_pdf_doc" / "_" / "pdf" / "#{extension}_extension.pdf"].invoke
end
Options:
desc <<~DESC
Generate PDF documentation for :extension that is defined or overlayed in :cfg
* EXT - The extension name
* CFG - The config name, required only when an overlay is required
* VERSION - A list of versions to include. May also be "all" or "latest".
Examples:
./do gen:ext_pdf EXT=Xqci CFG=qc_iu VERSION=latest
./do gen:ext_pdf EXT=B VERSION=all
./do gen:ext_pdf EXT=B VERSION=1.0.0
./do gen:ext_pdf EXT=B VERSION=1.0.0,1.1.0
The latest version will be used, but can be overloaded by setting the EXT_VERSION environment variable.
DESC
task :cfg_ext_pdf, [:extension, :cfg] do |_t, args|
raise ArgumentError, "Missing required argument :extension" if args[:extension].nil?
raise ArgumentError, "Missing required argument :cfg" if args[:cfg].nil?
task :ext_pdf, [:extension] do |_t, args|
raise ArgumentError, "Missing required argument EXT" if ENV["EXT"].nil?

extension = args[:extension]
extension = ENV["EXT"]
cfg = ENV["CFG"]
version = ENV["VERSION"]

versions = version.split(",")
raise ArgumentError, "Nothing else should be specified with 'all'" if versions.include?("all") && versions.size > 1

Rake::Task[$root / "gen" / "ext_pdf_doc" / args[:cfg] / "pdf" / "#{extension}_extension.pdf"].invoke(args)
if cfg.nil?
Rake::Task[$root / "gen" / "ext_pdf_doc" / "_" / "pdf" / "#{extension}_extension.pdf"].invoke
else
Rake::Task[$root / "gen" / "ext_pdf_doc" / cfg / "pdf" / "#{extension}_extension.pdf"].invoke(args)
end
end

desc <<~DESC
Expand Down
61 changes: 40 additions & 21 deletions backends/ext_pdf_doc/templates/ext_pdf.adoc.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[[header]]
:description: <%= ext.long_name %> (<%= ext.name %>)
:revdate: <%= ext_version.ratification_date.nil? ? Date.today : ext_version.ratification_date %>
:revnumber: <%= ext_version.version %>
:revdate: <%= max_version.ratification_date.nil? ? Date.today : max_version.ratification_date %>
:revnumber: <%= max_version.version %>
:revmark: <%=
case ext_version.state
case max_version.state
when "ratified"
<<~STATE
This document is in the http://riscv.org/spec-state[Ratified state] + \\
Expand All @@ -28,7 +28,7 @@
Change should be expected + \\
DEV_STATE
else
raise "TODO: #{ext_version.state} description"
raise "TODO: #{max_version.state} description"
end
%>
:company: <%= ext.company.nil? ? "unknown" : ext.company["name"] %>
Expand All @@ -41,7 +41,7 @@
:title-logo-image: image:risc-v_logo.png["RISC-V International Logo",pdfwidth=3.25in,align=center]
:back-cover-image: image:riscv-horizontal-color.svg[opacity=25%]
<%- end -%>
<%- if ext_version.state == "development" -%>
<%- if max_version.state == "development" -%>
:page-background-image: image:draft.png[opacity=20%]
<%- end -%>
// Settings
Expand Down Expand Up @@ -85,7 +85,7 @@ endif::[]

// Preamble
<%=
case ext_version.state
case max_version.state
when "ratified"
<<~RATIFIED_STATE
[WARNING]
Expand Down Expand Up @@ -115,20 +115,20 @@ endif::[]
====
DEV_STATE
else
raise "TODO: #{ext_version.state} description"
raise "TODO: #{max_version.state} description"
end
%>

[preface]
== Copyright and license information
This document is released under the <%= ext.doc_license.nil? ? "unknown" : ext.doc_license["url"] %>[<%= ext.doc_license.nil? ? "unknown" : ext.doc_license["name"] %>].

Copyright <%= ext_version.ratification_date.nil? ? Date.today.year : ext_version.ratification_date.split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.
Copyright <%= max_version.ratification_date.nil? ? Date.today.year : max_version.ratification_date.split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.

[preface]
== Acknowledgements

<%- ext.versions.each do |version| -%>
<%- versions.each do |version| -%>
Contributors to version <%= version.version %> of the specification (in alphabetical order) include: +

<%- unless version.contributors.empty? -%>
Expand All @@ -145,7 +145,13 @@ improved this specification through their comments and questions.
[preface]
== Versions

The following versions have been defined:
<%- if versions.size > 1 -%>
This specification documents versions <%= versions.map { |v| v.version }.join(', ') %> of <%= ext.name %>:
<%- else -%>
This specification documents version <%= max_version.version %> of <%= ext.name %>.
<%- end -%>

=== Version History

<%- ext.versions.each do |version| -%>
--
Expand Down Expand Up @@ -182,22 +188,31 @@ Requires::

<%= ext.description %>

<%- unless ext.implies.nil? -%>
<%- implications = versions.map { |v| v.implications }.flatten.uniq -%>
<%- unless implications.nil? -%>
=== Sub-extensions
<%- if ext.implies.size > 1 -%>
<%= ext.name %> defines the following #{ext.implies.size} sub-extensions:
<%- if implications.size > 1 -%>
<%= ext.name %> defines the following #{implications.size} sub-extensions:
<%- else -%>
<%= ext.name %> defines a single sub-extension:
<%- end -%>

<%- ext.implies.each do |sub_ext| -%>
==== <%= sub_ext.name %>
<%- implications.each do |sub_ext| -%>
==== <%= sub_ext.name %> (<%= sub_ext.version %>)

<%- if versions.size > 1 -%>
<%= sub_ext.name %> (<%= sub_ext.version %>) is implied by
version <%= versions.select { |v| v.implications.include?(sub_ext)}.map(&:version).join(", ") %>
of <%= ext.name %>.
<%- end -%>

<%= arch_def.extension(sub_ext.name).description %>

<%- unless sub_ext.requirements.empty? -%>
<%= sub_ext.name %> requires:

<%= sub_ext.requirements.to_asciidoc %>

<%- end -%>

<%- end -%>
Expand All @@ -211,27 +226,29 @@ The following <%= ext.instructions.size %> instructions are added by this extens

[%autowidth]
|===
| RV32 | RV64 | Mnemonic | Instruction | <%= ext.versions.map { |v| "v#{v.version}" }.join(" | ") %>
| RV32 | RV64 | Mnemonic | Instruction <%- if versions.size > 1 -%>| <%= versions.map { |v| "v#{v.version}" }.join(" | ") %><%- end -%>

<%- ext.instructions.each do |i| -%>
| <%= i.rv32? ? "&#x2713;" : "" %>
| <%= i.rv64? ? "&#x2713;" : "" %>
| `<%= i.name %> <%= i.assembly.gsub("x", "r").strip %>`
| xref:insns-<%= i.name.gsub('.', '_') %>[<%= i.long_name %>]
<%- if versions.size > 1 -%>
| <%= ext.versions.map { |v| i.defined_by?(ext.name, v.version) ? "&#x2713;" : "" }.join(" | ") %>
<%- end -%>
<%- end -%>
|===

<%- unless ext.implies.empty? -%>
<%- unless implications.empty? -%>
=== Instructions by sub-extension

[%autowidth]
|===
| Mnemonic | `<%= ext.name %>` | <%= ext.implies.map { |e| "`#{e.name}`" }.join(" | ") %>
| Mnemonic | <%= implications.map { |e| "`#{e.name}`" }.join(" | ") %>

<%- ext.instructions.each do |i| -%>
| `<%= i.name %>`
| &#x2713;
| <%= ext.implies.map { |e| i.defined_by?(e.name, arch_def.extension(e.name).max_version) ? "&#x2713;" : "" }.join(" | ") %>
| <%= implications.map { |e| i.defined_by?(e) ? "&#x2713;" : "" }.join(" | ") %>
<%- end -%>
|===

Expand All @@ -247,15 +264,17 @@ The following <%= ext.csrs.size %> are added by this extension.

[%autowidth]
|===
| RV32 | RV64 | CSR | Name | <%= ext.versions.map { |v| "v#{v.version}" }.join(" | ") %>
| RV32 | RV64 | CSR | Name <%- if versions.size > 1 -%>| <%= versions.map { |v| "v#{v.version}" }.join(" | ") %><%- end -%>

<%- ext.csrs.each do |csr| -%>
| <%= csr.defined_in_base32? ? "&#x2713;" : "" %>
| <%= csr.defined_in_base64? ? "&#x2713;" : "" %>
| xref:csrs-<%= csr.name.gsub('.', '_') %>[<%= csr.name %>]
| <%= csr.long_name %>
<%- if versions.size > 1 -%>
| <%= ext.versions.map { |v| csr.defined_by?(ext.name, v.version) ? "&#x2713;" : "" }.join(" | ") %>
<%- end -%>
<%- end -%>

|===

Expand Down
2 changes: 1 addition & 1 deletion backends/profile_doc/templates/profile_pdf.adoc.erb
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ end.join(" | ") -%>
: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.name,ext.min_version) } -%>
<%- insts = arch_def.instructions.select { |i| i.defined_by?(ext.min_version) } -%>
<%- unless insts.empty? -%>
==== Instructions

Expand Down
54 changes: 25 additions & 29 deletions lib/arch_obj_models/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,27 +145,27 @@ def versions
end
end

# @return [Array<Hash>] Ratified versions hash from config
# @return [Array<ExtensionVersion>] Ratified versions hash from config
def ratified_versions
@data["versions"].select { |v| v["state"] == "ratified" }
versions.select { |v| v.state == "ratified" }
end

# @return [Gem::Version] Mimumum defined version of this extension
# @return [ExtensionVersion] Mimumum defined version of this extension
def min_version
versions.map { |v| v.version }.min
versions.min { |a, b| a.version <=> b.version }
end

# @return [Gem::Version] Maximum defined version of this extension
# @return [ExtensionVersion] Maximum defined version of this extension
def max_version
versions.map { |v| v.version }.max
versions.max { |a, b| a.version <=> b.version }
end

# @return [Gem::Version] Mimumum defined ratified version of this extension
# @return [ExtensionVersion] Mimumum defined ratified version of this extension
# @return [nil] if there is no ratified version
def min_ratified_version
return nil if ratified_versions.empty?

ratified_versions.map { |v| v.version }.min
ratified_versions.min { |a, b| a.version <=> b.version }
end

# @return [Array<ExtensionParameter>] List of parameters added by this extension
Expand All @@ -191,22 +191,9 @@ def initialize(ext_data, arch_def)
# @param version_requirement [String] Version requirement
# @return [Array<ExtensionVersion>] Array of extensions implied by any version of this extension meeting version_requirement
def implies(version_requirement = ">= 0")
implications = []
@data["versions"].each do |v|
next unless Gem::Requirement.new(version_requirement).satisfied_by?(Gem::Version.new(v["version"]))

case v["implies"]
when nil
next
when Array
if v["implies"][0].is_a?(Array)
implications += v["implies"].map { |e| ExtensionVersion.new(e[0], e[1], @arch_def)}
else
implications << ExtensionVersion.new(v["implies"][0], v["implies"][1], @arch_def)
end
end
end
implications
return [] unless Gem::Requirement.new(version_requirement).satisfied_by?(max_version.version)

max_version.implications
end

def conflicts
Expand All @@ -215,18 +202,18 @@ def conflicts
to_extension_requirement_list(@data["conflicts"])
end

# @return [Array<Instruction>] the list of instructions implemented by this extension (may be empty)
# @return [Array<Instruction>] the list of instructions implemented by *any version* of this extension (may be empty)
def instructions
return @instructions unless @instructions.nil?

@instructions = arch_def.instructions.select { |i| @data["versions"].any? { |version| i.defined_by?(name, version["version"]) }}
@instructions = arch_def.instructions.select { |i| versions.any? { |v| i.defined_by?(v) }}
end

# @return [Array<Csr>] the list of CSRs implemented by this extension (may be empty)
# @return [Array<Csr>] the list of CSRs implemented by *any version* of this extension (may be empty)
def csrs
return @csrs unless @csrs.nil?

@csrs = arch_def.csrs.select { |csr| csr.defined_by?(ExtensionVersion.new(name, max_version, @arch_def)) }
@csrs = arch_def.csrs.select { |csr| versions.any? { |v| csr.defined_by?(v) } }
end

# @return [Array<Csr>] the list of CSRs implemented by this extension (may be empty)
Expand Down Expand Up @@ -364,6 +351,14 @@ def ==(other)
end
end

# @param other [ExtensionVersion] Comparison
# @return [Boolean] Whether or not +other+ is an ExtensionVersion with the same name and version
def eql?(other)
return false unless other.is_a?(ExtensionVersion)

@name == other.name && @version == other.version
end

def requirements
r = case @data["requires"]
when nil
Expand Down Expand Up @@ -392,11 +387,12 @@ def implications
return @implications
when Array
if @data["implies"][0].is_a?(Array)
@implications += @data["implies"].map { |e| ExtensionVersion.new(e[0], e[1], @arch_def)}
@implications += @data["implies"].map { |e| ExtensionVersion.new(e[0], e[1], @arch_def) }
else
@implications << ExtensionVersion.new(@data["implies"][0], @data["implies"][1], @arch_def)
end
end
@implications.uniq!
@implications
end

Expand Down

0 comments on commit 154904f

Please sign in to comment.