Skip to content

Commit

Permalink
Merge remote-tracking branch 'rvi/main' into dhower/backends
Browse files Browse the repository at this point in the history
  • Loading branch information
dhower-qc committed Jul 19, 2024
2 parents d1ada85 + 09448b6 commit d14f639
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 20 deletions.
2 changes: 1 addition & 1 deletion arch/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,6 @@ CSR fields are given a type, which _does not_ necessarily correspond to the WARL
| *RW-RH* | Read-write, only a restricted set of values are allowed, and hardware updates the field
|===

In many cases, the values of CSR and/or CSR field data are configuration dependent. Some of that is covered directly by the data model (_e.g._, with `location_rv32`, `location_rv64`), but some cases are too complex to express with YAML. For this reason, many of the keys can be specified as IDL functions. See the schema documentation and examples in the `arch/csr` folder for more information.
In many cases, the values of CSR and/or CSR field data are configuration dependent. Some of that is covered directly by the data model (_e.g._, with `location_rv32`, `location_rv64`), but some cases are too complex to express with YAML. For this reason, many of the keys can be specified as IDL functions. See the xref:csr/schema.adoc[schema] documentation and examples in the `arch/csr` folder for more information.

Some keys that only apply to certain CSRs are not shown above.
2 changes: 1 addition & 1 deletion arch/csr/mstatus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mstatus:
# MXLEN cannot change dynamically, so this will be converted to an integer
# in the genrated, configuration-dependent spec
length: MXLEN

description: The mstatus register tracks and controls the hart's current operating state.
definedBy: I
fields:
Expand Down
221 changes: 221 additions & 0 deletions arch/csr/schema.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
= Schema for CSR defintions

A CSR defintion is a mapping (_i.e._, hash, dictionary, ...) containing exactly one key
equal to the CSR name, and pointing to an object specified below. For example:

.CSR object
[source,yaml]
----
mstatus:
long_name: Machine status
# ...
----

The CSR object has the following information:

Long name::

[IMPORTANT] long_name is a required key

|===
| *key* | long_name
| *value type* | String
| *description* | A descriptive name for the CSR
|===

Description::

[IMPORTANT] description is a required key

|===
| *key* | description
| *value type* | String
| *description* | A full Asciidoc description of the CSR, indended to be used as documentation.
|===

Defining extension::

[IMPORTANT] definedBy is a required key

|===
| *key* | definedBy
| *value type* | String
| *description* | The extension that defines this CSR.
|===

Privilege Mode::

[IMPORTANT] `priv_mode` is a required key

|===
| *key* | priv_mode
| *value type* | one of ["M", "S", "U", or "VS"]
| *description* | The least-privilege mode that can access this CSR
|===

Length::

[IMPORTANT] `length` is a required key

|===
| *key* | length
| *value type* | one of [32, 64, "MXLEN", "SXLEN", "VSXLEN"]
| *description* | Length, in bits, of the CSR. Can either be a 32, 64 or MXLEN, SXLEN, VSXLEN to indicate that is is equal to the effective XLEN for a given mode
|===

Indirect::

|===
| *key* | indirect
| *value type* | Boolean
| *default* | false
| *description* | Whether or not the CSR is accessible through the indirect CSRs of the `Smcdrind`/`Sscdrind` extensions.
|===

Address::

[IMPORTANT] `address` is a required key *unless* the CSR is only accessible through the indirect registers of the `Smcsrind`/`Sscrind` extensions, in which case `indirect_address` is required. Both `address` and `indirect_address` may be specified when a CSR is accessible directly and indirectly.

|===
| *key* | address
| *value type* | Integer between 0-4095, inclusive
| *description* | Address of the CSR, as given to the CSR access instructions of the `Zicsr` extension
|===

|===
| *key* | indirect_address
| *value type* | Integer
| *description* | Indirect sddress of the CSR, as given to the indirect CSRs of the `Smcsrind`/`Sscdrind` extensions
|===

Virtual Address::

[IMPORTANT] `virtual_address` is required when the `priv_mode` of the CSR is VS.

|===
| *key* | virtual_address
| *value type* | Integer between 0-4095, inclusive
| *description* | Address of the CSR viewed from VS-mode
|===

Custom Software Read::

|===
| *key* | sw_read()
| *value type* | String of IDL code that returns a read value
| *description* | Function that returns the value of the CSR when read by software (i.e., a Zicsr instruction). If not specified, the value last written (possibly filtered through field `write(csr_value)` functions) is returned.
|===

Fields::

[IMPORTANT] `fields` is a required key

|===
| *key* | fields
| *value type* | Mapping of field name (String) to field data (Object)
| *description* | Function that returns the value of the CSR when read by software (i.e., a Zicsr instruction). If not specified, the value last written (possibly filtered through field `write(csr_value)` functions) is returned.
|===

== Schema for CSR fields

A CSR field defintion is a mapping (_i.e._, hash, dictionary, ...) containing exactly one key
equal to the CSR field name, in uppercase, and pointing to an object specified below.

Location::

[IMPORTANT] `location` is required *unless* the location is depenent on the XLEN of a certain mode, in which case both `location_rv32` and `location_rv64` are required

|===
| *key* | location
| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB"
| *description* | Location of the field within the CSR.
|===

|===
| *key* | location_rv32
| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB"
| *description* | Location of the field within the CSR in RV32.
|===

|===
| *key* | location_rv64
| *value type* | Integer (when the field is a single bit) -OR- a String of "MSB-LSB"
| *description* | Location of the field within the CSR in RV64.
|===

Base::

When a CSR field is only present in RV32 or RV64, the `base` field is used.

|===
| *key* | base
| *value type* | One of [32, 64]
| *description* | Effective XLEN for this field to exist.
|===

Reset Value::

[IMPORTANT] `reset_value` is required *unless* the reset value is dependent on a configuration option, in which case `reset_value()` is required.

|===
| *key* | reset_value
| *value type* | Integer -OR- "UNDEFINED_LEGAL"
| *description* | Value of the field coming out of reset. When the specific value is not defined, "UNDEFINED_LEGAL" is use to indicate that the value isn't known but is gauranteed to a legal value for the field.
|===

|===
| *key* | reset_value()
| *value type* | String of IDL code that returns a reset value
| *description* | Value of the field coming out of reset. When the specific value is not defined, the special value UNDEFINED_LEGAL can be returned to indicate that the value isn't known but is gauranteed to a legal value for the field.
|===

Type::

[IMPORTANT] `type` is required, unless the type is configuration-dependent, in which case `type()` is required

Each field specifies a type as one of:

[cols="1,4"]
|===
| Type | Meaning

| *RO* | Read-only
| *RO-H* | Read-only, and hardware updates the field
| *RW* | Read-write
| *RW-R* | Read-write, but only a restricted set of values are allowed
| *RW-H* | Read-write, and hardware updates the field
| *RW-RH* | Read-write, only a restricted set of values are allowed, and hardware updates the field
|===

|===
| *key* | type
| *value type* | One of ["RO", "RO-H", "RW", "RW-R", "RW-H", "RW-RH"]
| *description* | The type of the field, as described above
|===

|===
| *key* | type()
| *value type* | String of IDL code that returns a CsrFieldType
| *description* | Type of the field, as a CsrFieldType enum value
|===

Custom Write Function::

[IMPORTANT] `write(csr_value)` is required when the type of the field is restricted ("RW-R" or "RW-RH")

|===
| *key* | write(csr_value)
| *value type* | String of IDL code that is run when the software writes the field
| *description* | Function implementing custom write behavior for the CSR. The csr_value parameter is the *entire* attempted CSR write value. Fields within the attempted write value can be accessed with a dot operator (e.g., csr_value.SXL, csr_value.VGEIN, ...)
|===

|===
| *key* | legal?(csr_value)
| *value type* | String of IDL code that returns whether or not an attempted write is legal
| *description* | Function that returns whether or not an attempted value for the field is legal. The csr_value parameter is the *entire* attempted CSR write value. Fields within the attempted write value can be accessed with a dot operator (e.g., csr_value.SXL, csr_value.VGEIN, ...)
|===

Alias::

Some fields are aliases for another field, often in a different CSR. THe `alias` key is used to indicate that this field just points somewhere else.

18 changes: 16 additions & 2 deletions backends/arch_gen/lib/arch_gen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -749,12 +749,26 @@ def maybe_add_inst(inst_name, extra_env = {})
begin
inst_data = @validator.validate_str(inst_yaml, type: :inst)
rescue Validator::ValidationError => e
warn "Instruction definition in #{merged_path} did not validate"
warn "Instruction definition in #{gen_inst_path} did not validate"
raise e
end

inst_obj = Instruction.new(inst_data[inst_name])

possible_xlens = [@params["XLEN"]]
if @cfg["extensions"].any? { |e| e[0] == "S" }
possible_xlens << 32 if [32, 3264].include?(@params["SXLEN"])
possible_xlens << 64 if [64, 3264].include?(@params["SXLEN"])
end
if @cfg["extensions"].any? { |e| e[0] == "U" }
possible_xlens << 32 if [32, 3264].include?(@params["UXLEN"])
possible_xlens << 64 if [64, 3264].include?(@params["UXLEN"])
end
if @cfg["extensions"].any? { |e| e[0] == "H" }
possible_xlens << 32 if [32, 3264].include?(@params["VSXLEN"])
possible_xlens << 32 if [32, 3264].include?(@params["VUXLEN"])
possible_xlens << 64 if [64, 3264].include?(@params["VSXLEN"])
possible_xlens << 64 if [64, 3264].include?(@params["VUXLEN"])
end
belongs =
inst_obj.exists_in_cfg?(
possible_xlens.uniq,
Expand Down
66 changes: 50 additions & 16 deletions schemas/csr_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
},
"csr_register": {
"type": "object",
"required": ["long_name", "description", "address", "priv_mode", "definedBy"],
"required": ["long_name", "length", "description", "priv_mode", "definedBy"],

"properties": {
"name": {
Expand All @@ -195,10 +195,12 @@
"description": "When a CSR is only defined in RV32, or RV64, the base that defines it. When defined in both, this field should be absent."
},
"long_name": {
"type": "string"
"type": "string",
"description": "Descriptive name for the CSR"
},
"description": {
"type": "string"
"type": "string",
"description": "A full Asciidoc description of the CSR, indended to be used as documentation."
},
"definedBy": {
"oneOf": [
Expand All @@ -216,7 +218,18 @@
},
"address": {
"type": "integer",
"description": "CSR address"
"minValue": 0,
"maxValue": 4095,
"description": "Address of the CSR, as given to the CSR access instructions of the `Zicsr` extension"
},
"indirect_address": {
"type": "integer",
"description": "Indirect sddress of the CSR, as given to the indirect CSRs of the `Smcsrind`/`Sscdrind` extensions"
},
"indirect": {
"type": "boolean",
"default": false,
"description": "Whether or not the CSR is accessible via an indirect address"
},
"virtual_address": true, "$comment": "Conditionally required; see below",
"priv_mode": {
Expand All @@ -237,6 +250,7 @@
"$ref": "#/$defs/csr_field"
}
},
"description": "fields of this CSR",
"additionalProperties": false
},
"sw_read()": {
Expand All @@ -247,20 +261,40 @@
"additionalProperties": false,

"$comment": "If mode is VS, then there must be a virtual_address field",
"if": {
"properties": {
"priv_mode": { "const": "VS" }
}
},
"then": {
"properties": {
"virtual_address": {
"type": "number",
"description": "Address of the CSR viewed from VS-mode"
"allOf": [
{
"if": {
"properties": {
"priv_mode": { "const": "VS" }
}
},
"then": {
"properties": {
"virtual_address": {
"type": "number",
"description": "Address of the CSR viewed from VS-mode"
}
},
"required": ["virtual_address"]
}
},
"required": ["virtual_address"]
}
{
"oneOf": [
{
"properties": {
"indirect": { "const": false }
},
"required": ["address"]
},
{
"properties": {
"indirect": { "const": true }
},
"required": ["indirect_address"]
}
]
}
]
}
},

Expand Down

0 comments on commit d14f639

Please sign in to comment.