Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion arch/inst/A/lr.w.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ lr.w:
Software should not set the _rl_ bit on an LR instruction unless the _aq_ bit is also set.
LR.rl and SC.aq instructions are not guaranteed to provide any stronger ordering than those
with both bits clear, but may result in lower performance.
definedBy: A
definedBy:
anyOf: [A, Zalrsc]
assembly: xd, xs1
encoding:
match: 00010--00000-----010-----0101111
Expand Down
3 changes: 2 additions & 1 deletion arch/inst/A/sc.d.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ sc.d:
Software should not set the _rl_ bit on an LR instruction unless the _aq_ bit is also set.
LR.rl and SC.aq instructions are not guaranteed to provide any stronger ordering than those
with both bits clear, but may result in lower performance.
definedBy: A
definedBy:
anyOf: [A, Zalrsc]
assembly: xd, xs2, xs1
encoding:
match: 00011------------011-----0101111
Expand Down
3 changes: 2 additions & 1 deletion arch/inst/A/sc.w.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ sc.w:
Software should not set the _rl_ bit on an LR instruction unless the _aq_ bit is also set.
LR.rl and SC.aq instructions are not guaranteed to provide any stronger ordering than those
with both bits clear, but may result in lower performance.
definedBy: A
definedBy:
anyOf: [A, Zalrsc]
assembly: xd, xs2, xs1
encoding:
match: 00011------------010-----0101111
Expand Down
52 changes: 38 additions & 14 deletions backends/arch_gen/lib/arch_gen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -470,31 +470,51 @@ def interrupt_codes
end
private :env

def merge_helper(base_obj, updates, path_so_far)
obj = path_so_far.empty? ? updates : updates.dig(*path_so_far)
obj.each do |key, value|
if value.is_a?(Hash)
merge_helper(base_obj, updates, (path_so_far + [key]))
# merges patch into base_obj based on JSON Merge Patch (RFC 7386)
#
# @param base_obj [Hash] base object to merge into
# @param patch [Hash] patch to merge into base_obj
# @param path_so_far [Array<String>] path into the current object. Shouldn't be set by user (used during recursion)
# @return [Hash] merged object
def merge_patch(base, patch, path_so_far = [])
patch_obj = path_so_far.empty? ? patch : patch.dig(*path_so_far)
patch_obj.each do |key, patch_value|
if patch_value.is_a?(Hash)
# continue to dig
merge_patch(base, patch, (path_so_far + [key]))
else
(path_so_far + [key]).each_with_index do |k, idx|
base_obj[k] ||= {}
if idx != path_so_far.size
base_obj = base_obj[k]
else
base_obj[k] = value
base_ptr = base.dig(*path_so_far)
base_value = base_ptr&.dig(key)
case patch_value
when nil
# remove from base, if it exists
unless base_value.nil?
base_ptr[key] = nil
end
else
# add or overwrite value in base
if base_ptr.nil?
# need to create intermediate nodes, too
base_ptr = base
path_so_far.each do |k|
base_ptr[k] = {} unless base_ptr.key?(k)
base_ptr = base_ptr[k]
end
base_ptr = base.dig(*path_so_far)
end
base_ptr[key] = patch_value
end
end
end
end
private :merge_helper
private :merge_patch

# overwrites base_obj with any data in update
#
# @param base_obj [Hash] Base object
# @param updates [Hash] Object with overlays
# @return [Hash] Updated object
def merge(base_obj, updates) = merge_helper(base_obj, updates, [])
def merge(base_obj, updates) = merge_patch(base_obj, updates, [])
private :merge

# @param type [Symbol] Type of the object (@see Validator::SCHEMA_PATHS)
Expand Down Expand Up @@ -728,6 +748,7 @@ def maybe_add_csr(csr_name, extra_env = {})
end
belongs =
csr_obj.exists_in_cfg?(arch_def_mock)


@implemented_csrs ||= []
@implemented_csrs << csr_name if belongs
Expand Down Expand Up @@ -784,7 +805,10 @@ def maybe_add_ext(ext_name)

merged_path = gen_merged_def(:ext, arch_path, arch_overlay_path)

ext_obj = YAML.load_file(merged_path)[ext_name]
yaml_contents = YAML.load_file(merged_path)
raise "In #{merged_path}, key does not match file name" unless yaml_contents.key?(ext_name)

ext_obj = yaml_contents[ext_name]
ext_obj["name"] = ext_name

@implied_ext_map ||= {}
Expand Down
9 changes: 7 additions & 2 deletions backends/ext_pdf_doc/tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ rule %r{#{$root}/gen/ext_pdf_doc/.*/adoc/.*_extension\.adoc} => proc { |tname|
end
raise "Can't find extension '#{ext_name}'" if arch_yaml_paths.empty?

stamp = config_name == "_" ? "#{$root}/.stamps/arch-gen.stamp" : "#{$root}/.stamps/arch-gen-#{config_name}.stamp"
stamp = config_name == "_" ? "#{$root}/.stamps/arch-gen-_64.stamp" : "#{$root}/.stamps/arch-gen-#{config_name}.stamp"

[
stamp,
Expand All @@ -145,7 +145,12 @@ 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 = ENV.key?("EXT_VERSION") ? ENV["EXT_VERSION"] : ext.versions.sort { |v| Gem::Version.new(v["version"]) }.last["version"]
version_num =
if ENV.key?("EXT_VERSION")
ENV["EXT_VERSION"]
else
ext.versions.max { |a, b| Gem::Version.new(a["version"]) <=> Gem::Version.new(b["version"]) }["version"]
end
ext_version = ext.versions.find { |v| v["version"] == version_num }
FileUtils.mkdir_p File.dirname(t.name)
File.write t.name, AsciidocUtils.resolve_links(arch_def.find_replace_links(erb.result(binding)))
Expand Down
96 changes: 68 additions & 28 deletions backends/ext_pdf_doc/templates/ext_pdf.adoc.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
FROZEN_STATE
when "development"
<<~DEV_STATE
This document is in the http://riscv.org/spec-state[Development state].

Change should be expected
This document is in the http://riscv.org/spec-state[Development state]. + \\
+ \\
Change should be expected + \\
DEV_STATE
else
raise "TODO: #{ext_version["state"]} description"
Expand All @@ -37,11 +37,13 @@
:preface-title: Licensing and Acknowledgements
:colophon:
:appendix-caption: Appendix
<%- if !ext.company.nil? && (ext.company["name"] =~ /RISCV/) -%>
: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 -%>
<%- unless ext_version["state"] == "ratified" -%>
:page-background-image: image:draft.png[opacity=20%]
<%- end -%>
:back-cover-image: image:riscv-horizontal-color.svg[opacity=25%]
// Settings
:experimental:
:reproducible:
Expand Down Expand Up @@ -121,7 +123,7 @@ endif::[]
== 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"].split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.
Copyright <%= ext_version["ratification_date"].nil? ? Date.today.year : ext_version["ratification_date"].split("-")[0] %> by <%= ext.company.nil? ? "unknown" : ext.company["name"] %>.

[preface]
== Acknowledgements
Expand All @@ -131,7 +133,8 @@ Contributors to version <%= version["version"] %> of the specification (in alpha

<%- unless version["contributors"].nil? -%>
<%- version["contributors"].sort { |a, b| a["name"].split(" ").last <=> b["name"].split(" ").last }.each do |c| -%>
* <%= c["name"] %> <<%= c["email"] %>> (<%= c["company"] %>)
* <%= c["name"] %> <<%= c["email"] %>> (<%= c["company"] %>)

<%- end -%>
<%- end -%>
<%- end -%>
Expand All @@ -154,21 +157,69 @@ Ratification Date:: <%= version["ratification_date"] %>
<%- if version.key?("url") -%>
Design document:: <%= version["url"] %>
<%- end -%>
<%- if version.key?("change") -%>
<%- if version.key?("changes") -%>
Changes::
<%= version["changes"] %>
<%- end -%>
<%- unless version["implies"].nil? || version["implies"].empty? -%>
Implies::
* <%= version["implies"].map { |name, version| "#{name} (#{version})" }.join("\n* ") %>
<%- end -%>
--
<%- end -%>


<<<
== Extension description

<%= ext.description %>

<%- unless ext.implies.nil? -%>
<%- ext.implies.each do |e| -%>
=== Sub-extensions
The following sub-extensions are defined:

<%- ext.implies.each do |sub_ext| -%>
==== <%= sub_ext.name %>

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

<%- end -%>
<%- end -%>

<%- unless ext.instructions.empty? -%>
<<<
== Instruction summary

The following <%= ext.instructions.size %> instructions are added by this extension:

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

<%- 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 %>]
| <%= ext.versions.map { |v| i.defined_by?(ext.name, v["version"]) ? "&#x2713;" : "" }.join(" | ") %>
<%- end -%>
|===

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

|===
| Mnemonic | `<%= ext.name %>` | <%= ext.implies.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(" | ") %>
<%- end -%>
|===

<%- end -%>

<%- end -%>

<%- unless ext.csrs.empty? -%>
Expand Down Expand Up @@ -327,24 +378,6 @@ This CSR may return a value that is different from what is stored in hardware.
<%- end -%>

<%- unless ext.instructions.empty? -%>
<<<
== Instruction summary

The following <%= ext.instructions.size %> instructions are added by this extension:

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

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

<<<
[#insns,reftext="Instructions (in alphabetical order)"]
== Instructions (in alphabetical order)
Expand Down Expand Up @@ -387,8 +420,14 @@ RV64::
Description::
<%= i.description %>


Decode Variables::

<%- if i.multi_encoding? ? (i.decode_variables(32).empty? && i.decode_variables(64).empty?) : i.decode_variables(i.base.nil? ? 64 : i.base).empty? -%>

<%= i.name %> has no decode variables.

<%- else -%>
<%- if i.multi_encoding? -%>
RV32::
+
Expand All @@ -414,7 +453,8 @@ RV64::
<%= d.sext? ? 'signed ' : '' %>Bits<<%= d.size %>> <%= d.name %> = <%= d.extract %>;
<%- end -%>
----
<%- end -%>
<%- end # if multi_encoding? -%>
<%- end # if no decode variables-%>

Operation::
<%- unless i.data["operation()"].nil? -%>
Expand Down Expand Up @@ -455,4 +495,4 @@ h| Arguments l| <%= f.arguments_list_str.join (', ') %>
----
<%- end -%>

<%- end -%>
<%- end -%>
12 changes: 8 additions & 4 deletions lib/idl/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3601,7 +3601,11 @@ def initialize(input, interval, condition, true_expression, false_expression)
# @!macro type_check
def type_check(symtab)
condition.type_check(symtab)
type_error "ternary selector must be bool" unless condition.type(symtab).kind == :boolean
if condition.type(symtab).kind == :bits
type_error "ternary selector must be bool (maybe you meant '#{condition.text_value} != 0'?)"
else
type_error "ternary selector must be bool" unless condition.type(symtab).kind == :boolean
end

value_result = value_try do
cond = condition.value(symtab)
Expand Down Expand Up @@ -5740,9 +5744,9 @@ def calc_type(symtab)
fd = field_def(symtab)
if fd.nil?
if @idx.is_a?(IntLiteralAst)
internal_error "Could not find CSR[#{@idx.to_idl}]"
internal_error "Could not find CSR[#{@idx.to_idl}].#{@field_name}"
else
internal_error "Could not find CSR[#{@idx}]"
internal_error "Could not find CSR[#{@idx}].#{@field_name}"
end
end
if fd.defined_in_all_bases?
Expand Down Expand Up @@ -6026,7 +6030,7 @@ def value(symtab)
when "sw_read"
value_error "CSR not knowable" unless csr_known?(symtab)
cd = csr_def(symtab)
cd.fields.each { |f| value_error "#{csr_name}.#{f.name} not RO" unless f.type == "RO" }
cd.fields.each { |f| value_error "#{csr_name(symtab)}.#{f.name} not RO" unless f.type(symtab) == "RO" }

value_error "TODO: CSRs with sw_read function"
when "address"
Expand Down
2 changes: 1 addition & 1 deletion schemas/arch_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z][a-zA-Z0-9]+$",
"pattern": "^[a-z][a-zA-Z0-9_]+$",
"description": "CSR name"
}
},
Expand Down
2 changes: 1 addition & 1 deletion schemas/csr_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
"misa:\\n long_name: Machine ISA Control\\n address: 0x301\\n priv_mode: M\\n length: 64\\n description: Reports the XLEN and 'major' extensions supported by the ISA.\\n definedBy: I\\n fields:\\n MXL:\\n location: 63-62\\n description: XLEN in M-mode.\\n type: RO\\n value: 2\\n Extensions: location: 25-0\\n description: |\\n Indicates support for major (single letter) ISA extensions.\\n\\n Value corresponds to A, D, F, H, I, M, S, U\\n type: RO\\n value: 0x1411A9"
],
"patternProperties": {
"^[a-z][a-z0-9A-Z]+$": {
"^[a-z][a-z0-9A-Z_]+$": {
"description": "CSR name",
"$ref": "#/$defs/csr_register"
}
Expand Down
7 changes: 6 additions & 1 deletion schemas/inst_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
"properties": {
"match": {
"oneOf": [
{
"type": "string",
"pattern": "^[01-]{43}11111$",
"description": "48-bit encoding"
},
{
"type": "string",
"pattern": "^[01-]{30}11$",
Expand Down Expand Up @@ -217,4 +222,4 @@
},
"additionalProperties": false,
"maxProperties": 1
}
}
Loading