diff --git a/README.md b/README.md index 1eaf413da..0b23f8412 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ # OpenHW Group CORE-V CV32E40P RISC-V IP CV32E40P is a small and efficient, 32-bit, in-order RISC-V core with a 4-stage pipeline that implements -the RV32IM\[F\]C instruction set architecture, and the Xpulp custom extensions for achieving +the RV32IM\[F|Zfinx\]C instruction set architecture, and the PULP custom extensions for achieving higher code density, performance, and energy efficiency \[[1](https://doi.org/10.1109/TVLSI.2017.2654506)\], \[[2](https://doi.org/10.1109/PATMOS.2017.8106976)\]. It started its life as a fork of the OR10N CPU core that is based on the OpenRISC ISA. Then, under the name of RI5CY, it became a RISC-V core (2016), and it has been maintained by the [PULP platform](https://www.pulp-platform.org/) team until February 2020, when it has been contributed to [OpenHW Group](https://www.openhwgroup.org/). -

+

## Documentation @@ -33,7 +33,7 @@ The Makefiles supported in the **core-v-verif** project automatically clone the A changelog is generated automatically in the documentation from the individual pull requests. In order to enable automatic changelog generation within the CV32E40P documentation, the committer is required to label each pull request that touches any file in 'rtl' (or any of its subdirectories) with *Component:RTL* and label each pull request that touches any file in -'docs' (or any of its subdirectories) with *Component:Doc*. Pull requests taht are not labeled or labeled with *ignore-for-release* are +'docs' (or any of its subdirectories) with *Component:Doc*. Pull requests that are not labeled or labeled with *ignore-for-release* are ignored for the changelog generation. Only the person who actually performs the merge can add these labels (you need committer rights). The changelog flow only works if at most diff --git a/docs/CV32E40P_User_Manual.pdf b/docs/CV32E40P_User_Manual.pdf new file mode 100644 index 000000000..c668b3c0f Binary files /dev/null and b/docs/CV32E40P_User_Manual.pdf differ diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo new file mode 100644 index 000000000..dc046c3f4 --- /dev/null +++ b/docs/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 0b9656d7b13ba9b2c1e11f9c4adc455a +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/_images/CV32E40P_Block_Diagram.png b/docs/html/_images/CV32E40P_Block_Diagram.png new file mode 100644 index 000000000..919bacdc4 Binary files /dev/null and b/docs/html/_images/CV32E40P_Block_Diagram.png differ diff --git a/docs/html/_images/CV32E40P_Pipeline.png b/docs/html/_images/CV32E40P_Pipeline.png new file mode 100644 index 000000000..16511fb78 Binary files /dev/null and b/docs/html/_images/CV32E40P_Pipeline.png differ diff --git a/docs/html/_images/debug_halted.svg b/docs/html/_images/debug_halted.svg new file mode 100644 index 000000000..337fc02f4 --- /dev/null +++ b/docs/html/_images/debug_halted.svg @@ -0,0 +1,479 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +RESET + +BOOT_SET + +DBG_TAKEN_IF + +UNAVAILABLE + +HALTED + +clk_i + + +rst_ni + + +fetch_enable_i + + +debug_req_i + + +Controller FSM + + +debug_running_o + + +debug_halted_o + + +debug_havereset_o + + +Hart state + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/debug_running.svg b/docs/html/_images/debug_running.svg new file mode 100644 index 000000000..9da0b392a --- /dev/null +++ b/docs/html/_images/debug_running.svg @@ -0,0 +1,451 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +RESET + +BOOT_SET + +FIRST_FETCH + +UNAVAILABLE + +RUNNING + +clk_i + + +rst_ni + + +fetch_enable_i + + +debug_req_i + + +Controller FSM + + +debug_running_o + + +debug_halted_o + + +debug_havereset_o + + +Hart state + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/load_event.svg b/docs/html/_images/load_event.svg new file mode 100644 index 000000000..26c0fc395 --- /dev/null +++ b/docs/html/_images/load_event.svg @@ -0,0 +1,923 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 9 + + + 10 + + + 11 + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +P.ELW + +clk_i + + +clk (gated) + + +Instruction (ID) + + +data_req_o + + +data_gnt_i + + +data_rvalid_i + + +'IF or APU busy prevents sleep' + + +core_sleep_o + + +pulp_clock_en_i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_data_back_to_back.svg b/docs/html/_images/obi_data_back_to_back.svg new file mode 100644 index 000000000..b641a7454 --- /dev/null +++ b/docs/html/_images/obi_data_back_to_back.svg @@ -0,0 +1,512 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +WD0 + +RD1 + +WE0 + +BE0 + +A1 + +WD1 + +WE1 + +BE1 + +RD0 + +clk + + +data_req_o + + +data_gnt_i + + +data_addr_o + + +data_wdata_o + + +data_we_o + + +data_be_o + + +data_rvalid_i + + +data_rdata_i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_data_basic.svg b/docs/html/_images/obi_data_basic.svg new file mode 100644 index 000000000..dff392439 --- /dev/null +++ b/docs/html/_images/obi_data_basic.svg @@ -0,0 +1,462 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +WD0 + +RD0 + +WE0 + +BE0 + +clk + + +data_req_o + + +data_gnt_i + + +data_addr_o + + +data_wdata_o + + +data_we_o + + +data_be_o + + +data_rvalid_i + + +data_rdata_i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_data_multiple_outstanding.svg b/docs/html/_images/obi_data_multiple_outstanding.svg new file mode 100644 index 000000000..188749c4a --- /dev/null +++ b/docs/html/_images/obi_data_multiple_outstanding.svg @@ -0,0 +1,664 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +A1 + +A2 + +WD0 + +RD0 + +RD1 + +RD2 + +WD1 + +WE0 + +WE1 + +BE0 + +BE1 + +WD2 + +WE2 + +BE2 + +0 + +0 + +1 + +2 + +2 + +1 + +1 + +0 + +clk + + +data_req_o + + +data_gnt_i + + +data_addr_o + + +data_wdata_o + + +data_we_o + + +data_be_o + + +data_rvalid_i + + +data_rdata_i + + +Outstanding transactions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_data_slow_response.svg b/docs/html/_images/obi_data_slow_response.svg new file mode 100644 index 000000000..2fc35ac09 --- /dev/null +++ b/docs/html/_images/obi_data_slow_response.svg @@ -0,0 +1,462 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +WD0 + +RD0 + +WE0 + +BE0 + +clk + + +data_req_o + + +data_gnt_i + + +data_addr_o + + +data_wdata_o + + +data_we_o + + +data_be_o + + +data_rvalid_i + + +data_rdata_i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_instruction_basic.svg b/docs/html/_images/obi_instruction_basic.svg new file mode 100644 index 000000000..77932bbba --- /dev/null +++ b/docs/html/_images/obi_instruction_basic.svg @@ -0,0 +1,617 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +RD0 + +A1 + +A2 + +RD1 + +A3 + +A6 + +A4 + +A5 + +RD2 + +RD3 + +RD4 + +RD5 + +1 + +1 + +1 + +1 + +1 + +1 + +0 + +clk + + +instr_req_o + + +instr_addr_o + + +instr_gnt_i + + +instr_rdata_i + + +instr_rvalid_i + + +Outstanding transactions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/obi_instruction_multiple_outstanding.svg b/docs/html/_images/obi_instruction_multiple_outstanding.svg new file mode 100644 index 000000000..b86ac431c --- /dev/null +++ b/docs/html/_images/obi_instruction_multiple_outstanding.svg @@ -0,0 +1,553 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A0 + +RD0 + +A1 + +RD1 + +0 + +0 + +1 + +2 + +2 + +A2 + +2 + +1 + +A3 + +1 + +clk + + +instr_req_o + + +instr_addr_o + + +instr_gnt_i + + +instr_rdata_i + + +instr_rvalid_i + + +Outstanding transactions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_images/rtl_freeze_rules.png b/docs/html/_images/rtl_freeze_rules.png new file mode 100644 index 000000000..4a1e90025 Binary files /dev/null and b/docs/html/_images/rtl_freeze_rules.png differ diff --git a/docs/html/_images/wfi.svg b/docs/html/_images/wfi.svg new file mode 100644 index 000000000..0f2ec7139 --- /dev/null +++ b/docs/html/_images/wfi.svg @@ -0,0 +1,594 @@ + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + + + 8 + + + 9 + + + 10 + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +WFI + +clk_i + + +clk (gated) + + +Instruction (ID) + + +'IF / CTRL / LSU / APU prevents sleep' + + +core_sleep_o + + +'locally enabled pending interrupt' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_sources/control_status_registers.rst.txt b/docs/html/_sources/control_status_registers.rst.txt new file mode 100644 index 000000000..d18727951 --- /dev/null +++ b/docs/html/_sources/control_status_registers.rst.txt @@ -0,0 +1,1716 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _cs-registers: + +Control and Status Registers +============================ + +CV32E40P does not implement all control and status registers specified in +the RISC-V privileged specifications, but is limited to the registers +that were needed for the PULP system. The reason for this is that we +wanted to keep the footprint of the core as low as possible and avoid +any overhead that we do not explicitly need. + +CSR Map +------- + +:numref:`Control and Status Register Map` lists all +implemented CSRs. Two columns in :numref:`Control and Status Register Map` may require additional explanation: + +The **Privilege** column indicates the access mode of a CSR. The first letter +indicates the lowest privilege level required to access the CSR. Attempts to +access a CSR with a higher privilege level than the core is currently running +in will throw an illegal instruction exception. This is largely a moot point +for the CV32E40P as it only supports machine and debug modes. The remaining +letters indicate the read and/or write behavior of the CSR when accessed by +the indicated or higher privilge level: + +* **RW**: CSR is **read-write**. That is, CSR instructions (e.g. csrrw) may + write any value and that value will be returned on a subsequent read (unless + a side-effect causes the core to change the CSR value). + +* **RO**: CSR is **read-only**. Writes by CSR instructions raise an illegal + instruction exception. + +Writes of a non-supported value to **WLRL** bitfields of a **RW** CSR do not result in an illegal +instruction exception. The exact bitfield access types, e.g. **WLRL** or **WARL**, can be found in the RISC-V +privileged specification. + +In the **Description** column there is a specific comment which identifies those CSRs that are dependent on the value +of specific parameters. If these parameters are not set as +indicated in :numref:`Control and Status Register Map` then the associated CSR is not implemented. If the column does not +mention any parameter then the associated CSR is always implemented. + +Reads or writes to a CSR that is not implemented will result in an illegal +instruction exception. + +.. table:: Control and Status Register Map + :name: Control and Status Register Map + :widths: 13 17 15 55 + :class: no-scrollbar-table + + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **CSR Address** | **Name** | **Privilege** | **Description** | + +=================+===================+===============+==============================================================+ + | **User CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x001 | ``fflags`` | URW | Floating-point accrued exceptions. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x002 | ``frm`` | URW | Floating-point dynamic rounding mode. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x003 | ``fcsr`` | URW | Floating-point control and status register. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC00 | ``cycle`` | URO | (HPM) Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC02 | ``instret`` | URO | (HPM) Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC03 | ``hpmcounter3`` | URO | (HPM) Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC1F | ``hpmcounter31`` | URO | (HPM) Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC80 | ``cycleh`` | URO | (HPM) Upper 32 bits Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC82 | ``instreth`` | URO | (HPM) Upper 32 bits Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC83 | ``hpmcounterh3`` | URO | (HPM) Upper 32 bits Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC9F | ``hpmcounterh31`` | URO | (HPM) Upper 32 bits Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **User Custom CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC0 | ``lpstart0`` | URO | Hardware Loop 0 Start. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC1 | ``lpend0`` | URO | Hardware Loop 0 End. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC2 | ``lpcount0`` | URO | Hardware Loop 0 Counter. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC4 | ``lpstart1`` | URO | Hardware Loop 1 Start. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC5 | ``lpend1`` | URO | Hardware Loop 1 End. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC6 | ``lpcount1`` | URO | Hardware Loop 1 Counter. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD0 | ``uhartid`` | URO | Hardware Thread ID | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 & ``PULP_SECURE`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD1 | ``privlv`` | URO | Privilege Level | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 & ``PULP_SECURE`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD2 | ``zfinx`` | URO | ``ZFINX`` ISA | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **Machine CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x300 | ``mstatus`` | MRW | Machine Status | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x301 | ``misa`` | MRW | Machine ISA | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x304 | ``mie`` | MRW | Machine Interrupt Enable register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x305 | ``mtvec`` | MRW | Machine Trap-Handler Base Address | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x320 | ``mcountinhibit`` | MRW | (HPM) Machine Counter-Inhibit register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x323 | ``mhpmevent3`` | MRW | (HPM) Machine Performance-Monitoring Event Selector 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x33F | ``mhpmevent31`` | MRW | (HPM) Machine Performance-Monitoring Event Selector 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x340 | ``mscratch`` | MRW | Machine Scratch | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x341 | ``mepc`` | MRW | Machine Exception Program Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x342 | ``mcause`` | MRW | Machine Trap Cause | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x343 | ``mtval`` | MRW | Machine Trap Value | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x344 | ``mip`` | MRW | Machine Interrupt Pending register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A0 | ``tselect`` | MRW | Trigger Select register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A1 | ``tdata1`` | MRW | Trigger Data register 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A2 | ``tdata2`` | MRW | Trigger Data register 2 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A3 | ``tdata3`` | MRW | Trigger Data register 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A4 | ``tinfo`` | MRO | Trigger Info | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A8 | ``mcontext`` | MRW | Machine Context register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7AA | ``scontext`` | MRW | Machine Context register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B0 | ``dcsr`` | DRW | Debug Control and Status | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B1 | ``dpc`` | DRW | Debug PC | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B2 | ``dscratch0`` | DRW | Debug Scratch register 0 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B3 | ``dscratch1`` | DRW | Debug Scratch register 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB00 | ``mcycle`` | MRW | (HPM) Machine Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB02 | ``minstret`` | MRW | (HPM) Machine Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB03 | ``mhpmcounter3`` | MRW | (HPM) Machine Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB1F | ``mhpmcounter31`` | MRW | (HPM) Machine Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB80 | ``mcycleh`` | MRW | (HPM) Upper 32 bits Machine Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB82 | ``minstreth`` | MRW | (HPM) Upper 32 bits Machine Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB83 | ``mhpmcounterh3`` | MRW | (HPM) Upper 32 bits Machine Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB9F | ``mhpmcounterh31``| MRW | (HPM) Upper 32 bits Machine Performance-Monitoring Counter 31| + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF11 | ``mvendorid`` | MRO | Machine Vendor ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF12 | ``marchid`` | MRO | Machine Architecture ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF13 | ``mimpid`` | MRO | Machine Implementation ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF14 | ``mhartid`` | MRO | Hardware Thread ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + +.. only:: USER + + .. table:: Control and Status Register Map (additional CSRs for User mode) + :name: Control and Status Register Map (additional CSRs for User mode) + + +-------------------+----------------+---------------+------------------------------------------+ + | **CSR address** | **Name** | **Privilege** | **Description** | + +-------------------+----------------+---------------+------------------------------------------+ + | | | | | + +===================+================+===============+==========================================+ + | 0x000 | ``ustatus`` | URW | User Status | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x005 | ``utvec`` | URW | User Trap-Handler Base Address | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x041 | ``uepc`` | URW | User Exception Program Counter | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x042 | ``ucause`` | URW | User Trap Cause | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x306 | ``mcounteren`` | MRW | Machine Counter Enable | + +-------------------+----------------+---------------+------------------------------------------+ + +CSR Descriptions +----------------- + +What follows is a detailed definition of each of the CSRs listed above. The +**Mode** column defines the access mode behavior of each bit field when +accessed by the privilege level specified in :numref:`Control and Status Register Map` (or a higher privilege +level): + +* **RO**: **read-only** fields are not affect by CSR write instructions. Such + fields either return a fixed value, or a value determined by the operation of + the core. + +* **RW**: **read/write** fields store the value written by CSR writes. Subsequent + reads return either the previously written value or a value determined by the + operation of the core. + +Floating-point CSRs +::::::::::::::::::: + +.. _csr-fflags: + +Floating-point accrued exceptions (``fflags``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x001 (only present if ``FPU`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================+ + | 31:5 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+-------------------------------------------------------------------------+ + | 4 | RW | NV - Invalid Operation | + +-------------+-----------+-------------------------------------------------------------------------+ + | 3 | RW | DZ - Divide by Zero | + +-------------+-----------+-------------------------------------------------------------------------+ + | 2 | RW | OF - Overflow | + +-------------+-----------+-------------------------------------------------------------------------+ + | 1 | RW | UF - Underflow | + +-------------+-----------+-------------------------------------------------------------------------+ + | 0 | RW | NX - Inexact | + +-------------+-----------+-------------------------------------------------------------------------+ + +.. _csr-frm: + +Floating-point dynamic rounding mode (``frm``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x002 (only present if ``FPU`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+--------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+======================================+ + | 31:3 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+--------------------------------------+ + | 2:0 | RW | Rounding mode: | + | | | | + | | | 000 = RNE | + | | | | + | | | 001 = RTZ | + | | | | + | | | 010 = RDN | + | | | | + | | | 011 = RUP | + | | | | + | | | 100 = RMM | + | | | | + | | | 101 = Invalid | + | | | | + | | | 110 = Invalid | + | | | | + | | | 111 = DYN | + +-------------+-----------+--------------------------------------+ + +.. _csr-fcsr: + +Floating-point control and status register (``fcsr``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x003 (only present if ``FPU`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:8 | RO | Reserved. Writes are ignored; reads return 0. | + +-------------+-----------+------------------------------------------------------------------------+ + | 7:5 | RW | Rounding Mode (``frm``) | + +-------------+-----------+------------------------------------------------------------------------+ + | 4:0 | RW | Accrued Exceptions (``fflags``) | + +-------------+-----------+------------------------------------------------------------------------+ + +Hardware Loops CSRs +::::::::::::::::::: + +HWLoop Start Address 0/1 (``lpstart0/1``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCC0/0xCC4 (only present if ``COREV_PULP`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | Start Address of the HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ + +HWLoop End Address 0/1 (``lpend0/1``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCC1/0xCC5 (only present if ``COREV_PULP`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | End Address of the HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ + +HWLoop Count Address 0/1 (``lpcount0/1``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCC2/0xCC6 (only present if ``COREV_PULP`` = 1) + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | Number of iteration of HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ + +Other CSRs +:::::::::: + +Machine Status (``mstatus``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x300 + +Reset Value: 0x0000_1800 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================================================================+ + | 31 | RO | **SD:** State Dirty | + | | | | + | | | SD set to 1 if **FS** = 11 meaning Floating point State is dirty so save/restore is needed in case of context switch. | + | | | | + | | | Hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 30:15 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 14:13 | RW | **FS:** Floating point State | + | | | | + | | | 00 = Off | + | | | | + | | | 01 = Initial | + | | | | + | | | 10 = Clean | + | | | | + | | | 11 = Dirty | + | | | | + | | | Hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 12:11 | RO | **MPP:** Machine Previous Priviledge mode | + | | | | + | | | Hardwired to 11 when the user mode is not enabled. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 10:8 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 7 | RO | **MPIE:** Machine Previous Interrupt Enable | + | | | | + | | | When an exception is encountered, MPIE will be set to MIE. | + | | | When the mret instruction is executed, the value of MPIE will be stored to MIE. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 6:4 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 3 | RW | **MIE:** Machine Interrupt Enable | + | | | | + | | | If you want to enable interrupt handling in your exception handler, | + | | | set the Interrupt Enable MIE to 1 inside your handler code. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 2:0 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + +.. only:: USER + + User Status (``ustatus``) + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x000 + + Reset Value: 0x0000_0000 + + Detailed: + + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================================================================+ + | 4 | RW | **Previous User Interrupt Enable:** If user mode is enabled, when an exception is encountered, UPIE will be set to UIE. | + | | | When the uret instruction is executed, the value of UPIE will be stored to UIE. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 0 | RW | **User Interrupt Enable:** If you want to enable user level interrupt handling in your exception handler, | + | | | set the Interrupt Enable UIE to 1 inside your handler code. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + +Machine Interrupt Enable register (``mie``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x304 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==========================================================================================+ + | 31:16 | RW | Machine Fast Interrupt Enables | + | | | | + | | | Set bit x to enable interrupt irq_i[x] (x between 16 and 31). | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 15:12 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 11 | RW | **MEIE:** Machine External Interrupt Enable | + | | | | + | | | If set, irq_i[11] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 10:8 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 7 | RW | **MTIE:** Machine Timer Interrupt Enable | + | | | | + | | | If set, irq_i[7] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 6:4 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 3 | RW | **MSIE:** Machine Software Interrupt Enable | + | | | | + | | | If set, irq_i[3] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 2:0 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + +.. _csr-mtvec: + +Machine Trap-Vector Base Address (``mtvec``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x305 + +Reset Value: Defined + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===============================================================================================================+ + | 31 : 8 | RW | BASE[31:8] | + | | | | + | | | The trap-handler base address, always aligned to 256 bytes. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 7 : 2 | RO | BASE[7:2] | + | | | | + | | | The trap-handler base address, always aligned to 256 bytes, i.e., mtvec[7:2] is always set to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 1 | RO | MODE[1] | + | | | | + | | | 0 | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 0 | RW | MODE[0] | + | | | | + | | | 0 = Direct mode | + | | | | + | | | 1 = Vectored mode. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + +The initial value of ``mtvec`` is equal to {**mtvec_addr_i[31:8]**, 6'b0, 2'b01}. + +When an exception or an interrupt is encountered, the core jumps to the corresponding +handler using the content of the MTVEC[31:8] as base address. Only +8-byte aligned addresses are allowed. Both direct mode and vectored mode +are supported. + +Machine Scratch (``mscratch``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x340 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RW | Scratch value | + +-------------+-----------+------------------------------------------------------------------------+ + +Machine Exception PC (``mepc``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x341 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:1 | RW | **MEPC:** Machine Exception Program Counter | + +-------------+-----------+------------------------------------------------------------------------+ + | 0 | R0 | 0 | + +-------------+-----------+------------------------------------------------------------------------+ + +When an exception is encountered, the current program counter is saved +in MEPC, and the core jumps to the exception address. When a mret +instruction is executed, the value from MEPC replaces the current +program counter. + +Machine Cause (``mcause``) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x342 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==================================================================================+ + | 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | + +-------------+-----------+----------------------------------------------------------------------------------+ + | 30:5 | RO (0) | 0 | + +-------------+-----------+----------------------------------------------------------------------------------+ + | 4:0 | RW | **Exception Code** (See note below) | + +-------------+-----------+----------------------------------------------------------------------------------+ + +**NOTE**: software accesses to `mcause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, +when `mcause[31]` is set, writing 0x1 to `mcause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. + + +Machine Trap Value (``mtval``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x343 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+------------------------------------------------------------------------+ + +Machine Interrupt Pending register (``mip``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x344 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===================================================================================================+ + | 31:16 | RO | Machine Fast Interrupts Pending | + | | | | + | | | If bit x is set, interrupt irq_i[x] is pending (x between 16 and 31). | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 15:12 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 11 | RO | **MEIP:** Machine External Interrupt Pending | + | | | | + | | | If set, irq_i[11] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 10:8 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 7 | RO | **MTIP:** Machine Timer Interrupt Pending | + | | | | + | | | If set, irq_i[7] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 6:4 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 3 | RO | **MSIP:** Machine Software Interrupt Pending | + | | | | + | | | If set, irq_i[3] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 2:0 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + +Trigger CSRs +:::::::::::: + +.. _csr-tselect: + +Trigger Select register (``tselect``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A0 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================================+ + | 31:0 | RO | CV32E40P implements a single trigger, therefore this register will always read as zero.| + +-------------+-----------+----------------------------------------------------------------------------------------+ + +Accessible in Debug Mode or M-Mode. + +.. _csr-tdata1: + +Trigger Data register 1 (``tdata1``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A1 + +Reset Value: 0x2800_1040 + +Detailed: + +Accessible in Debug Mode or M-Mode. +Since native triggers are not supported, writes to this register from M-Mode will be ignored. + +.. note:: + + CV32E40P only implements one type of trigger, Match Control. Most fields of this register will read as a fixed value to + reflect the single mode that is supported, in particular, instruction address match as described in the Debug Specification + 0.13.2 section 5.2.2 & 5.2.9. The **type**, **dmode**, **hit**, **select**, **timing**, **sizelo**, **action**, **chain**, + **match**, **m**, **s**, **u**, **store** and **load** bitfields of this CSR, which are marked as R/W in Debug Specification + 0.13.2, are therefore implemented as WARL bitfields (corresponding to how these bitfields will be specified in the forthcoming + Debug Specification 0.14.0). + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:28 | RO (0x2) | **type:** 2 = Address/Data match trigger type. | + +-----------+----------+------------------------------------------------------------------+ + | 27 | RO (0x1) | **dmode:** 1 = Only debug mode can write tdata registers | + +-----------+----------+------------------------------------------------------------------+ + | 26:21 | RO (0x0) | **maskmax:** 0 = Only exact matching supported. | + +-----------+----------+------------------------------------------------------------------+ + | 20 | RO (0x0) | **hit:** 0 = Hit indication not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 19 | RO (0x0) | **select:** 0 = Only address matching is supported. | + +-----------+----------+------------------------------------------------------------------+ + | 18 | RO (0x0) | **timing:** 0 = Break before the instruction at the specified | + | | | address. | + +-----------+----------+------------------------------------------------------------------+ + | 17:16 | RO (0x0) | **sizelo:** 0 = Match accesses of any size. | + +-----------+----------+------------------------------------------------------------------+ + | 15:12 | RO (0x1) | **action:** 1 = Enter debug mode on match. | + +-----------+----------+------------------------------------------------------------------+ + | 11 | RO (0x0) | **chain:** 0 = Chaining not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 10:7 | RO (0x0) | **match:** 0 = Match the whole address. | + +-----------+----------+------------------------------------------------------------------+ + | 6 | RO (0x1) | **m:** 1 = Match in M-Mode. | + +-----------+----------+------------------------------------------------------------------+ + | 5 | RO (0x0) | zero. | + +-----------+----------+------------------------------------------------------------------+ + | 4 | RO (0x0) | **s:** 0 = S-Mode not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RO (0x0) | **u:** 0 = U-Mode not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | **execute:** Enable matching on instruction address. | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO (0x0) | **store:** 0 = Store address / data matching not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RO (0x0) | **load:** 0 = Load address / data matching not supported. | + +-----------+----------+------------------------------------------------------------------+ + +.. _csr-tdata2: + +Trigger Data register 2 (``tdata2``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A2 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | **data** | + +-----------+----------+------------------------------------------------------------------+ + +Accessible in Debug Mode or M-Mode. Since native triggers are not supported, writes to this register from M-Mode will be ignored. +This register stores the instruction address to match against for a breakpoint trigger. + +Trigger Data register 3 (``tdata3``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A3 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Accessible in Debug Mode or M-Mode. +CV32E40P does not support the features requiring this register. Writes are ignored and reads will always return zero. + +.. _csr-tinfo: + +Trigger Info (``tinfo``) +~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A4 + +Reset Value: 0x0000_0004 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:16 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 15:0 | RO (0x4) | **info**. Only type 2 is supported. | + +-----------+----------+------------------------------------------------------------------+ + +The **info** field contains one bit for each possible `type` enumerated in +`tdata1`. Bit N corresponds to type N. If the bit is set, then that type is +supported by the currently selected trigger. If the currently selected trigger +does not exist, this field contains 1. + +Accessible in Debug Mode or M-Mode. + +Machine Context register (``mcontext``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7A8 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Accessible in Debug Mode or M-Mode. +CV32E40P does not support the features requiring this register. Writes are ignored and +reads will always return zero. + +.. only:: SUPERVISOR + + Supervisor Context register (``scontext``) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x7AA + + Reset Value: 0x0000_0000 + + Detailed: + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + + Accessible in Debug Mode or M-Mode. + CV32E40P does not support the features requiring this register. Writes are ignored and + reads will always return zero. + +Debug CSRs +:::::::::: + +.. _csr-dcsr: + +Debug Control and Status (``dcsr``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7B0 + +Reset Value: 0x4000_0003 + +.. note:: + + The **ebreaks**, **ebreaku** and **prv** bitfields of this CSR are marked as R/W in Debug Specification 0.13.2. However, + as CV32E40P only supports machine mode, these bitfields are implemented as WARL bitfields (corresponding to how these bitfields will + be specified in the forthcoming Debug Specification 0.14.0). + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+===========+=================================================================================================+ + | 31:28 | RO (0x4) | **xdebugver:** returns 4 - External debug support exists as it is described in this document. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 27:16 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 15 | RW | **ebreakm** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 14 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 13 | RO (0x0) | **ebreaks**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 12 | RO (0x0) | **ebreaku**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 11 | RW | **stepie** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 10 | RO (0x0) | **stopcount**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 9 | RO (0x0) | **stoptime**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 8:6 | RO | **cause** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 5 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 4 | RO (0x0) | **mprven**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 3 | RO (0x0) | **nmip**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 2 | RW | **step** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 1:0 | RO (0x3) | **prv:** returns the current priviledge mode | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + +.. _csr-dpc: + +Debug PC (``dpc``) +~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7B1 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=================================================================================================+ + | 31:1 | RO | zero | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | 0 | RO | DPC | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + +When the core enters in Debug Mode, DPC contains the virtual address of +the next instruction to be executed. + +Debug Scratch register 0/1 (``dscratch0/1``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x7B2/0x7B3 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=================================================================================================+ + | 31:0 | RW | DSCRATCH0/1 | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + +Performances counters +::::::::::::::::::::: + +.. only:: USER + + Machine Counter Enable (``mcounteren``) + --------------------------------------- + + CSR Address: 0x306 + + Reset Value: 0x0000_0000 + + Detailed: + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:4 | RW | Dependent on number of counters implemented in design parameter | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RW | **selectors:** hpmcounter3 enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | instret enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RW | cycle enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + + Each bit in the machine counter-enable register allows the associated read-only + unprivileged shadow performance register to be read from user mode. If the bit + is clear an attempt to read the register in user mode will trigger an illegal + instruction exception. + +Machine Counter-Inhibit register (``mcountinhibit``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x320 + +Reset Value: 0x0000_000D + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:4 | RW | Dependent on number of counters implemented in design parameter | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RW | **selectors:** mhpmcounter3 inhibit | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | minstret inhibit | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RW | mcycle inhibit | + +-----------+----------+------------------------------------------------------------------+ + +The performance counter inhibit control register. The default value is to inihibit counters out of reset. +The bit returns a read value of 0 for non implemented counters. This reset value +shows the result using the default number of performance counters to be 1. + +Machine Performance Monitoring Event Selector (``mhpmevent3 .. mhpmevent31``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x323 - 0x33F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:16 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 15:0 | RW | **selectors:** Each bit represent a unique event to count | + +-----------+----------+------------------------------------------------------------------+ + +The event selector fields are further described in Performance Counters section. +Non implemented counters always return a read value of 0. + +Machine Cycle Counter (``mcycle``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB00 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | The lower 32 bits of the 64 bit machine mode cycle counter. | + +-----------+----------+------------------------------------------------------------------+ + + +Machine Instructions-Retired Counter (``minstret``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB02 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+---------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+===========================================================================+ + | 31:0 | RW | The lower 32 bits of the 64 bit machine mode instruction retired counter. | + +-----------+----------+---------------------------------------------------------------------------+ + + +Machine Performance Monitoring Counter (``mhpmcounter3 .. mhpmcounter31``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB03 - 0xB1F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | Machine performance-monitoring counter | + +-----------+----------+------------------------------------------------------------------+ + +The lower 32 bits of the 64 bit machine performance-monitoring counter(s). +The number of machine performance-monitoring counters is determined by the parameter ``NUM_MHPMCOUNTERS`` with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0. + +Upper 32 bits Machine Cycle Counter (``mcycleh``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB80 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | The upper 32 bits of the 64 bit machine mode cycle counter. | + +-----------+----------+------------------------------------------------------------------+ + + +Upper 32 bits Machine Instructions-Retired Counter (``minstreth``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB82 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+---------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+===========================================================================+ + | 31:0 | RW | The upper 32 bits of the 64 bit machine mode instruction retired counter. | + +-----------+----------+---------------------------------------------------------------------------+ + + +Upper 32 bits Machine Performance Monitoring Counter (``mhpmcounter3h .. mhpmcounter31h``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xB83 - 0xB9F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | Machine performance-monitoring counter | + +-----------+----------+------------------------------------------------------------------+ + +The upper 32 bits of the 64 bit machine performance-monitoring counter(s). +The number of machine performance-monitoring counters is determined by the parameter ``NUM_MHPMCOUNTERS`` with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0. + +Cycle Counter (``cycle``) +~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC00 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode cycle counter. + +Instructions-Retired Counter (``instret``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC02 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode instruction retired counter. + +Performance Monitoring Counter (``hpmcounter3 .. hpmcounter31``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC03 - 0xC1F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0. + +Upper 32 bits Cycle Counter (``cycleh``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC80 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode cycle counter. + +Upper 32 bits Instructions-Retired Counter (``instreth``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC82 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode instruction retired counter. + +Upper 32 bits Performance Monitoring Counter (``hpmcounter3h .. hpmcounter31h``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC83 - 0xC9F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0. + +ID CSRs +::::::: + +Machine ISA (``misa``) +~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x301 + +Reset Value: defined + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+------------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+============+========================================================================+ + | 31:30 | RO (0x1) | **MXL** (Machine XLEN) | + +-------------+------------+------------------------------------------------------------------------+ + | 29:26 | RO (0x0) | (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 25 | RO (0x0) | **Z** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 24 | RO (0x0) | **Y** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 23 | RO | **X** (Non-standard extensions present) | + +-------------+------------+------------------------------------------------------------------------+ + | 22 | RO (0x0) | **W** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 21 | RO (0x0) | **V** (Tentatively reserved for Vector extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 20 | RO (0x0) | **U** (User mode implemented) | + +-------------+------------+------------------------------------------------------------------------+ + | 19 | RO (0x0) | **T** (Tentatively reserved for Transactional Memory extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 18 | RO (0x0) | **S** (Supervisor mode implemented) | + +-------------+------------+------------------------------------------------------------------------+ + | 17 | RO (0x0) | **R** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 16 | RO (0x0) | **Q** (Quad-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 15 | RO (0x0) | **P** (Tentatively reserved for Packed-SIMD extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 14 | RO (0x0) | **O** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 13 | RO (0x0) | **N** (User-level interrupts supported) | + +-------------+------------+------------------------------------------------------------------------+ + | 12 | RO (0x1) | **M** (Integer Multiply/Divide extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 11 | RO (0x0) | **L** (Tentatively reserved for Decimal Floating-Point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 10 | RO (0x0) | **K** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 9 | RO (0x0) | **J** (Tentatively reserved for Dynamically Translated Languages | + | | | extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 8 | RO (0x1) | **I** (RV32I/64I/128I base ISA) | + +-------------+------------+------------------------------------------------------------------------+ + | 7 | RO (0x0) | **H** (Hypervisor extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 6 | RO (0x0) | **G** (Additional standard extensions present) | + +-------------+------------+------------------------------------------------------------------------+ + | 5 | RO | **F** (Single-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 4 | RO (0x0) | **E** (RV32E base ISA) | + +-------------+------------+------------------------------------------------------------------------+ + | 3 | RO (0x0) | **D** (Double-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 2 | RO (0x1) | **C** (Compressed extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 1 | RO (0x0) | **B** (Tentatively reserved for Bit-Manipulation extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 0 | RO (0x0) | **A** (Atomic extension) | + +-------------+------------+------------------------------------------------------------------------+ + +Writes are ignored and all bitfields in the ``misa`` CSR area read as 0 except for the following: + +* **C** = 1 +* **F** = 1 if ``FPU`` = 1 and ``ZFINX`` = 0 +* **I** = 1 +* **M** = 1 +* **X** = 1 if ``COREV_PULP`` = 1 or ``COREV_CLUSTER`` = 1 +* **MXL** = 1 (i.e. XLEN = 32) + +Machine Vendor ID (``mvendorid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xF11 + +Reset Value: 0x0000_0602 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:7 | RO | 0xC. Number of continuation codes in JEDEC manufacturer ID. | + +-------------+-----------+------------------------------------------------------------------------+ + | 6:0 | RO | 0x2. Final byte of JEDEC manufacturer ID, discarding the parity bit. | + +-------------+-----------+------------------------------------------------------------------------+ + +The ``mvendorid`` encodes the OpenHW JEDEC Manufacturer ID, which is 2 decimal (bank 13). + +Machine Architecture ID (``marchid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xF12 + +Reset Value: 0x0000_0004 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | Machine Architecture ID of CV32E40P is 4 | + +-------------+-----------+------------------------------------------------------------------------+ + +Machine Implementation ID (``mimpid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xF13 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | 0 | + +-------------+-----------+------------------------------------------------------------------------+ + +.. _csr-mhartid: + +Hardware Thread ID (``mhartid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xF14 + +Reset Value: Defined + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | + +-------------+-----------+----------------------------------------------------------------+ + +.. Comment: no attempt has been made to update these "USER" CSR descriptions +.. only:: USER + + User Trap-Vector Base Address (``utvec``) + ----------------------------------------- + + CSR Address: 0x005 + + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===============================================================================================================+ + | 31 : 2 | RW | BASE: The trap-handler base address, always aligned to 256 bytes, i.e., utvec[7:2] is always set to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 1 | RO | MODE[1]: Always 0 | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 0 | RW | MODE[0]: 0 = direct mode, 1 = vectored mode. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + + When an exception is encountered in user-mode, the core jumps to the + corresponding handler using the content of the UTVEC[31:8] as base + address. Only 8-byte aligned addresses are allowed. Both direct mode + and vectored mode are supported. + + User Exception PC (``uepc``) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x041 + + Reset Value: 0x0000_0000 + + Detailed: + + +------+-------+ + | 31 | 30: 0 | + +======+=======+ + | UEPC | | + +------+-------+ + + When an exception is encountered in user mode, the current program + counter is saved in UEPC, and the core jumps to the exception address. + When a uret instruction is executed, the value from UEPC replaces the + current program counter. + + User Cause (``ucause``) + ~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x042 + + Reset Value: 0x0000_0000 + + Detailed: + + +-------------+-----------+------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+====================================================================================+ + | 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | + +-------------+-----------+------------------------------------------------------------------------------------+ + | 30:5 | RO (0) | Always 0 | + +-------------+-----------+------------------------------------------------------------------------------------+ + | 4:0 | RW | **Exception Code** (See note below) | + +-------------+-----------+------------------------------------------------------------------------------------+ + + **NOTE**: software accesses to `ucause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, + when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. + + +.. only:: PMP + + PMP Configuration (``pmpcfgx``) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x3A{0,1,2,3} + + Reset Value: 0x0000_0000 + + Detailed: + + +----------+ + | 31 : 0 | + +==========+ + | PMPCFGx | + +----------+ + + If the PMP is enabled, these four registers contain the configuration of + the PMP as specified by the official privileged spec 1.10. + + PMP Address (``pmpaddrx``) + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CSR Address: 0x3B{0x0, 0x1, …. 0xF} + + Reset Value: 0x0000_0000 + + Detailed: + + +----------+ + | 31 : 0 | + +==========+ + | PMPADDRx | + +----------+ + + If the PMP is enabled, these sixteen registers contain the addresses of + the PMP as specified by the official privileged spec 1.10. + +Non-RISC-V CSRs +::::::::::::::: + +.. _csr-uhartid: + +User Hardware Thread ID (``uhartid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCD0 (only present if ``COREV_PULP`` = 1 and ``PULP_SECURE`` = 1) + +Reset Value: Defined + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | + +-------------+-----------+----------------------------------------------------------------+ + +Similar to ``mhartid`` the ``uhartid`` provides the Hardware Thread ID. It differs from ``mhartid`` only in the required privilege level. +On CV32E40P, as it is a machine mode only implementation, this difference is not noticeable. + +Privilege Level (``privlv``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCD1 (only present if ``COREV_PULP`` = 1 and ``PULP_SECURE`` = 1) + +Reset Value: 0x0000_0003 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+--------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==================================================+ + | 31:2 | RO | Reads as 0. | + +-------------+-----------+--------------------------------------------------+ + | 1:0 | RO | Current Privilege Level | + | | | | + | | | 00 = User | + | | | | + | | | 01 = Supervisor | + | | | | + | | | 10 = Hypervisor | + | | | | + | | | 11 = Machine | + | | | | + | | | CV32E40P only supports Machine mode. | + +-------------+-----------+--------------------------------------------------+ + +.. _csr-zfinx: + +ZFINX ISA (``zfinx``) +~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xCD2 + +Reset Value: Defined + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:1 | RO | Hardwired to 0. | + +-------------+-----------+----------------------------------------------------------------+ + | 0 | RO | 1 if ``FPU`` = 1 and ``ZFINX`` = 1 else 0. | + +-------------+-----------+----------------------------------------------------------------+ diff --git a/docs/html/_sources/core_versions.rst.txt b/docs/html/_sources/core_versions.rst.txt new file mode 100644 index 000000000..9af9a71dd --- /dev/null +++ b/docs/html/_sources/core_versions.rst.txt @@ -0,0 +1,183 @@ +.. + Copyright (c) 2020 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _core_versions: + +Core Versions and RTL Freeze Rules +================================== + +The CV32E40P is defined by the ``marchid`` and ``mimpid`` tuple. +The tuple identify which sets of parameters have been verified +by OpenHW Group, and once RTL Freeze is achieved, no further +non-logically equivalent changes are allowed on that set of parameters. + +The RTL Freeze version of the core is indentified by a GitHub +tag with the format cv32e40p_vMAJOR.MINOR.PATCH (e.g. cv32e40p_v1.0.0). +In addition, the release date is reported in the documentation. + +What happens after RTL Freeze? +------------------------------ + +RTL changes on verified parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Minor changes to the RTL on a frozen parameter set (e.g., nicer RTL code, clearer RTL code, etc) are allowed if, and only if, they are logically equivalent to the frozen (tagged) version of the core. +This is guaranteed by a CI flow that checks that pull requests are logically equivalent to a specific tag of the core as +explained `here `_. +For example, suppose we re-write "better" a portion of the ALU that affects the frozen set of parameters of the version cv32e40p_v1.0.0, +for instance, the adder. In that case, the proposed changes are compared with the code based on cv32e40p_v1.0.0, and if they are logically equivalent, they are accepted. Otherwise, they are rejected. See below for more case scenarios. + + +A bug is found +^^^^^^^^^^^^^^ + +If a bug is found that affect the already frozen parameter set, +the RTL changes required to fix such bug are non-logically equivalent by definition. +Therefore, the RTL changes are applied only on a different ``mimpid`` +value and the bug and the fix must be documented. +These changes are visible by software as the ``mimpid`` has a different value. +Every bug or set of bugs found must be followed by another RTL Freeze release and a new GitHub tag. + +RTL changes on non-verified yet parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If changes affecting the core on a non-frozen parameter set are required, +as for example, to fix bugs found in the communication to the FPU (e.g., affecting the core only if ``FPU=1``), +or to change the ISA Extensions decoding of PULP instructions (e.g., affecting the core only if ``PULP_XPULP=1``), +then such changes must remain logically equivalent for the already frozen set of parameters (except for the required ``mimpid`` update), and they must be applied on a different ``mimpid`` value. They can be non-logically equivalent to a non-frozen set of parameters. +These changes are visible by software as the ``mimpid`` has a different value. +Once the new set of parameters is verified and achieved the sign-off for RTL freeze, +a new GitHub tag and version of the core is released. + +PPA optimizations and new features +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Non-logically equivalent PPA optimizations and new features are not allowed on a given set +of RTL frozen parameters (e.g., a faster divider). +If PPA optimizations are logically-equivalent instead, they can be applied without +changing the ``mimpid`` value (as such changes are not visible in software). +However, a new GitHub tag should be release and changes documented. + +:numref:`rtl_freeze_rules` shows the aforementioned rules. + +.. figure:: ../images/rtl_freeze_rules.png + :name: rtl_freeze_rules + :align: center + :alt: + + Versions control of CV32E40P + +.. _backward_compatibility: + +Non-backward compatibility +-------------------------- + +For cv32e40p_v2.0.0, some modifications have been done on ``cv32e40p_top`` and ``cv32e40p_core`` parameters names. + +It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, backward compatibility is still correct as all parameters default values are set to v1 values. + +Parameters +^^^^^^^^^^ + +As RTL has been updated to fully support ratified RISC-V Zfinx, old PULP_ZFINX parameter has been renamed ZFINX in all design and verification files. + +To differentiate v1 to v2 encoding of PULP instructions, old PULP_XPULP and PULP_CLUSTER parameters have been renamed COREV_PULP and COREV_CLUSTER in all design and verification files. + +To easily change FPU instructions latencies, 2 new parameters have been added, FPU_ADDMUL_LAT for Addition/Multiplication lane and FPU_OTHERS_LAT for the other instructions (move, conversion, comparison...). + + +Released core versions +---------------------- + +The verified parameter sets of the core, their implementation version, GitHub tags, and dates are reported here. + +cv32e40p_v1.0.0 +^^^^^^^^^^^^^^^ + ++--------------------+-------------------+------------+--------------------+---------+ +| Git Tag | Tagged By | Date | Reason for Release | Comment | ++====================+===================+============+====================+=========+ +| cv32e40p_v1.0.0 | Arjan Bink | 2020-12-10 | RTL Freeze | | ++--------------------+-------------------+------------+--------------------+---------+ + +For this release ``mimpid`` value is fixed and is equal to ``0``. + +It refers to the CV32E40P core verified with the following parameters: + ++---------------------------+-------+ +| Name | Value | ++===========================+=======+ +| ``FPU`` | 0 | ++---------------------------+-------+ +| ``PULP_ZFINX`` | 0 | ++---------------------------+-------+ +| ``PULP_XPULP`` | 0 | ++---------------------------+-------+ +| ``PULP_CLUSTER`` | 0 | ++---------------------------+-------+ +| ``NUM_MHPMCOUNTERS`` | 1 | ++---------------------------+-------+ + +The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at: + +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Design_openissues.md +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Verification_openissues.md +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Documentation_openissues.md + +cv32e40p_v2.0.0 +^^^^^^^^^^^^^^^ + ++--------------------+-------------------+------------+--------------------+---------+ +| Git Tag | Tagged By | Date | Reason for Release | Comment | ++====================+===================+============+====================+=========+ +| cv32e40p_v2.0.0 | | | RTL Freeze | | ++--------------------+-------------------+------------+--------------------+---------+ + +For this release ``mimpid`` value is depending of parameters value. + +mimpid = 0 +~~~~~~~~~~ + +When parameters are set with the exact same values than for cv32e40p_v1.0.0 release then ``mimpid`` value is equal to ``0``. + ++---------------------------+-------+ +| Name | Value | ++===========================+=======+ +| ``FPU`` | 0 | ++---------------------------+-------+ +| ``ZFINX`` | 0 | ++---------------------------+-------+ +| ``COREV_PULP`` | 0 | ++---------------------------+-------+ +| ``COREV_CLUSTER`` | 0 | ++---------------------------+-------+ +| ``NUM_MHPMCOUNTERS`` | 1 | ++---------------------------+-------+ + +mimpid = 1 +~~~~~~~~~~ + +When one parameter is set with a different value than for cv32e40p_v1.0.0 release then ``mimpid`` value is equal to ``1``. + +This means either ``FPU``, ``ZFINX``, ``COREV_PULP`` or ``COREV_CLUSTER`` is set to 1. +Or ``NUM_MHPMCOUNTERS`` is set to a value greater than 1. + +.. The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at: + + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Design_openissues.md + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Verification_openissues.md + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Documentation_openissues.md diff --git a/docs/html/_sources/corev_hw_loop.rst.txt b/docs/html/_sources/corev_hw_loop.rst.txt new file mode 100644 index 000000000..11e422b31 --- /dev/null +++ b/docs/html/_sources/corev_hw_loop.rst.txt @@ -0,0 +1,131 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _hwloop-specs: + +CORE-V Hardware Loop Extensions +=============================== + +To increase the efficiency of small loops, CV32E40P supports hardware +loops (HWLoop). They can be enabled by setting the ``COREV_PULP`` parameter. +Hardware loops make executing a piece of code +multiple times possible, without the overhead of branches penalty or updating a counter. +Hardware loops involve zero stall cycles for jumping to the first +instruction of a loop. + +A hardware loop is defined by its start address (pointing to the first +instruction in the loop), its end address (pointing to the instruction +just after the last one executed by the loop) and a counter that is +decremented every time the last instruction of the loop body is executed. + +CV32E40P contains two hardware loop register sets to support nested hardware loops, +each of them can store these three values in separate flip flops which are +mapped in the CSR address space. +Loop number 0 has higher priority than loop number 1 in a nested loop +configuration, meaning that loop 0 represents the inner loop and loop 1 is the outer loop. + +Hardware Loop constraints +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Following constraints must be respected by any toolchain compiler or by hand-written assembly code. +``Violation of these constraints will not generate any hardware exception`` and behaviour is undefined. + +In order to catch **as early as possible** those software exceptions when executing a program either +on a verification Reference Model or on a virtual platform Instruction Set Simulator, ``those model/simulation platforms +must generate a fatal error`` with a meaningfull message related to Hardware Loops constraints violation. + +The HWLoop constraints are: + +- Start and End addresses of an HWLoop must be 32-bit aligned. + +- End Address must be strictly greater than Start Address. + +- End address of an HWLoop must point to the instruction just after the last one of the HWLoop body. + +- HWLoop body must contain at least 3 instructions. + +- When both loops are nested, the End address of the outermost HWLoop (must be #1) must be at least 2 + instructions further than the End address of the innermost HWLoop (must be #0), + i.e. HWLoop[1].endaddress >= HWLoop[0].endaddress + 8. + +- HWLoop must always be entered from its start location (no branch/jump to a location inside a HWLoop body). + +- No HWLoop #0 (resp. #1) CSR should be modified inside the HWLoop #0 (resp. #1) body. + +- No Compressed instructions (RVC) allowed in the HWLoop body. + +- No jump or branch instructions allowed in the HWLoop body. + +- No memory ordering instructions (fence, fence.i) allowed in the HWLoop body. + +- No privileged instructions (mret, dret, ecall, wfi) allowed in the HWLoop body, except for ebreak. + +The rationale of NOT generating any hardware exception when violating any of those constraints is that it would add resources +(32-bit adders and substractors needed for the third and fourth rules) which are costly in area and power consumption. +These additional (and costly) resources would be present just to catch situations that should never happen. +This in an architectural choice in order to keep CV32E40P area and power consumption to its lowest level. + +The rationale of putting the end-of-loop label to the first instruction after the last one of the loop body +is that it greatly simplifies compiler optimization (relative to basic blocks management). + +In order to use hardware loops, the compiler needs to setup the loops beforehand with cv.start/i, cv.end/i, cv.count/i or cv.setup/i instructions. +The compiler will use HWLoop automatically whenever possible without the need of assembly. + +For debugging and context switches, the hardware loop registers are mapped into the CSR custom read-only address space. +To read them csrr instructions should be used and to write them register flavour of hardware loop instructions should be used. +Using csrw instructions to write hardware loop registers will generate an illegal instruction exception. + +Since hardware loop feature could be used in interrupt routine/handler, the registers have +to be saved (resp. restored) at the beginning (resp. end) of the interrupt routine together with the general purpose registers. +The CSR HWLoop registers are described in the :ref:`cs-registers` section. + +Below an assembly code example of a nested HWLoop that computes a matrix addition. + +.. code-block:: c + :linenos: + + asm volatile ( + "add %[i],x0, x0;" + "add %[j],x0, x0;" + "cv.count 1, %[N];" + "cv.endi 1, endO;" + "cv.starti 1, startO;" + "cv.endi 0, endZ;" + "cv.starti 0, startZ;" + ".align 4;" + ".option norvc;" + "startO:;" + " cv.count 0, %[N];" + " startZ:;" + " addi %[i], %[i], 1;" + " addi %[i], %[i], 1;" + " addi %[i], %[i], 1;" + " endZ:;" + " addi %[j], %[j], 2;" + " addi %[j], %[j], 2;" + "endO:;" + : [i] "+r" (i), [j] "+r" (j) + : [N] "r" (10) + ); + + +At the beginning of the HWLoop, the registers %[i] and %[j] are 0. +The innermost loop, from startZ to (endZ - 4), adds to %[i] three times 1 and +it is executed 10x10 times. Whereas the outermost loop, from startO to (endO - 4), +executes 10 times the innermost loop and adds two times 2 to the register %[j]. +At the end of the loop, the register %[i] contains 300 and the register %[j] contains 40. + diff --git a/docs/html/_sources/debug.rst.txt b/docs/html/_sources/debug.rst.txt new file mode 100644 index 000000000..654183912 --- /dev/null +++ b/docs/html/_sources/debug.rst.txt @@ -0,0 +1,214 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _debug-support: + +Debug & Trigger +=============== + +CV32E40P offers support for execution-based debug according to the `RISC-V Debug Specification `_, version 0.13.2. +The main requirements for the core are described in Chapter 4: RISC-V Debug, Chapter 5: Trigger Module, and Appendix A.2: Execution Based. + +The following list shows the simplified overview of events that occur in the core when debug is requested: + + #. Enters Debug Mode + #. Saves the PC to DPC + #. Updates the cause in the DCSR + #. Points the PC to the location determined by the input port dm_haltaddr_i + #. Begins executing debug control code. + + +Debug Mode can be entered by one of the following conditions: + + - External debug event using the debug_req_i signal + - Trigger Module match event + - ebreak instruction when not in Debug Mode and when DCSR.EBREAKM == 1 (see :ref:`ebreak_behavior` below) + +A user wishing to perform an abstract access, whereby the user can observe or control a core’s GPR (either integer of floating-point one) or CSR register from the hart, +is done by invoking debug control code to move values to and from internal registers to an externally addressable Debug Module (DM). +Using this execution-based debug allows for the reduction of the overall number of debug interface signals. + +.. note:: + + Debug support in CV32E40P is only one of the components needed to build a System on Chip design with run-control debug support (think "the ability to attach GDB to a core over JTAG"). + Additionally, a Debug Module and a Debug Transport Module, compliant with the RISC-V Debug Specification, are needed. + + A supported open source implementation of these building blocks can be found in the `RISC-V Debug Support for PULP Cores IP block `_. + + +The CV3240P also supports a Trigger Module to enable entry into Debug Mode on a trigger event with the following features: + + - Number of trigger register(s) : 1 + - Supported trigger types: instruction address match (Match Control) + +The CV32E40P will not support the optional debug features 10, 11, & 12 listed in Section 4.1 of the `RISC-V Debug Specification `_. +Specifically, a control transfer instruction's destination location being in or out of the Program Buffer and instructions depending on PC value shall **not** cause an illegal instruction. + +Debug Interface +--------------- + +.. table:: Debug interface signals + :name: Debug interface signals + :widths: 30 15 55 + :class: no-scrollbar-table + + +-------------------------------+---------------+--------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +===============================+===============+============================================+ + | ``debug_req_i`` | input | Request to enter Debug Mode | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_havereset_o`` | output | Debug status: Core has been reset | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_running_o`` | output | Debug status: Core is running | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_halted_o`` | output | Debug status: Core is halted | + +-------------------------------+---------------+--------------------------------------------+ + | ``dm_halt_addr_i[31:0]`` | input | Address for debugger entry | + +-------------------------------+---------------+--------------------------------------------+ + | ``dm_exception_addr_i[31:0]`` | input | Address for debugger exception entry | + +-------------------------------+---------------+--------------------------------------------+ + +``debug_req_i`` is the "debug interrupt", issued by the debug module when the core should enter Debug Mode. +The ``debug_req_i`` is synchronous to ``clk_i`` and requires a minimum assertion of one clock period to enter Debug Mode. +The instruction being decoded during the same cycle that ``debug_req_i`` is first asserted shall not be executed before entering Debug Mode. + +``debug_havereset_o``, ``debug_running_o`` and ``debug_mode_o`` signals provide the operational status of the core to the debug module. +The assertion of these signals is mutually exclusive. + +``debug_havereset_o`` is used to signal that the CV32E40P has been reset. ``debug_havereset_o`` is set high during the assertion of ``rst_ni``. +It will be cleared low a few (unspecified) cycles after ``rst_ni`` has been deasserted **and** ``fetch_enable_i`` has been sampled high. + +``debug_running_o`` is used to signal that the CV32E40P is running normally. + +``debug_halted_o`` is used to signal that the CV32E40P is in debug mode. + +``dm_halt_addr_i`` is the address where the PC jumps to for a debug entry event. When in Debug Mode, an ebreak instruction will also cause the PC +to jump back to this address without affecting status registers (see :ref:`ebreak_behavior` below). + +``dm_exception_addr_i`` is the address where the PC jumps to when an exception occurs during Debug Mode. +When in Debug Mode, the mret or uret instruction will also cause the PC to jump back to this address without affecting status registers. + +Both ``dm_halt_addr_i`` and ``dm_exception_addr_i`` must be word aligned. + +Core Debug Registers +-------------------- + +CV32E40P implements four core debug registers, namely :ref:`csr-dcsr`, :ref:`csr-dpc` and two debug scratch registers. +Access to these registers in non Debug Mode results in an illegal instruction. + +Several trigger registers are required to adhere to specification. The following are the most relevant: :ref:`csr-tselect`, :ref:`csr-tdata1`, :ref:`csr-tdata2` and :ref:`csr-tinfo`. + +The TDATA1.DMODE is hardwired to a value of 1. In non Debug Mode, writes to Trigger registers are ignored and reads reflect CSR values. + +Debug state +----------- + +As specified in `RISC-V Debug Specification `_ every hart that can be selected by +the Debug Module is in exactly one of four states: ``nonexistent``, ``unavailable``, ``running`` or ``halted``. + +The remainder of this section assumes that the CV32E40P will not be classified as ``nonexistent`` by the integrator. + +The CV32E40P signals to the Debug Module whether it is ``running`` or ``halted`` via its ``debug_running_o`` and ``debug_halted_o`` pins +respectively. Therefore, assuming that this core will not be integrated as a ``nonexistent`` core, the CV32E40P is classified as ``unavailable`` +when neither ``debug_running_o`` or ``debug_halted_o`` is asserted. Upon ``rst_ni`` assertion the debug state will be ``unavailable`` until some +cycle(s) after ``rst_ni`` has been deasserted and ``fetch_enable_i`` has been sampled high. After this point (until a next reset assertion) the +core will transition between having its ``debug_halted_o`` or ``debug_running_o`` pin asserted depending whether the core is in debug mode or not. +Exactly one of the ``debug_havereset_o``, ``debug_running_o`` or ``debug_halted_o`` is asserted at all times. + +:numref:`debug-running` and show :numref:`debug-halted` show typical examples of transitioning into the ``running`` and ``halted`` states. + +.. figure:: ../images/debug_running.svg + :name: debug-running + :align: center + :alt: + + Transition into debug ``running`` state + +.. figure:: ../images/debug_halted.svg + :name: debug-halted + :align: center + :alt: + + Transition into debug ``halted`` state + +The key properties of the debug states are: + + * The CV32E40P can remain in its ``unavailable`` state for an arbitrarily long time (depending on ``rst_ni`` and ``fetch_enable_i``). + * If ``debug_req_i`` is asserted after ``rst_ni`` deassertion and before or coincident with the assertion of ``fetch_enable_i``, then the CV32E40P + is guaranteed to transition straight from its ``unavailable`` state into its ``halted`` state. If ``debug_req_i`` is asserted at a later + point in time, then the CV32E40P might transition through the ``running`` state on its ways to the ``halted`` state. + * If ``debug_req_i`` is asserted during the ``running`` state, the core will eventually transition into the ``halted`` state (typically after a couple of cycles). + +.. _ebreak_behavior: + +EBREAK Behavior +-------------------- + +The EBREAK instruction description is distributed across several RISC-V specifications: `RISC-V Debug Specification `_, +`RISC-V Priveleged Specification `_, +`RISC-V ISA `_. The following is a summary of the behavior for three common scenarios. + +Scenario 1 : Enter Exception +"""""""""""""""""""""""""""" + +Executing the EBREAK instruction when the core is **not** in Debug Mode and the DCSR.EBREAKM == 0 shall result in the following actions: + + - The core enters the exception handler routine located at MTVEC (Debug Mode is not entered) + - MEPC & MCAUSE are updated + +To properly return from the exception, the ebreak handler will need to increment the MEPC to the next instruction. +This requires querying the size of the ebreak instruction that was used to enter the exception (16 bit c.ebreak or 32 bit ebreak). + +.. note:: + + The CV32E40P does not support MTVAL CSR register which would have saved the value of the instruction for exceptions. This may be supported on a future core. + +Scenario 2 : Enter Debug Mode +""""""""""""""""""""""""""""" + +Executing the EBREAK instruction when the core is **not** in Debug Mode and the DCSR.EBREAKM == 1 shall result in the following actions: + +- The core enters Debug Mode and starts executing debug code located at ``dm_halt_addr_i`` (exception routine not called) +- DPC & DCSR are updated + +Similar to the exception scenario above, the debugger will need to increment the DPC to the next instruction before returning from Debug Mode. + +.. note:: + + The default value of DCSR.EBREAKM is 0 and the DCSR is only accessible in Debug Mode. To enter Debug Mode from EBREAK, + the user will first need to enter Debug Mode through some other means, such as from the external ``debug_req_i``, and set DCSR.EBREAKM. + +Scenario 3 : Exit Program Buffer & Restart Debug Code +""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Executing the EBREAK instruction when the core is in Debug Mode shall result in the following actions: + +- The core remains in Debug Mode and execution jumps back to the beginning of the debug code located at ``dm_halt_addr_i`` +- none of the CSRs are modified + + +.. _interrupts_single-stepping: + +Interrupts during Single-Step Behavior +-------------------------------------- + +The CV32E40P is not compliant with the intended interpretation of the RISC-V Debug spec 0.13.2 specification when interrupts occur during Single-Steps. +However, the intended behavior has been clarified a posteriori only in version 1.0.0. +See https://github.com/riscv/riscv-debug-spec/issues/510. +The CV32E40P executes the first instruction of the interrupt handler and retires it before re-entering in Debug Mode, which is prohibited in version 1.0.0 but not specified in 0.13.2. +For details about the specific use-case, please refer to https://github.com/openhwgroup/core-v-verif/issues/904. + diff --git a/docs/html/_sources/exceptions_interrupts.rst.txt b/docs/html/_sources/exceptions_interrupts.rst.txt new file mode 100644 index 000000000..086ce723a --- /dev/null +++ b/docs/html/_sources/exceptions_interrupts.rst.txt @@ -0,0 +1,195 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _exceptions-interrupts: + +Exceptions and Interrupts +========================= + +CV32E40P implements trap handling for interrupts and exceptions according to the RISC-V Privileged Specification, version 1.11. +The ``irq_i[31:16]`` interrupts are a custom extension. + +When entering an interrupt/exception handler, the core sets the ``mepc`` CSR to the current program counter and saves ``mstatus``.MIE to ``mstatus``.MPIE. +All exceptions cause the core to jump to the base address of the vector table in the ``mtvec`` CSR. +Interrupts are handled in either direct mode or vectored mode depending on the value of ``mtvec``.MODE. In direct mode the core +jumps to the base address of the vector table in the ``mtvec`` CSR. In vectored mode the core jumps to the base address +plus four times the interrupt ID. Upon executing an MRET instruction, the core jumps to the program counter previously saved in the +``mepc`` CSR and restores ``mstatus``.MPIE to ``mstatus``.MIE. + +The base address of the vector table must be aligned to 256 bytes (i.e., its least significant byte must be 0x00) and can be programmed +by writing to the ``mtvec`` CSR. For more information, see the :ref:`cs-registers` documentation. + +The core starts fetching at the address defined by ``boot_addr_i``. It is assumed that the boot address is supplied via a register +to avoid long paths to the instruction fetch unit. + +Interrupt Interface +------------------- + +:numref:`Interrupt interface signals` describes the interrupt interface. + +.. table:: Interrupt interface signals + :name: Interrupt interface signals + :widths: 20 15 65 + :class: no-scrollbar-table + + +-------------------------+---------------+--------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +=========================+===============+==================================================+ + | ``irq_i[31:0]`` | input | Level sensistive active high interrupt inputs. | + | | | Not all interrupt inputs can be used on | + | | | CV32E40P. Specifically irq_i[15:12], | + | | | irq_i[10:8], irq_i[6:4] and irq_i[2:0] shall be | + | | | tied to 0 externally as they are reserved for | + | | | future standard use (or for cores which are not | + | | | Machine mode only) in the RISC-V Privileged | + | | | specification. | + | | | | + | | | irq_i[11], irq_i[7], and irq_i[3] | + | | | correspond to the Machine External | + | | | Interrupt (MEI), Machine Timer Interrupt (MTI), | + | | | and Machine Software Interrupt (MSI) | + | | | respectively. | + | | | | + | | | The irq_i[31:16] interrupts | + | | | are a CV32E40P specific extension to the RISC-V | + | | | Basic (a.k.a. CLINT) interrupt scheme. | + +-------------------------+---------------+--------------------------------------------------+ + | ``irq_ack_o`` | output | Interrupt acknowledge | + | | | | + | | | Set to 1 for one cycle | + | | | when the interrupt with ID ``irq_id_o[4:0]`` is | + | | | taken. | + +-------------------------+---------------+--------------------------------------------------+ + | ``irq_id_o[4:0]`` | output | Interrupt index for taken interrupt | + | | | | + | | | Only valid when ``irq_ack_o`` = 1. | + +-------------------------+---------------+--------------------------------------------------+ + +Interrupts +---------- + +The ``irq_i[31:0]`` interrupts are controlled via the ``mstatus``, ``mie`` and ``mip`` CSRs. CV32E40P uses the upper 16 bits of ``mie`` and ``mip`` for custom interrupts (``irq_i[31:16]``), +which reflects an intended custom extension in the RISC-V Basic (a.k.a. CLINT) interrupt architecture. +After reset, all interrupts are disabled. +To enable interrupts, both the global interrupt enable (MIE) bit in the ``mstatus`` CSR and the corresponding individual interrupt enable bit in the ``mie`` CSR need to be set. +For more information, see the :ref:`cs-registers` documentation. + +If multiple interrupts are pending, they are handled in the fixed priority order defined by the RISC-V Privileged Specification, version 1.11 (see Machine Interrupt Registers, Section 3.1.9). +The highest priority is given to the interrupt with the highest ID, except for the Machine Timer Interrupt, which has the lowest priority. So from high to low priority the interrupts are +ordered as follows: ``irq_i[31]``, ``irq_i[30]``, ..., ``irq_i[16]``, ``irq_i[11]``, ``irq_i[3]``, ``irq_i[7]``. + +All interrupt lines are level-sensitive. There are two supported mechanisms by which interrupts can be cleared at the external source. + +* A software-based mechanism in which the interrupt handler signals completion of the handling routine to the interrupt source, e.g., through a memory-mapped register, which then deasserts the corresponding interrupt line. +* A hardware-based mechanism in which the ``irq_ack_o`` and ``irq_id_o[4:0]`` signals are used to clear the interrupt sourcee, e.g. by an external interrupt controller. ``irq_ack_o`` is a 1 ``clk_i`` cycle pulse during which ``irq_id_o[4:0]`` reflects the index in ``irq_id[*]`` of the taken interrupt. + +In Debug Mode, all interrupts are ignored independent of ``mstatus``.MIE and the content of the ``mie`` CSR. + +Exceptions +---------- + +CV32E40P can trigger an exception due to the following exception causes: + +.. table:: Exceptions + :name: Exceptions + :widths: 20 80 + :class: no-scrollbar-table + + +--------------------+---------------------------------------------------------------+ + | **Exception Code** | **Description** | + +====================+===============================================================+ + | 2 | Illegal instruction | + +--------------------+---------------------------------------------------------------+ + | 3 | Breakpoint | + +--------------------+---------------------------------------------------------------+ + | 11 | Environment call from M-Mode (ECALL) | + +--------------------+---------------------------------------------------------------+ + +The illegal instruction exception and M-Mode ECALL instruction exceptions cannot be disabled and are always active. +The core raises an illegal instruction exception for any instruction in the RISC-V privileged and unprivileged specifications that is explicitly defined as being illegal according to the ISA implemented by the core, as well as for any instruction that is left undefined in these specifications unless the instruction encoding is configured as a custom CV32E40P instruction for specific parameter settings as defined in (see :ref:`custom-isa-extensions`). +For example, in case the parameter ``FPU`` is set to 0, the CV32E40P raises an illegal instruction exception for any RVF instruction or CSR instruction trying to access F CSRs. +The same concerns PULP extensions everytime both parameters ``COREV_PULP`` and ``CORE_CLUSTER`` are set to 0 (see :ref:`core-integration`). + +.. only:: PMP + + +----------------+---------------------------------------------------------------+ + | Exception Code | Description | + +----------------+---------------------------------------------------------------+ + | 1 | Instruction access fault | + +----------------+---------------------------------------------------------------+ + | 5 | Load access fault | + +----------------+---------------------------------------------------------------+ + | 7 | Store access fault | + +----------------+---------------------------------------------------------------+ + + The instruction access fault and load-store access faults cannot be disabled and are always active. The PMP + itself can be disabled. + +.. only:: USER + + +----------------+---------------------------------------------------------------+ + | Exception Code | Description | + +----------------+---------------------------------------------------------------+ + | 8 | Environment call from U-Mode (ECALL) | + +----------------+---------------------------------------------------------------+ + + The U-Mode ECALL instruction exception cannot be disabled and is always active. + +Nested Interrupt/Exception Handling +----------------------------------- + +CV32E40P does support nested interrupt/exception handling in software. +The hardware automatically disables interrupts upon entering an interrupt/exception handler. +Otherwise, interrupts/exceptions during the critical part of the handler, i.e. before software has saved the ``mepc`` and ``mstatus`` CSRs, would cause those CSRs to be overwritten. +If desired, software can explicitly enable interrupts by setting ``mstatus``.MIE to 1 from within the handler. +However, software should only do this after saving ``mepc`` and ``mstatus``. +There is no limit on the maximum number of nested interrupts. +Note that, after enabling interrupts by setting ``mstatus``.MIE to 1, the current handler will be interrupted also by lower priority interrupts. +To allow higher priority interrupts only, the handler must configure ``mie`` accordingly. + +The following pseudo-code snippet visualizes how to perform nested interrupt handling in software. + +.. code-block:: c + :linenos: + + isr_handle_nested_interrupts(id) { + // Save mpec and mstatus to stack + mepc_bak = mepc; + mstatus_bak = mstatus; + + // Save mie to stack (optional) + mie_bak = mie; + + // Keep lower-priority interrupts disabled (optional) + mie = mie & ~((1 << (id + 1)) - 1); + + // Re-enable interrupts + mstatus.MIE = 1; + + // Handle interrupt + // This code block can be interrupted by other interrupts. + // ... + + // Restore mstatus (this disables interrupts) and mepc + mstatus = mstatus_bak; + mepc = mepc_bak; + + // Restore mie (optional) + mie = mie_bak; + } + +Nesting of interrupts/exceptions in hardware is not supported. diff --git a/docs/html/_sources/fpu.rst.txt b/docs/html/_sources/fpu.rst.txt new file mode 100644 index 000000000..9dc85aa2e --- /dev/null +++ b/docs/html/_sources/fpu.rst.txt @@ -0,0 +1,186 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _fpu: + +Floating Point Unit (FPU) +========================= + +The RV32F ISA extension for floating-point support in the form of IEEE-754 single +precision can be enabled by setting the parameter **FPU** of the ``cv32e40p_top`` top level module +to 1. This will extend the CV32E40P decoder accordingly and will instantiate the FPU. +The FPU repository used by the CV32E40P is available at `https://github.com/openhwgroup/cvfpu `_ and +its documentation can be found `here `_. +CVFPU v1.0.0 release has been copied in CV32E40P repository inside rtl/vendor (used for verification and implementation) so all core and FPU RTL files should be taken from CV32E40P repository. + +cv32e40p_fpu_manifest file is listing all necessary files for both the Core and CVFPU. + +CVFPU parameters +---------------- + +As CVFPU is an highly configurable IP, here is the list of its parameters and their actual value used when CVFPU is intantiated through a wrapper in ``cv32e40p_top`` module. + +.. table:: CVFPU Features parameter + :name: CVFPU Features parameter + :widths: 17 15 17 51 + :class: no-scrollbar-table + + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+================+==================+==========================================================================+ + | ``Width`` | int | 32 | **Datapath Width** | + | | | | | + | | | | Specifies the width of the input and output data ports and | + | | | | of the datapath. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableVectors`` | logic | 0 | **Vectorial Hardware Generation** | + | | | | | + | | | | Controls the generation of packed-SIMD computation units. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableNanBox`` | logic | 0 | **NaN-Boxing Check Control** | + | | | | | + | | | | Controls whether input value NaN-boxing is enforced. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``FpFmtMask`` | fmt_logic_t | {1, 0, 0, 0, 0} | **Enabled Floating-Point Formats** | + | | | | | + | | | | Enables respectively: | + | | | | | + | | | | IEEE Single-Precision format | + | | | | | + | | | | IEEE Double-Precision format | + | | | | | + | | | | IEEE Half-Precision format | + | | | | | + | | | | Custom Byte-Precision format | + | | | | | + | | | | Custom Alternate Half-Precision format | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``IntFmtMask`` | ifmt_logic_t | {0, 0, 1, 0} | **Enabled Integer Formats** | + | | | | | + | | | | Enables respectively: | + | | | | | + | | | | Byte format | + | | | | | + | | | | Half-Word format | + | | | | | + | | | | Word format | + | | | | | + | | | | Double-Word format | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + +.. table:: CVFPU Implementation parameter + :name: CVFPU Implementation parameter + :widths: 13 21 30 36 + :class: no-scrollbar-table + + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+========================+=====================================+============================================================================+ + | ``PipeRegs`` | opgrp_fmt_unsigned_t | { | **Number of Pipelining Stages** | + | | | | | + | | | {``FPU_ADDMUL_LAT``, 0, 0, 0, 0}, | This parameter sets a number of pipeline stages to be inserted into the | + | | | | computational units per operation group, per FP format. As such, | + | | | {default: 1}, | latencies for different operations and different formats can be freely | + | | | | configured. | + | | | {default: ``FPU_OTHERS_LAT``}, | | + | | | | Respectively: | + | | | {default: ``FPU_OTHERS_LAT``} | | + | | | | ADDition/MULtiplication operation group | + | | | } | | + | | | | DIVision/SQuare RooT operation group | + | | | | | + | | | | NON COMPuting operation group | + | | | | | + | | | | CONVersion operation group | + | | | | | + | | | | ``FPU_ADDMUL_LAT`` and ``FPU_OTHERS_LAT`` are ``cv32e40p_top`` parameters. | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | ``UnitTypes`` | opgrp_fmt_unit_types_t | { | **HW Unit Implementation** | + | | | | | + | | | {default: MERGED}, | This parameter allows to control resources by either removing operation | + | | | | units for certain formats and operations, | + | | | {default: MERGED}, | or merging multiple formats into one. | + | | | | | + | | | {default: PARALLEL}, | Respectively: | + | | | | | + | | | {default: MERGED} | ADDition/MULtiplication operation group | + | | | | | + | | | } | DIVision/SQuare RooT operation group | + | | | | | + | | | | NON COMPuting operation group | + | | | | | + | | | | CONVersion operation group | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | ``PipeConfig`` | pipe_config_t | AFTER | **Pipeline Register Placement** | + | | | | | + | | | | This parameter controls where pipeling registers (number defined by | + | | | | ``PipeRegs``) are placed in each operational unit. | + | | | | | + | | | | AFTER means they are all placed at the output of each operational unit. | + | | | | | + | | | | See :ref:`synthesis_with_fpu` advices to get best synthesis results. | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + +.. table:: Other CVFPU parameters + :name: Other CVFPU parameters + :widths: 20 15 10 55 + :class: no-scrollbar-table + + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+================+==================+==========================================================================+ + | ``TagType`` | | logic | The SystemVerilog data type of the operation tag input and output ports. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``TrueSIMDClass`` | int | 0 | Vectorial mode classify operation RISC-V compliancy. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableSIMDMask`` | int | 0 | Inactive vectorial lanes floating-point status flags masking. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + +FP Register File +---------------- + +By default a dedicated register file consisting of 32 +floating-point registers, ``f0``-``f31``, is instantiated. This default behavior +can be overruled by setting the parameter **ZFINX** of the ``cv32e40p_top`` top level +module to 1, in which case the dedicated register file is +not included and the general purpose register file is used instead to +host the floating-point operands. + +The latency of the individual instructions are explained in :ref:`instructions_latency_table` table. + +To allow FPU unit to be put in sleep mode at the same time the core is doing so, a clock gating cell is instantiated in ``cv32e40p_top`` top level module as well +with its enable signal being inverted ``core_sleep_o`` core output. + +FP CSR +------ + +When using floating-point extensions the standard specifies a +floating-point status and control register (:ref:`csr-fcsr`) which contains the +exceptions that occurred since it was last reset and the rounding mode. +:ref:`csr-fflags` and :ref:`csr-frm` can be accessed directly or via :ref:`csr-fcsr` which is mapped to +those two registers. + +Reminder for programmers +------------------------ + +As mentioned in RISC-V Privileged Architecture specification, ``mstatus``.FS should be set to Initial to be able to use FP instructions. +If ``mstatus``.FS = Off (reset value), any instruction that attempts to read or write the Floating-Point state (F registers or F CSRs) will cause an illegal instruction exception. + +Upon interrupt or context switch events, ``mstatus``.SD should be read to see if Floating-Point state has been altered. +If following executed program (interrupt routine or whatsover) is going to use FP instructions and only if ``mstatus``.SD = 1 (means FS = Dirty), +then the whole FP state (F registers and F CSRs) should be saved in memory and program should set ``mstatus``.FS to Clean. +When returning to interrupted or main program, if ``mstatus``.FS = Clean then the whole FP state should be restored from memory. diff --git a/docs/html/_sources/getting_started.rst.txt b/docs/html/_sources/getting_started.rst.txt new file mode 100644 index 000000000..4774abe62 --- /dev/null +++ b/docs/html/_sources/getting_started.rst.txt @@ -0,0 +1,45 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _getting-started: + +Getting Started with CV32E40P +============================= + +This page discusses initial steps and requirements to start using CV32E40P in your design. + +.. _clock-gating-cell: + +Clock Gating Cell +----------------- + +CV32E40P requires clock gating cells. +These cells are usually specific to the selected target technology and thus not provided as part of the RTL design. +A simulation-only version of the clock gating cell is provided in ``cv32e40p_sim_clock_gate.sv``. This file contains +a module called ``cv32e40p_clock_gate`` that has the following ports: + +* ``clk_i``: Clock Input +* ``en_i``: Clock Enable Input +* ``scan_cg_en_i``: Scan Clock Gate Enable Input (activates the clock even though ``en_i`` is not set) +* ``clk_o``: Gated Clock Output + +Inside CV32E40P, clock gating cells are used in both ``cv32e40p_sleep_unit.sv`` and ``cv32e40p_top.sv``. + +The ``cv32e40p_sim_clock_gate.sv`` file is not intended for synthesis. For ASIC synthesis and FPGA synthesis the manifest +should be adapted to use a customer specific file that implements the ``cv32e40p_clock_gate`` module using design primitives +that are appropriate for the intended synthesis target technology. + diff --git a/docs/html/_sources/glossary.rst.txt b/docs/html/_sources/glossary.rst.txt new file mode 100644 index 000000000..7269f96a9 --- /dev/null +++ b/docs/html/_sources/glossary.rst.txt @@ -0,0 +1,52 @@ +.. + Copyright (c) 2020 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _glossary: + +Glossary +======== + +* **ALU**: Arithmetic/Logic Unit +* **ASIC**: Application-Specific Integrated Circuit +* **Byte**: 8-bit data item +* **CPU**: Central Processing Unit, processor +* **CSR**: Control and Status Register +* **Custom extension**: Non-Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA) +* **EX**: Instruction Execute +* **FPGA**: Field Programmable Gate Array +* **FPU**: Floating Point Unit +* **Halfword**: 16-bit data item +* **Halfword aligned address**: An address is halfword aligned if it is divisible by 2 +* **ID**: Instruction Decode +* **IF**: Instruction Fetch (:ref:`instruction-fetch`) +* **ISA**: Instruction Set Architecture +* **KGE**: kilo gate equivalents (NAND2) +* **LSU**: Load Store Unit (:ref:`load-store-unit`) +* **M-Mode**: Machine Mode (RISC-V Instruction Set Manual, Volume II: Privileged Architecture) +* **OBI**: Open Bus Interface +* **PC**: Program Counter +* **PULP platform**: Parallel Ultra Low Power Platform () +* **RV32C**: RISC-V Compressed (C extension) +* **RV32F**: RISC-V Floating Point (F extension) +* **SIMD**: Single Instruction/Multiple Data +* **Standard extension**: Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA) +* **WARL**: Write Any Values, Reads Legal Values +* **WB**: Write Back of instruction results +* **WLRL**: Write/Read Only Legal Values +* **Word**: 32-bit data item +* **Word aligned address**: An address is word aligned if it is divisible by 4 +* **WPRI**: Reserved Writes Preserve Values, Reads Ignore Values diff --git a/docs/html/_sources/index.rst.txt b/docs/html/_sources/index.rst.txt new file mode 100644 index 000000000..5853a12b0 --- /dev/null +++ b/docs/html/_sources/index.rst.txt @@ -0,0 +1,43 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +OpenHW Group CV32E40P User Manual +================================= + +.. toctree:: + :maxdepth: 3 + :caption: Contents: + + preface + intro + getting_started + integration + verification + pipeline + instruction_fetch + load_store_unit + register_file + fpu + sleep + corev_hw_loop + control_status_registers + perf_counters + exceptions_interrupts + debug + instruction_set_extensions + core_versions + glossary diff --git a/docs/html/_sources/instruction_fetch.rst.txt b/docs/html/_sources/instruction_fetch.rst.txt new file mode 100644 index 000000000..2e5f77083 --- /dev/null +++ b/docs/html/_sources/instruction_fetch.rst.txt @@ -0,0 +1,99 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _instruction-fetch: + +Instruction Fetch +================= + +The Instruction Fetch (IF) stage of the CV32E40P is able to supply one instruction per cycle to +the Instruction Decode (ID ) stage if the external bus interface is able +to serve one fetch request per cycle. In case of executing compressed instructions, +on average less than one 32-bit fetch request will be needed per instruction +in the ID stage. + +For optimal performance and timing closure reasons, a prefetcher is used +which fetches instructions via the external bus interface from for example +an externally connected instruction memory or instruction cache. + +The prefetch buffer performs word-aligned 32-bit prefetches and stores the +fetched words in a FIFO with a number of entries depending of a local parameter. +It is called ``DEPTH`` and can be found in ``cv32e40p_prefetch_buffer.sv`` (default value of 2). +As a result of this (speculative) prefetch, CV32E40P can fetch up to ``DEPTH`` words outside of the code region +and care should therefore be taken that no unwanted read side effects occur +for such prefetches outside of the actual code region. + +:numref:`Instruction Fetch interface signals` describes the signals that are used to fetch instructions. This +interface is a simplified version of the interface that is used by the +LSU, which is described in :ref:`load-store-unit`. The difference is that no writes +are possible and thus it needs fewer signals. + +.. table:: Instruction Fetch interface signals + :name: Instruction Fetch interface signals + :widths: 25 15 60 + :class: no-scrollbar-table + + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | ``instr_addr_o[31:0]`` | output | Address, word aligned | + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | ``instr_req_o`` | output | Request valid, will stay high until ``instr_gnt_i`` is high for one cycle | + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | ``instr_gnt_i`` | input | The other side accepted the request. ``instr_addr_o`` may change in the next cycle. | + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when ``instr_rvalid_i`` is high. This signal will be high for exactly one cycle per request.| + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + | ``instr_rdata_i[31:0]`` | input | Data read from memory | + +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ + +Misaligned Accesses +------------------- + +Externally, the IF interface performs word-aligned instruction fetches only. +Misaligned instruction fetches are handled by performing two separate word-aligned instruction fetches. +Internally, the core can deal with both word- and half-word-aligned instruction addresses to support compressed instructions. +The LSB of the instruction address is ignored internally. + +Protocol +-------- + +The CV32E40P instruction fetch interface does not implement the following optional OBI signals: we, be, wdata, auser, wuser, aid, +rready, err, ruser, rid. These signals can be thought of as being tied off as specified in the OBI specification. + +.. note:: + + **Transactions Ordering** + As mentioned above, instruction fetch interface can generate up to ``DEPTH`` outstanding transactions. + OBI specification states that links are always in-order from master point of view. So as the fetch interface does not generate transaction id (aid), + interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information. + +:numref:`obi-instruction-basic` and :numref:`obi-instruction-multiple-outstanding` show example timing diagrams of the protocol. + +.. figure:: ../images/obi_instruction_basic.svg + :name: obi-instruction-basic + :align: center + :alt: + + Back-to-back Memory Transactions + +.. figure:: ../images/obi_instruction_multiple_outstanding.svg + :name: obi-instruction-multiple-outstanding + :align: center + :alt: + + Multiple Outstanding Memory Transactions diff --git a/docs/html/_sources/instruction_set_extensions.rst.txt b/docs/html/_sources/instruction_set_extensions.rst.txt new file mode 100644 index 000000000..82cc76af6 --- /dev/null +++ b/docs/html/_sources/instruction_set_extensions.rst.txt @@ -0,0 +1,2136 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _custom-isa-extensions: + +CORE-V Instruction Set Custom Extension +======================================= + +CV32E40P supports the following CORE-V ISA X Custom Extension, which can be enabled by setting ``COREV_PULP`` == 1. + + * Post-Increment load and stores, see :ref:`corev_load_store`, invoked in the tool chain with ``-march=rv32i*_xcvmem``. + * Hardware Loop extension, see :ref:`corev_hardware_loop`, invoked in the tool chain with ``-march=rv32i*_xcvhwlp``. + * ALU extensions, see :ref:`corev_alu`, which are divided into three sub-extensions: + + * bit manipulation instructions, invoked in the tool chain with ``-march=rv32i*_xcvbitmanip``; + * miscellaneous ALU instructions, invoked in the tool chain with ``-march=rv32i*_xcvalu``; and + * immediate branch instructions, invoked in the tool chain with ``-march=rv32i*_xcvbi``. + + * Multiply-Accumulate extensions, see :ref:`corev_multiply_accumulate`, invoked in the tool chain with ``-march=rv32i*_xcvmac``. + * Single Instruction Multiple Data (aka SIMD) extensions, see :ref:`corev_simd`, invoked in the tool chain with ``-march=rv32i*_xcvsimd``. + +Additionally the event load instruction (**cv.elw**) is supported by setting ``COREV_CLUSTER`` == 1, see :ref:`corev_event_load`. +This is a separate ISA extension, invoked in the tool chain with ``-march=rv32i*_xcvelw``. + +If not specified, all the operands are signed and immediate values are sign-extended. + +To use such instructions, you need to compile your SW with the CORE-V GCC or Clang/LLVM compiler. + +.. note:: + + Clang/LLVM assembler will be supported by 30 June 2023, with builtin function support by 31 December 2023. + +.. _corev_load_store: + +Post-Increment Load & Store Instructions and Register-Register Load & Store Instructions +---------------------------------------------------------------------------------------- + +Post-Increment load and store instructions perform a load, or a +store, respectively, while at the same time incrementing the address +that was used for the memory access. Since it is a post-incrementing +scheme, the base address is used for the access and the modified address +is written back to the register-file. There are versions of those +instructions that use immediates and those that use registers as +offsets. The base address always comes from a register. + +The custom post-increment load & store instructions and register-register +load & store instructions are only supported if ``COREV_PULP`` == 1. + +Load operations +^^^^^^^^^^^^^^^ + +.. table:: Load operations + :name: Load operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------------+-------------------------------+ + | **Mnemonic** | **Description** | + +====================================================+===============================+ + | **Register-Immediate Loads with Post-Increment** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, Imm(rs1!)** | rD = Sext(Mem8(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, Imm(rs1!)** | rD = Zext(Mem8(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, Imm(rs1!)** | rD = Sext(Mem16(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, Imm(rs1!)** | rD = Zext(Mem16(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, Imm(rs1!)** | rD = Mem32(rs1) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **Register-Register Loads with Post-Increment** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, rs2(rs1!)** | rD = Sext(Mem8(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, rs2(rs1!)** | rD = Zext(Mem8(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, rs2(rs1!)** | rD = Sext(Mem16(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, rs2(rs1!)** | rD = Zext(Mem16(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, rs2(rs1!)** | rD = Mem32(rs1) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **Register-Register Loads** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, rs2(rs1)** | rD = Sext(Mem8(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, rs2(rs1)** | rD = Zext(Mem8(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, rs2(rs1)** | rD = Sext(Mem16(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, rs2(rs1)** | rD = Zext(Mem16(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, rs2(rs1)** | rD = Mem32(rs1 + rs2) | + +----------------------------------------------------+-------------------------------+ + +Store operations +^^^^^^^^^^^^^^^^ + +.. table:: Store operations + :name: Store operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------------+--------------------------+ + | **Mnemonic** | **Description** | + +=====================================================+==========================+ + | **Register-Immediate Stores with Post-Increment** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, Imm(rs1!)** | Mem8(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2, Imm(rs1!)** | Mem16(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, Imm(rs1!)** | Mem32(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **Register-Register Stores with Post-Increment** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, rs3(rs1!)** | Mem8(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2, rs3(rs1!)** | Mem16(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, rs3(rs1!)** | Mem32(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **Register-Register Stores** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, rs3(rs1)** | Mem8(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2 rs3(rs1)** | Mem16(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, rs3(rs1)** | Mem32(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ + +Encoding +^^^^^^^^ + +.. table:: Post-Increment Register-Immediate Load operations encoding + :name: Post-Increment Register-Immediate Load operations encoding + :widths: 25 10 10 15 15 25 + :class: no-scrollbar-table + + +---------------+---------+------------+--------+------------+---------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +---------------+---------+------------+--------+------------+---------------------------+ + | **imm[11:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +===============+=========+============+========+============+===========================+ + | offset | base | 000 | dest | 000 1011 | **cv.lb rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 100 | dest | 000 1011 | **cv.lbu rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 001 | dest | 000 1011 | **cv.lh rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 101 | dest | 000 1011 | **cv.lhu rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 010 | dest | 000 1011 | **cv.lw rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + +.. table:: Post-Increment Register-Register Load operations encoding + :name: Post-Increment Register-Register Load operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +============+==========+=========+============+========+============+===========================+ + | 000 0000 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1000 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0001 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1001 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0010 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + +.. table:: Register-Register Load operations encoding + :name: Register-Register Load operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +============+==========+=========+============+========+============+===========================+ + | 000 0100 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1100 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0101 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1101 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0110 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + +.. table:: Post-Increment Register-Immediate Store operations encoding + :name: Post-Increment Register-Immediate Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | **imm[11:5]** | **rs2** | **rs1** | **funct3** | **imm[4:0]** | **opcode** | **Mnemonic** | + +================+=========+=========+============+===============+============+===========================+ + | offset[11:5] | src | base | 000 | offset[4:0] | 010 1011 | **cv.sb rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | offset[11:5] | src | base | 001 | offset[4:0] | 010 1011 | **cv.sh rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | offset[11:5] | src | base | 010 | offset[4:0] | 010 1011 | **cv.sw rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + +.. table:: Post-Increment Register-Register Store operations encoding + :name: Post-Increment Register-Register Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rs3** | **opcode** | **Mnemonic** | + +============+==========+=========+============+=========+============+===========================+ + | 001 0000 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0001 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0010 | src | base | 011 | offse t | 010 1011 | **cv.sw rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + +.. table:: Register-Register Store operations encoding + :name: Register-Register Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rs3** | **opcode** | **Mnemonic** | + +============+==========+=========+============+=========+============+===========================+ + | 001 0100 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0101 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0110 | src | base | 011 | offset | 010 1011 | **cv.sw rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + +.. _corev_event_load: + +Event Load Instruction +---------------------- + +The event load instruction **cv.elw** is only supported if the ``COREV_CLUSTER`` parameter is set to 1. +The event load performs a load word and can cause the CV32E40P to enter a sleep state as explained +in :ref:`pulp_cluster`. + +Event Load operation +^^^^^^^^^^^^^^^^^^^^ + +.. table:: Event Load operation + :name: Event Load operation + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------------+-------------------------------+ + | **Mnemonic** | **Description** | + +====================================================+===============================+ + | **Event Load** | + +----------------------------------------------------+-------------------------------+ + | **cv.elw rD, Imm(rs1)** | rD = Mem32(Sext(Imm) + rs1) | + +----------------------------------------------------+-------------------------------+ + +Encoding +^^^^^^^^ + +.. table:: Event Load operation encoding + :name: Event Load operation encoding + :widths: 25 10 10 15 15 25 + :class: no-scrollbar-table + + +---------------+---------+------------+--------+------------+---------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +---------------+---------+------------+--------+------------+---------------------------+ + | **imm[11:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +===============+=========+============+========+============+===========================+ + | offset | base | 011 | dest | 000 1011 | **cv.elw rD, Imm(rs1)** | + +---------------+---------+------------+--------+------------+---------------------------+ + +.. _corev_hardware_loop: + +Hardware Loops +-------------- + +The loop has to be setup before entering the loop body. For this purpose, there are two +methods, either the long commands that separately set start- and +end-addresses of the loop and the number of iterations, or the short +command that does all of this in a single instruction. The short command +has a limited range for the number of instructions contained in the loop +and the loop must start in the next instruction after the setup +instruction. + +Hardware loop instructions and related CSRs are only supported if ``COREV_PULP`` == 1. + +Details about the hardware loop constraints are provided in :ref:`hwloop-specs`. + +In the following tables, the hardware loop instructions are reported. +In assembly, **L** is referred by 0 or 1. + +Hardware Loops operations +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Long Hardware Loop Setup operations + :name: Long Hardware Loop Setup operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------+----------------------------------------------------------+ + | **Mnemonic** | **Description** | + +==============================================+==========================================================+ + | **cv.starti L, uimmL** | lpstart[L] = PC + (uimmL << 2) | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.start L, rs1** | lpstart[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.endi L, uimmL** | lpend[L] = PC + (uimmL << 2) | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.end L, rs1** | lpend[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.counti L, uimmL** | lpcount[L] = uimmL | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.count L, rs1** | lpcount[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + +.. table:: Short Hardware Loop Setup operations + :name: Short Hardware Loop Setup operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------+----------------------------------------------------------+ + | **Mnemonic** | **Description** | + +==============================================+==========================================================+ + | **cv.setupi L, uimmL, uimmS** | lpstart[L] = PC + 4 | + | | | + | | lpend[L] = PC + (uimmS << 2) | + | | | + | | lpcount[L] = uimmL | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.setup L, rs1, uimmL** | lpstart[L] = PC + 4 | + | | | + | | lpend[L] = PC + (uimmL << 2) | + | | | + | | lpcount[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + +Encoding +^^^^^^^^ + +.. table:: Hardware Loops operations encoding + :name: Hardware Loops operations encoding + :widths: 17 15 10 10 5 15 28 + :class: no-scrollbar-table + + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 8 | 7 | 6 : 0 | | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | **uimmL[11:0]** | **rs1** | **funct3** | **funct4** | **L** | **opcode** | **Mnemonic** | + +=================+============+============+============+=======+============+===============================+ + | uimmL[11:0] | 00000 | 100 | 0000 | L | 010 1011 | **cv.starti L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0001 | L | 010 1011 | **cv.start L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | 00000 | 100 | 0010 | L | 010 1011 | **cv.endi L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0011 | L | 010 1011 | **cv.end L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | 00000 | 100 | 0100 | L | 010 1011 | **cv.counti L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0101 | L | 010 1011 | **cv.count L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | uimmS[4:0] | 100 | 0110 | L | 010 1011 | **cv.setupi L, uimmL, uimmS** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | src1 | 100 | 0111 | L | 010 1011 | **cv.setup L, rs1, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + +.. _corev_alu: + +ALU +--- + +CV32E40P supports advanced ALU operations that allow to perform multiple +instructions that are specified in the base instruction set in one +single instruction and thus increases efficiency of the core. For +example, those instructions include zero-/sign-extension instructions +for 8-bit and 16-bit operands, simple bit manipulation/counting +instructions and min/max/avg instructions. The ALU does also support +saturating, clipping and normalizing instructions which make fixed-point +arithmetic more efficient. + +The custom ALU extensions are only supported if ``COREV_PULP`` == 1. + +The custom extensions to the ALU are split into several subgroups that belong +together. + +- Bit manipulation instructions are useful to work on single bits or + groups of bits within a word, see :ref:`corev_bit_manipulation`. + +- General ALU instructions try to fuse common used sequences into a + single instruction and thus increase the performance of small kernels + that use those sequence, see :ref:`corev_general_alu`. + +- Immediate branching instructions are useful to compare a register + with an immediate value before taking or not a branch, see see :ref:`corev_immediate_branching`. + +Extract, Insert, Clear and Set instructions have the following meaning: + +- Extract Is3+1 or rs2[9:5]+1 bits from position Is2 or rs2[4:0] [and sign extend it] + +- Insert Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0] + +- Clear Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0] + +- Set Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0] + + +Bit Reverse Instruction +^^^^^^^^^^^^^^^^^^^^^^^ + +This section will describe the `cv.bitrev` instruction from a bit manipulation +perspective without describing it's application as part of an FFT. The bit +reverse instruction will reverse bits in groupings of 1, 2 or 3 bits. The +number of grouped bits is described by *Is3* as follows: + +* **0** - reverse single bits +* **1** - reverse groups of 2 bits +* **2** - reverse groups of 3 bits + +The number of bits that are reversed can be controlled by *Is2*. This will +specify the number of bits that will be removed by a left shift prior to +the reverse operation resulting in the *32-Is2* least significant bits of +the input value being reversed and the *Is2* most significant bits of the +input value being thrown out. + +What follows is a few examples. + +.. highlight:: none + +:: + + cv.bitrev x18, x20, 0, 4 (groups of 1 bit; radix-2) + + in: 0xC64A5933 11000110010010100101100100110011 + shift: 0x64A59330 01100100101001011001001100110000 + out: 0x0CC9A526 00001100110010011010010100100110 + + Swap pattern: + A B C D E F G H . . . . . . . . . . . . . . . . . . . . . . . . + 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 1 1 0 0 0 0 + . . . . . . . . . . . . . . . . . . . . . . . . H G F E D C B A + 0 0 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 + +In this example the input value is first shifted by 4 (*Is2*). Each individual +bit is reversed. For example, bits 31 and 0 are swapped, 30 and 1, etc. + +:: + + cv.bitrev x18, x20, 1, 4 (groups of 2 bits; radix-4) + + in: 0xC64A5933 11000110010010100101100100110011 + shift: 0x64A59330 01100100101001011001001100110000 + out: 0x0CC65A19 00001100110001100101101000011001 + + Swap pattern: + A B C D E F G H I J K L M N O P + 01 10 01 00 10 10 01 01 10 01 00 11 00 11 00 00 + P O N M L K J I H G F E D C B A + 00 00 11 00 11 00 01 10 01 01 10 10 00 01 10 01 + +In this example the input value is first shifted by 4 (*Is2*). Each group of +two bits are reversed. For example, bits 31 and 30 are swapped with 1 and 0 +(retaining their position relative to each other), bits 29 and 28 are swapped +with 3 and 2, etc. + +:: + + cv.bitrev x18, x20, 2, 4 (groups of 3 bits; radix-8) + + in: 0xC64A5933 11000110010010100101100100110011 + shift: 0x64A59330 01100100101001011001001100110000 + out: 0x216B244B 00100001011010110010010001001011 + + Swap pattern: + A B C D E F G H I J + 011 001 001 010 010 110 010 011 001 100 00 + J I H G F E D C B A + 00 100 001 011 010 110 010 010 001 001 011 + +In this last example the input value is first shifted by 4 (*Is2*). Each group +of three bits are reversed. For example, bits 31, 30 and 29 are swapped with +4, 3 and 2 (retaining their position relative to each other), bits 28, 27 and +26 are swapped with 7, 6 and 5, etc. Notice in this example that bits 0 and 1 +are lost and the result is shifted right by two with bits 31 and 30 being tied +to zero. Also notice that when J (100) is swapped with A (011), the four most +significant bits are no longer zero as in the other cases. This may not be +desirable if the intention is to pack a specific number of grouped bits +aligned to the least significant bit and zero extended into the result. In +this case care should be taken to set *Is2* appropriately. + + +.. _corev_bit_manipulation: + +Bit Manipulation operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Bit Manipulation operations + :name: Bit Manipulation operations + :widths: 30 70 + :class: no-scrollbar-table + + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=============================================+==========================================================================================================================================+ + | **cv.extract rD, rs1, Is3, Is2** | rD = Sext(rs1[min(Is3+Is2,31):Is2]) | + | | | + | | Note: Sign extension is done over the MSB of the extracted part. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractu rD, rs1, Is3, Is2** | rD = Zext(rs1[min(Is3+Is2,31):Is2]) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractr rD, rs1, rs2** | rD = Sext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | + | | | + | | Note: Sign extension is done over the MSB of the extracted part. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractur rD, rs1, rs2** | rD = Zext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.insert rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] = rs1[Is3-(max(Is3+Is2,31)-31):0] | + | | | + | | The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Is3 + Is2 must be < 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.insertr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] = | + | | | + | | rs1[rs2[9:5]-(max(rs2[9:5]+rs2[4:0],31)-31):0] | + | | | + | | The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Is3 + Is2 must be < 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bclr rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 0 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bclrr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 0 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bset rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 1 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bsetr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 1 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.ff1 rD, rs1** | rD = bit position of the first bit set in rs1, starting from LSB. | + | | | + | | If bit 0 is set, rD will be 0. If only bit 31 is set, rD will be 31. | + | | | + | | If rs1 is 0, rD will be 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.fl1 rD, rs1** | rD = bit position of the last bit set in rs1, starting from MSB. | + | | | + | | If bit 31 is set, rD will be 31. If only bit 0 is set, rD will be 0. | + | | | + | | If rs1 is 0, rD will be 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.clb rD, rs1** | rD = count leading bits of rs1 | + | | | + | | Number of consecutive 1's or 0's starting from MSB. | + | | | + | | If rs1 is 0, rD will be 0. If rs1 is different than 0, returns (number - 1). | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.cnt rD, rs1** | rD = Population count of rs1 | + | | | + | | Number of bits set in rs1. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.ror rD, rs1, rs2** | rD = RotateRight(rs1, rs2) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bitrev rD, rs1, Is3, Is2** | Given an input rs1 it returns a bit reversed representation assuming | + | | | + | | FFT on 2^Is2 points in Radix 2^(Is3+1). | + | | | + | | Is3 can be either 0 (radix-2), 1 (radix-4) or 2 (radix-8). | + | | | + | | Note: When Is3 = 3, instruction has the same bahavior as if it was 0 (radix-2). | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + + +Bit Manipulation Encoding +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Immediate Bit Manipulation operations encoding + :name: Immediate Bit Manipulation operations encoding + :width: 50 + :widths: 5 14 13 5 8 6 16 33 + :class: no-scrollbar-table + + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **ls3[4:0]** | **ls2[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +========+======================+===============+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extract rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extractu rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.insert rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bclr rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bset rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 11 | 000, Luimm2[1:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bitrev rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + +.. table:: Register Bit Manipulation operations encoding + :name: Register Bit Manipulation operations encoding + :width: 50 + :widths: 19 13 5 8 6 16 33 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+================================+ + | 001 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractur rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.insertr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.bclrr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1101 | src2 | scr1 | 011 | dest | 010 1011 | **cv.bsetr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.ror rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.ff1 rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.fl1 rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.clb rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0100 | 00000 | src1 | 011 | dest | 010 1011 | **cv.cnt rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + +.. _corev_general_alu: + +General ALU operations +^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: General ALU operations + :name: General ALU operations + :widths: 30 70 + :class: no-scrollbar-table + + +-------------------------------------------+------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===========================================+========================================================================+ + | **cv.abs rD, rs1** | rD = rs1 < 0 ? -rs1 : rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.slet rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.sletu rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.min rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.minu rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.max rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.maxu rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.exths rD, rs1** | rD = Sext(rs1[15:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.exthz rD, rs1** | rD = Zext(rs1[15:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.extbs rD, rs1** | rD = Sext(rs1[7:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.extbz rD, rs1** | rD = Zext(rs1[7:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clip rD, rs1, Is2** | if rs1 <= -2^(Is2-1), rD = -2^(Is2-1), | + | | | + | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | + | | | + | | else rD = rs1 | + | | | + | | Note: If ls2 is equal to 0, | + | | | + | | -2^(Is2-1) is equivalent to -1 while (2^(Is2-1)-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipu rD, rs1, Is2** | if rs1 <= 0, rD = 0, | + | | | + | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | + | | | + | | else rD = rs1 | + | | | + | | Note: If ls2 is equal to 0, (2^(Is2-1)-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipr rD, rs1, rs2** | if rs1 <= -(rs2+1), rD = -(rs2+1), | + | | | + | | else if rs1 >=rs2, rD = rs2, | + | | | + | | else rD = rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipur rD, rs1, rs2** | if rs1 <= 0, rD = 0, | + | | | + | | else if rs1 >= rs2, rD = rs2, | + | | | + | | else rD = rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | Setting Is3 to 2 replaces former cv.avg. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | Setting Is3 to 2 replaces former cv.avg. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addRN rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduRN rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1))) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subN rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuN rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >> Is3 | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subRN rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuRN rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1))) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addNr rD, rs1, rs2** | rD = (rD + rs1) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduNr rD, rs1, rs2** | rD = (rD + rs1) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addRNr rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1)) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduRNr rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1))) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subNr rD, rs1, rs2** | rD = (rD - rs1) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuNr rD, rs1, rs2** | rD = (rD - rs1) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subRNr rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1)) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuRNr rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1))) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + +General ALU Encoding +^^^^^^^^^^^^^^^^^^^^ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+===========================+ + | 010 1000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.abs rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.slet rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.sletu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.min rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.minu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1101 | src2 | src1 | 011 | dest | 010 1011 | **cv.max rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1110 | src2 | src1 | 011 | dest | 010 1011 | **cv.maxu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exths rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exthz rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbs rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbz rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | **funct7** | **Is2[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+===============+=========+============+========+============+=============================+ + | 011 1000 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clip rD, rs1, Is2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1001 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clipu rD, rs1, Is2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipr rD, rs1, rs2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipur rD, rs1, rs2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 5 16 13 9 9 9 11 28 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+==================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | **funct7** | **Is3[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+==============+=========+============+========+============+=============================+ + | 100 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.addNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0001 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduNr rD, rs1, rs** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0010 | src2 | src1 | 011 | dest | 010 1011 | **cv.addRNr rD, rs1, rs** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0011 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0100 | src2 | src1 | 011 | dest | 010 1011 | **cv.subNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0101 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0110 | src2 | src1 | 011 | dest | 010 1011 | **cv.subRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0111 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + +.. _corev_immediate_branching: + +Immediate Branching operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Immediate Branching operations + :name: Immediate Branching operations + :widths: 30 70 + :class: no-scrollbar-table + + +---------------------------------+------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=================================+========================================================================+ + | **cv.beqimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is equal to Imm5. | + | | | + | | Note: Imm5 is signed. | + +---------------------------------+------------------------------------------------------------------------+ + | **cv.bneimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is not equal to Imm5. | + | | | + | | Note: Imm5 is signed. | + +---------------------------------+------------------------------------------------------------------------+ + +Immediate Branching Encoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Immediate Branching encoding + :name: General ALU operations encoding + :widths: 13 14 8 6 8 12 12 11 16 + :class: no-scrollbar-table + + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | 31 | 30 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 8 | 7 | 6 : 0 | | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | **Imm12[12]** | **Imm12[10:5]** | **Imm5** | **rs1** | **funct3** | **Imm12** | **Imm12** | **opcode** | | + +===============+=================+==========+==========+============+=============+============+============+=================================+ + | Imm12[12] | Imm12[10:5] | Imm5 | src1 | 110 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.beqimm rs1, Imm5, Imm12** | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | Imm12[12] | Imm12[10:5] | Imm5 | src1 | 111 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.bneimm rs1, Imm5, Imm12** | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + +.. _corev_multiply_accumulate: + +Multiply-Accumulate +------------------- + +CV32E40P supports custom extensions for multiply-accumulate and half-word multiplications with +an optional post-multiplication shift. + +The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` == 1. + +16-Bit x 16-Bit Multiplication operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 16-Bit Multiplication operations + :name: 16-Bit Multiplication operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===============================================+==============================================================================+ + | **cv.muluN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0])) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16])) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0])) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16])) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.muluRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + +16-Bit x 16-Bit Multiply-Accumulate operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 16-Bit Multiply-Accumulate operations + :name: 16-Bit Multiply-Accumulate operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===============================================+==============================================================================+ + | **cv.macuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + +32-Bit x 32-Bit Multiply-Accumulate operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 32-Bit Multiply-Accumulate operations + :name: 32-Bit Multiply-Accumulate operations + :widths: 30 70 + :class: no-scrollbar-table + + +--------------------------------+-------------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +================================+===========================================================================================+ + | **cv.mac rD, rs1, rs2** | rD = rD + rs1 \* rs2 | + +--------------------------------+-------------------------------------------------------------------------------------------+ + | **cv.msu rD, rs1, rs2** | rD = rD - rs1 \* rs2 | + +--------------------------------+-------------------------------------------------------------------------------------------+ + +Encoding +^^^^^^^^ + +.. table:: 16-Bit Multiplication operations + :name: 16-Bit Multiplication operations + :widths: 5 16 6 6 9 6 11 39 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + +.. table:: 16-Bit Multiply-Accumulate operations + :name: 16-Bit Multiply-Accumulate operations + :widths: 5 16 6 6 9 6 11 39 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + +.. table:: 32-Bit Multiply-Accumulate operations + :name: 32-Bit Multiply-Accumulate operations + :widths: 21 6 6 9 6 11 39 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+--------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+--------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+==========================+ + | 100 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.mac rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------+ + | 100 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.msu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------+ + +.. _corev_simd: + +SIMD +---- + +The SIMD instructions perform operations on multiple sub-word elements at the same time. This is done by segmenting +the data path into smaller parts when 8- or 16-bit operations should be performed. + +The custom SIMD extensions are only supported if ``COREV_PULP`` == 1. + +.. note:: + + See the comments at the start of :ref:`custom-isa-extensions` on availability of the compiler tool chains. + Support for SIMD will be primarily through assembly code and builtin functions, with no auto-vectorization and limited other optimization. + Simple auto-vectorization (add, sub...) and optimization will be evaluated once a stable GCC toolchain is available. + +SIMD instructions are available in two flavors: + +- 8-Bit, to perform four operations on the 4 bytes inside a 32-bit word + at the same time (.b) + +- 16-Bit, to perform two operations on the 2 half-words inside a 32-bit + word at the same time (.h) + +All the operations are rounded to the specified bidwidth as for the original +RISC-V arithmetic operations. This is described by the "and" operation with a +MASK. No overflow or carry-out flags are generated as for the 32-bit operations. + +Additionally, there are three modes that influence the second operand: + +1. Normal mode, vector-vector operation. Both operands, from rs1 and + rs2, are treated as vectors of bytes or half-words. + + e.g. cv.add.h x3,x2,x1 performs: + + x3[31:16] = x2[31:16] + x1[31:16] + + x3[15: 0] = x2[15: 0] + x1[15: 0] + +2. Scalar replication mode (.sc), vector-scalar operation. Operand 1 is + treated as a vector, while operand 2 is treated as a scalar and + replicated two or four times to form a complete vector. The LSP is + used for this purpose. + + e.g. cv.add.sc.h x3,x2,x1 performs: + + x3[31:16] = x2[31:16] + x1[15: 0] + + x3[15: 0] = x2[15: 0] + x1[15: 0] + +3. Immediate scalar replication mode (.sci), vector-scalar operation. + Operand 1 is treated as vector, while operand 2 is treated as a + scalar and comes from a 6-bit immediate. + + The immediate is either sign- or zero-extended depending on the operation. + If not specified, the immediate is sign-extended with the exception + of all cv.shuffle* where it is always unsigned. + + e.g. cv.add.sci.h x3,x2,0x2A performs: + + x3[31:16] = x2[31:16] + 0xFFEA + + x3[15: 0] = x2[15: 0] + 0xFFEA + +In the following tables, the index i ranges from 0 to 1 for 16-Bit operations and from 0 to 3 for 8-Bit operations: + +- The index 0 is 15:0 for 16-Bit operations or 7:0 for 8-Bit operations. + +- The index 1 is 31:16 for 16-Bit operations or 15:8 for 8-Bit operations. + +- The index 2 is 23:16 for 8-Bit operations. + +- The index 3 is 31:24 for 8-Bit operations. + +And I5, I4, I3, I2, I1 and I0 respectively represent bits 5, 4, 3, 2, 1 and 0 of the immediate value. + +SIMD ALU operations +^^^^^^^^^^^^^^^^^^^ + +.. table:: SIMD ALU operations + :name: SIMD ALU operations + :widths: 50 50 + :class: no-scrollbar-table + + +------------------------------------------------------------+------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +============================================================+==================================================================+ + | **cv.add[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] + op2[i]) & 0xFFFF | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sub[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] - op2[i]) & 0xFFFF | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.avg[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | + | | | + | | Note: Arithmetic right shift. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.avgu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | + | | | + | | Note: Logical shift right. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.min[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.minu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | + | | | + | | Note: Immediate is zero-extended, comparison is unsigned. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.max[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.maxu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | + | | | + | | Note: Immediate is zero-extended, comparison is unsigned. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.srl[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >> op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is logical. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sra[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >>> op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is arithmetic. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sll[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] << op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is logical. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.or[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] \| op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.xor[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] ^ op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.and[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] & op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.abs{.h,.b} rD, rs1** | rD[i] = rs1[i] < 0 ? -rs1[i] : rs1[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + +SIMD Bit Manipulation operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Bit Manipulation operations + :name: SIMD Bit Manipulation operations + :widths: 50 50 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.extract.h rD, rs1, Imm6** | rD = Sext(rs1[I0\*16+15:I0\*16]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extract.b rD, rs1, Imm6** | rD = Sext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extractu.h rD, rs1, Imm6** | rD = Zext(rs1[I0\*16+15:I0\*16]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extractu.b rD, rs1, Imm6** | rD = Zext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.insert.h rD, rs1, Imm6** | rD[I0\*16+15:I0\*16] = rs1[15:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.insert.b rD, rs1, Imm6** | rD[(I1:I0)\*8+7:(I1:I0)\*8] = rs1[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD Dot Product operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Dot Product operations + :name: SIMD Dot Product operations + :widths: 50 50 + :class: no-scrollbar-table + + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +============================================================+=======================================================================================+ + | **cv.dotup[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotup[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: rs1 is treated as unsigned, while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: rs1 is treated as unsigned, while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotup[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotup[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: rs1 is treated as unsigned while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: rs1 is treated as unsigned while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD Shuffle and Pack operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Shuffle and Pack operations + :name: SIMD Shuffle and Pack operations + :widths: 35 65 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.shuffle.h rD, rs1, rs2** | rD[31:16] = rs1[rs2[16]\*16+15:rs2[16]\*16] | + | | | + | | rD[15:0] = rs1[rs2[0]\*16+15:rs2[0]\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle.sci.h rD, rs1, Imm6** | rD[31:16] = rs1[I1\*16+15:I1\*16] | + | | | + | | rD[15:0] = rs1[I0\*16+15:I0\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle.b rD, rs1, rs2** | rD[31:24] = rs1[rs2[25:24]\*8+7:rs2[25:24]\*8] | + | | | + | | rD[23:16] = rs1[rs2[17:16]\*8+7:rs2[17:16]\*8] | + | | | + | | rD[15:8] = rs1[rs2[9:8]\*8+7:rs2[9:8]\*8] | + | | | + | | rD[7:0] = rs1[rs2[1:0]\*8+7:rs2[1:0]\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI0.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[7:0] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI1.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[15:8] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI2.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[23:16] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI3.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[31:24] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle2.h rD, rs1, rs2** | rD[31:16] = ((rs2[17] == 1) ? rs1 : rD)[rs2[16]\*16+15:rs2[16]\*16] | + | | | + | | rD[15:0] = ((rs2[1] == 1) ? rs1 : rD)[rs2[0]\*16+15:rs2[0]\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle2.b rD, rs1, rs2** | rD[31:24] = ((rs2[26] == 1) ? rs1 : rD)[rs2[25:24]\*8+7:rs2[25:24]\*8] | + | | | + | | rD[23:16] = ((rs2[18] == 1) ? rs1 : rD)[rs2[17:16]\*8+7:rs2[17:16]\*8] | + | | | + | | rD[15:8] = ((rs2[10] == 1) ? rs1 : rD)[rs2[9:8]\*8+7:rs2[9:8]\*8] | + | | | + | | rD[7:0] = ((rs2[2] == 1) ? rs1 : rD)[rs2[1:0]\*8+7:rs2[1:0]\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.pack rD, rs1, rs2** | rD[31:16] = rs1[15:0] | + | | | + | | rD[15:0] = rs2[15:0] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.pack.h rD, rs1, rs2** | rD[31:16] = rs1[31:16] | + | | | + | | rD[15:0] = rs2[31:16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.packhi.b rD, rs1, rs2** | rD[31:24] = rs1[7:0] | + | | | + | | rD[23:16] = rs2[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.packlo.b rD, rs1, rs2** | rD[15:8] = rs1[7:0] | + | | | + | | rD[7:0] = rs2[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD ALU Encoding +~~~~~~~~~~~~~~~~~ + +.. table:: SIMD ALU encoding + :name: SIMD ALU encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+======================================+ + | 0 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.add.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.add.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.add.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.add.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.add.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sub.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sub.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sub.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sub.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sub.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avg.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avg.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avg.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avg.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avg.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avg.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avgu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avgu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avgu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avgu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avgu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avgu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.min.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.min.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.min.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.min.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.min.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.min.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.minu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.minu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.minu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.minu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.minu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.minu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.max.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.max.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.max.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.max.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.max.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.max.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.maxu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.maxu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.maxu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.maxu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.maxu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.maxu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.srl.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.srl.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.srl.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.srl.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.srl.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.srl.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sra.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sra.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sra.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sra.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sra.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sra.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sll.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sll.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sll.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sll.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sll.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sll.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.or.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.or.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.or.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.or.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.or.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.or.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.xor.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.xor.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.xor.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.xor.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.xor.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.xor.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.and.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.and.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.and.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.and.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.and.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.and.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 000 | dest | 111 1011 | **cv.abs.h rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 001 | dest | 111 1011 | **cv.abs.b rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 000 | dest | 111 1011 | **cv.extract.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 001 | dest | 111 1011 | **cv.extract.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 010 | dest | 111 1011 | **cv.extractu.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 011 | dest | 111 1011 | **cv.extractu.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 100 | dest | 111 1011 | **cv.insert.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 101 | dest | 111 1011 | **cv.insert.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotup.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotup.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotup.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotup.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotusp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotusp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotsp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotsp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotup.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotup.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotup.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotup.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotusp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotusp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotsp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotsp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.shuffle.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI0.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI1.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI2.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI3.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle2.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle2.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 1 | src2 | src1 | 001 | dest | 111 1011 | **cv.packhi.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.packlo.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + + +SIMD Comparison operations +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SIMD comparisons are done on individual bytes (.b) or half-words +(.h), depending on the chosen mode. If the comparison result is true, +all bits in the corresponding byte/half-word are set to 1. If the +comparison result is false, all bits are set to 0. + +The default mode (no .sc, .sci) compares the lowest byte/half-word of +the first operand with the lowest byte/half-word of the second operand, +and so on. If the mode is set to scalar replication (.sc), always the +lowest byte/half-word of the second operand is used for comparisons, +thus instead of a vector comparison a scalar comparison is performed. In +the immediate scalar replication mode (.sci), the immediate given to the +instruction is used for the comparison. + +.. table:: SIMD Comparison operations + :name: SIMD Comparison operations + :widths: 50 50 + :class: no-scrollbar-table + + +---------------------------------------------------------------+-----------------------------------+ + | **Mnemonic** | **Description** | + +===============================================================+===================================+ + | **cv.cmpeq[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] == op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpne[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] != op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpge[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >=op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmplt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmple[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] <= op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgtu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgeu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >= op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpltu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpleu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] <= op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + +SIMD Comparison Encoding +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: SIMD Comparison encoding + :name: SIMD Comparison encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+===================================+ + | 0 0000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpeq.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpeq.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpeq.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpeq.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpeq.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpeq.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpne.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpne.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpne.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpne.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpne.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpne.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgt.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgt.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgt.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgt.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgt.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgt.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpge.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpge.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpge.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpge.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpge.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpge.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmplt.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmplt.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmplt.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmplt.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmplt.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmplt.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmple.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmple.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmple.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmple.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmple.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmple.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgtu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgtu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgtu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgtu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgtu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgtu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgeu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgeu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgeu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgeu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgeu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgeu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpltu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpltu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpltu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpltu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpltu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpltu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpleu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpleu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpleu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpleu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpleu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpleu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + +SIMD Complex-number operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SIMD Complex-number operations are extra instructions +that uses the packed-SIMD extentions to represent Complex-numbers. +These extentions use only the half-words mode and only operand in registers. +A number C = {Re, Im} is represented as a vector of two 16-Bits signed numbers. +C[0] is the real part [15:0], C[1] is the +imaginary part [31:16]. +Such operations are subtraction of 2 complexes with post rotation by -j, the complex and conjugate, +complex multiplications and complex additions/substractions. +The complex multiplications are performed in two separate instructions, one to compute the real part, +and one to compute the imaginary part. + + +As for all the other SIMD instructions, no flags are raised and CSR register are unmodified. +No carry, overflow is generated. Instructions are rounded up as the mask & 0xFFFF explicits. + +.. table:: SIMD Complex-number operations + :name: SIMD Complex-number operations + :widths: 35 65 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.cplxmul.r{/,.div2,.div4,.div8}** | rD[1] = rD[1] | + | | | + | | rD[0] = (rs1[0]\*rs2[0] - rs1[1]\*rs2[1]) >> {15,16,17,18} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.cplxmul.i{/,.div2,.div4,.div8}** | rD[1] = (rs1[0]\*rs2[1] + rs1[1]\*rs2[0]) >> {15,16,17,18} | + | | | + | | rD[0] = rD[0] | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.cplxconj** | rD[1] = -rs1[1] | + | | | + | | rD[0] = rs1[0] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.subrotmj{/,.div2,.div4,.div8}** | rD[1] = ((rs2[0] - rs1[0]) & 0xFFFF) >> {0,1,2,3} | + | | | + | | rD[0] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {0,1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.add{.div2,.div4,.div8}** | rD[1] = ((rs1[1] + rs2[1]) & 0xFFFF) >> {1,2,3} | + | | | + | | rD[0] = ((rs1[0] + rs2[0]) & 0xFFFF) >> {1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sub{.div2,.div4,.div8}** | rD[1] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {1,2,3} | + | | | + | | rD[0] = ((rs1[0] - rs2[0]) & 0xFFFF) >> {1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD Complex-numbers Encoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: SIMD ALU encoding + :name: SIMD ALU encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+====================================+ + | 0 1010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.r rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.r.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.r.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.r.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.i rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.i.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.i.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.i.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1011 | 1 | 0 | 00000 | src1 | 000 | dest | 111 1011 | **cv.cplxconj rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.subrotmj rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.subrotmj.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.subrotmj.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.subrotmj.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.add.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.add.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.sub.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.sub.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ diff --git a/docs/html/_sources/integration.rst.txt b/docs/html/_sources/integration.rst.txt new file mode 100644 index 000000000..253ae77fd --- /dev/null +++ b/docs/html/_sources/integration.rst.txt @@ -0,0 +1,205 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _core-integration: + +Core Integration +================ + +The main module is named ``cv32e40p_top`` and can be found in ``cv32e40p_top.sv``. +Below, the instantiation template is given and the parameters and interfaces are described. + +.. note:: + + ``cv32e40p_top`` instantiates former ``cv32e40p_core`` and a wrapped ``fpnew_top``. + It is highly suggested to use ``cv32e40p_top`` in place of ``cv32e40p_core`` as + it allows to easily enable/disable FPU parameter with no interface change. + As mentioned in :ref:`backward_compatibility`, v2.0.0 ``cv32e40p_core`` has **slight** + modifications that makes it not backward compatible with v1.0.0 one in some cases. + It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, + there is still backward compatibility as all parameters default value are set to v1 values. + +Instantiation Template +---------------------- + +.. code-block:: verilog + + cv32e40p_top #( + .FPU ( 0 ), + .FPU_ADDMUL_LAT ( 0 ), + .FPU_OTHERS_LAT ( 0 ), + .ZFINX ( 0 ), + .COREV_PULP ( 0 ), + .COREV_CLUSTER ( 0 ), + .NUM_MHPMCOUNTERS ( 1 ) + ) u_core ( + // Clock and reset + .rst_ni (), + .clk_i (), + .scan_cg_en_i (), + + // Special control signals + .fetch_enable_i (), + .pulp_clock_en_i (), + .core_sleep_o (), + + // Configuration + .boot_addr_i (), + .mtvec_addr_i (), + .dm_halt_addr_i (), + .dm_exception_addr_i (), + .hart_id_i (), + + // Instruction memory interface + .instr_addr_o (), + .instr_req_o (), + .instr_gnt_i (), + .instr_rvalid_i (), + .instr_rdata_i (), + + // Data memory interface + .data_addr_o (), + .data_req_o (), + .data_gnt_i (), + .data_we_o (), + .data_be_o (), + .data_wdata_o (), + .data_rvalid_i (), + .data_rdata_i (), + + // Interrupt interface + .irq_i (), + .irq_ack_o (), + .irq_id_o (), + + // Debug interface + .debug_req_i (), + .debug_havereset_o (), + .debug_running_o (), + .debug_halted_o () + ); + +Parameters +---------- + +.. table:: Parameters + :name: Parameters + :widths: 25 15 11 49 + :class: no-scrollbar-table + + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Default** | **Description** | + +==============================+================+=============+==================================================================+ + | ``FPU`` | bit | 0 | Enable Floating Point Unit (FPU) support, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``FPU_ADDMUL_LAT`` | int | 0 | Number of pipeline registers for Floating-Point | + | | | | addition and multiplication instructions, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``FPU_OTHERS_LAT`` | int | 0 | Number of pipeline registers for Floating-Point | + | | | | comparison, conversion and classify instructions, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``ZFINX`` | bit | 0 | Enable Floating Point instructions to use the General Purpose | + | | | | register file instead of requiring a dedicated Floating Point | + | | | | register file, see :ref:`fpu`. Only allowed to be set to 1 | + | | | | if ``FPU`` = 1 | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``COREV_PULP`` | bit | 0 | Enable all of the custom PULP ISA extensions (except **cv.elw**) | + | | | | (see :ref:`custom-isa-extensions`) and all custom CSRs | + | | | | (see :ref:`cs-registers`). | + | | | | | + | | | | Examples of PULP ISA | + | | | | extensions are post-incrementing load and stores | + | | | | (see :ref:`corev_load_store`) and hardware loops | + | | | | (see :ref:`corev_hardware_loop`). | + | | | | | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``COREV_CLUSTER`` | bit | 0 | Enable PULP Cluster support (**cv.elw**), see :ref:`pulp_cluster`| + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``NUM_MHPMCOUNTERS`` | int (0..29) | 1 | Number of MHPMCOUNTER performance counters, see | + | | | | :ref:`performance-counters` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + +Interfaces +---------- + +.. table:: Interfaces + :name: Interfaces + :widths: 25 10 7 58 + :class: no-scrollbar-table + + +-------------------------+-------------------------+---------+--------------------------------------------+ + | **Signal** | **Width** | **Dir** | **Description** | + +=========================+=========================+=========+============================================+ + | ``rst_ni`` | 1 | in | Active-low asynchronous reset | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``clk_i`` | 1 | in | Clock signal | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``scan_cg_en_i`` | 1 | in | Scan clock gate enable. Design for test | + | | | | (DfT) related signal. Can be used during | + | | | | scan testing operation to force | + | | | | instantiated clock gate(s) to be enabled. | + | | | | This signal should be 0 during normal / | + | | | | functional operation. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``fetch_enable_i`` | 1 | in | Enable the instruction fetch of CV32E40P. | + | | | | The first instruction fetch after reset | + | | | | de-assertion will not happen as long as | + | | | | this signal is 0. ``fetch_enable_i`` needs | + | | | | to be set to 1 for at least one cycle | + | | | | while not in reset to enable fetching. | + | | | | Once fetching has been enabled the value | + | | | | ``fetch_enable_i`` is ignored. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``core_sleep_o`` | 1 | out | Core is sleeping, see :ref:`sleep_unit`. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``pulp_clock_en_i`` | 1 | in | PULP clock enable (only used when | + | | | | ``COREV_CLUSTER`` = 1, tie to 0 otherwise),| + | | | | see :ref:`sleep_unit` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``boot_addr_i`` | 32 | in | Boot address. First program counter after | + | | | | reset = ``boot_addr_i``. Must be half-word | + | | | | aligned. Do not change after enabling core | + | | | | via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``mtvec_addr_i`` | 32 | in | ``mtvec`` address. Initial value for the | + | | | | address part of :ref:`csr-mtvec`. | + | | | | Do not change after enabling core | + | | | | via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``dm_halt_addr_i`` | 32 | in | Address to jump to when entering Debug | + | | | | Mode, see :ref:`debug-support`. Must be | + | | | | word-aligned. Do not change after enabling | + | | | | core via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``dm_exception_addr_i`` | 32 | in | Address to jump to when an exception | + | | | | occurs when executing code during Debug | + | | | | Mode, see :ref:`debug-support`. Must be | + | | | | word-aligned. Do not change after enabling | + | | | | core via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``hart_id_i`` | 32 | in | Hart ID, usually static, can be read from | + | | | | :ref:`csr-mhartid` and :ref:`csr-uhartid` | + | | | | CSRs | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``debug_*`` | Debug interface, see :ref:`debug-support` | + +-------------------------+-------------------------+---------+--------------------------------------------+ diff --git a/docs/html/_sources/intro.rst.txt b/docs/html/_sources/intro.rst.txt new file mode 100644 index 000000000..372dfdef5 --- /dev/null +++ b/docs/html/_sources/intro.rst.txt @@ -0,0 +1,290 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +Introduction +============= + +CV32E40P is a 4-stage in-order 32-bit RISC-V +processor core. The ISA of CV32E40P +has been extended to support multiple additional instructions including +hardware loops, post-increment load and store instructions, +additional ALU instructions and SIMD instructions that are not part of the standard RISC-V +ISA. :numref:`blockdiagram` shows a block diagram of the top level with the core and the FPU. + +.. figure:: ../images/CV32E40P_Block_Diagram.png + :name: blockdiagram + :align: center + :alt: + + Block Diagram of CV32E40P RISC-V Core + +License +------- +Copyright 2023 OpenHW Group. + +Copyright 2018 ETH Zurich and University of Bologna. + +Copyright and related rights are licensed under the Solderpad Hardware +License, Version 0.51 (the “License”); you may not use this file except +in compliance with the License. You may obtain a copy of the License at +http://solderpad.org/licenses/SHL-0.51. Unless required by applicable +law or agreed to in writing, software, hardware and materials +distributed under this License is distributed on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Bus Interfaces +-------------- + +The Instruction Fetch and Load/Store data bus interfaces are compliant to the **OBI** (Open Bus Interface) protocol. +See `OBI-v1.2.pdf `_ for details about the protocol. +Additional information can be found in the :ref:`instruction-fetch` and :ref:`load-store-unit` chapters of this document. + +Standards Compliance +-------------------- + +CV32E40P is a standards-compliant 32-bit RISC-V processor. +It follows these specifications: + +* `RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version 20191213 (December 13, 2019) `_ +* `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20190608-Base-Ratified (June 8, 2019) `_. CV32E40P implements the Machine ISA version 1.11. +* `RISC-V External Debug Support, draft version 0.13.2 `_ + +Many features in the RISC-V specification are optional, and CV32E40P can be parameterized to enable or disable some of them. + +CV32E40P supports the following base integer instruction set. + +* The RV32I Base Integer Instruction Set, version 2.1 + +In addition, the following standard instruction set extensions are available. + +.. list-table:: CV32E40P Standard Instruction Set Extensions + :header-rows: 1 + :widths: 55 12 33 + :class: no-scrollbar-table + + * - **Standard Extension** + - **Version** + - **Configurability** + + * - **C**: Standard Extension for Compressed Instructions + - 2.0 + - always enabled + + * - **M**: Standard Extension for Integer Multiplication and Division + - 2.0 + - always enabled + + * - **Zicntr**: Performance Counters + - 2.0 + - always enabled + + * - **Zicsr**: Control and Status Register Instructions + - 2.0 + - always enabled + + * - **Zifencei**: Instruction-Fetch Fence + - 2.0 + - always enabled + + * - **F**: Single-Precision Floating-Point using F registers + - 2.2 + - optionally enabled with the ``FPU`` parameter + + * - **Zfinx**: Single-Precision Floating-Point using X registers + - 1.0 + - optionally enabled with the ``ZFINX`` parameter (also requires the ``FPU`` parameter) + +The following custom instruction set extensions are available. + +.. list-table:: CV32E40P Custom Instruction Set Extensions + :header-rows: 1 + :widths: 40 12 48 + :class: no-scrollbar-table + + * - **Custom Extension** + - **Version** + - **Configurability** + + * - **Xcv**: CORE-V PULP ISA Extensions + - 1.0 + - optionally enabled with the ``COREV_PULP`` parameter + + * - **Xcvelw**: CORE-V PULP Cluster ISA Extension + - 1.0 + - optionally enabled with the ``COREV_CLUSTER`` parameter + +Most content of the RISC-V privileged specification is optional. +CV32E40P currently supports the following features according to the RISC-V Privileged Specification, version 1.11. + +* M-Mode +* All CSRs listed in :ref:`cs-registers` +* Hardware Performance Counters as described in :ref:`performance-counters` controlled by the ``NUM_MHPMCOUNTERS`` parameter +* Trap handling supporting direct mode or vectored mode as described at :ref:`exceptions-interrupts` + + +.. _synthesis_guidelines: + +Synthesis guidelines +-------------------- + +The CV32E40P core is fully synthesizable. +It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well. + +The top level module is called cv32e40p_top and includes both the core and the FPU. +All the core files are in ``rtl`` and ``rtl/include`` folders (all synthesizable) +while all the FPU files are in ``rtl/vendor/pulp_platform_common_cells``, ``rtl/vendor/pulp_platform_fpnew`` and ``rtl/vendor/pulp_platform_fpu_div_sqrt``. +.. while all the FPU files are in ``rtl/vendor/pulp_platform_common_cells``, ``rtl/vendor/pulp_platform_fpnew`` and ``rtl/vendor/opene906``. +cv32e40p_fpu_manifest.flist is listing all the required files. + +The user must provide a clock-gating module that instantiates the functionally equivalent clock-gating cell of the target technology. +This file must have the same interface and module name as the one provided for simulation-only purposes at ``bhv/cv32e40p_sim_clock_gate.sv`` (see :ref:`clock-gating-cell`). + +The ``constraints/cv32e40p_core.sdc`` file provides an example of synthesis constraints. + + +ASIC Synthesis +^^^^^^^^^^^^^^ + +ASIC synthesis is supported for CV32E40P. The whole design is completely +synchronous and uses positive-edge triggered flip-flops. The +core occupies an area of about XX kGE. +With the FPU, the area increases to about XX kGE (XX kGE +FPU, XX kGE additional register file). A technology specific implementation +of a clock gating cell as described in :ref:`clock-gating-cell` needs to +be provided. + +FPGA Synthesis +^^^^^^^^^^^^^^^ + +FPGA synthesis is only supported for CV32E40P. +The user needs to provide a technology specific implementation of a clock gating cell as described +in :ref:`clock-gating-cell`. + +.. _synthesis_with_fpu: + +Synthesizing with the FPU +^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default the pipeline of the FPU is purely combinatorial (FPU_*_LAT = 0). In this case FPU instructions latency is the same than simple ALU operations (except FP multicycle DIV/SQRT ones). +But as FPU operations are much more complex than ALU ones, maximum achievable frequency is much lower than ALU one when FPU is enabled. +If this can be fine for low frequency systems, it is possible to indicate how many pipeline registers are instantiated in the FPU to reach higher target frequency. +This is done with FPU_*_LAT CV32E40P parameters setting to perfectly fit target frequency. +It should be noted that any additional pipeline register is impacting FPU instructions latency and could cause performances degradation depending of applications using Floating-Point operations. +Those pipeline registers are all added at the end of the FPU pipeline with all operators before them. Optimal frequency is only achievable using automatic retiming commands in implementation tools. +This can be achieved with the following command for Synopsys Design Compiler: +“set_optimize_registers true -designs [get_object_name [get_designs "*fpnew_wrapper*"]]”. + +Contents +-------- + + * :ref:`getting-started` discusses the requirements and initial steps to start using CV32E40P. + * :ref:`core-integration` provides the instantiation template and gives descriptions of the design parameters as well as the input and output ports. + * :ref:`verification` gives a brief overview of the verification methodology. + * :ref:`pipeline-details` described the overal pipeline structure. + * The instruction and data interfaces of CV32E40P are explained in :ref:`instruction-fetch` and :ref:`load-store-unit`, respectively. + * The two register-file flavors are described in :ref:`register-file`. + * :ref:`fpu` describes the Floating Point Unit (FPU). + * :ref:`sleep_unit` describes the Sleep unit including the PULP Cluster extension. + * :ref:`hwloop-specs` describes the PULP Hardware Loop extension. + * The control and status registers are explained in :ref:`cs-registers`. + * :ref:`performance-counters` gives an overview of the performance monitors and event counters available in CV32E40P. + * :ref:`exceptions-interrupts` deals with the infrastructure for handling exceptions and interrupts. + * :ref:`debug-support` gives a brief overview on the debug infrastructure. + * :ref:`custom-isa-extensions` describes the custom instruction set extensions. + * :ref:`core_versions` describes the core versioning. + * :ref:`glossary` provides definitions of used terminology. + +History +------- + +CV32E40P started its life as a fork of the OR10N CPU core based on the OpenRISC ISA. Then, under the name of RI5CY, it became a RISC-V core (2016), +and it has been maintained by the PULP platform team until February 2020, when it has been contributed to OpenHW Group https://www.openhwgroup.org. + +As RI5CY has been used in several projects, a list of all the changes made by OpenHW Group since February 2020 follows: + +Memory-Protocol +^^^^^^^^^^^^^^^ + +The Instruction and Data memory interfaces are now compliant with the OBI protocol (see `OBI-v1.2.pdf `_). +Such memory interface is slightly different from the one used by RI5CY as: the grant signal can now be kept high by the bus even without the core raising a request; and the request signal does not depend anymore on the rvalid signal (no combinatorial dependency). The OBI is easier to be interfaced to the AMBA AXI and AHB protocols and improves timing as it removes rvalid->req dependency. Also, the protocol forces the address stability. Thus, the core can not retract memory requests once issued, nor can it change the issued address (as was the case for the RI5CY instruction memory interface). + +RV32F Extensions +^^^^^^^^^^^^^^^^ + +Previously, RI5CY could select with a parameter whether the FPU was instantiated inside the EX stage or via the APU interface. Now in CV32E40P, the FPU is not instantiated in the core EX stage anymore. +A new file called cv32e40p_top.sv is instantiating the core together with the FPU and APU interface is not visible on I/Os. +This is this new top level which has been used for Verification and Implementation. + +RV32A Extensions, Security and Memory Protection +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CV32E40P core does not support the RV32A (atomic) extensions, the U-mode, and the PMP anymore. +Most of the previous RTL descriptions of these features have been kept but not maintained. The RTL code has been partially kept to allow previous users of these features to develop their own by reusing previously developed RI5CY modules. + +CSR Address Re-Mapping +^^^^^^^^^^^^^^^^^^^^^^ + +RI5CY used to have custom performance counters 32b wide (not compliant with RISC-V) in the CSR address space {0x7A0, 0x7A1, 0x780-0x79F}. +CV32E40P is now fully compliant with the RISC-V spec on performance counters side. +And the custom PULP HWLoop CSRs have been moved from the 0x7C* to RISC-V user custom read-only 0xCC0-0xCFF address space. + +Interrupts +^^^^^^^^^^ + +RI5CY used to have a req plus a 5 bits ID interrupt interface, supporting up to 32 interrupt requests (only one active at a time), with the priority defined outside in an interrupt controller. CV32E40P is now compliant with the CLINT RISC-V spec, extended with 16 custom interrupts lines called fast, for a total of 19 interrupt lines. They can be all active simultaneously, and priority and per-request interrupt enable bit is controlled by the core CLINT definition. + +PULP HWLoop Spec +^^^^^^^^^^^^^^^^ + +RI5CY supported two nested HWLoops. Every loop had a minimum of two instructions. The start and end of the loop addresses +could be misaligned, and the instructions in the loop body could be of any kind. CV32E40P has a more restricted spec for the +HWLoop (see :ref:`hwloop-specs`). + +Compliancy, bug fixing, code clean-up, and documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The CV32E40P has been verified. It is fully compliant with RISC-V (RI5CY was partially compliant). Many bugs have been fixed, and the RTL code cleaned-up. The documentation has been formatted with reStructuredText and has been developed following at industrial quality level. + + + +References +---------- + +1. `Gautschi, Michael, et al. "Near-Threshold RISC-V Core With DSP Extensions for Scalable IoT Endpoint Devices." in IEEE Transactions on Very Large Scale Integration (VLSI) Systems, vol. 25, no. 10, pp. 2700-2713, Oct. 2017 `_ + +2. `Schiavone, Pasquale Davide, et al. "Slow and steady wins the race? A comparison of ultra-low-power RISC-V cores for Internet-of-Things applications." 27th International Symposium on Power and Timing Modeling, Optimization and Simulation (PATMOS 2017) `_ + +Contributors +------------ + +| Andreas Traber (`atraber@iis.ee.ethz.ch `__) +| Michael Gautschi (`gautschi@iis.ee.ethz.ch `__) +| Pasquale Davide Schiavone (`pschiavo@iis.ee.ethz.ch `__) + +| Arjan Bink (`arjan.bink@silabs.com `__) +| Paul Zavalney (`paul.zavalney@silabs.com `__) + +| Pascal Gouédo (`pascal.gouedo@dolphin.fr `__) + +| Micrel Lab and Multitherman Lab +| University of Bologna, Italy + +| Integrated Systems Lab +| ETH Zürich, Switzerland + diff --git a/docs/html/_sources/load_store_unit.rst.txt b/docs/html/_sources/load_store_unit.rst.txt new file mode 100644 index 000000000..ebaf837cc --- /dev/null +++ b/docs/html/_sources/load_store_unit.rst.txt @@ -0,0 +1,161 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _load-store-unit: + +Load-Store-Unit (LSU) +===================== + +The Load-Store Unit (LSU) of the core takes care of accessing the data memory. Load and +stores on words (32 bit), half words (16 bit) and bytes (8 bit) are +supported. The CV32E40P data interface can cause up to 2 outstanding +transactions and there is no FIFO to allow more outstanding requests. + +:numref:`LSU interface signals` describes the signals that are used by the LSU. + +.. table:: LSU interface signals + :name: LSU interface signals + :widths: 25 15 60 + :class: no-scrollbar-table + + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_addr_o[31:0]`` | output | Address | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_req_o`` | output | Request valid, will stay high until ``data_gnt_i`` is high for one cycle | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_gnt_i`` | input | The other side accepted the request. ``data_addr_o`` may change in the next cycle. | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_we_o`` | output | Write Enable, high for writes, low for reads. Sent together with ``data_req_o`` | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to write/read, sent together with ``data_req_o`` | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together with ``data_req_o`` | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_rvalid_i`` | input | ``data_rvalid_i`` will be high for exactly one cycle to signal the end of the response phase of for both read and write | + | | | transactions. For a read transaction ``data_rdata_i`` holds valid data when ``data_rvalid_i`` is high. | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_rdata_i[31:0]`` | input | Data read from memory | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + +Misaligned Accesses +------------------- + +The LSU never raises address-misaligned exceptions. For loads and stores where the effective address is not naturally aligned to the referenced +datatype (i.e., on a four-byte boundary for word accesses, and a two-byte boundary for halfword accesses) the load/store is performed as two +bus transactions in case that the data item crosses a word boundary. A single load/store instruction is therefore performed as two bus +transactions for the following scenarios: + +* Load/store of a word for a non-word-aligned address +* Load/store of a halfword crossing a word address boundary + +In both cases the transfer corresponding to the lowest address is performed first. All other scenarios can be handled with a single bus transaction. + +Protocol +-------- + +The CV32E40P data interface does not implement the following optional OBI signals: auser, wuser, aid, rready, err, ruser, rid. +These signals can be thought of as being tied off as specified in the OBI specification. + +.. note:: + + **Transactions Ordering** + As mentioned above, data interface can generate up to 2 outstanding transactions. + OBI specification states that links are always in-order from master point of view. So as the data interface does not generate transaction id (aid), + interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information. + +The OBI protocol that is used by the LSU to communicate with a memory works +as follows. + +The LSU provides a valid address on ``data_addr_o``, control information +on ``data_we_o``, ``data_be_o`` (as well as write data on ``data_wdata_o`` in +case of a store) and sets ``data_req_o`` high. The memory sets ``data_gnt_i`` +high as soon as it is ready to serve the request. This may happen at any +time, even before the request was sent. After a request has been granted +the address phase signals (``data_addr_o``, ``data_we_o``, ``data_be_o`` and +``data_wdata_o``) may be changed in the next cycle by the LSU as the memory +is assumed to already have processed and stored that information. After +granting a request, the memory answers with a ``data_rvalid_i`` set high +if ``data_rdata_i`` is valid. This may happen one or more cycles after the +request has been granted. Note that ``data_rvalid_i`` must also be set high +to signal the end of the response phase for a write transaction (although +the ``data_rdata_i`` has no meaning in that case). When multiple granted requests +are outstanding, it is assumed that the memory requests will be kept in-order and +one ``data_rvalid_i`` will be signalled for each of them, in the order they were issued. + +:numref:`obi-data-basic`, :numref:`obi-data-back-to-back`, :numref:`obi-data-slow-response` and +:numref:`obi-data-multiple-outstanding` show example timing diagrams of the protocol. + +.. figure:: ../images/obi_data_basic.svg + :name: obi-data-basic + :align: center + :alt: + + Basic Memory Transaction + +.. figure:: ../images/obi_data_back_to_back.svg + :name: obi-data-back-to-back + :align: center + :alt: + + Back-to-back Memory Transactions + +.. figure:: ../images/obi_data_slow_response.svg + :name: obi-data-slow-response + :align: center + :alt: + + Slow Response Memory Transaction + +.. figure:: ../images/obi_data_multiple_outstanding.svg + :name: obi-data-multiple-outstanding + :align: center + :alt: + + Multiple Outstanding Memory Transactions + +Post-Incrementing Load and Store Instructions +--------------------------------------------- + +This section is only valid if ``COREV_PULP = 1`` + +Post-incrementing load and store instructions perform a load/store +operation from/to the data memory while at the same time increasing the +base address by the specified offset. For the memory access, the base +address without offset is used. + +Post-incrementing load and stores reduce the number of required +instructions to execute code with regular data access patterns, which +can typically be found in loops. These post-incrementing load/store +instructions allow the address increment to be embedded in the memory +access instructions and get rid of separate instructions to handle +pointers. Coupled with hardware loop extension, these instructions allow +to reduce the loop overhead significantly. + +.. only:: PMP + + Physical Memory Protection (PMP) Unit + ------------------------------------- + + The CV32E40P core has a PMP module which can be enabled by setting the + parameter PULP_SECURE=1 which also enabled the core to possibly run in + USER MODE. Such unit has a configurable number of entries (up to 16) and + supports all the modes as TOR, NAPOT and NA4. Every fetch, load and + store access executed in USER MODE are first filtered by the PMP unit + which can possibly generated exceptions. For the moment, the MPRV bit in + MSTATUS as well as the LOCK mechanism in the PMP are not supported. diff --git a/docs/html/_sources/perf_counters.rst.txt b/docs/html/_sources/perf_counters.rst.txt new file mode 100644 index 000000000..bbed0c545 --- /dev/null +++ b/docs/html/_sources/perf_counters.rst.txt @@ -0,0 +1,133 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _performance-counters: + +Performance Counters +==================== + +CV32E40P implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware Performance Monitor, Section 3.1.11). +The performance counters are placed inside the Control and Status Registers (CSRs) and can be accessed with the ``CSRRW(I)`` and ``CSRRS/C(I)`` instructions. + +CV32E40P implements the clock cycle counter ``mcycle(h)``, the retired instruction counter ``minstret(h)``, as well as the parameterizable number of event counters +``mhpmcounter3(h)`` - ``mhpmcounter31(h)`` and the corresponding event selector CSRs ``mhpmevent3`` - ``mhpmevent31``, and the ``mcountinhibit`` CSR to individually enable/disable the counters. +``mcycle(h)`` and ``minstret(h)`` are always available. + +All counters are 64 bit wide. + +The number of event counters is determined by the parameter ``NUM_MHPMCOUNTERS`` with a range from 0 to 29 (default value of 1). + +Unimplemented counters always read 0. + +.. note:: + + All performance counters are using the gated version of ``clk_i``. The **wfi** instruction, the + **cv.elw** instruction, and ``pulp_clock_en_i`` impact the gating of ``clk_i`` as explained + in :ref:`sleep_unit` and can therefore affect the counters. + +.. _event_selector: + +Event Selector +-------------- + +The following events can be monitored using the performance counters of CV32E40P. + +.. table:: Event Selector + :name: Event Selector + :widths: 10 20 65 + :class: no-scrollbar-table + + +-------------+-----------------+-------------------------------------------+ + | **Bit #** | **Event Name** | **Description** | + +=============+=================+===========================================+ + | 0 | CYCLES | Number of cycles | + +-------------+-----------------+-------------------------------------------+ + | 1 | INSTR | Number of instructions retired | + +-------------+-----------------+-------------------------------------------+ + | 2 | LD_STALL | Number of load use hazards | + +-------------+-----------------+-------------------------------------------+ + | 3 | JMP_STALL | Number of jump register hazards | + +-------------+-----------------+-------------------------------------------+ + | 4 | IMISS | Cycles waiting for instruction fethces, | + | | | excluding jumps and branches | + +-------------+-----------------+-------------------------------------------+ + | 5 | LD | Number of load instructions | + +-------------+-----------------+-------------------------------------------+ + | 6 | ST | Number of store instructions | + +-------------+-----------------+-------------------------------------------+ + | 7 | JUMP | Number of jumps (unconditional) | + +-------------+-----------------+-------------------------------------------+ + | 8 | BRANCH | Number of branches (conditional) | + +-------------+-----------------+-------------------------------------------+ + | 9 | BRANCH_TAKEN | Number of branches taken (conditional) | + +-------------+-----------------+-------------------------------------------+ + | 10 | COMP_INSTR | Number of compressed instructions retired | + +-------------+-----------------+-------------------------------------------+ + | 11 | PIPE_STALL | Cycles from stalled pipeline | + +-------------+-----------------+-------------------------------------------+ + | 12 | APU_TYPE | Numbe of type conflicts on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 13 | APU_CONT | Number of contentions on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 14 | APU_DEP | Number of dependency stall on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 15 | APU_WB | Number of write backs on APUB/FP | + +-------------+-----------------+-------------------------------------------+ + +The event selector CSRs ``mhpmevent3`` - ``mhpmevent31`` define which of these events are counted by the event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)``. +If a specific bit in an event selector CSR is set to 1, this means that events with this ID are being counted by the counter associated with that selector CSR. +If an event selector CSR is 0, this means that the corresponding counter is not counting any event. + +.. note:: + + At most 1 bit should be set in an event selector. If multiple bits are set in an event selector, then the operation of the associated counter is undefined. + + +Controlling the counters from software +-------------------------------------- + +By default, all available counters are disabled after reset in order to provide the lowest power consumption. + +They can be individually enabled/disabled by overwriting the corresponding bit in the ``mcountinhibit`` CSR at address ``0x320`` as described in the RISC-V Privileged Specification, +version 1.11 (see Machine Counter-Inhibit CSR, Section 3.1.13). +In particular, to enable/disable ``mcycle(h)``, bit 0 must be written. For ``minstret(h)``, it is bit 2. For event counter ``mhpmcounterX(h)``, it is bit X. + +The lower 32 bits of all counters can be accessed through the base register, whereas the upper 32 bits are accessed through the ``h``-register. +Reads of all these registers are non-destructive. + +Parametrization at synthesis time +--------------------------------- + +The ``mcycle(h)`` and ``minstret(h)`` counters are always available and 64 bit wide. + +The number of available event counters ``mhpmcounterX(h)`` can be controlled via the ``NUM_MHPMCOUNTERS`` parameter. +By default ``NUM_MHPCOUNTERS`` set to 1. + +An increment of 1 to the NUM_MHPCOUNTERS results in the addition of the following: + + - 64 flops for ``mhpmcounterX`` + - 15 flops for `mhpmeventX` + - 1 flop for `mcountinhibit[X]` + - Adder and event enablement logic + +Time Registers (``time(h)``) +---------------------------- + +The user mode ``time(h)`` registers are not implemented. Any access to these +registers will cause an illegal instruction trap. It is recommended that a software trap handler is +implemented to detect access of these CSRs and convert that into access of the +platform-defined ``mtime`` register (if implemented in the platform). diff --git a/docs/html/_sources/pipeline.rst.txt b/docs/html/_sources/pipeline.rst.txt new file mode 100644 index 000000000..8ee1231cc --- /dev/null +++ b/docs/html/_sources/pipeline.rst.txt @@ -0,0 +1,146 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _pipeline-details: + +Pipeline Details +================ + +.. figure:: ../images/CV32E40P_Pipeline.png + :name: cv32e40p-pipeline + :align: center + + CV32E40P Pipeline + +CV32E40P has a 4-stage in-order completion pipeline, the 4 stages are: + +Instruction Fetch (IF) + Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. This prefetech buffer is able to store 2 32-b data. The IF stage also pre-decodes RVC instructions into RV32I base instructions. See :ref:`instruction-fetch` for details. + +Instruction Decode (ID) + Decodes fetched instruction and performs required register file reads. Jumps are taken from the ID stage. + +Execute (EX) + Executes the instructions. The EX stage contains the ALU, Multiplier and Divider. Branches (with their condition met) are taken from the EX stage. Multi-cycle instructions will stall this stage until they are complete. The ALU, Multiplier and Divider instructions write back their result to the register file from the EX stage. The address generation part of the load-store-unit (LSU) is contained in EX as well. + + The FPU writes back its result from EX stage as well when FPU_*_LAT is either 0 cycle or more than 1 cycle. It is reusing register file ALU/Mult/Div write port and it has the highest priority so it will stall EX stage if there is a conflict (when FPU_*_LAT > 1). + +Writeback (WB) + Writes the result of Load instructions back to the register file. + + The FPU writes back its result from WB stage as well when FPU_*_LAT is 1 cycle. It is reusing register file LSU write port but LSU has the highest priority over FPU if there is a conflict. + +Hazards +------- + +There is a forwarding path betwen ALU, Multiplier and Divider result in EX stage and ID stage flip-flops to avoid the need of a write-through register file. +This allows to have 0-cycle penalty between those instructions and immediately following one when using result. +This is the same with 0-cycle latency FPU instructions. + +But the CV32E40P experiences a 1-cycle penalty on the following hazards: + + * Load data hazard in case the instruction immediately following a load uses the result of that load + * Jump register (jalr) data hazard in case that a jalr depends on the result of an immediately preceding instruction + * FPU data hazard when FPU_*_LAT = 1 in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU + +More than 1-cycle penalty will happen when: + + * FPU data hazard of FPU_*_LAT cycles (FPU_*_LAT > 1) in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU + * FPU data hazard in case the instruction immediately following FDIV/FSQRT uses the result of those instructions + + +Those cycles penalty can be hidden if the compiler is able to add instructions between the instructions causing this data hazard. + +Single- and Multi-Cycle Instructions +------------------------------------ + +:numref:`Cycle counts per instruction type` shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. The cycle counts assume zero stall on the instruction-side interface and zero stall on the data-side memory interface. + +.. _instructions_latency_table: +.. table:: Cycle counts per instruction type + :name: Cycle counts per instruction type + :widths: 20 30 50 + :class: no-scrollbar-table + + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | **Instruction Type** | **Cycles** | **Description** | + +========================+======================================+=============================================================+ + | Integer | 1 | Integer Computational Instructions are defined in the | + | | | RISCV-V RV32I Base Integer Instruction Set. | + | Computational | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Multiplication | 1 (mul) | CV32E40P uses a single-cycle 32-bit x 32-bit multiplier | + | | | with a 32-bit result. The multiplications with upper-word | + | | 5 (mulh, mulhsu, mulhu) | result take 5 cycles to compute. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Division | 3..35 | The number of cycles depends on the divider operand value | + | | | (operand b), i.e. in the number of leading bits at 0. | + | Remainder | 3..35 | The minimum number of cycles is 3 when the divider has zero | + | | | leading bits at 0 (e.g., 0x8000000). | + | | | The maximum number of cycles is 35 when the divider is 0. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Load/Store | 1 | Load/Store is handled in 1 bus transaction using both EX | + | | | and WB stages for 1 cycle each. For misaligned word | + | | 2 (non-word aligned word | transfers and for halfword transfers that cross a word | + | | transfer) | boundary 2 bus transactions are performed using EX and WB | + | | | stages for 2 cycles each. | + | | 2 (halfword transfer crossing | A **cv.elw** takes 4 cycles. | + | | word boundary) | | + | | | | + | | 4 (cv.elw) | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Jump | 2 | Jumps are performed in the ID stage. Upon a jump the IF | + | | | stage (including prefetch buffer) is flushed. The new PC | + | | 3 (target is a non-word-aligned | request will appear on the instruction-side memory | + | | non-RVC instruction) | interface the same cycle the jump instruction is in the ID | + | | | stage. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Branch | 1 | Any branch where the condition is not met will | + | | | not stall. | + | (Not-Taken) | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Branch | 3 | The EX stage is used to compute the branch decision. Any | + | | | branch where the condition is met will be taken from the | + | (Taken) | 4 (target is a non-word-aligned | EX stage and will cause a flush of the IF stage (including | + | | non-RVC instruction) | prefetch buffer) and ID stage. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | CSR Access | 4 (mstatus, mepc, mtvec, mcause, | CSR Access Instruction are defined in 'Zicsr' of the | + | | mcycle, minstret, mhpmcounter*, | RISC-V specification. | + | | mcycleh, minstreth, mhpmcounter*h, | | + | | mcountinhibit, mhpmevent*, dscr, | | + | | dpc, dscratch0, dscratch1) | | + | | | | + | | 1 (all the other CSRs) | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Instruction Fence | 2 | The FENCE.I instruction as defined in 'Zifencei' of the | + | | | RISC-V specification. Internally it is implemented as a | + | | 3 (target is a non-word-aligned | jump to the instruction following the fence. The jump | + | | non-RVC instruction) | performs the required flushing as described above. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Floating-Point | 1..FPU_ADDMUL_LAT + 1 | Floating-Point instructions are dispatched to the FPU. | + | Addition or | | Following instructions can be executed by the Core as long | + | Multiplication | | as they are not FPU ones and there are no Read-After-Write | + +------------------------+--------------------------------------+ or Write-After-Write data hazard between them and the | + | Floating-Point | 1..FPU_OTHERS_LAT + 1 | destination register of the outstanding FPU instruction. | + | Comparison, Conversion | | If there are enough instructions between FPU one and | + | or Classify | | the instruction using the result then cycle number is 1. | + +------------------------+--------------------------------------+ "Enough instruction" number is either FPU_ADDMUL_LAT, | + | Single Precision | 1..12 | FPU_OTHERS_LAT or 11. | + | Floating-Point | | If there are no instruction in between then cycle number is | + | Division and | | the maximum value for each category. | + | Square-Root | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ diff --git a/docs/html/_sources/preface.rst.txt b/docs/html/_sources/preface.rst.txt new file mode 100644 index 000000000..f6b516214 --- /dev/null +++ b/docs/html/_sources/preface.rst.txt @@ -0,0 +1,7 @@ +Changelog +========= + +.. changelog:: + :changelog-url: https://cv32e40p-user-manual.readthedocs.io/en/stable/#changelog + :github: https://github.com/openhwgroup/cv32e40p/releases/ + diff --git a/docs/html/_sources/register_file.rst.txt b/docs/html/_sources/register_file.rst.txt new file mode 100644 index 000000000..2c16e90e7 --- /dev/null +++ b/docs/html/_sources/register_file.rst.txt @@ -0,0 +1,49 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _register-file: + +Register File +============= + +Source files: :file:`rtl/cv32e40p_register_file_ff.sv` + +CV32E40P has 31 32-bit wide registers which form registers ``x1`` to ``x31``. +Register ``x0`` is statically bound to 0 and can only be read, it does not +contain any sequential logic. + +The register file has three read ports and two write ports. Register file reads are performed in the ID stage. +Register file writes are performed in the WB stage. + +Floating-Point Register File +---------------------------- + +If the optional FPU is instantiated, unless ``ZFINX`` is configured, the register file is extended +with an additional register bank of 32 registers ``f0``-``f31``. These registers +are stacked on top of the existing register file and can be accessed +concurrently with the limitation that a maximum of three operands per +cycle can be read. Each of the three operands addresses is extended with +an register file select signal which is generated in the instruction decoder +when a FP instruction is decoded. This additional signals determines if +the operand is located in the integer or the floating point register +file. + +Forwarding paths, and write-back logic are shared for the integer and +floating point operations and are not replicated. + +If ``ZFINX`` parameter is set, there is no additional register bank and FPU instructions are using +the same register file than for integer instructions. diff --git a/docs/html/_sources/sleep.rst.txt b/docs/html/_sources/sleep.rst.txt new file mode 100644 index 000000000..cc01f4c65 --- /dev/null +++ b/docs/html/_sources/sleep.rst.txt @@ -0,0 +1,176 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _sleep_unit: + +Sleep Unit +========== + +Source File: :file:`rtl/cv32e40p_sleep_unit.sv` + +The Sleep Unit contains and controls the instantiated clock gate (see :ref:`clock-gating-cell`) that gates ``clk_i`` and produces a gated clock +for use by the other modules inside CV32E40P. The Sleep Unit is the only place in which ``clk_i`` itself is used; all other modules use the gated version of ``clk_i``. + +The clock gating in the Sleep Unit is impacted by the following: + + * ``rst_ni`` + * ``fetch_enable_i`` + * **wfi** instruction (only when ``COREV_CLUSTER`` = 0) + * **cv.elw** instruction (only when ``COREV_CLUSTER`` = 1) + * ``pulp_clock_en_i`` (only when ``COREV_CLUSTER`` = 1) + +:numref:`Sleep Unit interface signals` describes the Sleep Unit interface. + +.. table:: Sleep Unit interface signals + :name: Sleep Unit interface signals + :widths: 20 15 65 + :class: no-scrollbar-table + + +--------------------------------------+---------------+----------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +======================================+===============+====================================================+ + | ``pulp_clock_en_i`` | input | ``COREV_CLUSTER`` = 0: | + | | | | + | | | ``pulp_clock_en_i`` is not used. Tie to 0. | + | | +----------------------------------------------------+ + | | | ``COREV_CLUSTER`` = 1: | + | | | | + | | | ``pulp_clock_en_i`` can be used to gate ``clk_i`` | + | | | internal to the core when ``core_sleep_o`` = 1. | + | | | | + | | | See :ref:`pulp_cluster` for details. | + +--------------------------------------+---------------+----------------------------------------------------+ + | ``core_sleep_o`` | output | ``COREV_CLUSTER`` = 0: | + | | | | + | | | Core is sleeping because of a **wfi** instruction. | + | | | If ``core_sleep_o`` = 1 then ``clk_i`` is gated | + | | | off internally and it is allowing to gate off | + | | | ``clk_i`` externally as well (e.g. FPU). | + | | | | + | | | See :ref:`wfi` for details. | + | | +----------------------------------------------------+ + | | | ``COREV_CLUSTER`` = 1: | + | | | | + | | | Core is sleeping because | + | | | of a **cv.elw** instruction. | + | | | If ``core_sleep_o`` = 1, | + | | | then the ``pulp_clock_en_i`` directly | + | | | controls the internally instantiated clock gate | + | | | and therefore ``pulp_clock_en_i`` can be set | + | | | to 0 to internally gate off ``clk_i``. If | + | | | ``core_sleep_o`` = 0, then it is not allowed | + | | | to set ``pulp_clock_en_i`` to 0. | + | | | | + | | | See :ref:`pulp_cluster` for details. | + +--------------------------------------+---------------+----------------------------------------------------+ + +.. note:: + + The semantics of ``pulp_clock_en_i`` and ``core_sleep_o`` depend on the ``COREV_CLUSTER`` parameter. + +Startup behavior +---------------- + +``clk_i`` is internally gated off (while signaling ``core_sleep_o`` = 0) during CV32E40P startup: + + * ``clk_i`` is internally gated off during ``rst_ni`` assertion + * ``clk_i`` is internally gated off from ``rst_ni`` deassertion until ``fetch_enable_i`` = 1 + +After initial assertion of ``fetch_enable_i``, the ``fetch_enable_i`` signal is ignored until after a next reset assertion. + +.. _wfi: + +WFI +--- + +The **wfi** instruction can under certain conditions be used to enter sleep mode awaiting a locally enabled +interrupt to become pending. The operation of **wfi** is unaffected by the global interrupt bits in **mstatus**. + +A **wfi** will not enter sleep mode but will be executed as a regular **nop**, if any of the following conditions apply: + + * ``debug_req_i`` = 1 or a debug request is pending + * The core is in debug mode + * The core is performing single stepping (debug) + * The core has a trigger match (debug) + * ``COREV_CLUSTER`` = 1 + +If a **wfi** causes sleep mode entry, then ``core_sleep_o`` is set to 1 and ``clk_i`` is gated off internally. +``clk_i`` is allowed to be gated off externally as well in this scenario. A wake-up can be triggered by any of the following: + + * A locally enabled interrupt is pending + * A debug request is pending + * Core is in debug mode + +Upon wake-up ``core_sleep_o`` is set to 0, ``clk_i`` will no longer be gated internally, must not be gated off externally, and +instruction execution resumes. + +If one of the above wake-up conditions coincides with the **wfi** instruction, then sleep mode is not entered and ``core_sleep_o`` +will not become 1. + +:numref:`wfi-example` shows an example waveform for sleep mode entry because of a **wfi** instruction. + +.. figure:: ../images/wfi.svg + :name: wfi-example + :align: center + + **wfi** example + +.. _pulp_cluster: + +PULP Cluster Extension +---------------------- + +CV32E40P has an optional extension to enable its usage in a PULP Cluster in the PULP (Parallel Ultra Low Power) platform. +This extension is enabled by setting the ``COREV_CLUSTER`` parameter to 1. The PULP platform is organized as clusters of +multiple (typically 4 or 8) CV32E40P cores that share a tightly-coupled data memory, aimed at running digital signal processing +applications efficiently. + +The mechanism via which CV32E40P cores in a PULP Cluster synchronize with each other is implemented via the custom **cv.elw** instruction +that performs a read transaction on an external Event Unit (which for example implements barriers and semaphores). This +read transaction to the Event Unit together with the ``core_sleep_o`` signal inform the Event Unit that the CV32E40P is not busy and +ready to go to sleep. Only in that case the Event Unit is allowed to set ``pulp_clock_en_i`` to 0, thereby gating off ``clk_i`` +internal to the core. Once the CV32E40P core is ready to start again (e.g. when the last core meets the barrier), ``pulp_clock_en_i`` is +set to 1 thereby enabling the CV32E40P to run again. + +If the PULP Cluster extension is not used (``COREV_CLUSTER`` = 0), the ``pulp_clock_en_i`` signal is not used and should be tied to 0. + +Execution of a **cv.elw** instructions causes ``core_sleep_o`` = 1 only if all of the following conditions are met: + + * The **cv.elw** did not yet complete (which can be achieved by witholding ``data_gnt_i`` and/or ``data_rvalid_i``) + * No debug request is pending + * The core is not in debug mode + * The core is not single stepping (debug) + * The core does not have a trigger match (debug) + +As ``pulp_clock_en_i`` can directly impact the internal clock gate, certain requirements are imposed on the environment of CV32E40P +in case ``COREV_CLUSTER`` = 1: + + * If ``core_sleep_o`` = 0, then ``pulp_clock_en_i`` must be 1 + * If ``pulp_clock_en_i`` = 0, then ``irq_i[*]`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``debug_req_i`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``instr_rvalid_i`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``instr_gnt_i`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``data_rvalid_i`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``data_gnt_i`` must be 0 + +:numref:`load_event-example` shows an example waveform for sleep mode entry because of a **cv.elw** instruction. + +.. figure:: ../images/load_event.svg + :name: load_event-example + :align: center + + **cv.elw** example diff --git a/docs/html/_sources/verification.rst.txt b/docs/html/_sources/verification.rst.txt new file mode 100644 index 000000000..afb4b3490 --- /dev/null +++ b/docs/html/_sources/verification.rst.txt @@ -0,0 +1,200 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _verification: + +Verification +============ + +The verification environment (testbenches, testcases, etc.) for the CV32E40P +core can be found at `core-v-verif `_. +It is recommended to start by reviewing the +`CORE-V Verification Strategy `_. + +v1.0.0 verification +------------------- + +In early 2021 the CV32E40P achieved Functional RTL Freeze (released with cv32e40p_v1.0.0 version), meaning that is has been fully verified as per its +`Verification Plan `_. +Final functional, code and test coverage reports can be found `here `_. + +The unofficial start date for the CV32E40P verification effort is 2020-02-27, +which is the date the core-v-verif environment "went live". Between then and +RTL Freeze, a total of 47 RTL issues and 38 User Manual issues were identified +and resolved [1]_. A breakdown of the RTL issues is as follows: + +.. table:: How RTL Issues Were Found + :name: How RTL Issues Were Found + :class: no-scrollbar-table + + +---------------------+-----------+----------------------------------------------------+ + | **"Found By"** | **Count** | **Note** | + +=====================+===========+====================================================+ + | Simulation | 18 | See classification below | + +---------------------+-----------+----------------------------------------------------+ + | Inspection | 13 | Human review of the RTL | + +---------------------+-----------+----------------------------------------------------+ + | Formal Verification | 13 | This includes both Designer and Verifier use of FV | + +---------------------+-----------+----------------------------------------------------+ + | Lint | 2 | | + +---------------------+-----------+----------------------------------------------------+ + | Unknown | 1 | | + +---------------------+-----------+----------------------------------------------------+ + +A classification of the simulation issues by method used to identify them is informative: + +.. table:: Breakdown of Issues found by Simulation + :name: Breakdown of Issues found by Simulation + :widths: 27 10 63 + :class: no-scrollbar-table + + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | **Simulation Method** | **Count** | **Note** | + +==============================+===========+========================================================================================+ + | Directed, self-checking test | 10 | Many test supplied by Design team and a couple from the Open Source Community at large | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Step & Compare | 6 | Issues directly attributed to S&C against ISS | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Constrained-Random | 2 | Test generated by corev-dv (extension of riscv-dv) | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + + + + + + +A classification of the issues themselves: + +.. table:: Issue Classification + :name: Issue Classification + :class: no-scrollbar-table + + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | **Issue Type** | **Count** | **Note** | + +==============================+===========+========================================================================================+ + | RTL Functional | 40 | A bug! | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | RTL coding style | 4 | Linter issues, removing TODOs, removing \`ifdefs, etc. | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Non-RTL functional | 1 | Issue related to behavioral tracer (not part of the core) | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Unreproducible | 1 | | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Invalid | 1 | | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + +Additional details are available as part of the `CV32E40P v1.0.0 Report `_. + +.. [1] + It is a testament on the quality of the work done by the PULP platform team + that it took a team of professonal verification engineers more than 9 months + to find all these issues. + + +v2.0.0 verification +------------------- + +Simulation verification +^^^^^^^^^^^^^^^^^^^^^^^ + +core-v-verif verification environment for v1.0.0 was using a *step&compare* methodology with an instruction set simulator (ISS) from Imperas Software as the reference model. +This strategy was successful, but inefficient because the *step&compare* logic in the testbench must compensate for the cycle-time effects of events that are asynchronous to the instruction stream such as interrupts, debug resets plus bus errors and random delays on instruction fetch and load/store memory buses. +For verification of v2.0.0 release of the CV32E40P core, the step-and-compare and the ISS have been replaced by a true reference model (RM) called ImperasDV. In addition, the Imperas Reference Model has been extended to support the v2 Xpulp instructions specification. + +Another innovation for v2.0.0 was the adoption of a standardized tracer interface to the DUT and RM, based on the open-source RISC-V Verification Interface (RVVI). The use of well documented, standardized interfaces greatly simplifies the integration of the DUT with the RM. + +WIP... + +.. ADD VERIFIED PARAMETERS VALUES TABLE + +.. ADD PLANS AND REPORTS LINKS + +.. `Verification Plan `_. + +.. TO DEVELOP ... + +Formal verification +^^^^^^^^^^^^^^^^^^^ + +To accelerate the verification of more than 300 Xpulp instructions, Formal Verification methodology has been used with Siemens EDA Onespin tools and their RISC-V ISA app. + +The Xpulp instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and Xpulp extensions. +This has been applied on 5 different core configurations (controlled via SystemVerilog parameters). + +WIP... + +.. ADD VERIFIED PARAMETERS VALUES TABLE + +.. ADD PLANS AND REPORTS LINKS + +.. `Verification Plan `_. +.. Final functional, code and test coverage reports can be found `here `_. + +.. TO DEVELOP ... + +Reports +^^^^^^^ + +WIP... + +.. ADD BUG LIST LINK AND TABLE LIKE ABOVE + +.. ADD MERGED RTL CODE COVERAGE GENERATED REPORTS LINK + + +Tracer +------ + +TODO: To re-work with ImperasDV tracer. + +.. ALL CHAPTER TO ADAPT WITH NEW IMPERASDV METHODOLOGY AND RVVI TRACER + +The module ``cv32e40p_tracer`` can be used to create a log of the executed instructions. +It is a behavioral, non-synthesizable, module instantiated in the example testbench that is provided for +the ``cv32e40p_top``. It can be enabled during simulation by defining **CV32E40P_TRACE_EXECUTION**. + +Output file +^^^^^^^^^^^ + +All traced instructions are written to a log file. +The log file is named ``trace_core_.log``, with ```` being the 32 digit hart ID of the core being traced. + +Trace output format +^^^^^^^^^^^^^^^^^^^ + +The trace output is in tab-separated columns. + +1. **Time**: The current simulation time. +2. **Cycle**: The number of cycles since the last reset. +3. **PC**: The program counter +4. **Instr**: The executed instruction (base 16). + 32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions. +5. **Decoded instruction**: The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like ``objdump -Mnumeric -Mno-aliases -D``. + - Unsigned numbers are given in hex (prefixed with ``0x``), signed numbers are given as decimal numbers. + - Numeric register names are used (e.g. ``x1``). + - Symbolic CSR names are used. + - Jump/branch targets are given as absolute address if possible (PC + immediate). +6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the address and the loaded and stored data are given. + +.. code-block:: text + + Time Cycle PC Instr Decoded instruction Register and memory contents + 130 61 00000150 4481 c.li x9,0 x9=0x00000000 + 132 62 00000152 00008437 lui x8,0x8 x8=0x00008000 + 134 63 00000156 fff40413 addi x8,x8,-1 x8:0x00008000 x8=0x00007fff + 136 64 0000015a 8c65 c.and x8,x9 x8:0x00007fff x9:0x00000000 x8=0x00000000 + 142 67 0000015c c622 c.swsp x8,12(x2) x2:0x00002000 x8:0x00000000 PA:0x0000200c diff --git a/docs/html/_static/basic.css b/docs/html/_static/basic.css new file mode 100644 index 000000000..bf18350b6 --- /dev/null +++ b/docs/html/_static/basic.css @@ -0,0 +1,906 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/_static/css/badge_only.css b/docs/html/_static/css/badge_only.css new file mode 100644 index 000000000..e380325bc --- /dev/null +++ b/docs/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/html/_static/css/custom.css b/docs/html/_static/css/custom.css new file mode 100644 index 000000000..3ae7d9ae9 --- /dev/null +++ b/docs/html/_static/css/custom.css @@ -0,0 +1,3 @@ +.no-scrollbar-table td { + white-space: normal !important; +} diff --git a/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 000000000..6cb600001 Binary files /dev/null and b/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 000000000..7059e2314 Binary files /dev/null and b/docs/html/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 000000000..f815f63f9 Binary files /dev/null and b/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 000000000..f2c76e5bd Binary files /dev/null and b/docs/html/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/html/_static/css/fonts/fontawesome-webfont.eot b/docs/html/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/docs/html/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/html/_static/css/fonts/fontawesome-webfont.svg b/docs/html/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/docs/html/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/html/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/docs/html/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/html/_static/css/fonts/fontawesome-webfont.woff b/docs/html/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/docs/html/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/html/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/docs/html/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/html/_static/css/fonts/lato-bold-italic.woff b/docs/html/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 000000000..88ad05b9f Binary files /dev/null and b/docs/html/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/html/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 000000000..c4e3d804b Binary files /dev/null and b/docs/html/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/html/_static/css/fonts/lato-bold.woff b/docs/html/_static/css/fonts/lato-bold.woff new file mode 100644 index 000000000..c6dff51f0 Binary files /dev/null and b/docs/html/_static/css/fonts/lato-bold.woff differ diff --git a/docs/html/_static/css/fonts/lato-bold.woff2 b/docs/html/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 000000000..bb195043c Binary files /dev/null and b/docs/html/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/html/_static/css/fonts/lato-normal-italic.woff b/docs/html/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 000000000..76114bc03 Binary files /dev/null and b/docs/html/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/html/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 000000000..3404f37e2 Binary files /dev/null and b/docs/html/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/html/_static/css/fonts/lato-normal.woff b/docs/html/_static/css/fonts/lato-normal.woff new file mode 100644 index 000000000..ae1307ff5 Binary files /dev/null and b/docs/html/_static/css/fonts/lato-normal.woff differ diff --git a/docs/html/_static/css/fonts/lato-normal.woff2 b/docs/html/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 000000000..3bf984332 Binary files /dev/null and b/docs/html/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/html/_static/css/theme.css b/docs/html/_static/css/theme.css new file mode 100644 index 000000000..0d9ae7e1a --- /dev/null +++ b/docs/html/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/html/_static/doctools.js b/docs/html/_static/doctools.js new file mode 100644 index 000000000..e1bfd708b --- /dev/null +++ b/docs/html/_static/doctools.js @@ -0,0 +1,358 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + this.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + var url = new URL(window.location); + url.searchParams.delete('highlight'); + window.history.replaceState({}, '', url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar : function() { + $('input[name=q]').first().focus(); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + return; + + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON') { + if (event.altKey || event.ctrlKey || event.metaKey) + return; + + if (!event.shiftKey) { + switch (event.key) { + case 'ArrowLeft': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 'ArrowRight': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + case 'Escape': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.hideSearchWords(); + return false; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case '/': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.focusSearchBar(); + return false; + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js new file mode 100644 index 000000000..b57ae3b83 --- /dev/null +++ b/docs/html/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/html/_static/file.png b/docs/html/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/docs/html/_static/file.png differ diff --git a/docs/html/_static/jquery-3.5.1.js b/docs/html/_static/jquery-3.5.1.js new file mode 100644 index 000000000..50937333b --- /dev/null +++ b/docs/html/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Control and Status Registers

+

CV32E40P does not implement all control and status registers specified in +the RISC-V privileged specifications, but is limited to the registers +that were needed for the PULP system. The reason for this is that we +wanted to keep the footprint of the core as low as possible and avoid +any overhead that we do not explicitly need.

+
+

CSR Map

+

Table 15 lists all +implemented CSRs. Two columns in Table 15 may require additional explanation:

+

The Privilege column indicates the access mode of a CSR. The first letter +indicates the lowest privilege level required to access the CSR. Attempts to +access a CSR with a higher privilege level than the core is currently running +in will throw an illegal instruction exception. This is largely a moot point +for the CV32E40P as it only supports machine and debug modes. The remaining +letters indicate the read and/or write behavior of the CSR when accessed by +the indicated or higher privilge level:

+
    +
  • RW: CSR is read-write. That is, CSR instructions (e.g. csrrw) may +write any value and that value will be returned on a subsequent read (unless +a side-effect causes the core to change the CSR value).

  • +
  • RO: CSR is read-only. Writes by CSR instructions raise an illegal +instruction exception.

  • +
+

Writes of a non-supported value to WLRL bitfields of a RW CSR do not result in an illegal +instruction exception. The exact bitfield access types, e.g. WLRL or WARL, can be found in the RISC-V +privileged specification.

+

In the Description column there is a specific comment which identifies those CSRs that are dependent on the value +of specific parameters. If these parameters are not set as +indicated in Table 15 then the associated CSR is not implemented. If the column does not +mention any parameter then the associated CSR is always implemented.

+

Reads or writes to a CSR that is not implemented will result in an illegal +instruction exception.

+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 15 Control and Status Register Map

CSR Address

Name

Privilege

Description

User CSRs

0x001

fflags

URW

Floating-point accrued exceptions.

+

Only present if FPU = 1

+

0x002

frm

URW

Floating-point dynamic rounding mode.

+

Only present if FPU = 1

+

0x003

fcsr

URW

Floating-point control and status register.

+

Only present if FPU = 1

+

0xC00

cycle

URO

(HPM) Cycle Counter

0xC02

instret

URO

(HPM) Instructions-Retired Counter

0xC03

hpmcounter3

URO

(HPM) Performance-Monitoring Counter 3

. . . .

0xC1F

hpmcounter31

URO

(HPM) Performance-Monitoring Counter 31

0xC80

cycleh

URO

(HPM) Upper 32 bits Cycle Counter

0xC82

instreth

URO

(HPM) Upper 32 bits Instructions-Retired Counter

0xC83

hpmcounterh3

URO

(HPM) Upper 32 bits Performance-Monitoring Counter 3

. . . .

0xC9F

hpmcounterh31

URO

(HPM) Upper 32 bits Performance-Monitoring Counter 31

User Custom CSRs

0xCC0

lpstart0

URO

Hardware Loop 0 Start.

+

Only present if COREV_PULP = 1

+

0xCC1

lpend0

URO

Hardware Loop 0 End.

+

Only present if COREV_PULP = 1

+

0xCC2

lpcount0

URO

Hardware Loop 0 Counter.

+

Only present if COREV_PULP = 1

+

0xCC4

lpstart1

URO

Hardware Loop 1 Start.

+

Only present if COREV_PULP = 1

+

0xCC5

lpend1

URO

Hardware Loop 1 End.

+

Only present if COREV_PULP = 1

+

0xCC6

lpcount1

URO

Hardware Loop 1 Counter.

+

Only present if COREV_PULP = 1

+

0xCD0

uhartid

URO

Hardware Thread ID

+

Only present if COREV_PULP = 1 & PULP_SECURE = 1

+

0xCD1

privlv

URO

Privilege Level

+

Only present if COREV_PULP = 1 & PULP_SECURE = 1

+

0xCD2

zfinx

URO

ZFINX ISA

Machine CSRs

0x300

mstatus

MRW

Machine Status

0x301

misa

MRW

Machine ISA

0x304

mie

MRW

Machine Interrupt Enable register

0x305

mtvec

MRW

Machine Trap-Handler Base Address

0x320

mcountinhibit

MRW

(HPM) Machine Counter-Inhibit register

0x323

mhpmevent3

MRW

(HPM) Machine Performance-Monitoring Event Selector 3

. . . .

0x33F

mhpmevent31

MRW

(HPM) Machine Performance-Monitoring Event Selector 31

0x340

mscratch

MRW

Machine Scratch

0x341

mepc

MRW

Machine Exception Program Counter

0x342

mcause

MRW

Machine Trap Cause

0x343

mtval

MRW

Machine Trap Value

0x344

mip

MRW

Machine Interrupt Pending register

0x7A0

tselect

MRW

Trigger Select register

0x7A1

tdata1

MRW

Trigger Data register 1

0x7A2

tdata2

MRW

Trigger Data register 2

0x7A3

tdata3

MRW

Trigger Data register 3

0x7A4

tinfo

MRO

Trigger Info

0x7A8

mcontext

MRW

Machine Context register

0x7AA

scontext

MRW

Machine Context register

0x7B0

dcsr

DRW

Debug Control and Status

0x7B1

dpc

DRW

Debug PC

0x7B2

dscratch0

DRW

Debug Scratch register 0

0x7B3

dscratch1

DRW

Debug Scratch register 1

0xB00

mcycle

MRW

(HPM) Machine Cycle Counter

0xB02

minstret

MRW

(HPM) Machine Instructions-Retired Counter

0xB03

mhpmcounter3

MRW

(HPM) Machine Performance-Monitoring Counter 3

. . . .

0xB1F

mhpmcounter31

MRW

(HPM) Machine Performance-Monitoring Counter 31

0xB80

mcycleh

MRW

(HPM) Upper 32 bits Machine Cycle Counter

0xB82

minstreth

MRW

(HPM) Upper 32 bits Machine Instructions-Retired Counter

0xB83

mhpmcounterh3

MRW

(HPM) Upper 32 bits Machine Performance-Monitoring Counter 3

. . . .

0xB9F

mhpmcounterh31

MRW

(HPM) Upper 32 bits Machine Performance-Monitoring Counter 31

0xF11

mvendorid

MRO

Machine Vendor ID

0xF12

marchid

MRO

Machine Architecture ID

0xF13

mimpid

MRO

Machine Implementation ID

0xF14

mhartid

MRO

Hardware Thread ID

+
+
+

CSR Descriptions

+

What follows is a detailed definition of each of the CSRs listed above. The +Mode column defines the access mode behavior of each bit field when +accessed by the privilege level specified in Table 15 (or a higher privilege +level):

+
    +
  • RO: read-only fields are not affect by CSR write instructions. Such +fields either return a fixed value, or a value determined by the operation of +the core.

  • +
  • RW: read/write fields store the value written by CSR writes. Subsequent +reads return either the previously written value or a value determined by the +operation of the core.

  • +
+
+

Floating-point CSRs

+
+

Floating-point accrued exceptions (fflags)

+

CSR Address: 0x001 (only present if FPU = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:5

RO

Writes are ignored; reads return 0.

4

RW

NV - Invalid Operation

3

RW

DZ - Divide by Zero

2

RW

OF - Overflow

1

RW

UF - Underflow

0

RW

NX - Inexact

+
+
+

Floating-point dynamic rounding mode (frm)

+

CSR Address: 0x002 (only present if FPU = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:3

RO

Writes are ignored; reads return 0.

2:0

RW

Rounding mode:

+

000 = RNE

+

001 = RTZ

+

010 = RDN

+

011 = RUP

+

100 = RMM

+

101 = Invalid

+

110 = Invalid

+

111 = DYN

+
+
+
+

Floating-point control and status register (fcsr)

+

CSR Address: 0x003 (only present if FPU = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:8

RO

Reserved. Writes are ignored; reads return 0.

7:5

RW

Rounding Mode (frm)

4:0

RW

Accrued Exceptions (fflags)

+
+
+
+

Hardware Loops CSRs

+
+

HWLoop Start Address 0/1 (lpstart0/1)

+

CSR Address: 0xCC0/0xCC4 (only present if COREV_PULP = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

Start Address of the HWLoop 0/1.

+
+
+

HWLoop End Address 0/1 (lpend0/1)

+

CSR Address: 0xCC1/0xCC5 (only present if COREV_PULP = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

End Address of the HWLoop 0/1.

+
+
+

HWLoop Count Address 0/1 (lpcount0/1)

+

CSR Address: 0xCC2/0xCC6 (only present if COREV_PULP = 1)

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

Number of iteration of HWLoop 0/1.

+
+
+
+

Other CSRs

+
+

Machine Status (mstatus)

+

CSR Address: 0x300

+

Reset Value: 0x0000_1800

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31

RO

SD: State Dirty

+

SD set to 1 if FS = 11 meaning Floating point State is dirty so save/restore is needed in case of context switch.

+

Hardwired to 0 if FPU = 0 or ZFINX = 1.

+

30:15

RO

Unimplemented, hardwired to 0.

14:13

RW

FS: Floating point State

+

00 = Off

+

01 = Initial

+

10 = Clean

+

11 = Dirty

+

Hardwired to 0 if FPU = 0 or ZFINX = 1.

+

12:11

RO

MPP: Machine Previous Priviledge mode

+

Hardwired to 11 when the user mode is not enabled.

+

10:8

RO

Unimplemented, hardwired to 0.

7

RO

MPIE: Machine Previous Interrupt Enable

+

When an exception is encountered, MPIE will be set to MIE. +When the mret instruction is executed, the value of MPIE will be stored to MIE.

+

6:4

RO

Unimplemented, hardwired to 0.

3

RW

MIE: Machine Interrupt Enable

+

If you want to enable interrupt handling in your exception handler, +set the Interrupt Enable MIE to 1 inside your handler code.

+

2:0

RO

Unimplemented, hardwired to 0.

+
+
+

Machine Interrupt Enable register (mie)

+

CSR Address: 0x304

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:16

RW

Machine Fast Interrupt Enables

+

Set bit x to enable interrupt irq_i[x] (x between 16 and 31).

+

15:12

RO

Hardwired to 0.

11

RW

MEIE: Machine External Interrupt Enable

+

If set, irq_i[11] is enabled.

+

10:8

RO

Hardwired to 0.

7

RW

MTIE: Machine Timer Interrupt Enable

+

If set, irq_i[7] is enabled.

+

6:4

RO

Hardwired to 0.

3

RW

MSIE: Machine Software Interrupt Enable

+

If set, irq_i[3] is enabled.

+

2:0

RO

Hardwired to 0.

+
+
+

Machine Trap-Vector Base Address (mtvec)

+

CSR Address: 0x305

+

Reset Value: Defined

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31 : 8

RW

BASE[31:8]

+

The trap-handler base address, always aligned to 256 bytes.

+

7 : 2

RO

BASE[7:2]

+

The trap-handler base address, always aligned to 256 bytes, i.e., mtvec[7:2] is always set to 0.

+

1

RO

MODE[1]

+

0

+

0

RW

MODE[0]

+

0 = Direct mode

+

1 = Vectored mode.

+
+

The initial value of mtvec is equal to {mtvec_addr_i[31:8], 6’b0, 2’b01}.

+

When an exception or an interrupt is encountered, the core jumps to the corresponding +handler using the content of the MTVEC[31:8] as base address. Only +8-byte aligned addresses are allowed. Both direct mode and vectored mode +are supported.

+
+
+

Machine Scratch (mscratch)

+

CSR Address: 0x340

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

Scratch value

+
+
+

Machine Exception PC (mepc)

+

CSR Address: 0x341

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:1

RW

MEPC: Machine Exception Program Counter

0

R0

0

+

When an exception is encountered, the current program counter is saved +in MEPC, and the core jumps to the exception address. When a mret +instruction is executed, the value from MEPC replaces the current +program counter.

+
+
+

Machine Cause (mcause)

+

CSR Address: 0x342

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31

RW

Interrupt: This bit is set when the exception was triggered by an interrupt.

30:5

RO (0)

0

4:0

RW

Exception Code (See note below)

+

NOTE: software accesses to mcause[4:0] must be sensitive to the WLRL field specification of this CSR. For example, +when mcause[31] is set, writing 0x1 to mcause[1] (Supervisor software interrupt) will result in UNDEFINED behavior.

+
+
+

Machine Trap Value (mtval)

+

CSR Address: 0x343

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

Writes are ignored; reads return 0.

+
+
+

Machine Interrupt Pending register (mip)

+

CSR Address: 0x344

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:16

RO

Machine Fast Interrupts Pending

+

If bit x is set, interrupt irq_i[x] is pending (x between 16 and 31).

+

15:12

RO

Hardwired to 0.

11

RO

MEIP: Machine External Interrupt Pending

+

If set, irq_i[11] is pending.

+

10:8

RO

Hardwired to 0.

7

RO

MTIP: Machine Timer Interrupt Pending

+

If set, irq_i[7] is pending.

+

6:4

RO

Hardwired to 0.

3

RO

MSIP: Machine Software Interrupt Pending

+

If set, irq_i[3] is pending.

+

2:0

RO

Hardwired to 0.

+
+
+
+

Trigger CSRs

+
+

Trigger Select register (tselect)

+

CSR Address: 0x7A0

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

CV32E40P implements a single trigger, therefore this register will always read as zero.

+

Accessible in Debug Mode or M-Mode.

+
+
+

Trigger Data register 1 (tdata1)

+

CSR Address: 0x7A1

+

Reset Value: 0x2800_1040

+

Detailed:

+

Accessible in Debug Mode or M-Mode. +Since native triggers are not supported, writes to this register from M-Mode will be ignored.

+
+

Note

+

CV32E40P only implements one type of trigger, Match Control. Most fields of this register will read as a fixed value to +reflect the single mode that is supported, in particular, instruction address match as described in the Debug Specification +0.13.2 section 5.2.2 & 5.2.9. The type, dmode, hit, select, timing, sizelo, action, chain, +match, m, s, u, store and load bitfields of this CSR, which are marked as R/W in Debug Specification +0.13.2, are therefore implemented as WARL bitfields (corresponding to how these bitfields will be specified in the forthcoming +Debug Specification 0.14.0).

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:28

RO (0x2)

type: 2 = Address/Data match trigger type.

27

RO (0x1)

dmode: 1 = Only debug mode can write tdata registers

26:21

RO (0x0)

maskmax: 0 = Only exact matching supported.

20

RO (0x0)

hit: 0 = Hit indication not supported.

19

RO (0x0)

select: 0 = Only address matching is supported.

18

RO (0x0)

timing: 0 = Break before the instruction at the specified +address.

17:16

RO (0x0)

sizelo: 0 = Match accesses of any size.

15:12

RO (0x1)

action: 1 = Enter debug mode on match.

11

RO (0x0)

chain: 0 = Chaining not supported.

10:7

RO (0x0)

match: 0 = Match the whole address.

6

RO (0x1)

m: 1 = Match in M-Mode.

5

RO (0x0)

zero.

4

RO (0x0)

s: 0 = S-Mode not supported.

3

RO (0x0)

u: 0 = U-Mode not supported.

2

RW

execute: Enable matching on instruction address.

1

RO (0x0)

store: 0 = Store address / data matching not supported.

0

RO (0x0)

load: 0 = Load address / data matching not supported.

+
+
+

Trigger Data register 2 (tdata2)

+

CSR Address: 0x7A2

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

data

+

Accessible in Debug Mode or M-Mode. Since native triggers are not supported, writes to this register from M-Mode will be ignored. +This register stores the instruction address to match against for a breakpoint trigger.

+
+
+

Trigger Data register 3 (tdata3)

+

CSR Address: 0x7A3

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Accessible in Debug Mode or M-Mode. +CV32E40P does not support the features requiring this register. Writes are ignored and reads will always return zero.

+
+
+

Trigger Info (tinfo)

+

CSR Address: 0x7A4

+

Reset Value: 0x0000_0004

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:16

RO

0

15:0

RO (0x4)

info. Only type 2 is supported.

+

The info field contains one bit for each possible type enumerated in +tdata1. Bit N corresponds to type N. If the bit is set, then that type is +supported by the currently selected trigger. If the currently selected trigger +does not exist, this field contains 1.

+

Accessible in Debug Mode or M-Mode.

+
+
+

Machine Context register (mcontext)

+

CSR Address: 0x7A8

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Accessible in Debug Mode or M-Mode. +CV32E40P does not support the features requiring this register. Writes are ignored and +reads will always return zero.

+
+
+
+

Debug CSRs

+
+

Debug Control and Status (dcsr)

+

CSR Address: 0x7B0

+

Reset Value: 0x4000_0003

+
+

Note

+

The ebreaks, ebreaku and prv bitfields of this CSR are marked as R/W in Debug Specification 0.13.2. However, +as CV32E40P only supports machine mode, these bitfields are implemented as WARL bitfields (corresponding to how these bitfields will +be specified in the forthcoming Debug Specification 0.14.0).

+
+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:28

RO (0x4)

xdebugver: returns 4 - External debug support exists as it is described in this document.

27:16

RO (0x0)

Reserved

15

RW

ebreakm

14

RO (0x0)

Reserved

13

RO (0x0)

ebreaks. Always 0.

12

RO (0x0)

ebreaku. Always 0.

11

RW

stepie

10

RO (0x0)

stopcount. Always 0.

9

RO (0x0)

stoptime. Always 0.

8:6

RO

cause

5

RO (0x0)

Reserved

4

RO (0x0)

mprven. Always 0.

3

RO (0x0)

nmip. Always 0.

2

RW

step

1:0

RO (0x3)

prv: returns the current priviledge mode

+
+
+

Debug PC (dpc)

+

CSR Address: 0x7B1

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:1

RO

zero

0

RO

DPC

+

When the core enters in Debug Mode, DPC contains the virtual address of +the next instruction to be executed.

+
+
+

Debug Scratch register 0/1 (dscratch0/1)

+

CSR Address: 0x7B2/0x7B3

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

DSCRATCH0/1

+
+
+
+

Performances counters

+
+

Machine Counter-Inhibit register (mcountinhibit)

+

CSR Address: 0x320

+

Reset Value: 0x0000_000D

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:4

RW

Dependent on number of counters implemented in design parameter

3

RW

selectors: mhpmcounter3 inhibit

2

RW

minstret inhibit

1

RO

0

0

RW

mcycle inhibit

+

The performance counter inhibit control register. The default value is to inihibit counters out of reset. +The bit returns a read value of 0 for non implemented counters. This reset value +shows the result using the default number of performance counters to be 1.

+
+
+

Machine Performance Monitoring Event Selector (mhpmevent3 .. mhpmevent31)

+

CSR Address: 0x323 - 0x33F

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:16

RO

0

15:0

RW

selectors: Each bit represent a unique event to count

+

The event selector fields are further described in Performance Counters section. +Non implemented counters always return a read value of 0.

+
+
+

Machine Cycle Counter (mcycle)

+

CSR Address: 0xB00

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

The lower 32 bits of the 64 bit machine mode cycle counter.

+
+
+

Machine Instructions-Retired Counter (minstret)

+

CSR Address: 0xB02

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

The lower 32 bits of the 64 bit machine mode instruction retired counter.

+
+
+

Machine Performance Monitoring Counter (mhpmcounter3 .. mhpmcounter31)

+

CSR Address: 0xB03 - 0xB1F

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

Machine performance-monitoring counter

+

The lower 32 bits of the 64 bit machine performance-monitoring counter(s). +The number of machine performance-monitoring counters is determined by the parameter NUM_MHPMCOUNTERS with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0.

+
+
+

Upper 32 bits Machine Cycle Counter (mcycleh)

+

CSR Address: 0xB80

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

The upper 32 bits of the 64 bit machine mode cycle counter.

+
+
+

Upper 32 bits Machine Instructions-Retired Counter (minstreth)

+

CSR Address: 0xB82

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

The upper 32 bits of the 64 bit machine mode instruction retired counter.

+
+
+

Upper 32 bits Machine Performance Monitoring Counter (mhpmcounter3h .. mhpmcounter31h)

+

CSR Address: 0xB83 - 0xB9F

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RW

Machine performance-monitoring counter

+

The upper 32 bits of the 64 bit machine performance-monitoring counter(s). +The number of machine performance-monitoring counters is determined by the parameter NUM_MHPMCOUNTERS with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0.

+
+
+

Cycle Counter (cycle)

+

CSR Address: 0xC00

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode cycle counter.

+
+
+

Instructions-Retired Counter (instret)

+

CSR Address: 0xC02

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode instruction retired counter.

+
+
+

Performance Monitoring Counter (hpmcounter3 .. hpmcounter31)

+

CSR Address: 0xC03 - 0xC1F

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0.

+
+
+

Upper 32 bits Cycle Counter (cycleh)

+

CSR Address: 0xC80

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode cycle counter.

+
+
+

Upper 32 bits Instructions-Retired Counter (instreth)

+

CSR Address: 0xC82

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode instruction retired counter.

+
+
+

Upper 32 bits Performance Monitoring Counter (hpmcounter3h .. hpmcounter31h)

+

CSR Address: 0xC83 - 0xC9F

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+

Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0.

+
+
+
+

ID CSRs

+
+

Machine ISA (misa)

+

CSR Address: 0x301

+

Reset Value: defined

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:30

RO (0x1)

MXL (Machine XLEN)

29:26

RO (0x0)

(Reserved)

25

RO (0x0)

Z (Reserved)

24

RO (0x0)

Y (Reserved)

23

RO

X (Non-standard extensions present)

22

RO (0x0)

W (Reserved)

21

RO (0x0)

V (Tentatively reserved for Vector extension)

20

RO (0x0)

U (User mode implemented)

19

RO (0x0)

T (Tentatively reserved for Transactional Memory extension)

18

RO (0x0)

S (Supervisor mode implemented)

17

RO (0x0)

R (Reserved)

16

RO (0x0)

Q (Quad-precision floating-point extension)

15

RO (0x0)

P (Tentatively reserved for Packed-SIMD extension)

14

RO (0x0)

O (Reserved)

13

RO (0x0)

N (User-level interrupts supported)

12

RO (0x1)

M (Integer Multiply/Divide extension)

11

RO (0x0)

L (Tentatively reserved for Decimal Floating-Point extension)

10

RO (0x0)

K (Reserved)

9

RO (0x0)

J (Tentatively reserved for Dynamically Translated Languages +extension)

8

RO (0x1)

I (RV32I/64I/128I base ISA)

7

RO (0x0)

H (Hypervisor extension)

6

RO (0x0)

G (Additional standard extensions present)

5

RO

F (Single-precision floating-point extension)

4

RO (0x0)

E (RV32E base ISA)

3

RO (0x0)

D (Double-precision floating-point extension)

2

RO (0x1)

C (Compressed extension)

1

RO (0x0)

B (Tentatively reserved for Bit-Manipulation extension)

0

RO (0x0)

A (Atomic extension)

+

Writes are ignored and all bitfields in the misa CSR area read as 0 except for the following:

+
    +
  • C = 1

  • +
  • F = 1 if FPU = 1 and ZFINX = 0

  • +
  • I = 1

  • +
  • M = 1

  • +
  • X = 1 if COREV_PULP = 1 or COREV_CLUSTER = 1

  • +
  • MXL = 1 (i.e. XLEN = 32)

  • +
+
+
+

Machine Vendor ID (mvendorid)

+

CSR Address: 0xF11

+

Reset Value: 0x0000_0602

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:7

RO

0xC. Number of continuation codes in JEDEC manufacturer ID.

6:0

RO

0x2. Final byte of JEDEC manufacturer ID, discarding the parity bit.

+

The mvendorid encodes the OpenHW JEDEC Manufacturer ID, which is 2 decimal (bank 13).

+
+
+

Machine Architecture ID (marchid)

+

CSR Address: 0xF12

+

Reset Value: 0x0000_0004

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

Machine Architecture ID of CV32E40P is 4

+
+
+

Machine Implementation ID (mimpid)

+

CSR Address: 0xF13

+

Reset Value: 0x0000_0000

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

0

+
+
+

Hardware Thread ID (mhartid)

+

CSR Address: 0xF14

+

Reset Value: Defined

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

Hardware Thread ID hart_id_i, see Core Integration

+
+
+
+

Non-RISC-V CSRs

+
+

User Hardware Thread ID (uhartid)

+

CSR Address: 0xCD0 (only present if COREV_PULP = 1 and PULP_SECURE = 1)

+

Reset Value: Defined

+

Detailed:

+ +++++ + + + + + + + + + + + + +

Bit #

Mode

Description

31:0

RO

Hardware Thread ID hart_id_i, see Core Integration

+

Similar to mhartid the uhartid provides the Hardware Thread ID. It differs from mhartid only in the required privilege level. +On CV32E40P, as it is a machine mode only implementation, this difference is not noticeable.

+
+
+

Privilege Level (privlv)

+

CSR Address: 0xCD1 (only present if COREV_PULP = 1 and PULP_SECURE = 1)

+

Reset Value: 0x0000_0003

+

Detailed:

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:2

RO

Reads as 0.

1:0

RO

Current Privilege Level

+

00 = User

+

01 = Supervisor

+

10 = Hypervisor

+

11 = Machine

+

CV32E40P only supports Machine mode.

+
+
+
+

ZFINX ISA (zfinx)

+

CSR Address: 0xCD2

+

Reset Value: Defined

+ +++++ + + + + + + + + + + + + + + + + +

Bit #

Mode

Description

31:1

RO

Hardwired to 0.

0

RO

1 if FPU = 1 and ZFINX = 1 else 0.

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/core_versions.html b/docs/html/core_versions.html new file mode 100644 index 000000000..1a7a3abfa --- /dev/null +++ b/docs/html/core_versions.html @@ -0,0 +1,344 @@ + + + + + + + Core Versions and RTL Freeze Rules — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Core Versions and RTL Freeze Rules

+

The CV32E40P is defined by the marchid and mimpid tuple. +The tuple identify which sets of parameters have been verified +by OpenHW Group, and once RTL Freeze is achieved, no further +non-logically equivalent changes are allowed on that set of parameters.

+

The RTL Freeze version of the core is indentified by a GitHub +tag with the format cv32e40p_vMAJOR.MINOR.PATCH (e.g. cv32e40p_v1.0.0). +In addition, the release date is reported in the documentation.

+
+

What happens after RTL Freeze?

+
+

RTL changes on verified parameters

+

Minor changes to the RTL on a frozen parameter set (e.g., nicer RTL code, clearer RTL code, etc) are allowed if, and only if, they are logically equivalent to the frozen (tagged) version of the core. +This is guaranteed by a CI flow that checks that pull requests are logically equivalent to a specific tag of the core as +explained here. +For example, suppose we re-write “better” a portion of the ALU that affects the frozen set of parameters of the version cv32e40p_v1.0.0, +for instance, the adder. In that case, the proposed changes are compared with the code based on cv32e40p_v1.0.0, and if they are logically equivalent, they are accepted. Otherwise, they are rejected. See below for more case scenarios.

+
+
+

A bug is found

+

If a bug is found that affect the already frozen parameter set, +the RTL changes required to fix such bug are non-logically equivalent by definition. +Therefore, the RTL changes are applied only on a different mimpid +value and the bug and the fix must be documented. +These changes are visible by software as the mimpid has a different value. +Every bug or set of bugs found must be followed by another RTL Freeze release and a new GitHub tag.

+
+
+

RTL changes on non-verified yet parameters

+

If changes affecting the core on a non-frozen parameter set are required, +as for example, to fix bugs found in the communication to the FPU (e.g., affecting the core only if FPU=1), +or to change the ISA Extensions decoding of PULP instructions (e.g., affecting the core only if PULP_XPULP=1), +then such changes must remain logically equivalent for the already frozen set of parameters (except for the required mimpid update), and they must be applied on a different mimpid value. They can be non-logically equivalent to a non-frozen set of parameters. +These changes are visible by software as the mimpid has a different value. +Once the new set of parameters is verified and achieved the sign-off for RTL freeze, +a new GitHub tag and version of the core is released.

+
+
+

PPA optimizations and new features

+

Non-logically equivalent PPA optimizations and new features are not allowed on a given set +of RTL frozen parameters (e.g., a faster divider). +If PPA optimizations are logically-equivalent instead, they can be applied without +changing the mimpid value (as such changes are not visible in software). +However, a new GitHub tag should be release and changes documented.

+

Figure 13 shows the aforementioned rules.

+
+ +
+

Figure 13 Versions control of CV32E40P

+
+
+
+
+
+

Non-backward compatibility

+

For cv32e40p_v2.0.0, some modifications have been done on cv32e40p_top and cv32e40p_core parameters names.

+

It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, backward compatibility is still correct as all parameters default values are set to v1 values.

+
+

Parameters

+

As RTL has been updated to fully support ratified RISC-V Zfinx, old PULP_ZFINX parameter has been renamed ZFINX in all design and verification files.

+

To differentiate v1 to v2 encoding of PULP instructions, old PULP_XPULP and PULP_CLUSTER parameters have been renamed COREV_PULP and COREV_CLUSTER in all design and verification files.

+

To easily change FPU instructions latencies, 2 new parameters have been added, FPU_ADDMUL_LAT for Addition/Multiplication lane and FPU_OTHERS_LAT for the other instructions (move, conversion, comparison…).

+
+
+
+

Released core versions

+

The verified parameter sets of the core, their implementation version, GitHub tags, and dates are reported here.

+
+

cv32e40p_v1.0.0

+ +++++++ + + + + + + + + + + + + + + + + +

Git Tag

Tagged By

Date

Reason for Release

Comment

cv32e40p_v1.0.0

Arjan Bink

2020-12-10

RTL Freeze

+

For this release mimpid value is fixed and is equal to 0.

+

It refers to the CV32E40P core verified with the following parameters:

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Name

Value

FPU

0

PULP_ZFINX

0

PULP_XPULP

0

PULP_CLUSTER

0

NUM_MHPMCOUNTERS

1

+

The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at:

+ +
+
+

cv32e40p_v2.0.0

+ +++++++ + + + + + + + + + + + + + + + + +

Git Tag

Tagged By

Date

Reason for Release

Comment

cv32e40p_v2.0.0

RTL Freeze

+

For this release mimpid value is depending of parameters value.

+
+

mimpid = 0

+

When parameters are set with the exact same values than for cv32e40p_v1.0.0 release then mimpid value is equal to 0.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

Name

Value

FPU

0

ZFINX

0

COREV_PULP

0

COREV_CLUSTER

0

NUM_MHPMCOUNTERS

1

+
+
+

mimpid = 1

+

When one parameter is set with a different value than for cv32e40p_v1.0.0 release then mimpid value is equal to 1.

+

This means either FPU, ZFINX, COREV_PULP or COREV_CLUSTER is set to 1. +Or NUM_MHPMCOUNTERS is set to a value greater than 1.

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/corev_hw_loop.html b/docs/html/corev_hw_loop.html new file mode 100644 index 000000000..553b15129 --- /dev/null +++ b/docs/html/corev_hw_loop.html @@ -0,0 +1,211 @@ + + + + + + + CORE-V Hardware Loop Extensions — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CORE-V Hardware Loop Extensions

+

To increase the efficiency of small loops, CV32E40P supports hardware +loops (HWLoop). They can be enabled by setting the COREV_PULP parameter. +Hardware loops make executing a piece of code +multiple times possible, without the overhead of branches penalty or updating a counter. +Hardware loops involve zero stall cycles for jumping to the first +instruction of a loop.

+

A hardware loop is defined by its start address (pointing to the first +instruction in the loop), its end address (pointing to the instruction +just after the last one executed by the loop) and a counter that is +decremented every time the last instruction of the loop body is executed.

+

CV32E40P contains two hardware loop register sets to support nested hardware loops, +each of them can store these three values in separate flip flops which are +mapped in the CSR address space. +Loop number 0 has higher priority than loop number 1 in a nested loop +configuration, meaning that loop 0 represents the inner loop and loop 1 is the outer loop.

+
+

Hardware Loop constraints

+

Following constraints must be respected by any toolchain compiler or by hand-written assembly code. +Violation of these constraints will not generate any hardware exception and behaviour is undefined.

+

In order to catch as early as possible those software exceptions when executing a program either +on a verification Reference Model or on a virtual platform Instruction Set Simulator, those model/simulation platforms +must generate a fatal error with a meaningfull message related to Hardware Loops constraints violation.

+

The HWLoop constraints are:

+
    +
  • Start and End addresses of an HWLoop must be 32-bit aligned.

  • +
  • End Address must be strictly greater than Start Address.

  • +
  • End address of an HWLoop must point to the instruction just after the last one of the HWLoop body.

  • +
  • HWLoop body must contain at least 3 instructions.

  • +
  • When both loops are nested, the End address of the outermost HWLoop (must be #1) must be at least 2 +instructions further than the End address of the innermost HWLoop (must be #0), +i.e. HWLoop[1].endaddress >= HWLoop[0].endaddress + 8.

  • +
  • HWLoop must always be entered from its start location (no branch/jump to a location inside a HWLoop body).

  • +
  • No HWLoop #0 (resp. #1) CSR should be modified inside the HWLoop #0 (resp. #1) body.

  • +
  • No Compressed instructions (RVC) allowed in the HWLoop body.

  • +
  • No jump or branch instructions allowed in the HWLoop body.

  • +
  • No memory ordering instructions (fence, fence.i) allowed in the HWLoop body.

  • +
  • No privileged instructions (mret, dret, ecall, wfi) allowed in the HWLoop body, except for ebreak.

  • +
+

The rationale of NOT generating any hardware exception when violating any of those constraints is that it would add resources +(32-bit adders and substractors needed for the third and fourth rules) which are costly in area and power consumption. +These additional (and costly) resources would be present just to catch situations that should never happen. +This in an architectural choice in order to keep CV32E40P area and power consumption to its lowest level.

+

The rationale of putting the end-of-loop label to the first instruction after the last one of the loop body +is that it greatly simplifies compiler optimization (relative to basic blocks management).

+

In order to use hardware loops, the compiler needs to setup the loops beforehand with cv.start/i, cv.end/i, cv.count/i or cv.setup/i instructions. +The compiler will use HWLoop automatically whenever possible without the need of assembly.

+

For debugging and context switches, the hardware loop registers are mapped into the CSR custom read-only address space. +To read them csrr instructions should be used and to write them register flavour of hardware loop instructions should be used. +Using csrw instructions to write hardware loop registers will generate an illegal instruction exception.

+

Since hardware loop feature could be used in interrupt routine/handler, the registers have +to be saved (resp. restored) at the beginning (resp. end) of the interrupt routine together with the general purpose registers. +The CSR HWLoop registers are described in the Control and Status Registers section.

+

Below an assembly code example of a nested HWLoop that computes a matrix addition.

+
 1asm volatile (
+ 2    "add %[i],x0, x0;"
+ 3    "add %[j],x0, x0;"
+ 4    "cv.count  1, %[N];"
+ 5    "cv.endi   1, endO;"
+ 6    "cv.starti 1, startO;"
+ 7    "cv.endi   0, endZ;"
+ 8    "cv.starti 0, startZ;"
+ 9    ".align 4;"
+10    ".option norvc;"
+11    "startO:;"
+12    "    cv.count 0, %[N];"
+13    "    startZ:;"
+14    "        addi %[i], %[i], 1;"
+15    "        addi %[i], %[i], 1;"
+16    "        addi %[i], %[i], 1;"
+17    "    endZ:;"
+18    "    addi %[j], %[j], 2;"
+19    "    addi %[j], %[j], 2;"
+20    "endO:;"
+21    : [i] "+r" (i), [j] "+r" (j)
+22    : [N] "r" (10)
+23);
+
+
+

At the beginning of the HWLoop, the registers %[i] and %[j] are 0. +The innermost loop, from startZ to (endZ - 4), adds to %[i] three times 1 and +it is executed 10x10 times. Whereas the outermost loop, from startO to (endO - 4), +executes 10 times the innermost loop and adds two times 2 to the register %[j]. +At the end of the loop, the register %[i] contains 300 and the register %[j] contains 40.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/debug.html b/docs/html/debug.html new file mode 100644 index 000000000..2ba202442 --- /dev/null +++ b/docs/html/debug.html @@ -0,0 +1,323 @@ + + + + + + + Debug & Trigger — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Debug & Trigger

+

CV32E40P offers support for execution-based debug according to the RISC-V Debug Specification, version 0.13.2. +The main requirements for the core are described in Chapter 4: RISC-V Debug, Chapter 5: Trigger Module, and Appendix A.2: Execution Based.

+

The following list shows the simplified overview of events that occur in the core when debug is requested:

+
+
    +
  1. Enters Debug Mode

  2. +
  3. Saves the PC to DPC

  4. +
  5. Updates the cause in the DCSR

  6. +
  7. Points the PC to the location determined by the input port dm_haltaddr_i

  8. +
  9. Begins executing debug control code.

  10. +
+
+

Debug Mode can be entered by one of the following conditions:

+
+
    +
  • External debug event using the debug_req_i signal

  • +
  • Trigger Module match event

  • +
  • ebreak instruction when not in Debug Mode and when DCSR.EBREAKM == 1 (see EBREAK Behavior below)

  • +
+
+

A user wishing to perform an abstract access, whereby the user can observe or control a core’s GPR (either integer of floating-point one) or CSR register from the hart, +is done by invoking debug control code to move values to and from internal registers to an externally addressable Debug Module (DM). +Using this execution-based debug allows for the reduction of the overall number of debug interface signals.

+
+

Note

+

Debug support in CV32E40P is only one of the components needed to build a System on Chip design with run-control debug support (think “the ability to attach GDB to a core over JTAG”). +Additionally, a Debug Module and a Debug Transport Module, compliant with the RISC-V Debug Specification, are needed.

+

A supported open source implementation of these building blocks can be found in the RISC-V Debug Support for PULP Cores IP block.

+
+

The CV3240P also supports a Trigger Module to enable entry into Debug Mode on a trigger event with the following features:

+
+
    +
  • Number of trigger register(s) : 1

  • +
  • Supported trigger types: instruction address match (Match Control)

  • +
+
+

The CV32E40P will not support the optional debug features 10, 11, & 12 listed in Section 4.1 of the RISC-V Debug Specification. +Specifically, a control transfer instruction’s destination location being in or out of the Program Buffer and instructions depending on PC value shall not cause an illegal instruction.

+
+

Debug Interface

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 20 Debug interface signals

Signal

Direction

Description

debug_req_i

input

Request to enter Debug Mode

debug_havereset_o

output

Debug status: Core has been reset

debug_running_o

output

Debug status: Core is running

debug_halted_o

output

Debug status: Core is halted

dm_halt_addr_i[31:0]

input

Address for debugger entry

dm_exception_addr_i[31:0]

input

Address for debugger exception entry

+

debug_req_i is the “debug interrupt”, issued by the debug module when the core should enter Debug Mode. +The debug_req_i is synchronous to clk_i and requires a minimum assertion of one clock period to enter Debug Mode. +The instruction being decoded during the same cycle that debug_req_i is first asserted shall not be executed before entering Debug Mode.

+

debug_havereset_o, debug_running_o and debug_mode_o signals provide the operational status of the core to the debug module. +The assertion of these signals is mutually exclusive.

+

debug_havereset_o is used to signal that the CV32E40P has been reset. debug_havereset_o is set high during the assertion of rst_ni. +It will be cleared low a few (unspecified) cycles after rst_ni has been deasserted and fetch_enable_i has been sampled high.

+

debug_running_o is used to signal that the CV32E40P is running normally.

+

debug_halted_o is used to signal that the CV32E40P is in debug mode.

+

dm_halt_addr_i is the address where the PC jumps to for a debug entry event. When in Debug Mode, an ebreak instruction will also cause the PC +to jump back to this address without affecting status registers (see EBREAK Behavior below).

+

dm_exception_addr_i is the address where the PC jumps to when an exception occurs during Debug Mode. +When in Debug Mode, the mret or uret instruction will also cause the PC to jump back to this address without affecting status registers.

+

Both dm_halt_addr_i and dm_exception_addr_i must be word aligned.

+
+
+

Core Debug Registers

+

CV32E40P implements four core debug registers, namely Debug Control and Status (dcsr), Debug PC (dpc) and two debug scratch registers. +Access to these registers in non Debug Mode results in an illegal instruction.

+

Several trigger registers are required to adhere to specification. The following are the most relevant: Trigger Select register (tselect), Trigger Data register 1 (tdata1), Trigger Data register 2 (tdata2) and Trigger Info (tinfo).

+

The TDATA1.DMODE is hardwired to a value of 1. In non Debug Mode, writes to Trigger registers are ignored and reads reflect CSR values.

+
+
+

Debug state

+

As specified in RISC-V Debug Specification every hart that can be selected by +the Debug Module is in exactly one of four states: nonexistent, unavailable, running or halted.

+

The remainder of this section assumes that the CV32E40P will not be classified as nonexistent by the integrator.

+

The CV32E40P signals to the Debug Module whether it is running or halted via its debug_running_o and debug_halted_o pins +respectively. Therefore, assuming that this core will not be integrated as a nonexistent core, the CV32E40P is classified as unavailable +when neither debug_running_o or debug_halted_o is asserted. Upon rst_ni assertion the debug state will be unavailable until some +cycle(s) after rst_ni has been deasserted and fetch_enable_i has been sampled high. After this point (until a next reset assertion) the +core will transition between having its debug_halted_o or debug_running_o pin asserted depending whether the core is in debug mode or not. +Exactly one of the debug_havereset_o, debug_running_o or debug_halted_o is asserted at all times.

+

Figure 11 and show Figure 12 show typical examples of transitioning into the running and halted states.

+
+
+

Figure 11 Transition into debug running state

+
+
+
+
+

Figure 12 Transition into debug halted state

+
+
+

The key properties of the debug states are:

+
+
    +
  • The CV32E40P can remain in its unavailable state for an arbitrarily long time (depending on rst_ni and fetch_enable_i).

  • +
  • If debug_req_i is asserted after rst_ni deassertion and before or coincident with the assertion of fetch_enable_i, then the CV32E40P +is guaranteed to transition straight from its unavailable state into its halted state. If debug_req_i is asserted at a later +point in time, then the CV32E40P might transition through the running state on its ways to the halted state.

  • +
  • If debug_req_i is asserted during the running state, the core will eventually transition into the halted state (typically after a couple of cycles).

  • +
+
+
+
+

EBREAK Behavior

+

The EBREAK instruction description is distributed across several RISC-V specifications: RISC-V Debug Specification, +RISC-V Priveleged Specification, +RISC-V ISA. The following is a summary of the behavior for three common scenarios.

+
+

Scenario 1 : Enter Exception

+

Executing the EBREAK instruction when the core is not in Debug Mode and the DCSR.EBREAKM == 0 shall result in the following actions:

+
+
    +
  • The core enters the exception handler routine located at MTVEC (Debug Mode is not entered)

  • +
  • MEPC & MCAUSE are updated

  • +
+
+

To properly return from the exception, the ebreak handler will need to increment the MEPC to the next instruction. +This requires querying the size of the ebreak instruction that was used to enter the exception (16 bit c.ebreak or 32 bit ebreak).

+
+

Note

+

The CV32E40P does not support MTVAL CSR register which would have saved the value of the instruction for exceptions. This may be supported on a future core.

+
+
+
+

Scenario 2 : Enter Debug Mode

+

Executing the EBREAK instruction when the core is not in Debug Mode and the DCSR.EBREAKM == 1 shall result in the following actions:

+
    +
  • The core enters Debug Mode and starts executing debug code located at dm_halt_addr_i (exception routine not called)

  • +
  • DPC & DCSR are updated

  • +
+

Similar to the exception scenario above, the debugger will need to increment the DPC to the next instruction before returning from Debug Mode.

+
+

Note

+

The default value of DCSR.EBREAKM is 0 and the DCSR is only accessible in Debug Mode. To enter Debug Mode from EBREAK, +the user will first need to enter Debug Mode through some other means, such as from the external debug_req_i, and set DCSR.EBREAKM.

+
+
+
+

Scenario 3 : Exit Program Buffer & Restart Debug Code

+

Executing the EBREAK instruction when the core is in Debug Mode shall result in the following actions:

+
    +
  • The core remains in Debug Mode and execution jumps back to the beginning of the debug code located at dm_halt_addr_i

  • +
  • none of the CSRs are modified

  • +
+
+
+
+

Interrupts during Single-Step Behavior

+

The CV32E40P is not compliant with the intended interpretation of the RISC-V Debug spec 0.13.2 specification when interrupts occur during Single-Steps. +However, the intended behavior has been clarified a posteriori only in version 1.0.0. +See https://github.com/riscv/riscv-debug-spec/issues/510. +The CV32E40P executes the first instruction of the interrupt handler and retires it before re-entering in Debug Mode, which is prohibited in version 1.0.0 but not specified in 0.13.2. +For details about the specific use-case, please refer to https://github.com/openhwgroup/core-v-verif/issues/904.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/exceptions_interrupts.html b/docs/html/exceptions_interrupts.html new file mode 100644 index 000000000..6b52e0f17 --- /dev/null +++ b/docs/html/exceptions_interrupts.html @@ -0,0 +1,284 @@ + + + + + + + Exceptions and Interrupts — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exceptions and Interrupts

+

CV32E40P implements trap handling for interrupts and exceptions according to the RISC-V Privileged Specification, version 1.11. +The irq_i[31:16] interrupts are a custom extension.

+

When entering an interrupt/exception handler, the core sets the mepc CSR to the current program counter and saves mstatus.MIE to mstatus.MPIE. +All exceptions cause the core to jump to the base address of the vector table in the mtvec CSR. +Interrupts are handled in either direct mode or vectored mode depending on the value of mtvec.MODE. In direct mode the core +jumps to the base address of the vector table in the mtvec CSR. In vectored mode the core jumps to the base address +plus four times the interrupt ID. Upon executing an MRET instruction, the core jumps to the program counter previously saved in the +mepc CSR and restores mstatus.MPIE to mstatus.MIE.

+

The base address of the vector table must be aligned to 256 bytes (i.e., its least significant byte must be 0x00) and can be programmed +by writing to the mtvec CSR. For more information, see the Control and Status Registers documentation.

+

The core starts fetching at the address defined by boot_addr_i. It is assumed that the boot address is supplied via a register +to avoid long paths to the instruction fetch unit.

+
+

Interrupt Interface

+

Table 18 describes the interrupt interface.

+ + +++++ + + + + + + + + + + + + + + + + + + + + +
Table 18 Interrupt interface signals

Signal

Direction

Description

irq_i[31:0]

input

Level sensistive active high interrupt inputs. +Not all interrupt inputs can be used on +CV32E40P. Specifically irq_i[15:12], +irq_i[10:8], irq_i[6:4] and irq_i[2:0] shall be +tied to 0 externally as they are reserved for +future standard use (or for cores which are not +Machine mode only) in the RISC-V Privileged +specification.

+

irq_i[11], irq_i[7], and irq_i[3] +correspond to the Machine External +Interrupt (MEI), Machine Timer Interrupt (MTI), +and Machine Software Interrupt (MSI) +respectively.

+

The irq_i[31:16] interrupts +are a CV32E40P specific extension to the RISC-V +Basic (a.k.a. CLINT) interrupt scheme.

+

irq_ack_o

output

Interrupt acknowledge

+

Set to 1 for one cycle +when the interrupt with ID irq_id_o[4:0] is +taken.

+

irq_id_o[4:0]

output

Interrupt index for taken interrupt

+

Only valid when irq_ack_o = 1.

+
+
+
+

Interrupts

+

The irq_i[31:0] interrupts are controlled via the mstatus, mie and mip CSRs. CV32E40P uses the upper 16 bits of mie and mip for custom interrupts (irq_i[31:16]), +which reflects an intended custom extension in the RISC-V Basic (a.k.a. CLINT) interrupt architecture. +After reset, all interrupts are disabled. +To enable interrupts, both the global interrupt enable (MIE) bit in the mstatus CSR and the corresponding individual interrupt enable bit in the mie CSR need to be set. +For more information, see the Control and Status Registers documentation.

+

If multiple interrupts are pending, they are handled in the fixed priority order defined by the RISC-V Privileged Specification, version 1.11 (see Machine Interrupt Registers, Section 3.1.9). +The highest priority is given to the interrupt with the highest ID, except for the Machine Timer Interrupt, which has the lowest priority. So from high to low priority the interrupts are +ordered as follows: irq_i[31], irq_i[30], …, irq_i[16], irq_i[11], irq_i[3], irq_i[7].

+

All interrupt lines are level-sensitive. There are two supported mechanisms by which interrupts can be cleared at the external source.

+
    +
  • A software-based mechanism in which the interrupt handler signals completion of the handling routine to the interrupt source, e.g., through a memory-mapped register, which then deasserts the corresponding interrupt line.

  • +
  • A hardware-based mechanism in which the irq_ack_o and irq_id_o[4:0] signals are used to clear the interrupt sourcee, e.g. by an external interrupt controller. irq_ack_o is a 1 clk_i cycle pulse during which irq_id_o[4:0] reflects the index in irq_id[*] of the taken interrupt.

  • +
+

In Debug Mode, all interrupts are ignored independent of mstatus.MIE and the content of the mie CSR.

+
+
+

Exceptions

+

CV32E40P can trigger an exception due to the following exception causes:

+ + ++++ + + + + + + + + + + + + + + + + +
Table 19 Exceptions

Exception Code

Description

2

Illegal instruction

3

Breakpoint

11

Environment call from M-Mode (ECALL)

+

The illegal instruction exception and M-Mode ECALL instruction exceptions cannot be disabled and are always active. +The core raises an illegal instruction exception for any instruction in the RISC-V privileged and unprivileged specifications that is explicitly defined as being illegal according to the ISA implemented by the core, as well as for any instruction that is left undefined in these specifications unless the instruction encoding is configured as a custom CV32E40P instruction for specific parameter settings as defined in (see CORE-V Instruction Set Custom Extension). +For example, in case the parameter FPU is set to 0, the CV32E40P raises an illegal instruction exception for any RVF instruction or CSR instruction trying to access F CSRs. +The same concerns PULP extensions everytime both parameters COREV_PULP and CORE_CLUSTER are set to 0 (see Core Integration).

+
+
+

Nested Interrupt/Exception Handling

+

CV32E40P does support nested interrupt/exception handling in software. +The hardware automatically disables interrupts upon entering an interrupt/exception handler. +Otherwise, interrupts/exceptions during the critical part of the handler, i.e. before software has saved the mepc and mstatus CSRs, would cause those CSRs to be overwritten. +If desired, software can explicitly enable interrupts by setting mstatus.MIE to 1 from within the handler. +However, software should only do this after saving mepc and mstatus. +There is no limit on the maximum number of nested interrupts. +Note that, after enabling interrupts by setting mstatus.MIE to 1, the current handler will be interrupted also by lower priority interrupts. +To allow higher priority interrupts only, the handler must configure mie accordingly.

+

The following pseudo-code snippet visualizes how to perform nested interrupt handling in software.

+
 1isr_handle_nested_interrupts(id) {
+ 2  // Save mpec and mstatus to stack
+ 3  mepc_bak = mepc;
+ 4  mstatus_bak = mstatus;
+ 5
+ 6  // Save mie to stack (optional)
+ 7  mie_bak = mie;
+ 8
+ 9  // Keep lower-priority interrupts disabled (optional)
+10  mie = mie & ~((1 << (id + 1)) - 1);
+11
+12  // Re-enable interrupts
+13  mstatus.MIE = 1;
+14
+15  // Handle interrupt
+16  // This code block can be interrupted by other interrupts.
+17  // ...
+18
+19  // Restore mstatus (this disables interrupts) and mepc
+20  mstatus = mstatus_bak;
+21  mepc = mepc_bak;
+22
+23  // Restore mie (optional)
+24  mie = mie_bak;
+25}
+
+
+

Nesting of interrupts/exceptions in hardware is not supported.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/fpu.html b/docs/html/fpu.html new file mode 100644 index 000000000..fc22d95cc --- /dev/null +++ b/docs/html/fpu.html @@ -0,0 +1,336 @@ + + + + + + + Floating Point Unit (FPU) — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Floating Point Unit (FPU)

+

The RV32F ISA extension for floating-point support in the form of IEEE-754 single +precision can be enabled by setting the parameter FPU of the cv32e40p_top top level module +to 1. This will extend the CV32E40P decoder accordingly and will instantiate the FPU. +The FPU repository used by the CV32E40P is available at https://github.com/openhwgroup/cvfpu and +its documentation can be found here. +CVFPU v1.0.0 release has been copied in CV32E40P repository inside rtl/vendor (used for verification and implementation) so all core and FPU RTL files should be taken from CV32E40P repository.

+

cv32e40p_fpu_manifest file is listing all necessary files for both the Core and CVFPU.

+
+

CVFPU parameters

+

As CVFPU is an highly configurable IP, here is the list of its parameters and their actual value used when CVFPU is intantiated through a wrapper in cv32e40p_top module.

+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 11 CVFPU Features parameter

Name

Type/Range

Value

Description

Width

int

32

Datapath Width

+

Specifies the width of the input and output data ports and +of the datapath.

+

EnableVectors

logic

0

Vectorial Hardware Generation

+

Controls the generation of packed-SIMD computation units.

+

EnableNanBox

logic

0

NaN-Boxing Check Control

+

Controls whether input value NaN-boxing is enforced.

+

FpFmtMask

fmt_logic_t

{1, 0, 0, 0, 0}

Enabled Floating-Point Formats

+

Enables respectively:

+

IEEE Single-Precision format

+

IEEE Double-Precision format

+

IEEE Half-Precision format

+

Custom Byte-Precision format

+

Custom Alternate Half-Precision format

+

IntFmtMask

ifmt_logic_t

{0, 0, 1, 0}

Enabled Integer Formats

+

Enables respectively:

+

Byte format

+

Half-Word format

+

Word format

+

Double-Word format

+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 12 CVFPU Implementation parameter

Name

Type/Range

Value

Description

PipeRegs

opgrp_fmt_unsigned_t

{

+

{FPU_ADDMUL_LAT, 0, 0, 0, 0},

+

{default: 1},

+

{default: FPU_OTHERS_LAT},

+

{default: FPU_OTHERS_LAT}

+

}

+

Number of Pipelining Stages

+

This parameter sets a number of pipeline stages to be inserted into the +computational units per operation group, per FP format. As such, +latencies for different operations and different formats can be freely +configured.

+

Respectively:

+

ADDition/MULtiplication operation group

+

DIVision/SQuare RooT operation group

+

NON COMPuting operation group

+

CONVersion operation group

+

FPU_ADDMUL_LAT and FPU_OTHERS_LAT are cv32e40p_top parameters.

+

UnitTypes

opgrp_fmt_unit_types_t

{

+

{default: MERGED},

+

{default: MERGED},

+

{default: PARALLEL},

+

{default: MERGED}

+

}

+

HW Unit Implementation

+

This parameter allows to control resources by either removing operation +units for certain formats and operations, +or merging multiple formats into one.

+

Respectively:

+

ADDition/MULtiplication operation group

+

DIVision/SQuare RooT operation group

+

NON COMPuting operation group

+

CONVersion operation group

+

PipeConfig

pipe_config_t

AFTER

Pipeline Register Placement

+

This parameter controls where pipeling registers (number defined by +PipeRegs) are placed in each operational unit.

+

AFTER means they are all placed at the output of each operational unit.

+

See Synthesizing with the FPU advices to get best synthesis results.

+
+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 13 Other CVFPU parameters

Name

Type/Range

Value

Description

TagType

logic

The SystemVerilog data type of the operation tag input and output ports.

TrueSIMDClass

int

0

Vectorial mode classify operation RISC-V compliancy.

EnableSIMDMask

int

0

Inactive vectorial lanes floating-point status flags masking.

+
+
+

FP Register File

+

By default a dedicated register file consisting of 32 +floating-point registers, f0-f31, is instantiated. This default behavior +can be overruled by setting the parameter ZFINX of the cv32e40p_top top level +module to 1, in which case the dedicated register file is +not included and the general purpose register file is used instead to +host the floating-point operands.

+

The latency of the individual instructions are explained in Cycle counts per instruction type table.

+

To allow FPU unit to be put in sleep mode at the same time the core is doing so, a clock gating cell is instantiated in cv32e40p_top top level module as well +with its enable signal being inverted core_sleep_o core output.

+
+
+

FP CSR

+

When using floating-point extensions the standard specifies a +floating-point status and control register (Floating-point control and status register (fcsr)) which contains the +exceptions that occurred since it was last reset and the rounding mode. +Floating-point accrued exceptions (fflags) and Floating-point dynamic rounding mode (frm) can be accessed directly or via Floating-point control and status register (fcsr) which is mapped to +those two registers.

+
+
+

Reminder for programmers

+

As mentioned in RISC-V Privileged Architecture specification, mstatus.FS should be set to Initial to be able to use FP instructions. +If mstatus.FS = Off (reset value), any instruction that attempts to read or write the Floating-Point state (F registers or F CSRs) will cause an illegal instruction exception.

+

Upon interrupt or context switch events, mstatus.SD should be read to see if Floating-Point state has been altered. +If following executed program (interrupt routine or whatsover) is going to use FP instructions and only if mstatus.SD = 1 (means FS = Dirty), +then the whole FP state (F registers and F CSRs) should be saved in memory and program should set mstatus.FS to Clean. +When returning to interrupted or main program, if mstatus.FS = Clean then the whole FP state should be restored from memory.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/genindex.html b/docs/html/genindex.html new file mode 100644 index 000000000..674b33a36 --- /dev/null +++ b/docs/html/genindex.html @@ -0,0 +1,120 @@ + + + + + + Index — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/html/getting_started.html b/docs/html/getting_started.html new file mode 100644 index 000000000..814d3a133 --- /dev/null +++ b/docs/html/getting_started.html @@ -0,0 +1,145 @@ + + + + + + + Getting Started with CV32E40P — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Getting Started with CV32E40P

+

This page discusses initial steps and requirements to start using CV32E40P in your design.

+
+

Clock Gating Cell

+

CV32E40P requires clock gating cells. +These cells are usually specific to the selected target technology and thus not provided as part of the RTL design. +A simulation-only version of the clock gating cell is provided in cv32e40p_sim_clock_gate.sv. This file contains +a module called cv32e40p_clock_gate that has the following ports:

+
    +
  • clk_i: Clock Input

  • +
  • en_i: Clock Enable Input

  • +
  • scan_cg_en_i: Scan Clock Gate Enable Input (activates the clock even though en_i is not set)

  • +
  • clk_o: Gated Clock Output

  • +
+

Inside CV32E40P, clock gating cells are used in both cv32e40p_sleep_unit.sv and cv32e40p_top.sv.

+

The cv32e40p_sim_clock_gate.sv file is not intended for synthesis. For ASIC synthesis and FPGA synthesis the manifest +should be adapted to use a customer specific file that implements the cv32e40p_clock_gate module using design primitives +that are appropriate for the intended synthesis target technology.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/glossary.html b/docs/html/glossary.html new file mode 100644 index 000000000..b611cb632 --- /dev/null +++ b/docs/html/glossary.html @@ -0,0 +1,154 @@ + + + + + + + Glossary — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Glossary

+
    +
  • ALU: Arithmetic/Logic Unit

  • +
  • ASIC: Application-Specific Integrated Circuit

  • +
  • Byte: 8-bit data item

  • +
  • CPU: Central Processing Unit, processor

  • +
  • CSR: Control and Status Register

  • +
  • Custom extension: Non-Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA)

  • +
  • EX: Instruction Execute

  • +
  • FPGA: Field Programmable Gate Array

  • +
  • FPU: Floating Point Unit

  • +
  • Halfword: 16-bit data item

  • +
  • Halfword aligned address: An address is halfword aligned if it is divisible by 2

  • +
  • ID: Instruction Decode

  • +
  • IF: Instruction Fetch (Instruction Fetch)

  • +
  • ISA: Instruction Set Architecture

  • +
  • KGE: kilo gate equivalents (NAND2)

  • +
  • LSU: Load Store Unit (Load-Store-Unit (LSU))

  • +
  • M-Mode: Machine Mode (RISC-V Instruction Set Manual, Volume II: Privileged Architecture)

  • +
  • OBI: Open Bus Interface

  • +
  • PC: Program Counter

  • +
  • PULP platform: Parallel Ultra Low Power Platform (<https://pulp-platform.org>)

  • +
  • RV32C: RISC-V Compressed (C extension)

  • +
  • RV32F: RISC-V Floating Point (F extension)

  • +
  • SIMD: Single Instruction/Multiple Data

  • +
  • Standard extension: Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA)

  • +
  • WARL: Write Any Values, Reads Legal Values

  • +
  • WB: Write Back of instruction results

  • +
  • WLRL: Write/Read Only Legal Values

  • +
  • Word: 32-bit data item

  • +
  • Word aligned address: An address is word aligned if it is divisible by 4

  • +
  • WPRI: Reserved Writes Preserve Values, Reads Ignore Values

  • +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/index.html b/docs/html/index.html new file mode 100644 index 000000000..3d677debf --- /dev/null +++ b/docs/html/index.html @@ -0,0 +1,321 @@ + + + + + + + OpenHW Group CV32E40P User Manual — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

OpenHW Group CV32E40P User Manual

+
+

Contents:

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/instruction_fetch.html b/docs/html/instruction_fetch.html new file mode 100644 index 000000000..82a2ed72d --- /dev/null +++ b/docs/html/instruction_fetch.html @@ -0,0 +1,210 @@ + + + + + + + Instruction Fetch — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Instruction Fetch

+

The Instruction Fetch (IF) stage of the CV32E40P is able to supply one instruction per cycle to +the Instruction Decode (ID ) stage if the external bus interface is able +to serve one fetch request per cycle. In case of executing compressed instructions, +on average less than one 32-bit fetch request will be needed per instruction +in the ID stage.

+

For optimal performance and timing closure reasons, a prefetcher is used +which fetches instructions via the external bus interface from for example +an externally connected instruction memory or instruction cache.

+

The prefetch buffer performs word-aligned 32-bit prefetches and stores the +fetched words in a FIFO with a number of entries depending of a local parameter. +It is called DEPTH and can be found in cv32e40p_prefetch_buffer.sv (default value of 2). +As a result of this (speculative) prefetch, CV32E40P can fetch up to DEPTH words outside of the code region +and care should therefore be taken that no unwanted read side effects occur +for such prefetches outside of the actual code region.

+

Table 9 describes the signals that are used to fetch instructions. This +interface is a simplified version of the interface that is used by the +LSU, which is described in Load-Store-Unit (LSU). The difference is that no writes +are possible and thus it needs fewer signals.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 9 Instruction Fetch interface signals

Signal

Direction

Description

instr_addr_o[31:0]

output

Address, word aligned

instr_req_o

output

Request valid, will stay high until instr_gnt_i is high for one cycle

instr_gnt_i

input

The other side accepted the request. instr_addr_o may change in the next cycle.

instr_rvalid_i

input

instr_rdata_i holds valid data when instr_rvalid_i is high. This signal will be high for exactly one cycle per request.

instr_rdata_i[31:0]

input

Data read from memory

+
+

Misaligned Accesses

+

Externally, the IF interface performs word-aligned instruction fetches only. +Misaligned instruction fetches are handled by performing two separate word-aligned instruction fetches. +Internally, the core can deal with both word- and half-word-aligned instruction addresses to support compressed instructions. +The LSB of the instruction address is ignored internally.

+
+
+

Protocol

+

The CV32E40P instruction fetch interface does not implement the following optional OBI signals: we, be, wdata, auser, wuser, aid, +rready, err, ruser, rid. These signals can be thought of as being tied off as specified in the OBI specification.

+
+

Note

+

Transactions Ordering +As mentioned above, instruction fetch interface can generate up to DEPTH outstanding transactions. +OBI specification states that links are always in-order from master point of view. So as the fetch interface does not generate transaction id (aid), +interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information.

+
+

Figure 3 and Figure 4 show example timing diagrams of the protocol.

+
+
+

Figure 3 Back-to-back Memory Transactions

+
+
+
+
+

Figure 4 Multiple Outstanding Memory Transactions

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/instruction_set_extensions.html b/docs/html/instruction_set_extensions.html new file mode 100644 index 000000000..3fca7c81a --- /dev/null +++ b/docs/html/instruction_set_extensions.html @@ -0,0 +1,5197 @@ + + + + + + + CORE-V Instruction Set Custom Extension — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CORE-V Instruction Set Custom Extension

+

CV32E40P supports the following CORE-V ISA X Custom Extension, which can be enabled by setting COREV_PULP == 1.

+
+
    +
  • Post-Increment load and stores, see Post-Increment Load & Store Instructions and Register-Register Load & Store Instructions, invoked in the tool chain with -march=rv32i*_xcvmem.

  • +
  • Hardware Loop extension, see Hardware Loops, invoked in the tool chain with -march=rv32i*_xcvhwlp.

  • +
  • ALU extensions, see ALU, which are divided into three sub-extensions:

    +
      +
    • bit manipulation instructions, invoked in the tool chain with -march=rv32i*_xcvbitmanip;

    • +
    • miscellaneous ALU instructions, invoked in the tool chain with -march=rv32i*_xcvalu; and

    • +
    • immediate branch instructions, invoked in the tool chain with -march=rv32i*_xcvbi.

    • +
    +
  • +
  • Multiply-Accumulate extensions, see Multiply-Accumulate, invoked in the tool chain with -march=rv32i*_xcvmac.

  • +
  • Single Instruction Multiple Data (aka SIMD) extensions, see SIMD, invoked in the tool chain with -march=rv32i*_xcvsimd.

  • +
+
+

Additionally the event load instruction (cv.elw) is supported by setting COREV_CLUSTER == 1, see Event Load Instruction. +This is a separate ISA extension, invoked in the tool chain with -march=rv32i*_xcvelw.

+

If not specified, all the operands are signed and immediate values are sign-extended.

+

To use such instructions, you need to compile your SW with the CORE-V GCC or Clang/LLVM compiler.

+
+

Note

+

Clang/LLVM assembler will be supported by 30 June 2023, with builtin function support by 31 December 2023.

+
+
+

Post-Increment Load & Store Instructions and Register-Register Load & Store Instructions

+

Post-Increment load and store instructions perform a load, or a +store, respectively, while at the same time incrementing the address +that was used for the memory access. Since it is a post-incrementing +scheme, the base address is used for the access and the modified address +is written back to the register-file. There are versions of those +instructions that use immediates and those that use registers as +offsets. The base address always comes from a register.

+

The custom post-increment load & store instructions and register-register +load & store instructions are only supported if COREV_PULP == 1.

+
+

Load operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 21 Load operations

Mnemonic

Description

Register-Immediate Loads with Post-Increment

cv.lb rD, Imm(rs1!)

rD = Sext(Mem8(rs1))

+

rs1 += Sext(Imm[11:0])

+

cv.lbu rD, Imm(rs1!)

rD = Zext(Mem8(rs1))

+

rs1 += Sext(Imm[11:0])

+

cv.lh rD, Imm(rs1!)

rD = Sext(Mem16(rs1))

+

rs1 += Sext(Imm[11:0])

+

cv.lhu rD, Imm(rs1!)

rD = Zext(Mem16(rs1))

+

rs1 += Sext(Imm[11:0])

+

cv.lw rD, Imm(rs1!)

rD = Mem32(rs1)

+

rs1 += Sext(Imm[11:0])

+

Register-Register Loads with Post-Increment

cv.lb rD, rs2(rs1!)

rD = Sext(Mem8(rs1))

+

rs1 += rs2

+

cv.lbu rD, rs2(rs1!)

rD = Zext(Mem8(rs1))

+

rs1 += rs2

+

cv.lh rD, rs2(rs1!)

rD = Sext(Mem16(rs1))

+

rs1 += rs2

+

cv.lhu rD, rs2(rs1!)

rD = Zext(Mem16(rs1))

+

rs1 += rs2

+

cv.lw rD, rs2(rs1!)

rD = Mem32(rs1)

+

rs1 += rs2

+

Register-Register Loads

cv.lb rD, rs2(rs1)

rD = Sext(Mem8(rs1 + rs2))

cv.lbu rD, rs2(rs1)

rD = Zext(Mem8(rs1 + rs2))

cv.lh rD, rs2(rs1)

rD = Sext(Mem16(rs1 + rs2))

cv.lhu rD, rs2(rs1)

rD = Zext(Mem16(rs1 + rs2))

cv.lw rD, rs2(rs1)

rD = Mem32(rs1 + rs2)

+
+
+

Store operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 22 Store operations

Mnemonic

Description

Register-Immediate Stores with Post-Increment

cv.sb rs2, Imm(rs1!)

Mem8(rs1) = rs2

+

rs1 += Sext(Imm[11:0])

+

cv.sh rs2, Imm(rs1!)

Mem16(rs1) = rs2

+

rs1 += Sext(Imm[11:0])

+

cv.sw rs2, Imm(rs1!)

Mem32(rs1) = rs2

+

rs1 += Sext(Imm[11:0])

+

Register-Register Stores with Post-Increment

cv.sb rs2, rs3(rs1!)

Mem8(rs1) = rs2

+

rs1 += rs3

+

cv.sh rs2, rs3(rs1!)

Mem16(rs1) = rs2

+

rs1 += rs3

+

cv.sw rs2, rs3(rs1!)

Mem32(rs1) = rs2

+

rs1 += rs3

+

Register-Register Stores

cv.sb rs2, rs3(rs1)

Mem8(rs1 + rs3) = rs2

cv.sh rs2 rs3(rs1)

Mem16(rs1 + rs3) = rs2

cv.sw rs2, rs3(rs1)

Mem32(rs1 + rs3) = rs2

+
+
+

Encoding

+ + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 23 Post-Increment Register-Immediate Load operations encoding

31 : 20

19 : 15

14 : 12

11 : 7

6 : 0

imm[11:0]

rs1

funct3

rD

opcode

Mnemonic

offset

base

000

dest

000 1011

cv.lb rD, Imm(rs1!)

offset

base

100

dest

000 1011

cv.lbu rD, Imm(rs1!)

offset

base

001

dest

000 1011

cv.lh rD, Imm(rs1!)

offset

base

101

dest

000 1011

cv.lhu rD, Imm(rs1!)

offset

base

010

dest

000 1011

cv.lw rD, Imm(rs1!)

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 24 Post-Increment Register-Register Load operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rD

opcode

Mnemonic

000 0000

offset

base

011

dest

010 1011

cv.lb rD, rs2(rs1!)

000 1000

offset

base

011

dest

010 1011

cv.lbu rD, rs2(rs1!)

000 0001

offset

base

011

dest

010 1011

cv.lh rD, rs2(rs1!)

000 1001

offset

base

011

dest

010 1011

cv.lhu rD, rs2(rs1!)

000 0010

offset

base

011

dest

010 1011

cv.lw rD, rs2(rs1!)

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 25 Register-Register Load operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rD

opcode

Mnemonic

000 0100

offset

base

011

dest

010 1011

cv.lb rD, rs2(rs1)

000 1100

offset

base

011

dest

010 1011

cv.lbu rD, rs2(rs1)

000 0101

offset

base

011

dest

010 1011

cv.lh rD, rs2(rs1)

000 1101

offset

base

011

dest

010 1011

cv.lhu rD, rs2(rs1)

000 0110

offset

base

011

dest

010 1011

cv.lw rD, rs2(rs1)

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 26 Post-Increment Register-Immediate Store operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

imm[11:5]

rs2

rs1

funct3

imm[4:0]

opcode

Mnemonic

offset[11:5]

src

base

000

offset[4:0]

010 1011

cv.sb rs2, Imm(rs1!)

offset[11:5]

src

base

001

offset[4:0]

010 1011

cv.sh rs2, Imm(rs1!)

offset[11:5]

src

base

010

offset[4:0]

010 1011

cv.sw rs2, Imm(rs1!)

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 27 Post-Increment Register-Register Store operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rs3

opcode

Mnemonic

001 0000

src

base

011

offset

010 1011

cv.sb rs2, rs3(rs1!)

001 0001

src

base

011

offset

010 1011

cv.sh rs2, rs3(rs1!)

001 0010

src

base

011

offse t

010 1011

cv.sw rs2, rs3(rs1!)

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 28 Register-Register Store operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rs3

opcode

Mnemonic

001 0100

src

base

011

offset

010 1011

cv.sb rs2, rs3(rs1)

001 0101

src

base

011

offset

010 1011

cv.sh rs2, rs3(rs1)

001 0110

src

base

011

offset

010 1011

cv.sw rs2, rs3(rs1)

+
+
+
+

Event Load Instruction

+

The event load instruction cv.elw is only supported if the COREV_CLUSTER parameter is set to 1. +The event load performs a load word and can cause the CV32E40P to enter a sleep state as explained +in PULP Cluster Extension.

+
+

Event Load operation

+ + ++++ + + + + + + + + + + + + +
Table 29 Event Load operation

Mnemonic

Description

Event Load

cv.elw rD, Imm(rs1)

rD = Mem32(Sext(Imm) + rs1)

+
+
+

Encoding

+ + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 30 Event Load operation encoding

31 : 20

19 : 15

14 : 12

11 : 7

6 : 0

imm[11:0]

rs1

funct3

rD

opcode

Mnemonic

offset

base

011

dest

000 1011

cv.elw rD, Imm(rs1)

+
+
+
+

Hardware Loops

+

The loop has to be setup before entering the loop body. For this purpose, there are two +methods, either the long commands that separately set start- and +end-addresses of the loop and the number of iterations, or the short +command that does all of this in a single instruction. The short command +has a limited range for the number of instructions contained in the loop +and the loop must start in the next instruction after the setup +instruction.

+

Hardware loop instructions and related CSRs are only supported if COREV_PULP == 1.

+

Details about the hardware loop constraints are provided in CORE-V Hardware Loop Extensions.

+

In the following tables, the hardware loop instructions are reported. +In assembly, L is referred by 0 or 1.

+
+

Hardware Loops operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 31 Long Hardware Loop Setup operations

Mnemonic

Description

cv.starti L, uimmL

lpstart[L] = PC + (uimmL << 2)

cv.start L, rs1

lpstart[L] = rs1

cv.endi L, uimmL

lpend[L] = PC + (uimmL << 2)

cv.end L, rs1

lpend[L] = rs1

cv.counti L, uimmL

lpcount[L] = uimmL

cv.count L, rs1

lpcount[L] = rs1

+ + ++++ + + + + + + + + + + + + + +
Table 32 Short Hardware Loop Setup operations

Mnemonic

Description

cv.setupi L, uimmL, uimmS

lpstart[L] = PC + 4

+

lpend[L] = PC + (uimmS << 2)

+

lpcount[L] = uimmL

+

cv.setup L, rs1, uimmL

lpstart[L] = PC + 4

+

lpend[L] = PC + (uimmL << 2)

+

lpcount[L] = rs1

+
+
+
+

Encoding

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 33 Hardware Loops operations encoding

31 : 20

19 : 15

14 : 12

11 : 8

7

6 : 0

uimmL[11:0]

rs1

funct3

funct4

L

opcode

Mnemonic

uimmL[11:0]

00000

100

0000

L

010 1011

cv.starti L, uimmL

0000 0000 0000

src1

100

0001

L

010 1011

cv.start L, rs1

uimmL[11:0]

00000

100

0010

L

010 1011

cv.endi L, uimmL

0000 0000 0000

src1

100

0011

L

010 1011

cv.end L, rs1

uimmL[11:0]

00000

100

0100

L

010 1011

cv.counti L, uimmL

0000 0000 0000

src1

100

0101

L

010 1011

cv.count L, rs1

uimmL[11:0]

uimmS[4:0]

100

0110

L

010 1011

cv.setupi L, uimmL, uimmS

uimmL[11:0]

src1

100

0111

L

010 1011

cv.setup L, rs1, uimmL

+
+
+
+

ALU

+

CV32E40P supports advanced ALU operations that allow to perform multiple +instructions that are specified in the base instruction set in one +single instruction and thus increases efficiency of the core. For +example, those instructions include zero-/sign-extension instructions +for 8-bit and 16-bit operands, simple bit manipulation/counting +instructions and min/max/avg instructions. The ALU does also support +saturating, clipping and normalizing instructions which make fixed-point +arithmetic more efficient.

+

The custom ALU extensions are only supported if COREV_PULP == 1.

+

The custom extensions to the ALU are split into several subgroups that belong +together.

+
    +
  • Bit manipulation instructions are useful to work on single bits or +groups of bits within a word, see Bit Manipulation operations.

  • +
  • General ALU instructions try to fuse common used sequences into a +single instruction and thus increase the performance of small kernels +that use those sequence, see General ALU operations.

  • +
  • Immediate branching instructions are useful to compare a register +with an immediate value before taking or not a branch, see see Immediate Branching operations.

  • +
+

Extract, Insert, Clear and Set instructions have the following meaning:

+
    +
  • Extract Is3+1 or rs2[9:5]+1 bits from position Is2 or rs2[4:0] [and sign extend it]

  • +
  • Insert Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0]

  • +
  • Clear Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0]

  • +
  • Set Is3+1 or rs2[9:5]+1 bits at position Is2 or rs2[4:0]

  • +
+
+

Bit Reverse Instruction

+

This section will describe the cv.bitrev instruction from a bit manipulation +perspective without describing it’s application as part of an FFT. The bit +reverse instruction will reverse bits in groupings of 1, 2 or 3 bits. The +number of grouped bits is described by Is3 as follows:

+
    +
  • 0 - reverse single bits

  • +
  • 1 - reverse groups of 2 bits

  • +
  • 2 - reverse groups of 3 bits

  • +
+

The number of bits that are reversed can be controlled by Is2. This will +specify the number of bits that will be removed by a left shift prior to +the reverse operation resulting in the 32-Is2 least significant bits of +the input value being reversed and the Is2 most significant bits of the +input value being thrown out.

+

What follows is a few examples.

+
cv.bitrev x18, x20, 0, 4 (groups of 1 bit; radix-2)
+
+in:    0xC64A5933 11000110010010100101100100110011
+shift: 0x64A59330 01100100101001011001001100110000
+out:   0x0CC9A526 00001100110010011010010100100110
+
+Swap pattern:
+A B C D E F G H . . . . . . . . . . . . . . . . . . . . . . . .
+0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 1 1 0 0 0 0
+. . . . . . . . . . . . . . . . . . . . . . . . H G F E D C B A
+0 0 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0
+
+
+

In this example the input value is first shifted by 4 (Is2). Each individual +bit is reversed. For example, bits 31 and 0 are swapped, 30 and 1, etc.

+
cv.bitrev x18, x20, 1, 4 (groups of 2 bits; radix-4)
+
+in:    0xC64A5933 11000110010010100101100100110011
+shift: 0x64A59330 01100100101001011001001100110000
+out:   0x0CC65A19 00001100110001100101101000011001
+
+Swap pattern:
+A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P
+01 10 01 00 10 10 01 01 10 01 00 11 00 11 00 00
+P  O  N  M  L  K  J  I  H  G  F  E  D  C  B  A
+00 00 11 00 11 00 01 10 01 01 10 10 00 01 10 01
+
+
+

In this example the input value is first shifted by 4 (Is2). Each group of +two bits are reversed. For example, bits 31 and 30 are swapped with 1 and 0 +(retaining their position relative to each other), bits 29 and 28 are swapped +with 3 and 2, etc.

+
cv.bitrev x18, x20, 2, 4 (groups of 3 bits; radix-8)
+
+in:    0xC64A5933 11000110010010100101100100110011
+shift: 0x64A59330 01100100101001011001001100110000
+out:   0x216B244B 00100001011010110010010001001011
+
+Swap pattern:
+A   B   C   D   E   F   G   H   I   J
+011 001 001 010 010 110 010 011 001 100 00
+   J   I   H   G   F   E   D   C   B   A
+00 100 001 011 010 110 010 010 001 001 011
+
+
+

In this last example the input value is first shifted by 4 (Is2). Each group +of three bits are reversed. For example, bits 31, 30 and 29 are swapped with +4, 3 and 2 (retaining their position relative to each other), bits 28, 27 and +26 are swapped with 7, 6 and 5, etc. Notice in this example that bits 0 and 1 +are lost and the result is shifted right by two with bits 31 and 30 being tied +to zero. Also notice that when J (100) is swapped with A (011), the four most +significant bits are no longer zero as in the other cases. This may not be +desirable if the intention is to pack a specific number of grouped bits +aligned to the least significant bit and zero extended into the result. In +this case care should be taken to set Is2 appropriately.

+
+
+

Bit Manipulation operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 34 Bit Manipulation operations

Mnemonic

Description

cv.extract rD, rs1, Is3, Is2

rD = Sext(rs1[min(Is3+Is2,31):Is2])

+

Note: Sign extension is done over the MSB of the extracted part.

+

cv.extractu rD, rs1, Is3, Is2

rD = Zext(rs1[min(Is3+Is2,31):Is2])

cv.extractr rD, rs1, rs2

rD = Sext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]])

+

Note: Sign extension is done over the MSB of the extracted part.

+

cv.extractur rD, rs1, rs2

rD = Zext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]])

cv.insert rD, rs1, Is3, Is2

rD[min(Is3+Is2,31):Is2] = rs1[Is3-(max(Is3+Is2,31)-31):0]

+

The rest of the bits of rD are untouched and keep their previous value.

+

Is3 + Is2 must be < 32.

+

cv.insertr rD, rs1, rs2

rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] =

+

rs1[rs2[9:5]-(max(rs2[9:5]+rs2[4:0],31)-31):0]

+

The rest of the bits of rD are untouched and keep their previous value.

+

Is3 + Is2 must be < 32.

+

cv.bclr rD, rs1, Is3, Is2

rD[min(Is3+Is2,31):Is2] bits set to 0

+

The rest of the bits of rD are passed through from rs1 and are not modified.

+

cv.bclrr rD, rs1, rs2

rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 0

+

The rest of the bits of rD are passed through from rs1 and are not modified.

+

cv.bset rD, rs1, Is3, Is2

rD[min(Is3+Is2,31):Is2] bits set to 1

+

The rest of the bits of rD are passed through from rs1 and are not modified.

+

cv.bsetr rD, rs1, rs2

rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 1

+

The rest of the bits of rD are passed through from rs1 and are not modified.

+

cv.ff1 rD, rs1

rD = bit position of the first bit set in rs1, starting from LSB.

+

If bit 0 is set, rD will be 0. If only bit 31 is set, rD will be 31.

+

If rs1 is 0, rD will be 32.

+

cv.fl1 rD, rs1

rD = bit position of the last bit set in rs1, starting from MSB.

+

If bit 31 is set, rD will be 31. If only bit 0 is set, rD will be 0.

+

If rs1 is 0, rD will be 32.

+

cv.clb rD, rs1

rD = count leading bits of rs1

+

Number of consecutive 1’s or 0’s starting from MSB.

+

If rs1 is 0, rD will be 0. If rs1 is different than 0, returns (number - 1).

+

cv.cnt rD, rs1

rD = Population count of rs1

+

Number of bits set in rs1.

+

cv.ror rD, rs1, rs2

rD = RotateRight(rs1, rs2)

cv.bitrev rD, rs1, Is3, Is2

Given an input rs1 it returns a bit reversed representation assuming

+

FFT on 2^Is2 points in Radix 2^(Is3+1).

+

Is3 can be either 0 (radix-2), 1 (radix-4) or 2 (radix-8).

+

Note: When Is3 = 3, instruction has the same bahavior as if it was 0 (radix-2).

+
+
+
+

Bit Manipulation Encoding

+ + ++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 35 Immediate Bit Manipulation operations encoding

31: 30

29 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

f2

ls3[4:0]

ls2[4:0]

rs1

funct3

rD

opcode

Mnemonic

00

Luimm5[4:0]

Iuimm5[4:0]

src

000

dest

101 1011

cv.extract rD, rs1, Is3, Is2

01

Luimm5[4:0]

Iuimm5[4:0]

src

000

dest

101 1011

cv.extractu rD, rs1, Is3, Is2

10

Luimm5[4:0]

Iuimm5[4:0]

src

000

dest

101 1011

cv.insert rD, rs1, Is3, Is2

00

Luimm5[4:0]

Iuimm5[4:0]

src

001

dest

101 1011

cv.bclr rD, rs1, Is3, Is2

01

Luimm5[4:0]

Iuimm5[4:0]

src

001

dest

101 1011

cv.bset rD, rs1, Is3, Is2

11

000, Luimm2[1:0]

Iuimm5[4:0]

src

001

dest

101 1011

cv.bitrev rD, rs1, Is3, Is2

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 36 Register Bit Manipulation operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rD

opcode

001 1000

src2

src1

011

dest

010 1011

cv.extractr rD, rs1, rs2

001 1001

src2

src1

011

dest

010 1011

cv.extractur rD, rs1, rs2

001 1010

src2

src1

011

dest

010 1011

cv.insertr rD, rs1, rs2

001 1100

src2

src1

011

dest

010 1011

cv.bclrr rD, rs1, rs2

001 1101

src2

scr1

011

dest

010 1011

cv.bsetr rD, rs1, rs2

010 0000

src2

src1

011

dest

010 1011

cv.ror rD, rs1, rs2

010 0001

00000

src1

011

dest

010 1011

cv.ff1 rD, rs1

010 0010

00000

src1

011

dest

010 1011

cv.fl1 rD, rs1

010 0011

00000

src1

011

dest

010 1011

cv.clb rD, rs1

010 0100

00000

src1

011

dest

010 1011

cv.cnt rD, rs1

+
+
+

General ALU operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 37 General ALU operations

Mnemonic

Description

cv.abs rD, rs1

rD = rs1 < 0 ? -rs1 : rs1

cv.slet rD, rs1, rs2

rD = rs1 <= rs2 ? 1 : 0

+

Note: Comparison is signed.

+

cv.sletu rD, rs1, rs2

rD = rs1 <= rs2 ? 1 : 0

+

Note: Comparison is unsigned.

+

cv.min rD, rs1, rs2

rD = rs1 < rs2 ? rs1 : rs2

+

Note: Comparison is signed.

+

cv.minu rD, rs1, rs2

rD = rs1 < rs2 ? rs1 : rs2

+

Note: Comparison is unsigned.

+

cv.max rD, rs1, rs2

rD = rs1 < rs2 ? rs2 : rs1

+

Note: Comparison is signed.

+

cv.maxu rD, rs1, rs2

rD = rs1 < rs2 ? rs2 : rs1

+

Note: Comparison is unsigned.

+

cv.exths rD, rs1

rD = Sext(rs1[15:0])

cv.exthz rD, rs1

rD = Zext(rs1[15:0])

cv.extbs rD, rs1

rD = Sext(rs1[7:0])

cv.extbz rD, rs1

rD = Zext(rs1[7:0])

cv.clip rD, rs1, Is2

if rs1 <= -2^(Is2-1), rD = -2^(Is2-1),

+

else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1,

+

else rD = rs1

+

Note: If ls2 is equal to 0,

+

-2^(Is2-1) is equivalent to -1 while (2^(Is2-1)-1) is equivalent to 0.

+

cv.clipu rD, rs1, Is2

if rs1 <= 0, rD = 0,

+

else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1,

+

else rD = rs1

+

Note: If ls2 is equal to 0, (2^(Is2-1)-1) is equivalent to 0.

+

cv.clipr rD, rs1, rs2

if rs1 <= -(rs2+1), rD = -(rs2+1),

+

else if rs1 >=rs2, rD = rs2,

+

else rD = rs1

+

cv.clipur rD, rs1, rs2

if rs1 <= 0, rD = 0,

+

else if rs1 >= rs2, rD = rs2,

+

else rD = rs1

+

cv.addN rD, rs1, rs2, Is3

rD = (rs1 + rs2) >>> Is3

+

Note: Arithmetic shift right.

+

Setting Is3 to 2 replaces former cv.avg.

+

cv.adduN rD, rs1, rs2, Is3

rD = (rs1 + rs2) >> Is3

+

Note: Logical shift right.

+

Setting Is3 to 2 replaces former cv.avg.

+

cv.addRN rD, rs1, rs2, Is3

rD = (rs1 + rs2 + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.adduRN rD, rs1, rs2, Is3

rD = (rs1 + rs2 + 2^(Is3-1))) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.subN rD, rs1, rs2, Is3

rD = (rs1 - rs2) >>> Is3

+

Note: Arithmetic shift right.

+

cv.subuN rD, rs1, rs2, Is3

rD = (rs1 - rs2) >> Is3

+

Note: Logical shift right.

+

cv.subRN rD, rs1, rs2, Is3

rD = (rs1 - rs2 + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.subuRN rD, rs1, rs2, Is3

rD = (rs1 - rs2 + 2^(Is3-1))) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.addNr rD, rs1, rs2

rD = (rD + rs1) >>> rs2[4:0]

+

Note: Arithmetic shift right.

+

cv.adduNr rD, rs1, rs2

rD = (rD + rs1) >> rs2[4:0]

+

Note: Logical shift right.

+

cv.addRNr rD, rs1, rs2

rD = (rD + rs1 + 2^(rs2[4:0]-1)) >>> rs2[4:0]

+

Note: Arithmetic shift right.

+

If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0.

+

cv.adduRNr rD, rs1, rs2

rD = (rD + rs1 + 2^(rs2[4:0]-1))) >> rs2[4:0]

+

Note: Logical shift right.

+

If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0.

+

cv.subNr rD, rs1, rs2

rD = (rD - rs1) >>> rs2[4:0]

+

Note: Arithmetic shift right.

+

cv.subuNr rD, rs1, rs2

rD = (rD - rs1) >> rs2[4:0]

+

Note: Logical shift right.

+

cv.subRNr rD, rs1, rs2

rD = (rD - rs1+ 2^(rs2[4:0]-1)) >>> rs2[4:0]

+

Note: Arithmetic shift right.

+

If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0.

+

cv.subuRNr rD, rs1, rs2

rD = (rD - rs1+ 2^(rs2[4:0]-1))) >> rs2[4:0]

+

Note: Logical shift right.

+

If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0.

+
+
+
+

General ALU Encoding

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 38 General ALU operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rD

opcode

010 1000

00000

src1

011

dest

010 1011

cv.abs rD, rs1

010 1001

src2

src1

011

dest

010 1011

cv.slet rD, rs1, rs2

010 1010

src2

src1

011

dest

010 1011

cv.sletu rD, rs1, rs2

010 1011

src2

src1

011

dest

010 1011

cv.min rD, rs1, rs2

010 1100

src2

src1

011

dest

010 1011

cv.minu rD, rs1, rs2

010 1101

src2

src1

011

dest

010 1011

cv.max rD, rs1, rs2

010 1110

src2

src1

011

dest

010 1011

cv.maxu rD, rs1, rs2

011 0000

00000

src1

011

dest

010 1011

cv.exths rD, rs1

011 0001

00000

src1

011

dest

010 1011

cv.exthz rD, rs1

011 0010

00000

src1

011

dest

010 1011

cv.extbs rD, rs1

011 0011

00000

src1

011

dest

010 1011

cv.extbz rD, rs1

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 39 General ALU operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

Is2[4:0]

rs1

funct3

rD

opcode

011 1000

Iuimm5[4:0]

src1

011

dest

010 1011

cv.clip rD, rs1, Is2

011 1001

Iuimm5[4:0]

src1

011

dest

010 1011

cv.clipu rD, rs1, Is2

011 1010

src2

src1

011

dest

010 1011

cv.clipr rD, rs1, rs2

011 1011

src2

src1

011

dest

010 1011

cv.clipur rD, rs1, rs2

+ + ++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 40 General ALU operations encoding

31: 30

29 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

f2

Is3[4:0]

rs2

rs1

funct3

rD

opcode

00

Luimm5[4:0]

src2

src1

010

dest

101 1011

cv.addN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

010

dest

101 1011

cv.adduN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

010

dest

101 1011

cv.addRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

010

dest

101 1011

cv.adduRN rD, rs1, rs2, Is3

00

Luimm5[4:0]

src2

src1

011

dest

101 1011

cv.subN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

011

dest

101 1011

cv.subuN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

011

dest

101 1011

cv.subRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

011

dest

101 1011

cv.subuRN rD, rs1, rs2, Is3

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 41 General ALU operations encoding

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

Is3[4:0]

rs1

funct3

rD

opcode

100 0000

src2

src1

011

dest

010 1011

cv.addNr rD, rs1, rs2

100 0001

src2

src1

011

dest

010 1011

cv.adduNr rD, rs1, rs

100 0010

src2

src1

011

dest

010 1011

cv.addRNr rD, rs1, rs

100 0011

src2

src1

011

dest

010 1011

cv.adduRNr rD, rs1, rs2

100 0100

src2

src1

011

dest

010 1011

cv.subNr rD, rs1, rs2

100 0101

src2

src1

011

dest

010 1011

cv.subuNr rD, rs1, rs2

100 0110

src2

src1

011

dest

010 1011

cv.subRNr rD, rs1, rs2

100 0111

src2

src1

011

dest

010 1011

cv.subuRNr rD, rs1, rs2

+
+
+

Immediate Branching operations

+ + ++++ + + + + + + + + + + + + + +
Table 42 Immediate Branching operations

Mnemonic

Description

cv.beqimm rs1, Imm5, Imm12

Branch to PC + (Imm12 << 1) if rs1 is equal to Imm5.

+

Note: Imm5 is signed.

+

cv.bneimm rs1, Imm5, Imm12

Branch to PC + (Imm12 << 1) if rs1 is not equal to Imm5.

+

Note: Imm5 is signed.

+
+
+
+

Immediate Branching Encoding

+ + +++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 43 Immediate Branching encoding

31

30 : 25

24 : 20

19 : 15

14 : 12

11 : 8

7

6 : 0

Imm12[12]

Imm12[10:5]

Imm5

rs1

funct3

Imm12

Imm12

opcode

Imm12[12]

Imm12[10:5]

Imm5

src1

110

Imm12[4:1]

Imm12[11]

000 1011

cv.beqimm rs1, Imm5, Imm12

Imm12[12]

Imm12[10:5]

Imm5

src1

111

Imm12[4:1]

Imm12[11]

000 1011

cv.bneimm rs1, Imm5, Imm12

+
+
+
+

Multiply-Accumulate

+

CV32E40P supports custom extensions for multiply-accumulate and half-word multiplications with +an optional post-multiplication shift.

+

The custom multiply-accumulate extensions are only supported if COREV_PULP == 1.

+
+

16-Bit x 16-Bit Multiplication operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 44 16-Bit Multiplication operations

Mnemonic

Description

cv.muluN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0])) >> Is3

+

Note: Logical shift right.

+

cv.mulhhuN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16])) >> Is3

+

Note: Logical shift right.

+

cv.mulsN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0])) >>> Is3

+

Note: Arithmetic shift right.

+

cv.mulhhsN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16])) >>> Is3

+

Note: Arithmetic shift right.

+

cv.muluRN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + 2^(Is3-1)) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.mulhhuRN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + 2^(Is3-1)) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.mulsRN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.mulhhsRN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+
+
+
+

16-Bit x 16-Bit Multiply-Accumulate operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 45 16-Bit Multiply-Accumulate operations

Mnemonic

Description

cv.macuN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + rD) >> Is3

+

Note: Logical shift right.

+

cv.machhuN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + rD) >> Is3

+

Note: Logical shift right.

+

cv.macsN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + rD) >>> Is3

+

Note: Arithmetic shift right.

+

cv.machhsN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + rD) >>> Is3

+

Note: Arithmetic shift right.

+

cv.macuRN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + rD + 2^(Is3-1)) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.machhuRN rD, rs1, rs2, Is3

rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + rD + 2^(Is3-1)) >> Is3

+

Note: Logical shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.macsRN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + rD + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+

cv.machhsRN rD, rs1, rs2, Is3

rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + rD + 2^(Is3-1)) >>> Is3

+

Note: Arithmetic shift right.

+

If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0.

+
+
+
+

32-Bit x 32-Bit Multiply-Accumulate operations

+ + ++++ + + + + + + + + + + + + + +
Table 46 32-Bit Multiply-Accumulate operations

Mnemonic

Description

cv.mac rD, rs1, rs2

rD = rD + rs1 * rs2

cv.msu rD, rs1, rs2

rD = rD - rs1 * rs2

+
+
+

Encoding

+ + ++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 47 16-Bit Multiplication operations

31: 30

29 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

f2

Is3[4:0]

rs2

rs1

funct3

rD

opcode

00

Luimm5[4:0]

src2

src1

101

dest

101 1011

cv.muluN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

101

dest

101 1011

cv.mulhhuN rD, rs1, rs2, Is3

00

Luimm5[4:0]

src2

src1

100

dest

101 1011

cv.mulsN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

100

dest

101 1011

cv.mulhhsN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

101

dest

101 1011

cv.muluRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

101

dest

101 1011

cv.mulhhuRN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

100

dest

101 1011

cv.mulsRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

100

dest

101 1011

cv.mulhhsRN rD, rs1, rs2, Is3

+ + ++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 48 16-Bit Multiply-Accumulate operations

31: 30

29 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

f2

Is3[4:0]

rs2

rs1

funct3

rD

opcode

00

Luimm5[4:0]

src2

src1

111

dest

101 1011

cv.macuN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

111

dest

101 1011

cv.machhuN rD, rs1, rs2, Is3

00

Luimm5[4:0]

src2

src1

110

dest

101 1011

cv.macsN rD, rs1, rs2, Is3

01

Luimm5[4:0]

src2

src1

110

dest

101 1011

cv.machhsN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

111

dest

101 1011

cv.macuRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

111

dest

101 1011

cv.machhuRN rD, rs1, rs2, Is3

10

Luimm5[4:0]

src2

src1

110

dest

101 1011

cv.macsRN rD, rs1, rs2, Is3

11

Luimm5[4:0]

src2

src1

110

dest

101 1011

cv.machhsRN rD, rs1, rs2, Is3

+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 49 32-Bit Multiply-Accumulate operations

31 : 25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct7

rs2

rs1

funct3

rD

opcode

100 1000

src2

src1

011

dest

010 1011

cv.mac rD, rs1, rs2

100 1001

src2

src1

011

dest

010 1011

cv.msu rD, rs1, rs2

+
+
+
+

SIMD

+

The SIMD instructions perform operations on multiple sub-word elements at the same time. This is done by segmenting +the data path into smaller parts when 8- or 16-bit operations should be performed.

+

The custom SIMD extensions are only supported if COREV_PULP == 1.

+
+

Note

+

See the comments at the start of CORE-V Instruction Set Custom Extension on availability of the compiler tool chains. +Support for SIMD will be primarily through assembly code and builtin functions, with no auto-vectorization and limited other optimization. +Simple auto-vectorization (add, sub…) and optimization will be evaluated once a stable GCC toolchain is available.

+
+

SIMD instructions are available in two flavors:

+
    +
  • 8-Bit, to perform four operations on the 4 bytes inside a 32-bit word +at the same time (.b)

  • +
  • 16-Bit, to perform two operations on the 2 half-words inside a 32-bit +word at the same time (.h)

  • +
+

All the operations are rounded to the specified bidwidth as for the original +RISC-V arithmetic operations. This is described by the “and” operation with a +MASK. No overflow or carry-out flags are generated as for the 32-bit operations.

+

Additionally, there are three modes that influence the second operand:

+
    +
  1. Normal mode, vector-vector operation. Both operands, from rs1 and +rs2, are treated as vectors of bytes or half-words.

    +

    e.g. cv.add.h x3,x2,x1 performs:

    +
    +

    x3[31:16] = x2[31:16] + x1[31:16]

    +

    x3[15: 0] = x2[15: 0] + x1[15: 0]

    +
    +
  2. +
  3. Scalar replication mode (.sc), vector-scalar operation. Operand 1 is +treated as a vector, while operand 2 is treated as a scalar and +replicated two or four times to form a complete vector. The LSP is +used for this purpose.

    +

    e.g. cv.add.sc.h x3,x2,x1 performs:

    +
    +

    x3[31:16] = x2[31:16] + x1[15: 0]

    +

    x3[15: 0] = x2[15: 0] + x1[15: 0]

    +
    +
  4. +
  5. Immediate scalar replication mode (.sci), vector-scalar operation. +Operand 1 is treated as vector, while operand 2 is treated as a +scalar and comes from a 6-bit immediate.

    +

    The immediate is either sign- or zero-extended depending on the operation. +If not specified, the immediate is sign-extended with the exception +of all cv.shuffle* where it is always unsigned.

    +

    e.g. cv.add.sci.h x3,x2,0x2A performs:

    +
    +

    x3[31:16] = x2[31:16] + 0xFFEA

    +

    x3[15: 0] = x2[15: 0] + 0xFFEA

    +
    +
  6. +
+

In the following tables, the index i ranges from 0 to 1 for 16-Bit operations and from 0 to 3 for 8-Bit operations:

+
    +
  • The index 0 is 15:0 for 16-Bit operations or 7:0 for 8-Bit operations.

  • +
  • The index 1 is 31:16 for 16-Bit operations or 15:8 for 8-Bit operations.

  • +
  • The index 2 is 23:16 for 8-Bit operations.

  • +
  • The index 3 is 31:24 for 8-Bit operations.

  • +
+

And I5, I4, I3, I2, I1 and I0 respectively represent bits 5, 4, 3, 2, 1 and 0 of the immediate value.

+
+

SIMD ALU operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 50 SIMD ALU operations

Mnemonic

Description

cv.add[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = (rs1[i] + op2[i]) & 0xFFFF

cv.sub[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = (rs1[i] - op2[i]) & 0xFFFF

cv.avg[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1

+

Note: Arithmetic right shift.

+

cv.avgu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1

+

Note: Logical shift right.

+

cv.min[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i]

cv.minu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i]

+

Note: Immediate is zero-extended, comparison is unsigned.

+

cv.max[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i]

cv.maxu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i]

+

Note: Immediate is zero-extended, comparison is unsigned.

+

cv.srl[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] >> op2[i]

+

Note: Immediate is zero-extended, shift is logical.

+

cv.sra[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] >>> op2[i]

+

Note: Immediate is zero-extended, shift is arithmetic.

+

cv.sll[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] << op2[i]

+

Note: Immediate is zero-extended, shift is logical.

+

cv.or[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] | op2[i]

cv.xor[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] ^ op2[i]

cv.and[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] & op2[i]

cv.abs{.h,.b} rD, rs1

rD[i] = rs1[i] < 0 ? -rs1[i] : rs1[i]

+
+

SIMD Bit Manipulation operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 51 SIMD Bit Manipulation operations

Mnemonic

Description

cv.extract.h rD, rs1, Imm6

rD = Sext(rs1[I0*16+15:I0*16])

cv.extract.b rD, rs1, Imm6

rD = Sext(rs1[(I1:I0)*8+7:(I1:I0)*8])

cv.extractu.h rD, rs1, Imm6

rD = Zext(rs1[I0*16+15:I0*16])

cv.extractu.b rD, rs1, Imm6

rD = Zext(rs1[(I1:I0)*8+7:(I1:I0)*8])

cv.insert.h rD, rs1, Imm6

rD[I0*16+15:I0*16] = rs1[15:0]

+

Note: The rest of the bits of rD are untouched and keep their previous value.

+

cv.insert.b rD, rs1, Imm6

rD[(I1:I0)*8+7:(I1:I0)*8] = rs1[7:0]

+

Note: The rest of the bits of rD are untouched and keep their previous value.

+
+
+
+

SIMD Dot Product operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 52 SIMD Dot Product operations

Mnemonic

Description

cv.dotup[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: All operands are unsigned.

+

cv.dotup[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: All operands are unsigned.

+

cv.dotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: rs1 is treated as unsigned, while op2 is treated as signed.

+

cv.dotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: rs1 is treated as unsigned, while op2 is treated as signed.

+

cv.dotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: All operands are signed.

+

cv.dotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: All operands are signed.

+

cv.sdotup[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: All operands are unsigned.

+

cv.sdotup[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: All operands are unsigned.

+

cv.sdotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: rs1 is treated as unsigned while op2 is treated as signed.

+

cv.sdotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: rs1 is treated as unsigned while op2 is treated as signed.

+

cv.sdotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1]

+

Note: All operands are signed.

+

cv.sdotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]

rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] +

+

rs1[2] * op2[2] + rs1[3] * op2[3]

+

Note: All operands are signed.

+
+
+
+

SIMD Shuffle and Pack operations

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 53 SIMD Shuffle and Pack operations

Mnemonic

Description

cv.shuffle.h rD, rs1, rs2

rD[31:16] = rs1[rs2[16]*16+15:rs2[16]*16]

+

rD[15:0] = rs1[rs2[0]*16+15:rs2[0]*16]

+

cv.shuffle.sci.h rD, rs1, Imm6

rD[31:16] = rs1[I1*16+15:I1*16]

+

rD[15:0] = rs1[I0*16+15:I0*16]

+

cv.shuffle.b rD, rs1, rs2

rD[31:24] = rs1[rs2[25:24]*8+7:rs2[25:24]*8]

+

rD[23:16] = rs1[rs2[17:16]*8+7:rs2[17:16]*8]

+

rD[15:8] = rs1[rs2[9:8]*8+7:rs2[9:8]*8]

+

rD[7:0] = rs1[rs2[1:0]*8+7:rs2[1:0]*8]

+

cv.shuffleI0.sci.b rD, rs1, Imm6

rD[31:24] = rs1[7:0]

+

rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8]

+

rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8]

+

rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]

+

cv.shuffleI1.sci.b rD, rs1, Imm6

rD[31:24] = rs1[15:8]

+

rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8]

+

rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8]

+

rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]

+

cv.shuffleI2.sci.b rD, rs1, Imm6

rD[31:24] = rs1[23:16]

+

rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8]

+

rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8]

+

rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]

+

cv.shuffleI3.sci.b rD, rs1, Imm6

rD[31:24] = rs1[31:24]

+

rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8]

+

rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8]

+

rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]

+

cv.shuffle2.h rD, rs1, rs2

rD[31:16] = ((rs2[17] == 1) ? rs1 : rD)[rs2[16]*16+15:rs2[16]*16]

+

rD[15:0] = ((rs2[1] == 1) ? rs1 : rD)[rs2[0]*16+15:rs2[0]*16]

+

cv.shuffle2.b rD, rs1, rs2

rD[31:24] = ((rs2[26] == 1) ? rs1 : rD)[rs2[25:24]*8+7:rs2[25:24]*8]

+

rD[23:16] = ((rs2[18] == 1) ? rs1 : rD)[rs2[17:16]*8+7:rs2[17:16]*8]

+

rD[15:8] = ((rs2[10] == 1) ? rs1 : rD)[rs2[9:8]*8+7:rs2[9:8]*8]

+

rD[7:0] = ((rs2[2] == 1) ? rs1 : rD)[rs2[1:0]*8+7:rs2[1:0]*8]

+

cv.pack rD, rs1, rs2

rD[31:16] = rs1[15:0]

+

rD[15:0] = rs2[15:0]

+

cv.pack.h rD, rs1, rs2

rD[31:16] = rs1[31:16]

+

rD[15:0] = rs2[31:16]

+

cv.packhi.b rD, rs1, rs2

rD[31:24] = rs1[7:0]

+

rD[23:16] = rs2[7:0]

+

Note: The rest of the bits of rD are untouched and keep their previous value.

+

cv.packlo.b rD, rs1, rs2

rD[15:8] = rs1[7:0]

+

rD[7:0] = rs2[7:0]

+

Note: The rest of the bits of rD are untouched and keep their previous value.

+
+
+
+

SIMD ALU Encoding

+ + +++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 54 SIMD ALU encoding

31 : 27

26

25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct5

F

rs2

rs1

funct3

rD

opcode

0 0000

0

0

src2

src1

000

dest

111 1011

cv.add.h rD, rs1, rs2

0 0000

0

0

src2

src1

100

dest

111 1011

cv.add.sc.h rD, rs1, rs2

0 0000

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.add.sci.h rD, rs1, Imm6

0 0000

0

0

src2

src1

001

dest

111 1011

cv.add.b rD, rs1, rs2

0 0000

0

0

src2

src1

101

dest

111 1011

cv.add.sc.b rD, rs1, rs2

0 0000

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.add.sci.b rD, rs1, Imm6

0 0001

0

0

src2

src1

000

dest

111 1011

cv.sub.h rD, rs1, rs2

0 0001

0

0

src2

src1

100

dest

111 1011

cv.sub.sc.h rD, rs1, rs2

0 0001

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sub.sci.h rD, rs1, Imm6

0 0001

0

0

src2

src1

001

dest

111 1011

cv.sub.b rD, rs1, rs2

0 0001

0

0

src2

src1

101

dest

111 1011

cv.sub.sc.b rD, rs1, rs2

0 0001

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sub.sci.b rD, rs1, Imm6

0 0010

0

0

src2

src1

000

dest

111 1011

cv.avg.h rD, rs1, rs2

0 0010

0

0

src2

src1

100

dest

111 1011

cv.avg.sc.h rD, rs1, rs2

0 0010

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.avg.sci.h rD, rs1, Imm6

0 0010

0

0

src2

src1

001

dest

111 1011

cv.avg.b rD, rs1, rs2

0 0010

0

0

src2

src1

101

dest

111 1011

cv.avg.sc.b rD, rs1, rs2

0 0010

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.avg.sci.b rD, rs1, Imm6

0 0011

0

0

src2

src1

000

dest

111 1011

cv.avgu.h rD, rs1, rs2

0 0011

0

0

src2

src1

100

dest

111 1011

cv.avgu.sc.h rD, rs1, rs2

0 0011

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.avgu.sci.h rD, rs1, Imm6

0 0011

0

0

src2

src1

001

dest

111 1011

cv.avgu.b rD, rs1, rs2

0 0011

0

0

src2

src1

101

dest

111 1011

cv.avgu.sc.b rD, rs1, rs2

0 0011

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.avgu.sci.b rD, rs1, Imm6

0 0100

0

0

src2

src1

000

dest

111 1011

cv.min.h rD, rs1, rs2

0 0100

0

0

src2

src1

100

dest

111 1011

cv.min.sc.h rD, rs1, rs2

0 0100

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.min.sci.h rD, rs1, Imm6

0 0100

0

0

src2

src1

001

dest

111 1011

cv.min.b rD, rs1, rs2

0 0100

0

0

src2

src1

101

dest

111 1011

cv.min.sc.b rD, rs1, rs2

0 0100

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.min.sci.b rD, rs1, Imm6

0 0101

0

0

src2

src1

000

dest

111 1011

cv.minu.h rD, rs1, rs2

0 0101

0

0

src2

src1

100

dest

111 1011

cv.minu.sc.h rD, rs1, rs2

0 0101

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.minu.sci.h rD, rs1, Imm6

0 0101

0

0

src2

src1

001

dest

111 1011

cv.minu.b rD, rs1, rs2

0 0101

0

0

src2

src1

101

dest

111 1011

cv.minu.sc.b rD, rs1, rs2

0 0101

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.minu.sci.b rD, rs1, Imm6

0 0110

0

0

src2

src1

000

dest

111 1011

cv.max.h rD, rs1, rs2

0 0110

0

0

src2

src1

100

dest

111 1011

cv.max.sc.h rD, rs1, rs2

0 0110

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.max.sci.h rD, rs1, Imm6

0 0110

0

0

src2

src1

001

dest

111 1011

cv.max.b rD, rs1, rs2

0 0110

0

0

src2

src1

101

dest

111 1011

cv.max.sc.b rD, rs1, rs2

0 0110

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.max.sci.b rD, rs1, Imm6

0 0111

0

0

src2

src1

000

dest

111 1011

cv.maxu.h rD, rs1, rs2

0 0111

0

0

src2

src1

100

dest

111 1011

cv.maxu.sc.h rD, rs1, rs2

0 0111

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.maxu.sci.h rD, rs1, Imm6

0 0111

0

0

src2

src1

001

dest

111 1011

cv.maxu.b rD, rs1, rs2

0 0111

0

0

src2

src1

101

dest

111 1011

cv.maxu.sc.b rD, rs1, rs2

0 0111

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.maxu.sci.b rD, rs1, Imm6

0 1000

0

0

src2

src1

000

dest

111 1011

cv.srl.h rD, rs1, rs2

0 1000

0

0

src2

src1

100

dest

111 1011

cv.srl.sc.h rD, rs1, rs2

0 1000

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.srl.sci.h rD, rs1, Imm6

0 1000

0

0

src2

src1

001

dest

111 1011

cv.srl.b rD, rs1, rs2

0 1000

0

0

src2

src1

101

dest

111 1011

cv.srl.sc.b rD, rs1, rs2

0 1000

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.srl.sci.b rD, rs1, Imm6

0 1001

0

0

src2

src1

000

dest

111 1011

cv.sra.h rD, rs1, rs2

0 1001

0

0

src2

src1

100

dest

111 1011

cv.sra.sc.h rD, rs1, rs2

0 1001

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sra.sci.h rD, rs1, Imm6

0 1001

0

0

src2

src1

001

dest

111 1011

cv.sra.b rD, rs1, rs2

0 1001

0

0

src2

src1

101

dest

111 1011

cv.sra.sc.b rD, rs1, rs2

0 1001

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sra.sci.b rD, rs1, Imm6

0 1010

0

0

src2

src1

000

dest

111 1011

cv.sll.h rD, rs1, rs2

0 1010

0

0

src2

src1

100

dest

111 1011

cv.sll.sc.h rD, rs1, rs2

0 1010

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sll.sci.h rD, rs1, Imm6

0 1010

0

0

src2

src1

001

dest

111 1011

cv.sll.b rD, rs1, rs2

0 1010

0

0

src2

src1

101

dest

111 1011

cv.sll.sc.b rD, rs1, rs2

0 1010

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sll.sci.b rD, rs1, Imm6

0 1011

0

0

src2

src1

000

dest

111 1011

cv.or.h rD, rs1, rs2

0 1011

0

0

src2

src1

100

dest

111 1011

cv.or.sc.h rD, rs1, rs2

0 1011

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.or.sci.h rD, rs1, Imm6

0 1011

0

0

src2

src1

001

dest

111 1011

cv.or.b rD, rs1, rs2

0 1011

0

0

src2

src1

101

dest

111 1011

cv.or.sc.b rD, rs1, rs2

0 1011

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.or.sci.b rD, rs1, Imm6

0 1100

0

0

src2

src1

000

dest

111 1011

cv.xor.h rD, rs1, rs2

0 1100

0

0

src2

src1

100

dest

111 1011

cv.xor.sc.h rD, rs1, rs2

0 1100

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.xor.sci.h rD, rs1, Imm6

0 1100

0

0

src2

src1

001

dest

111 1011

cv.xor.b rD, rs1, rs2

0 1100

0

0

src2

src1

101

dest

111 1011

cv.xor.sc.b rD, rs1, rs2

0 1100

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.xor.sci.b rD, rs1, Imm6

0 1101

0

0

src2

src1

000

dest

111 1011

cv.and.h rD, rs1, rs2

0 1101

0

0

src2

src1

100

dest

111 1011

cv.and.sc.h rD, rs1, rs2

0 1101

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.and.sci.h rD, rs1, Imm6

0 1101

0

0

src2

src1

001

dest

111 1011

cv.and.b rD, rs1, rs2

0 1101

0

0

src2

src1

101

dest

111 1011

cv.and.sc.b rD, rs1, rs2

0 1101

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.and.sci.b rD, rs1, Imm6

0 1110

0

0

0

src1

000

dest

111 1011

cv.abs.h rD, rs1

0 1110

0

0

0

src1

001

dest

111 1011

cv.abs.b rD, rs1

1 0111

0

Imm6[0|5:1]

src1

000

dest

111 1011

cv.extract.h rD, rs1, Imm6

1 0111

0

Imm6[0|5:1]

src1

001

dest

111 1011

cv.extract.b rD, rs1, Imm6

1 0111

0

Imm6[0|5:1]

src1

010

dest

111 1011

cv.extractu.h rD, rs1, Imm6

1 0111

0

Imm6[0|5:1]

src1

011

dest

111 1011

cv.extractu.b rD, rs1, Imm6

1 0111

0

Imm6[0|5:1]

src1

100

dest

111 1011

cv.insert.h rD, rs1, Imm6

1 0111

0

Imm6[0|5:1]

src1

101

dest

111 1011

cv.insert.b rD, rs1, Imm6

1 0000

0

0

src2

src1

000

dest

111 1011

cv.dotup.h rD, rs1, rs2

1 0000

0

0

src2

src1

100

dest

111 1011

cv.dotup.sc.h rD, rs1, rs2

1 0000

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.dotup.sci.h rD, rs1, Imm6

1 0000

0

0

src2

src1

001

dest

111 1011

cv.dotup.b rD, rs1, rs2

1 0000

0

0

src2

src1

101

dest

111 1011

cv.dotup.sc.b rD, rs1, rs2

1 0000

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.dotup.sci.b rD, rs1, Imm6

1 0001

0

0

src2

src1

000

dest

111 1011

cv.dotusp.h rD, rs1, rs2

1 0001

0

0

src2

src1

100

dest

111 1011

cv.dotusp.sc.h rD, rs1, rs2

1 0001

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.dotusp.sci.h rD, rs1, Imm6

1 0001

0

0

src2

src1

001

dest

111 1011

cv.dotusp.b rD, rs1, rs2

1 0001

0

0

src2

src1

101

dest

111 1011

cv.dotusp.sc.b rD, rs1, rs2

1 0001

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.dotusp.sci.b rD, rs1, Imm6

1 0010

0

0

src2

src1

000

dest

111 1011

cv.dotsp.h rD, rs1, rs2

1 0010

0

0

src2

src1

100

dest

111 1011

cv.dotsp.sc.h rD, rs1, rs2

1 0010

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.dotsp.sci.h rD, rs1, Imm6

1 0010

0

0

src2

src1

001

dest

111 1011

cv.dotsp.b rD, rs1, rs2

1 0010

0

0

src2

src1

101

dest

111 1011

cv.dotsp.sc.b rD, rs1, rs2

1 0010

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.dotsp.sci.b rD, rs1, Imm6

1 0011

0

0

src2

src1

000

dest

111 1011

cv.sdotup.h rD, rs1, rs2

1 0011

0

0

src2

src1

100

dest

111 1011

cv.sdotup.sc.h rD, rs1, rs2

1 0011

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sdotup.sci.h rD, rs1, Imm6

1 0011

0

0

src2

src1

001

dest

111 1011

cv.sdotup.b rD, rs1, rs2

1 0011

0

0

src2

src1

101

dest

111 1011

cv.sdotup.sc.b rD, rs1, rs2

1 0011

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sdotup.sci.b rD, rs1, Imm6

1 0100

0

0

src2

src1

000

dest

111 1011

cv.sdotusp.h rD, rs1, rs2

1 0100

0

0

src2

src1

100

dest

111 1011

cv.sdotusp.sc.h rD, rs1, rs2

1 0100

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sdotusp.sci.h rD, rs1, Imm6

1 0100

0

0

src2

src1

001

dest

111 1011

cv.sdotusp.b rD, rs1, rs2

1 0100

0

0

src2

src1

101

dest

111 1011

cv.sdotusp.sc.b rD, rs1, rs2

1 0100

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sdotusp.sci.b rD, rs1, Imm6

1 0101

0

0

src2

src1

000

dest

111 1011

cv.sdotsp.h rD, rs1, rs2

1 0101

0

0

src2

src1

100

dest

111 1011

cv.sdotsp.sc.h rD, rs1, rs2

1 0101

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.sdotsp.sci.h rD, rs1, Imm6

1 0101

0

0

src2

src1

001

dest

111 1011

cv.sdotsp.b rD, rs1, rs2

1 0101

0

0

src2

src1

101

dest

111 1011

cv.sdotsp.sc.b rD, rs1, rs2

1 0101

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.sdotsp.sci.b rD, rs1, Imm6

1 1000

0

0

src2

src1

000

dest

111 1011

cv.shuffle.h rD, rs1, rs2

1 1000

0

Imm6[0|5:1]

src1

110

dest

111 1011

cv.shuffle.sci.h rD, rs1, Imm6

1 1000

0

0

src2

src1

001

dest

111 1011

cv.shuffle.b rD, rs1, rs2

1 1000

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.shuffleI0.sci.b rD, rs1, Imm6

1 1001

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.shuffleI1.sci.b rD, rs1, Imm6

1 1010

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.shuffleI2.sci.b rD, rs1, Imm6

1 1011

0

Imm6[0|5:1]

src1

111

dest

111 1011

cv.shuffleI3.sci.b rD, rs1, Imm6

1 1100

0

0

src2

src1

000

dest

111 1011

cv.shuffle2.h rD, rs1, rs2

1 1100

0

0

src2

src1

001

dest

111 1011

cv.shuffle2.b rD, rs1, rs2

1 1110

0

0

src2

src1

000

dest

111 1011

cv.pack rD, rs1, rs2

1 1110

0

1

src2

src1

000

dest

111 1011

cv.pack.h rD, rs1, rs2

1 1111

0

1

src2

src1

001

dest

111 1011

cv.packhi.b rD, rs1, rs2

1 1111

0

0

src2

src1

001

dest

111 1011

cv.packlo.b rD, rs1, rs2

+
+
+
+

SIMD Comparison operations

+

SIMD comparisons are done on individual bytes (.b) or half-words +(.h), depending on the chosen mode. If the comparison result is true, +all bits in the corresponding byte/half-word are set to 1. If the +comparison result is false, all bits are set to 0.

+

The default mode (no .sc, .sci) compares the lowest byte/half-word of +the first operand with the lowest byte/half-word of the second operand, +and so on. If the mode is set to scalar replication (.sc), always the +lowest byte/half-word of the second operand is used for comparisons, +thus instead of a vector comparison a scalar comparison is performed. In +the immediate scalar replication mode (.sci), the immediate given to the +instruction is used for the comparison.

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 55 SIMD Comparison operations

Mnemonic

Description

cv.cmpeq[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] == op2 ? ‘1 : ‘0

cv.cmpne[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] != op2 ? ‘1 : ‘0

cv.cmpgt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] > op2 ? ‘1 : ‘0

cv.cmpge[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] >=op2 ? ‘1 : ‘0

cv.cmplt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] < op2 ? ‘1 : ‘0

cv.cmple[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] <= op2 ? ‘1 : ‘0

cv.cmpgtu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] > op2 ? ‘1 : ‘0

+

Note: Unsigned comparison.

+

cv.cmpgeu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] >= op2 ? ‘1 : ‘0

+

Note: Unsigned comparison.

+

cv.cmpltu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] < op2 ? ‘1 : ‘0

+

Note: Unsigned comparison.

+

cv.cmpleu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]

rD[i] = rs1[i] <= op2 ? ‘1 : ‘0

+

Note: Unsigned comparison.

+
+
+
+

SIMD Comparison Encoding

+ + +++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 56 SIMD Comparison encoding

31 : 27

26

25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct5

F

rs2

rs1

funct3

rD

opcode

0 0000

1

0

src2

src1

000

dest

111 1011

cv.cmpeq.h rD, rs1, rs2

0 0000

1

0

src2

src1

100

dest

111 1011

cv.cmpeq.sc.h rD, rs1, rs2

0 0000

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpeq.sci.h rD, rs1, Imm6

0 0000

1

0

src2

src1

001

dest

111 1011

cv.cmpeq.b rD, rs1, rs2

0 0000

1

0

src2

src1

101

dest

111 1011

cv.cmpeq.sc.b rD, rs1, rs2

0 0000

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpeq.sci.b rD, rs1, Imm6

0 0001

1

0

src2

src1

000

dest

111 1011

cv.cmpne.h rD, rs1, rs2

0 0001

1

0

src2

src1

100

dest

111 1011

cv.cmpne.sc.h rD, rs1, rs2

0 0001

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpne.sci.h rD, rs1, Imm6

0 0001

1

0

src2

src1

001

dest

111 1011

cv.cmpne.b rD, rs1, rs2

0 0001

1

0

src2

src1

101

dest

111 1011

cv.cmpne.sc.b rD, rs1, rs2

0 0001

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpne.sci.b rD, rs1, Imm6

0 0010

1

0

src2

src1

000

dest

111 1011

cv.cmpgt.h rD, rs1, rs2

0 0010

1

0

src2

src1

100

dest

111 1011

cv.cmpgt.sc.h rD, rs1, rs2

0 0010

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpgt.sci.h rD, rs1, Imm6

0 0010

1

0

src2

src1

001

dest

111 1011

cv.cmpgt.b rD, rs1, rs2

0 0010

1

0

src2

src1

101

dest

111 1011

cv.cmpgt.sc.b rD, rs1, rs2

0 0010

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpgt.sci.b rD, rs1, Imm6

0 0011

1

0

src2

src1

000

dest

111 1011

cv.cmpge.h rD, rs1, rs2

0 0011

1

0

src2

src1

100

dest

111 1011

cv.cmpge.sc.h rD, rs1, rs2

0 0011

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpge.sci.h rD, rs1, Imm6

0 0011

1

0

src2

src1

001

dest

111 1011

cv.cmpge.b rD, rs1, rs2

0 0011

1

0

src2

src1

101

dest

111 1011

cv.cmpge.sc.b rD, rs1, rs2

0 0011

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpge.sci.b rD, rs1, Imm6

0 0100

1

0

src2

src1

000

dest

111 1011

cv.cmplt.h rD, rs1, rs2

0 0100

1

0

src2

src1

100

dest

111 1011

cv.cmplt.sc.h rD, rs1, rs2

0 0100

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmplt.sci.h rD, rs1, Imm6

0 0100

1

0

src2

src1

001

dest

111 1011

cv.cmplt.b rD, rs1, rs2

0 0100

1

0

src2

src1

101

dest

111 1011

cv.cmplt.sc.b rD, rs1, rs2

0 0100

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmplt.sci.b rD, rs1, Imm6

0 0101

1

0

src2

src1

000

dest

111 1011

cv.cmple.h rD, rs1, rs2

0 0101

1

0

src2

src1

100

dest

111 1011

cv.cmple.sc.h rD, rs1, rs2

0 0101

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmple.sci.h rD, rs1, Imm6

0 0101

1

0

src2

src1

001

dest

111 1011

cv.cmple.b rD, rs1, rs2

0 0101

1

0

src2

src1

101

dest

111 1011

cv.cmple.sc.b rD, rs1, rs2

0 0101

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmple.sci.b rD, rs1, Imm6

0 0110

1

0

src2

src1

000

dest

111 1011

cv.cmpgtu.h rD, rs1, rs2

0 0110

1

0

src2

src1

100

dest

111 1011

cv.cmpgtu.sc.h rD, rs1, rs2

0 0110

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpgtu.sci.h rD, rs1, Imm6

0 0110

1

0

src2

src1

001

dest

111 1011

cv.cmpgtu.b rD, rs1, rs2

0 0110

1

0

src2

src1

101

dest

111 1011

cv.cmpgtu.sc.b rD, rs1, rs2

0 0110

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpgtu.sci.b rD, rs1, Imm6

0 0111

1

0

src2

src1

000

dest

111 1011

cv.cmpgeu.h rD, rs1, rs2

0 0111

1

0

src2

src1

100

dest

111 1011

cv.cmpgeu.sc.h rD, rs1, rs2

0 0111

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpgeu.sci.h rD, rs1, Imm6

0 0111

1

0

src2

src1

001

dest

111 1011

cv.cmpgeu.b rD, rs1, rs2

0 0111

1

0

src2

src1

101

dest

111 1011

cv.cmpgeu.sc.b rD, rs1, rs2

0 0111

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpgeu.sci.b rD, rs1, Imm6

0 1000

1

0

src2

src1

000

dest

111 1011

cv.cmpltu.h rD, rs1, rs2

0 1000

1

0

src2

src1

100

dest

111 1011

cv.cmpltu.sc.h rD, rs1, rs2

0 1000

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpltu.sci.h rD, rs1, Imm6

0 1000

1

0

src2

src1

001

dest

111 1011

cv.cmpltu.b rD, rs1, rs2

0 1000

1

0

src2

src1

101

dest

111 1011

cv.cmpltu.sc.b rD, rs1, rs2

0 1000

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpltu.sci.b rD, rs1, Imm6

0 1001

1

0

src2

src1

000

dest

111 1011

cv.cmpleu.h rD, rs1, rs2

0 1001

1

0

src2

src1

100

dest

111 1011

cv.cmpleu.sc.h rD, rs1, rs2

0 1001

1

Imm6[0|5:1]

src1

110

dest

111 1011

cv.cmpleu.sci.h rD, rs1, Imm6

0 1001

1

0

src2

src1

001

dest

111 1011

cv.cmpleu.b rD, rs1, rs2

0 1001

1

0

src2

src1

101

dest

111 1011

cv.cmpleu.sc.b rD, rs1, rs2

0 1001

1

Imm6[0|5:1]

src1

111

dest

111 1011

cv.cmpleu.sci.b rD, rs1, Imm6

+
+
+

SIMD Complex-number operations

+

SIMD Complex-number operations are extra instructions +that uses the packed-SIMD extentions to represent Complex-numbers. +These extentions use only the half-words mode and only operand in registers. +A number C = {Re, Im} is represented as a vector of two 16-Bits signed numbers. +C[0] is the real part [15:0], C[1] is the +imaginary part [31:16]. +Such operations are subtraction of 2 complexes with post rotation by -j, the complex and conjugate, +complex multiplications and complex additions/substractions. +The complex multiplications are performed in two separate instructions, one to compute the real part, +and one to compute the imaginary part.

+

As for all the other SIMD instructions, no flags are raised and CSR register are unmodified. +No carry, overflow is generated. Instructions are rounded up as the mask & 0xFFFF explicits.

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 57 SIMD Complex-number operations

Mnemonic

Description

cv.cplxmul.r{/,.div2,.div4,.div8}

rD[1] = rD[1]

+

rD[0] = (rs1[0]*rs2[0] - rs1[1]*rs2[1]) >> {15,16,17,18}

+

Note: Arithmetic shift right.

+

cv.cplxmul.i{/,.div2,.div4,.div8}

rD[1] = (rs1[0]*rs2[1] + rs1[1]*rs2[0]) >> {15,16,17,18}

+

rD[0] = rD[0]

+

Note: Arithmetic shift right.

+

cv.cplxconj

rD[1] = -rs1[1]

+

rD[0] = rs1[0]

+

cv.subrotmj{/,.div2,.div4,.div8}

rD[1] = ((rs2[0] - rs1[0]) & 0xFFFF) >> {0,1,2,3}

+

rD[0] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {0,1,2,3}

+

Note: Arithmetic shift right.

+

cv.add{.div2,.div4,.div8}

rD[1] = ((rs1[1] + rs2[1]) & 0xFFFF) >> {1,2,3}

+

rD[0] = ((rs1[0] + rs2[0]) & 0xFFFF) >> {1,2,3}

+

Note: Arithmetic shift right.

+

cv.sub{.div2,.div4,.div8}

rD[1] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {1,2,3}

+

rD[0] = ((rs1[0] - rs2[0]) & 0xFFFF) >> {1,2,3}

+

Note: Arithmetic shift right.

+
+
+
+

SIMD Complex-numbers Encoding

+ + +++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 58 SIMD ALU encoding

31 : 27

26

25

24 : 20

19 : 15

14 : 12

11 : 7

6 : 0

funct5

F

rs2

rs1

funct3

rD

opcode

0 1010

1

0

src2

src1

000

dest

111 1011

cv.cplxmul.r rD, rs1, rs2

0 1010

1

0

src2

src1

010

dest

111 1011

cv.cplxmul.r.div2 rD, rs1, rs2

0 1010

1

0

src2

src1

100

dest

111 1011

cv.cplxmul.r.div4 rD, rs1, rs2

0 1010

1

0

src2

src1

110

dest

111 1011

cv.cplxmul.r.div8 rD, rs1, rs2

0 1010

1

1

src2

src1

000

dest

111 1011

cv.cplxmul.i rD, rs1, rs2

0 1010

1

1

src2

src1

010

dest

111 1011

cv.cplxmul.i.div2 rD, rs1, rs2

0 1010

1

1

src2

src1

100

dest

111 1011

cv.cplxmul.i.div4 rD, rs1, rs2

0 1010

1

1

src2

src1

110

dest

111 1011

cv.cplxmul.i.div8 rD, rs1, rs2

0 1011

1

0

00000

src1

000

dest

111 1011

cv.cplxconj rD, rs1

0 1100

1

0

src2

src1

000

dest

111 1011

cv.subrotmj rD, rs1, rs2

0 1100

1

0

src2

src1

010

dest

111 1011

cv.subrotmj.div2 rD, rs1, rs2

0 1100

1

0

src2

src1

100

dest

111 1011

cv.subrotmj.div4 rD, rs1, rs2

0 1100

1

0

src2

src1

110

dest

111 1011

cv.subrotmj.div8 rD, rs1, rs2

0 1101

1

0

src2

src1

010

dest

111 1011

cv.add.div2 rD, rs1, rs2

0 1101

1

0

src2

src1

100

dest

111 1011

cv.add.div4 rD, rs1, rs2

0 1101

1

0

src2

src1

110

dest

111 1011

cv.add.div8 rD, rs1, rs2

0 1110

1

0

src2

src1

010

dest

111 1011

cv.sub.div2 rD, rs1, rs2

0 1110

1

0

src2

src1

100

dest

111 1011

cv.sub.div4 rD, rs1, rs2

0 1110

1

0

src2

src1

110

dest

111 1011

cv.sub.div8 rD, rs1, rs2

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/integration.html b/docs/html/integration.html new file mode 100644 index 000000000..50039fdbe --- /dev/null +++ b/docs/html/integration.html @@ -0,0 +1,386 @@ + + + + + + + Core Integration — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Core Integration

+

The main module is named cv32e40p_top and can be found in cv32e40p_top.sv. +Below, the instantiation template is given and the parameters and interfaces are described.

+
+

Note

+

cv32e40p_top instantiates former cv32e40p_core and a wrapped fpnew_top. +It is highly suggested to use cv32e40p_top in place of cv32e40p_core as +it allows to easily enable/disable FPU parameter with no interface change. +As mentioned in Non-backward compatibility, v2.0.0 cv32e40p_core has slight +modifications that makes it not backward compatible with v1.0.0 one in some cases. +It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, +there is still backward compatibility as all parameters default value are set to v1 values.

+
+
+

Instantiation Template

+
cv32e40p_top #(
+    .FPU                      ( 0 ),
+    .FPU_ADDMUL_LAT           ( 0 ),
+    .FPU_OTHERS_LAT           ( 0 ),
+    .ZFINX                    ( 0 ),
+    .COREV_PULP               ( 0 ),
+    .COREV_CLUSTER            ( 0 ),
+    .NUM_MHPMCOUNTERS         ( 1 )
+) u_core (
+    // Clock and reset
+    .rst_ni                   (),
+    .clk_i                    (),
+    .scan_cg_en_i             (),
+
+    // Special control signals
+    .fetch_enable_i           (),
+    .pulp_clock_en_i          (),
+    .core_sleep_o             (),
+
+    // Configuration
+    .boot_addr_i              (),
+    .mtvec_addr_i             (),
+    .dm_halt_addr_i           (),
+    .dm_exception_addr_i      (),
+    .hart_id_i                (),
+
+    // Instruction memory interface
+    .instr_addr_o             (),
+    .instr_req_o              (),
+    .instr_gnt_i              (),
+    .instr_rvalid_i           (),
+    .instr_rdata_i            (),
+
+    // Data memory interface
+    .data_addr_o              (),
+    .data_req_o               (),
+    .data_gnt_i               (),
+    .data_we_o                (),
+    .data_be_o                (),
+    .data_wdata_o             (),
+    .data_rvalid_i            (),
+    .data_rdata_i             (),
+
+     // Interrupt interface
+    .irq_i                    (),
+    .irq_ack_o                (),
+    .irq_id_o                 (),
+
+    // Debug interface
+    .debug_req_i              (),
+    .debug_havereset_o        (),
+    .debug_running_o          (),
+    .debug_halted_o           ()
+);
+
+
+
+
+

Parameters

+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3 Parameters

Name

Type/Range

Default

Description

FPU

bit

0

Enable Floating Point Unit (FPU) support, see Floating Point Unit (FPU)

FPU_ADDMUL_LAT

int

0

Number of pipeline registers for Floating-Point +addition and multiplication instructions, see Floating Point Unit (FPU)

FPU_OTHERS_LAT

int

0

Number of pipeline registers for Floating-Point +comparison, conversion and classify instructions, see Floating Point Unit (FPU)

ZFINX

bit

0

Enable Floating Point instructions to use the General Purpose +register file instead of requiring a dedicated Floating Point +register file, see Floating Point Unit (FPU). Only allowed to be set to 1 +if FPU = 1

COREV_PULP

bit

0

Enable all of the custom PULP ISA extensions (except cv.elw) +(see CORE-V Instruction Set Custom Extension) and all custom CSRs +(see Control and Status Registers).

+

Examples of PULP ISA +extensions are post-incrementing load and stores +(see Post-Increment Load & Store Instructions and Register-Register Load & Store Instructions) and hardware loops +(see Hardware Loops).

+

COREV_CLUSTER

bit

0

Enable PULP Cluster support (cv.elw), see PULP Cluster Extension

NUM_MHPMCOUNTERS

int (0..29)

1

Number of MHPMCOUNTER performance counters, see +Performance Counters

+
+
+

Interfaces

+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4 Interfaces

Signal

Width

Dir

Description

rst_ni

1

in

Active-low asynchronous reset

clk_i

1

in

Clock signal

scan_cg_en_i

1

in

Scan clock gate enable. Design for test +(DfT) related signal. Can be used during +scan testing operation to force +instantiated clock gate(s) to be enabled. +This signal should be 0 during normal / +functional operation.

fetch_enable_i

1

in

Enable the instruction fetch of CV32E40P. +The first instruction fetch after reset +de-assertion will not happen as long as +this signal is 0. fetch_enable_i needs +to be set to 1 for at least one cycle +while not in reset to enable fetching. +Once fetching has been enabled the value +fetch_enable_i is ignored.

core_sleep_o

1

out

Core is sleeping, see Sleep Unit.

pulp_clock_en_i

1

in

PULP clock enable (only used when +COREV_CLUSTER = 1, tie to 0 otherwise), +see Sleep Unit

boot_addr_i

32

in

Boot address. First program counter after +reset = boot_addr_i. Must be half-word +aligned. Do not change after enabling core +via fetch_enable_i

mtvec_addr_i

32

in

mtvec address. Initial value for the +address part of Machine Trap-Vector Base Address (mtvec). +Do not change after enabling core +via fetch_enable_i

dm_halt_addr_i

32

in

Address to jump to when entering Debug +Mode, see Debug & Trigger. Must be +word-aligned. Do not change after enabling +core via fetch_enable_i

dm_exception_addr_i

32

in

Address to jump to when an exception +occurs when executing code during Debug +Mode, see Debug & Trigger. Must be +word-aligned. Do not change after enabling +core via fetch_enable_i

hart_id_i

32

in

Hart ID, usually static, can be read from +Hardware Thread ID (mhartid) and User Hardware Thread ID (uhartid) +CSRs

instr_*

Instruction fetch interface, see Instruction Fetch

data_*

Load-store unit interface, see Load-Store-Unit (LSU)

irq_*

Interrupt inputs, see Exceptions and Interrupts

debug_*

Debug interface, see Debug & Trigger

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/intro.html b/docs/html/intro.html new file mode 100644 index 000000000..fd728cde1 --- /dev/null +++ b/docs/html/intro.html @@ -0,0 +1,408 @@ + + + + + + + Introduction — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Introduction

+

CV32E40P is a 4-stage in-order 32-bit RISC-V +processor core. The ISA of CV32E40P +has been extended to support multiple additional instructions including +hardware loops, post-increment load and store instructions, +additional ALU instructions and SIMD instructions that are not part of the standard RISC-V +ISA. Figure 1 shows a block diagram of the top level with the core and the FPU.

+
+ +
+

Figure 1 Block Diagram of CV32E40P RISC-V Core

+
+
+
+

License

+

Copyright 2023 OpenHW Group.

+

Copyright 2018 ETH Zurich and University of Bologna.

+

Copyright and related rights are licensed under the Solderpad Hardware +License, Version 0.51 (the “License”); you may not use this file except +in compliance with the License. You may obtain a copy of the License at +http://solderpad.org/licenses/SHL-0.51. Unless required by applicable +law or agreed to in writing, software, hardware and materials +distributed under this License is distributed on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.

+
+
+

Bus Interfaces

+

The Instruction Fetch and Load/Store data bus interfaces are compliant to the OBI (Open Bus Interface) protocol. +See OBI-v1.2.pdf for details about the protocol. +Additional information can be found in the Instruction Fetch and Load-Store-Unit (LSU) chapters of this document.

+
+
+

Standards Compliance

+

CV32E40P is a standards-compliant 32-bit RISC-V processor. +It follows these specifications:

+ +

Many features in the RISC-V specification are optional, and CV32E40P can be parameterized to enable or disable some of them.

+

CV32E40P supports the following base integer instruction set.

+
    +
  • The RV32I Base Integer Instruction Set, version 2.1

  • +
+

In addition, the following standard instruction set extensions are available.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1 CV32E40P Standard Instruction Set Extensions

Standard Extension

Version

Configurability

C: Standard Extension for Compressed Instructions

2.0

always enabled

M: Standard Extension for Integer Multiplication and Division

2.0

always enabled

Zicntr: Performance Counters

2.0

always enabled

Zicsr: Control and Status Register Instructions

2.0

always enabled

Zifencei: Instruction-Fetch Fence

2.0

always enabled

F: Single-Precision Floating-Point using F registers

2.2

optionally enabled with the FPU parameter

Zfinx: Single-Precision Floating-Point using X registers

1.0

optionally enabled with the ZFINX parameter (also requires the FPU parameter)

+

The following custom instruction set extensions are available.

+ + +++++ + + + + + + + + + + + + + + + + +
Table 2 CV32E40P Custom Instruction Set Extensions

Custom Extension

Version

Configurability

Xcv: CORE-V PULP ISA Extensions

1.0

optionally enabled with the COREV_PULP parameter

Xcvelw: CORE-V PULP Cluster ISA Extension

1.0

optionally enabled with the COREV_CLUSTER parameter

+

Most content of the RISC-V privileged specification is optional. +CV32E40P currently supports the following features according to the RISC-V Privileged Specification, version 1.11.

+ +
+
+

Synthesis guidelines

+

The CV32E40P core is fully synthesizable. +It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well.

+

The top level module is called cv32e40p_top and includes both the core and the FPU. +All the core files are in rtl and rtl/include folders (all synthesizable) +while all the FPU files are in rtl/vendor/pulp_platform_common_cells, rtl/vendor/pulp_platform_fpnew and rtl/vendor/pulp_platform_fpu_div_sqrt. +.. while all the FPU files are in rtl/vendor/pulp_platform_common_cells, rtl/vendor/pulp_platform_fpnew and rtl/vendor/opene906. +cv32e40p_fpu_manifest.flist is listing all the required files.

+

The user must provide a clock-gating module that instantiates the functionally equivalent clock-gating cell of the target technology. +This file must have the same interface and module name as the one provided for simulation-only purposes at bhv/cv32e40p_sim_clock_gate.sv (see Clock Gating Cell).

+

The constraints/cv32e40p_core.sdc file provides an example of synthesis constraints.

+
+

ASIC Synthesis

+

ASIC synthesis is supported for CV32E40P. The whole design is completely +synchronous and uses positive-edge triggered flip-flops. The +core occupies an area of about XX kGE. +With the FPU, the area increases to about XX kGE (XX kGE +FPU, XX kGE additional register file). A technology specific implementation +of a clock gating cell as described in Clock Gating Cell needs to +be provided.

+
+
+

FPGA Synthesis

+

FPGA synthesis is only supported for CV32E40P. +The user needs to provide a technology specific implementation of a clock gating cell as described +in Clock Gating Cell.

+
+
+

Synthesizing with the FPU

+

By default the pipeline of the FPU is purely combinatorial (FPU_*_LAT = 0). In this case FPU instructions latency is the same than simple ALU operations (except FP multicycle DIV/SQRT ones). +But as FPU operations are much more complex than ALU ones, maximum achievable frequency is much lower than ALU one when FPU is enabled. +If this can be fine for low frequency systems, it is possible to indicate how many pipeline registers are instantiated in the FPU to reach higher target frequency. +This is done with FPU_*_LAT CV32E40P parameters setting to perfectly fit target frequency. +It should be noted that any additional pipeline register is impacting FPU instructions latency and could cause performances degradation depending of applications using Floating-Point operations. +Those pipeline registers are all added at the end of the FPU pipeline with all operators before them. Optimal frequency is only achievable using automatic retiming commands in implementation tools. +This can be achieved with the following command for Synopsys Design Compiler: +“set_optimize_registers true -designs [get_object_name [get_designs “fpnew_wrapper”]]”.

+
+
+
+

Contents

+
+
+
+
+
+

History

+

CV32E40P started its life as a fork of the OR10N CPU core based on the OpenRISC ISA. Then, under the name of RI5CY, it became a RISC-V core (2016), +and it has been maintained by the PULP platform <https://pulp-platform.org> team until February 2020, when it has been contributed to OpenHW Group https://www.openhwgroup.org.

+

As RI5CY has been used in several projects, a list of all the changes made by OpenHW Group since February 2020 follows:

+
+

Memory-Protocol

+

The Instruction and Data memory interfaces are now compliant with the OBI protocol (see OBI-v1.2.pdf). +Such memory interface is slightly different from the one used by RI5CY as: the grant signal can now be kept high by the bus even without the core raising a request; and the request signal does not depend anymore on the rvalid signal (no combinatorial dependency). The OBI is easier to be interfaced to the AMBA AXI and AHB protocols and improves timing as it removes rvalid->req dependency. Also, the protocol forces the address stability. Thus, the core can not retract memory requests once issued, nor can it change the issued address (as was the case for the RI5CY instruction memory interface).

+
+
+

RV32F Extensions

+

Previously, RI5CY could select with a parameter whether the FPU was instantiated inside the EX stage or via the APU interface. Now in CV32E40P, the FPU is not instantiated in the core EX stage anymore. +A new file called cv32e40p_top.sv is instantiating the core together with the FPU and APU interface is not visible on I/Os. +This is this new top level which has been used for Verification and Implementation.

+
+
+

RV32A Extensions, Security and Memory Protection

+

CV32E40P core does not support the RV32A (atomic) extensions, the U-mode, and the PMP anymore. +Most of the previous RTL descriptions of these features have been kept but not maintained. The RTL code has been partially kept to allow previous users of these features to develop their own by reusing previously developed RI5CY modules.

+
+
+

CSR Address Re-Mapping

+

RI5CY used to have custom performance counters 32b wide (not compliant with RISC-V) in the CSR address space {0x7A0, 0x7A1, 0x780-0x79F}. +CV32E40P is now fully compliant with the RISC-V spec on performance counters side. +And the custom PULP HWLoop CSRs have been moved from the 0x7C* to RISC-V user custom read-only 0xCC0-0xCFF address space.

+
+
+

Interrupts

+

RI5CY used to have a req plus a 5 bits ID interrupt interface, supporting up to 32 interrupt requests (only one active at a time), with the priority defined outside in an interrupt controller. CV32E40P is now compliant with the CLINT RISC-V spec, extended with 16 custom interrupts lines called fast, for a total of 19 interrupt lines. They can be all active simultaneously, and priority and per-request interrupt enable bit is controlled by the core CLINT definition.

+
+
+

PULP HWLoop Spec

+

RI5CY supported two nested HWLoops. Every loop had a minimum of two instructions. The start and end of the loop addresses +could be misaligned, and the instructions in the loop body could be of any kind. CV32E40P has a more restricted spec for the +HWLoop (see CORE-V Hardware Loop Extensions).

+
+
+

Compliancy, bug fixing, code clean-up, and documentation

+

The CV32E40P has been verified. It is fully compliant with RISC-V (RI5CY was partially compliant). Many bugs have been fixed, and the RTL code cleaned-up. The documentation has been formatted with reStructuredText and has been developed following at industrial quality level.

+
+
+
+

References

+
    +
  1. Gautschi, Michael, et al. “Near-Threshold RISC-V Core With DSP Extensions for Scalable IoT Endpoint Devices.” in IEEE Transactions on Very Large Scale Integration (VLSI) Systems, vol. 25, no. 10, pp. 2700-2713, Oct. 2017

  2. +
  3. Schiavone, Pasquale Davide, et al. “Slow and steady wins the race? A comparison of ultra-low-power RISC-V cores for Internet-of-Things applications.” 27th International Symposium on Power and Timing Modeling, Optimization and Simulation (PATMOS 2017)

  4. +
+
+
+

Contributors

+
+
Andreas Traber (atraber@iis.ee.ethz.ch)
+
Michael Gautschi (gautschi@iis.ee.ethz.ch)
+
Pasquale Davide Schiavone (pschiavo@iis.ee.ethz.ch)
+
+
+ +
Paul Zavalney (paul.zavalney@silabs.com)
+
+
+
Pascal Gouédo (pascal.gouedo@dolphin.fr)
+
+
+
Micrel Lab and Multitherman Lab
+
University of Bologna, Italy
+
+
+
Integrated Systems Lab
+
ETH Zürich, Switzerland
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/load_store_unit.html b/docs/html/load_store_unit.html new file mode 100644 index 000000000..e40d89d59 --- /dev/null +++ b/docs/html/load_store_unit.html @@ -0,0 +1,259 @@ + + + + + + + Load-Store-Unit (LSU) — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Load-Store-Unit (LSU)

+

The Load-Store Unit (LSU) of the core takes care of accessing the data memory. Load and +stores on words (32 bit), half words (16 bit) and bytes (8 bit) are +supported. The CV32E40P data interface can cause up to 2 outstanding +transactions and there is no FIFO to allow more outstanding requests.

+

Table 10 describes the signals that are used by the LSU.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 10 LSU interface signals

Signal

Direction

Description

data_addr_o[31:0]

output

Address

data_req_o

output

Request valid, will stay high until data_gnt_i is high for one cycle

data_gnt_i

input

The other side accepted the request. data_addr_o may change in the next cycle.

data_we_o

output

Write Enable, high for writes, low for reads. Sent together with data_req_o

data_be_o[3:0]

output

Byte Enable. Is set for the bytes to write/read, sent together with data_req_o

data_wdata_o[31:0]

output

Data to be written to memory, sent together with data_req_o

data_rvalid_i

input

data_rvalid_i will be high for exactly one cycle to signal the end of the response phase of for both read and write +transactions. For a read transaction data_rdata_i holds valid data when data_rvalid_i is high.

data_rdata_i[31:0]

input

Data read from memory

+
+

Misaligned Accesses

+

The LSU never raises address-misaligned exceptions. For loads and stores where the effective address is not naturally aligned to the referenced +datatype (i.e., on a four-byte boundary for word accesses, and a two-byte boundary for halfword accesses) the load/store is performed as two +bus transactions in case that the data item crosses a word boundary. A single load/store instruction is therefore performed as two bus +transactions for the following scenarios:

+
    +
  • Load/store of a word for a non-word-aligned address

  • +
  • Load/store of a halfword crossing a word address boundary

  • +
+

In both cases the transfer corresponding to the lowest address is performed first. All other scenarios can be handled with a single bus transaction.

+
+
+

Protocol

+

The CV32E40P data interface does not implement the following optional OBI signals: auser, wuser, aid, rready, err, ruser, rid. +These signals can be thought of as being tied off as specified in the OBI specification.

+
+

Note

+

Transactions Ordering +As mentioned above, data interface can generate up to 2 outstanding transactions. +OBI specification states that links are always in-order from master point of view. So as the data interface does not generate transaction id (aid), +interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information.

+
+

The OBI protocol that is used by the LSU to communicate with a memory works +as follows.

+

The LSU provides a valid address on data_addr_o, control information +on data_we_o, data_be_o (as well as write data on data_wdata_o in +case of a store) and sets data_req_o high. The memory sets data_gnt_i +high as soon as it is ready to serve the request. This may happen at any +time, even before the request was sent. After a request has been granted +the address phase signals (data_addr_o, data_we_o, data_be_o and +data_wdata_o) may be changed in the next cycle by the LSU as the memory +is assumed to already have processed and stored that information. After +granting a request, the memory answers with a data_rvalid_i set high +if data_rdata_i is valid. This may happen one or more cycles after the +request has been granted. Note that data_rvalid_i must also be set high +to signal the end of the response phase for a write transaction (although +the data_rdata_i has no meaning in that case). When multiple granted requests +are outstanding, it is assumed that the memory requests will be kept in-order and +one data_rvalid_i will be signalled for each of them, in the order they were issued.

+

Figure 5, Figure 6, Figure 7 and +Figure 8 show example timing diagrams of the protocol.

+
+
+

Figure 5 Basic Memory Transaction

+
+
+
+
+

Figure 6 Back-to-back Memory Transactions

+
+
+
+
+

Figure 7 Slow Response Memory Transaction

+
+
+
+
+

Figure 8 Multiple Outstanding Memory Transactions

+
+
+
+
+

Post-Incrementing Load and Store Instructions

+

This section is only valid if COREV_PULP = 1

+

Post-incrementing load and store instructions perform a load/store +operation from/to the data memory while at the same time increasing the +base address by the specified offset. For the memory access, the base +address without offset is used.

+

Post-incrementing load and stores reduce the number of required +instructions to execute code with regular data access patterns, which +can typically be found in loops. These post-incrementing load/store +instructions allow the address increment to be embedded in the memory +access instructions and get rid of separate instructions to handle +pointers. Coupled with hardware loop extension, these instructions allow +to reduce the loop overhead significantly.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/objects.inv b/docs/html/objects.inv new file mode 100644 index 000000000..28c139e4e Binary files /dev/null and b/docs/html/objects.inv differ diff --git a/docs/html/perf_counters.html b/docs/html/perf_counters.html new file mode 100644 index 000000000..9fa11d509 --- /dev/null +++ b/docs/html/perf_counters.html @@ -0,0 +1,267 @@ + + + + + + + Performance Counters — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Performance Counters

+

CV32E40P implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware Performance Monitor, Section 3.1.11). +The performance counters are placed inside the Control and Status Registers (CSRs) and can be accessed with the CSRRW(I) and CSRRS/C(I) instructions.

+

CV32E40P implements the clock cycle counter mcycle(h), the retired instruction counter minstret(h), as well as the parameterizable number of event counters +mhpmcounter3(h) - mhpmcounter31(h) and the corresponding event selector CSRs mhpmevent3 - mhpmevent31, and the mcountinhibit CSR to individually enable/disable the counters. +mcycle(h) and minstret(h) are always available.

+

All counters are 64 bit wide.

+

The number of event counters is determined by the parameter NUM_MHPMCOUNTERS with a range from 0 to 29 (default value of 1).

+

Unimplemented counters always read 0.

+
+

Note

+

All performance counters are using the gated version of clk_i. The wfi instruction, the +cv.elw instruction, and pulp_clock_en_i impact the gating of clk_i as explained +in Sleep Unit and can therefore affect the counters.

+
+
+

Event Selector

+

The following events can be monitored using the performance counters of CV32E40P.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 17 Event Selector

Bit #

Event Name

Description

0

CYCLES

Number of cycles

1

INSTR

Number of instructions retired

2

LD_STALL

Number of load use hazards

3

JMP_STALL

Number of jump register hazards

4

IMISS

Cycles waiting for instruction fethces, +excluding jumps and branches

5

LD

Number of load instructions

6

ST

Number of store instructions

7

JUMP

Number of jumps (unconditional)

8

BRANCH

Number of branches (conditional)

9

BRANCH_TAKEN

Number of branches taken (conditional)

10

COMP_INSTR

Number of compressed instructions retired

11

PIPE_STALL

Cycles from stalled pipeline

12

APU_TYPE

Numbe of type conflicts on APU/FP

13

APU_CONT

Number of contentions on APU/FP

14

APU_DEP

Number of dependency stall on APU/FP

15

APU_WB

Number of write backs on APUB/FP

+

The event selector CSRs mhpmevent3 - mhpmevent31 define which of these events are counted by the event counters mhpmcounter3(h) - mhpmcounter31(h). +If a specific bit in an event selector CSR is set to 1, this means that events with this ID are being counted by the counter associated with that selector CSR. +If an event selector CSR is 0, this means that the corresponding counter is not counting any event.

+
+

Note

+

At most 1 bit should be set in an event selector. If multiple bits are set in an event selector, then the operation of the associated counter is undefined.

+
+
+
+

Controlling the counters from software

+

By default, all available counters are disabled after reset in order to provide the lowest power consumption.

+

They can be individually enabled/disabled by overwriting the corresponding bit in the mcountinhibit CSR at address 0x320 as described in the RISC-V Privileged Specification, +version 1.11 (see Machine Counter-Inhibit CSR, Section 3.1.13). +In particular, to enable/disable mcycle(h), bit 0 must be written. For minstret(h), it is bit 2. For event counter mhpmcounterX(h), it is bit X.

+

The lower 32 bits of all counters can be accessed through the base register, whereas the upper 32 bits are accessed through the h-register. +Reads of all these registers are non-destructive.

+
+
+

Parametrization at synthesis time

+

The mcycle(h) and minstret(h) counters are always available and 64 bit wide.

+

The number of available event counters mhpmcounterX(h) can be controlled via the NUM_MHPMCOUNTERS parameter. +By default NUM_MHPCOUNTERS set to 1.

+

An increment of 1 to the NUM_MHPCOUNTERS results in the addition of the following:

+
+
    +
  • 64 flops for mhpmcounterX

  • +
  • 15 flops for mhpmeventX

  • +
  • 1 flop for mcountinhibit[X]

  • +
  • Adder and event enablement logic

  • +
+
+
+
+

Time Registers (time(h))

+

The user mode time(h) registers are not implemented. Any access to these +registers will cause an illegal instruction trap. It is recommended that a software trap handler is +implemented to detect access of these CSRs and convert that into access of the +platform-defined mtime register (if implemented in the platform).

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/pipeline.html b/docs/html/pipeline.html new file mode 100644 index 000000000..59f9696d7 --- /dev/null +++ b/docs/html/pipeline.html @@ -0,0 +1,309 @@ + + + + + + + Pipeline Details — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Pipeline Details

+
+_images/CV32E40P_Pipeline.png +
+

Figure 2 CV32E40P Pipeline

+
+
+

CV32E40P has a 4-stage in-order completion pipeline, the 4 stages are:

+
+
Instruction Fetch (IF)

Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. This prefetech buffer is able to store 2 32-b data. The IF stage also pre-decodes RVC instructions into RV32I base instructions. See Instruction Fetch for details.

+
+
Instruction Decode (ID)

Decodes fetched instruction and performs required register file reads. Jumps are taken from the ID stage.

+
+
Execute (EX)

Executes the instructions. The EX stage contains the ALU, Multiplier and Divider. Branches (with their condition met) are taken from the EX stage. Multi-cycle instructions will stall this stage until they are complete. The ALU, Multiplier and Divider instructions write back their result to the register file from the EX stage. The address generation part of the load-store-unit (LSU) is contained in EX as well.

+

The FPU writes back its result from EX stage as well when FPU_*_LAT is either 0 cycle or more than 1 cycle. It is reusing register file ALU/Mult/Div write port and it has the highest priority so it will stall EX stage if there is a conflict (when FPU_*_LAT > 1).

+
+
Writeback (WB)

Writes the result of Load instructions back to the register file.

+

The FPU writes back its result from WB stage as well when FPU_*_LAT is 1 cycle. It is reusing register file LSU write port but LSU has the highest priority over FPU if there is a conflict.

+
+
+
+

Hazards

+

There is a forwarding path betwen ALU, Multiplier and Divider result in EX stage and ID stage flip-flops to avoid the need of a write-through register file. +This allows to have 0-cycle penalty between those instructions and immediately following one when using result. +This is the same with 0-cycle latency FPU instructions.

+

But the CV32E40P experiences a 1-cycle penalty on the following hazards:

+
+
    +
  • Load data hazard in case the instruction immediately following a load uses the result of that load

  • +
  • Jump register (jalr) data hazard in case that a jalr depends on the result of an immediately preceding instruction

  • +
  • FPU data hazard when FPU_*_LAT = 1 in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU

  • +
+
+

More than 1-cycle penalty will happen when:

+
+
    +
  • FPU data hazard of FPU_*_LAT cycles (FPU_*_LAT > 1) in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU

  • +
  • FPU data hazard in case the instruction immediately following FDIV/FSQRT uses the result of those instructions

  • +
+
+

Those cycles penalty can be hidden if the compiler is able to add instructions between the instructions causing this data hazard.

+
+
+

Single- and Multi-Cycle Instructions

+

Table 8 shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. The cycle counts assume zero stall on the instruction-side interface and zero stall on the data-side memory interface.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 8 Cycle counts per instruction type

Instruction Type

Cycles

Description

Integer

+

Computational

+

1

Integer Computational Instructions are defined in the +RISCV-V RV32I Base Integer Instruction Set.

Multiplication

1 (mul)

+

5 (mulh, mulhsu, mulhu)

+

CV32E40P uses a single-cycle 32-bit x 32-bit multiplier +with a 32-bit result. The multiplications with upper-word +result take 5 cycles to compute.

Division

+

Remainder

+

3..35

+

3..35

+

The number of cycles depends on the divider operand value +(operand b), i.e. in the number of leading bits at 0. +The minimum number of cycles is 3 when the divider has zero +leading bits at 0 (e.g., 0x8000000). +The maximum number of cycles is 35 when the divider is 0.

Load/Store

1

+

2 (non-word aligned word +transfer)

+

2 (halfword transfer crossing +word boundary)

+

4 (cv.elw)

+

Load/Store is handled in 1 bus transaction using both EX +and WB stages for 1 cycle each. For misaligned word +transfers and for halfword transfers that cross a word +boundary 2 bus transactions are performed using EX and WB +stages for 2 cycles each. +A cv.elw takes 4 cycles.

Jump

2

+

3 (target is a non-word-aligned +non-RVC instruction)

+

Jumps are performed in the ID stage. Upon a jump the IF +stage (including prefetch buffer) is flushed. The new PC +request will appear on the instruction-side memory +interface the same cycle the jump instruction is in the ID +stage.

Branch

+

(Not-Taken)

+

1

Any branch where the condition is not met will +not stall.

Branch

+

(Taken)

+

3

+

4 (target is a non-word-aligned +non-RVC instruction)

+

The EX stage is used to compute the branch decision. Any +branch where the condition is met will be taken from the +EX stage and will cause a flush of the IF stage (including +prefetch buffer) and ID stage.

CSR Access

4 (mstatus, mepc, mtvec, mcause, +mcycle, minstret, mhpmcounter*, +mcycleh, minstreth, mhpmcounter*h, +mcountinhibit, mhpmevent*, dscr, +dpc, dscratch0, dscratch1)

+

1 (all the other CSRs)

+

CSR Access Instruction are defined in ‘Zicsr’ of the +RISC-V specification.

Instruction Fence

2

+

3 (target is a non-word-aligned +non-RVC instruction)

+

The FENCE.I instruction as defined in ‘Zifencei’ of the +RISC-V specification. Internally it is implemented as a +jump to the instruction following the fence. The jump +performs the required flushing as described above.

Floating-Point +Addition or +Multiplication

1..FPU_ADDMUL_LAT + 1

Floating-Point instructions are dispatched to the FPU. +Following instructions can be executed by the Core as long +as they are not FPU ones and there are no Read-After-Write +or Write-After-Write data hazard between them and the +destination register of the outstanding FPU instruction. +If there are enough instructions between FPU one and +the instruction using the result then cycle number is 1. +“Enough instruction” number is either FPU_ADDMUL_LAT, +FPU_OTHERS_LAT or 11. +If there are no instruction in between then cycle number is +the maximum value for each category.

Floating-Point +Comparison, Conversion +or Classify

1..FPU_OTHERS_LAT + 1

Single Precision +Floating-Point +Division and +Square-Root

1..12

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/preface.html b/docs/html/preface.html new file mode 100644 index 000000000..8530fb45a --- /dev/null +++ b/docs/html/preface.html @@ -0,0 +1,132 @@ + + + + + + + Changelog — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Changelog

+
+

Warning

+

Changelog was not built because sphinx_github_changelog_token parameter is missing in the documentation configuration.

+
+
+

Tip

+

Find the project changelog here.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/register_file.html b/docs/html/register_file.html new file mode 100644 index 000000000..ad6605466 --- /dev/null +++ b/docs/html/register_file.html @@ -0,0 +1,149 @@ + + + + + + + Register File — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Register File

+

Source files: rtl/cv32e40p_register_file_ff.sv

+

CV32E40P has 31 32-bit wide registers which form registers x1 to x31. +Register x0 is statically bound to 0 and can only be read, it does not +contain any sequential logic.

+

The register file has three read ports and two write ports. Register file reads are performed in the ID stage. +Register file writes are performed in the WB stage.

+
+

Floating-Point Register File

+

If the optional FPU is instantiated, unless ZFINX is configured, the register file is extended +with an additional register bank of 32 registers f0-f31. These registers +are stacked on top of the existing register file and can be accessed +concurrently with the limitation that a maximum of three operands per +cycle can be read. Each of the three operands addresses is extended with +an register file select signal which is generated in the instruction decoder +when a FP instruction is decoded. This additional signals determines if +the operand is located in the integer or the floating point register +file.

+

Forwarding paths, and write-back logic are shared for the integer and +floating point operations and are not replicated.

+

If ZFINX parameter is set, there is no additional register bank and FPU instructions are using +the same register file than for integer instructions.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/search.html b/docs/html/search.html new file mode 100644 index 000000000..66b9c74b1 --- /dev/null +++ b/docs/html/search.html @@ -0,0 +1,135 @@ + + + + + + Search — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • »
  • +
  • Search
  • +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js new file mode 100644 index 000000000..d4b9d52ae --- /dev/null +++ b/docs/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["control_status_registers","core_versions","corev_hw_loop","debug","exceptions_interrupts","fpu","getting_started","glossary","index","instruction_fetch","instruction_set_extensions","integration","intro","load_store_unit","perf_counters","pipeline","preface","register_file","sleep","verification"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,sphinx:56},filenames:["control_status_registers.rst","core_versions.rst","corev_hw_loop.rst","debug.rst","exceptions_interrupts.rst","fpu.rst","getting_started.rst","glossary.rst","index.rst","instruction_fetch.rst","instruction_set_extensions.rst","integration.rst","intro.rst","load_store_unit.rst","perf_counters.rst","pipeline.rst","preface.rst","register_file.rst","sleep.rst","verification.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[2,3,4,5,8,9,10,11,12,13,14,15,17,18],"00":[0,10],"000":[0,10],"0000":10,"00000":10,"00000150":19,"00000152":19,"00000156":19,"0000015a":19,"0000015c":19,"00001100110001100101101000011001":10,"00001100110010011010010100100110":10,"00008437":19,"0001":10,"001":[0,10],"0010":10,"00100001011010110010010001001011":10,"0011":10,"01":[0,10],"010":[0,10],"0100":10,"0101":10,"011":[0,10],"0110":10,"01100100101001011001001100110000":10,"0111":10,"02":19,"0x":19,"0x0":0,"0x00":4,"0x00000000":19,"0x00002000":19,"0x0000200c":19,"0x00007fff":19,"0x00008000":19,"0x0000_0000":0,"0x0000_0003":0,"0x0000_0004":0,"0x0000_000d":0,"0x0000_0602":0,"0x0000_1800":0,"0x001":0,"0x002":0,"0x003":0,"0x0cc65a19":10,"0x0cc9a526":10,"0x1":0,"0x2":0,"0x216b244b":10,"0x2800_1040":0,"0x2a":10,"0x3":0,"0x300":0,"0x301":0,"0x304":0,"0x305":0,"0x320":[0,14],"0x323":0,"0x33f":0,"0x340":0,"0x341":0,"0x342":0,"0x343":0,"0x344":0,"0x4":0,"0x4000_0003":0,"0x64a59330":10,"0x780":12,"0x79f":12,"0x7a0":[0,12],"0x7a1":[0,12],"0x7a2":0,"0x7a3":0,"0x7a4":0,"0x7a8":0,"0x7aa":0,"0x7b0":0,"0x7b1":0,"0x7b2":0,"0x7b3":0,"0x7c":12,"0x8":19,"0x8000000":15,"0xb00":0,"0xb02":0,"0xb03":0,"0xb1f":0,"0xb80":0,"0xb82":0,"0xb83":0,"0xb9f":0,"0xc":0,"0xc00":0,"0xc02":0,"0xc03":0,"0xc1f":0,"0xc64a5933":10,"0xc80":0,"0xc82":0,"0xc83":0,"0xc9f":0,"0xcc0":[0,12],"0xcc1":0,"0xcc2":0,"0xcc4":0,"0xcc5":0,"0xcc6":0,"0xcd0":0,"0xcd1":0,"0xcd2":0,"0xcff":12,"0xf11":0,"0xf12":0,"0xf13":0,"0xf14":0,"0xff":10,"0xffea":10,"0xffff":10,"1":[2,4,5,8,10,11,12,13,14,15,18,19],"10":[0,1,2,3,4,10,12,13,14,18,19],"100":[0,10],"1000":10,"1001":10,"101":[0,10],"1010":10,"1011":10,"10x10":2,"11":[0,3,4,10,12,14,15],"110":[0,10],"1100":10,"11000110010010100101100100110011":10,"1101":10,"111":[0,10],"1110":10,"1111":10,"12":[0,1,3,4,10,14,15,19],"128i":0,"13":[0,1,3,12,14,19],"130":19,"132":19,"134":19,"136":19,"14":[0,10,14,18],"142":19,"15":[0,4,10,14],"16":[0,3,4,7,8,12,13,19],"17":[0,10],"18":[0,4,10,19],"19":[0,10,12],"2":[1,2,4,7,8,9,10,12,13,14,15,19],"20":[0,10],"2016":12,"2017":12,"2018":12,"2019":12,"20190608":12,"20191213":12,"2020":[1,12,19],"2021":19,"2023":[10,12],"21":0,"22":0,"23":[0,10],"24":[0,10],"25":[0,10,12],"256":[0,4],"26":[0,10],"27":[0,10,19],"2700":12,"2713":12,"27th":12,"28":[0,10],"29":[0,10,11,14],"3":[2,4,8,9,10,13,14,15],"30":[0,4,10],"300":[2,19],"31":[0,3,4,9,10,13,17],"32":[2,3,5,7,8,9,11,12,13,14,15,17,19],"32b":12,"35":15,"38":19,"4":[0,2,3,4,7,9,10,12,14,15,18,19],"40":[2,19],"4481":19,"47":19,"5":[0,3,10,12,13,14,15,19],"51":12,"510":3,"6":[0,4,10,13,14,19],"61":19,"62":19,"63":19,"64":[0,14,19],"64i":0,"67":19,"7":[0,4,10,13,14],"754":5,"7a72508c90484a7835590a97038eb9dd53bd8c32":1,"8":[0,2,4,7,10,12,13,14,15,18,19],"8c65":19,"9":[0,4,9,10,14,18,19],"904":3,"abstract":3,"break":0,"byte":[0,4,5,7,10,13],"case":[0,1,3,4,5,9,10,11,12,13,15,18],"catch":2,"default":[0,1,3,5,9,10,11,12,14],"do":[0,4,5,11],"final":[0,19],"float":[3,7,8,11,12,15],"function":[10,11,12,19],"gou\u00e9do":12,"int":[5,11],"long":[3,4,11,15],"new":[8,12,15,19],"return":[0,3,5,10],"static":[11,17],"switch":[0,2,5],"throw":0,"true":[10,12,19],"try":[4,10],"while":[10,11,12,13,18],"z\u00fcrich":12,A:[0,2,3,4,6,8,10,12,13,15,18,19],AS:12,And:[10,12],As:[1,3,5,9,10,11,12,13,18],At:[2,14],But:[12,15],By:[1,5,12,14,19],For:[0,1,2,3,4,6,9,10,13,14,15,19],IF:[7,9,15],IS:12,If:[0,1,3,4,5,10,12,14,15,17,18],In:[0,1,2,3,4,9,10,12,13,14,19],Is:13,It:[0,1,3,4,9,11,12,14,15,19],NOT:2,Near:12,No:[2,10,18],Not:[4,15],OF:[0,12],OR:12,On:0,Or:1,Such:[0,10,12],That:0,The:[0,1,2,3,4,5,6,9,10,11,12,13,14,15,17,18,19],Then:12,There:[4,10,15],These:[1,2,6,9,10,13,17],To:[1,2,3,4,5,10,19],With:12,_lat:[12,15],_xcvalu:10,_xcvbi:10,_xcvbitmanip:10,_xcvelw:10,_xcvhwlp:10,_xcvmac:10,_xcvmem:10,_xcvsimd:10,ab:10,abil:3,abl:[5,9,15],about:[3,10,12],abov:[0,3,9,13,15,18],absolut:19,acceler:19,accept:[1,9,13],access:[0,3,4,5,8,10,14,15,17,19],accord:[3,4,12,14],accordingli:[4,5],accru:5,accumul:8,achiev:[1,12,18,19],acknowledg:4,across:3,action:[0,3],activ:[4,6,11,12],actual:[5,9],ad:[1,9,12,13,19],adapt:6,add:[2,10,15],adder:[1,2,14],addi:[2,19],addit:[0,1,2,5,9,10,11,12,13,14,15,17,19],addition:[3,10],addn:10,addnr:10,address:[2,3,4,7,8,9,10,11,13,14,15,17,19],addrn:10,addrnr:10,addun:10,addunr:10,addurn:10,addurnr:10,adher:3,adopt:19,advanc:10,advic:5,affect:[0,1,3,14],aforement:1,after:[2,3,4,5,8,10,11,13,14,15,18,19],again:18,against:[0,19],agre:12,ahb:12,aid:[9,13],aim:18,aka:10,al:12,alias:19,align:[0,2,3,4,7,9,10,11,13,15],all:[0,1,3,4,5,10,11,12,13,14,15,18,19],allow:[0,1,2,3,4,5,10,11,12,13,15,18],alreadi:[1,13],also:[3,4,10,12,13,15],alter:5,altern:5,although:13,alu:[1,7,8,12,15],alwai:[0,2,4,9,10,12,13,14],amba:12,an:[0,2,3,4,5,7,9,10,11,12,14,15,17,18,19],andrea:12,ani:[0,2,4,5,7,12,13,14,15,17,18],anoth:[1,19],answer:13,anymor:12,app:19,appear:15,appendix:3,appli:[1,18,19],applic:[7,10,12,18],appropri:[6,10],apu:[12,14],apu_cont:14,apu_dep:14,apu_typ:14,apu_wb:14,apub:14,ar:[0,1,2,3,4,5,6,9,10,11,12,13,14,15,17,18,19],arbitrarili:3,architectur:[2,4,5,7,12],area:[0,2,12],arithmet:[7,10],arjan:[1,12],arrai:7,asic:[6,7,8],asm:2,assembl:[2,10],assert:[3,11,18],associ:[0,14],assum:[3,4,10,13,15],asynchron:[11,19],atom:[0,12],atrab:12,attach:3,attempt:[0,5],attribut:19,auser:[9,13],auto:10,automat:[2,4,12],avail:[5,10,12,14,19],averag:9,avg:10,avgu:10,avoid:[0,4,15],await:18,axi:12,b01:0,b0:0,b:[0,10,15],back:[3,7,9,10,13,14,15,17],backward:[8,11],bahavior:10,bank:[0,17],barrier:18,base:[1,3,4,7,10,11,12,13,14,15,19],basi:12,basic:[2,4,13],bclr:10,bclrr:10,becam:12,becaus:[16,18,19],becom:18,been:[1,3,5,11,12,13,19],befor:[0,3,4,10,12,13,19],beforehand:2,begin:[2,3],behavior:[0,5,8,19],behaviour:2,being:[3,4,5,9,10,13,14,19],belong:10,below:[0,1,2,3,11,19],beqimm:10,best:5,better:1,between:[0,3,15,19],betwen:15,bhv:12,bidwidth:10,bink:[1,12],bit:[2,3,4,7,8,9,11,12,13,14,15,17,18,19],bitfield:0,bitrev:10,blob:1,block:[2,3,4,12],bneimm:10,bodi:[2,10,12],bologna:12,boot:[4,11],boot_addr_i:[4,11],both:[0,2,3,4,5,6,9,10,12,13,15,19],bound:17,boundari:[13,15],box:5,branch:[2,8,14,15,19],branch_taken:14,breakpoint:[0,4],brief:12,bset:10,bsetr:10,bu:[7,8,9,13,15,19],buffer:[8,9,15],bug:[8,19],build:3,built:16,builtin:10,buse:19,busi:18,c622:19,c:[0,3,7,10,12,14,19],cach:9,call:[3,4,6,9,12,19],can:[0,1,2,3,4,5,9,10,11,12,13,14,15,17,18,19],cannot:4,capabl:15,care:[9,10,13],carri:10,categori:15,caus:[3,4,5,10,12,13,14,15,18],cell:[5,8,12,18],central:7,certain:[5,18],ch:12,chain:[0,10],chang:[0,8,9,11,12,13],changelog:8,chapter:[3,12],check:[1,5,19],chip:3,choic:2,chosen:10,ci:1,circuit:7,clang:10,clarifi:3,classifi:[3,5,11,15],clb:10,clean:[0,5,8],clear:[3,4,10],clearer:1,clint:[4,12],clip:10,clipr:10,clipu:10,clipur:10,clk_i:[3,4,6,11,14,18],clk_o:6,clock:[3,5,8,11,12,14,18],closur:9,cluster:[8,10,11,12],cmpeq:10,cmpge:10,cmpgeu:10,cmpgt:10,cmpgtu:10,cmple:10,cmpleu:10,cmplt:10,cmpltu:10,cmpne:10,cnt:10,code:[0,1,2,4,8,9,10,11,13,19],coincid:[3,18],column:[0,19],com:[1,3,5,12],combinatori:12,come:[9,10,13],command:[10,12],comment:[0,1,10],common:[3,10],commun:[1,13,19],comp_instr:14,compar:[1,10,19],comparison:[1,8,11,12,15],compat:[8,11],compens:19,compil:[2,10,12,15],complet:[4,10,12,15,18],complex:[8,12],complianc:[5,8],compliant:[3,12],compon:3,compress:[0,2,7,9,12,14,19],comput:[2,5,10,15],concern:4,concurr:17,condit:[3,12,14,15,18],configur:[2,4,5,11,12,16,17,19],conflict:[14,15],conjug:10,connect:9,consecut:10,consist:5,constrain:19,constraint:[8,10,12],consumpt:[2,14],contain:[0,2,5,6,10,15,17,18],content:[0,4,14,19],context:[2,5],continu:0,contribut:12,contributor:8,control:[1,2,3,4,5,7,8,10,11,12,13,18,19],convers:[1,5,11,15],convert:14,copi:[5,12],copyright:12,core:[0,4,5,8,9,12,13,15,18,19],core_clust:4,core_sleep_o:[5,11,18],corev:19,corev_clust:[0,1,10,11,12,18],corev_pulp:[0,1,2,4,10,11,12,13],correct:1,correspond:[0,4,10,13,14],costli:2,could:[2,12],count:[2,5,10,14,19],counter:[2,4,7,8,11,12,19],counti:10,coupl:[3,13,18,19],coverag:19,cplxconj:10,cplxmul:10,cpu:[7,12],creat:19,critic:4,cross:[13,15],csr:[2,3,4,7,8,10,11,14,15,19],csrr:[2,14],csrrw:[0,14],csrw:2,current:[0,4,12,19],custom:[0,2,4,5,6,7,8,11,18],cv3240p:3,cv32e40p:[0,1,2,3,4,5,9,10,11,13,14,15,17,18,19],cv32e40p_clock_g:6,cv32e40p_cor:[1,11,12],cv32e40p_fpu_manifest:[5,12],cv32e40p_prefetch_buff:9,cv32e40p_register_file_ff:17,cv32e40p_sim_clock_g:[6,12],cv32e40p_sleep_unit:[6,18],cv32e40p_top:[1,5,6,11,12,19],cv32e40p_trac:19,cv32e40p_trace_execut:19,cv32e40p_v1:[8,19],cv32e40p_v2:8,cv32e40p_vmajor:1,cv:[2,10,11,14,15,18],cvfpu:8,cycl:[2,3,4,5,8,9,11,13,14,17,19],d:[0,10,19],data:[3,5,7,9,10,11,12,13,15,18,19],data_:11,data_addr_o:[11,13],data_be_o:[11,13],data_gnt_i:[11,13,18],data_rdata_i:[11,13],data_req_o:[11,13],data_rvalid_i:[11,13,18],data_wdata_o:[11,13],data_we_o:[11,13],datapath:5,datatyp:13,date:[1,19],david:12,dcsr:3,de:11,deal:[9,12],deassert:[3,4,18],debug:[2,4,8,11,12,18,19],debug_:11,debug_halted_o:[3,11],debug_havereset_o:[3,11],debug_mode_o:3,debug_req_i:[3,11,18],debug_running_o:[3,11],debugg:3,decemb:[10,12],decim:[0,19],decis:15,decod:[1,3,5,7,9,15,17,19],decrement:2,dedic:[5,11],defin:[0,1,2,4,5,12,14,15,19],definit:[0,1,12],degrad:12,delai:19,depend:[0,1,3,4,9,10,12,14,15,18],depth:9,describ:[0,2,3,4,9,10,11,12,13,14,15,18],descript:[3,4,5,8,9,10,11,12,13,14,15,18,19],design:[0,1,3,6,11,12,19],design_openissu:1,desir:[4,10],dest:10,destin:[3,15],destruct:14,detail:[0,3,8,10,12,18,19],detect:14,determin:[0,3,14,17],develop:12,devic:12,dft:11,diagram:[9,12,13],did:18,differ:[0,1,5,9,10,12,19],differenti:1,digit:[18,19],dir:11,direct:[0,3,4,9,12,13,18,19],directli:[5,18,19],dirti:[0,5],disabl:[4,11,12,14],disassembl:19,discard:0,discuss:[6,12],dispatch:15,distribut:[3,12],div2:10,div4:10,div8:10,div:[12,15],divid:[0,1,10,15],divis:[5,7,12,15],dm:3,dm_exception_addr_i:[3,11],dm_halt_addr_i:[3,11],dm_haltaddr_i:3,dmode:[0,3],document:[0,1,4,5,8,16,19],documentation_openissu:1,doe:[0,3,4,9,10,12,13,17,18],dolphin:12,done:[1,3,10,12,19],dotsp:10,dotup:10,dotusp:10,doubl:[0,5],dpc:[3,15],draft:12,dret:2,drw:0,dscr:15,dscratch0:15,dscratch1:[0,15],dsp:12,due:4,dure:[4,8,11,18,19],dut:19,dv:19,dyn:0,dynam:5,dz:0,e:[0,1,2,4,10,13,15,18,19],each:[0,2,5,10,13,15,17,18],earli:[2,19],easier:12,easili:[1,11],ebreak:[0,2,8],ebreakm:[0,3],ebreaku:0,ecal:[2,4],eda:19,edg:12,ee:12,effect:[0,9,13,19],effici:[2,10,18],effort:19,either:[0,1,2,3,4,5,10,12,15],element:10,els:[0,10],elw:[10,11,14,15,18],embed:13,en_i:6,enabl:[2,3,4,5,6,10,11,12,13,14,18,19],enablenanbox:5,enablesimdmask:5,enablevector:5,encod:[0,1,4,8],encount:0,end:[2,10,12,13],endaddress:2,endi:[2,10],endo:2,endpoint:12,endz:2,enforc:5,engin:19,enough:15,ensur:[9,13],enter:[0,2,4,8,10,11,18],entri:[3,9,18],enumer:0,environ:[4,18,19],equal:[0,1,10,19],equival:[1,7,10,12],err:[9,13],error:[2,19],et:12,etc:[1,10,19],eth:12,ethz:12,evalu:10,even:[6,12,13],event:[3,5,8,12,18,19],eventu:3,everi:[1,2,3,12],everytim:4,ex:[7,12,15],exact:[0,1],exactli:[3,9,13],exampl:[0,1,2,3,4,9,10,11,12,13,18,19],except:[1,2,5,8,10,11,12,13,15],exclud:14,exclus:3,execut:[0,2,3,4,5,7,9,11,13,15,18,19],exist:[0,17],exit:8,experi:15,explain:[1,5,10,12,14],explan:0,explicit:10,explicitli:[0,4],express:12,extb:10,extbz:10,extend:[5,10,12,17,19],extens:[0,1,4,5,7,8,11,13,19],extent:10,extern:[0,3,4,9,12,18],exth:10,exthz:10,extra:10,extract:10,extractr:10,extractu:10,extractur:10,f0:[5,17],f2:10,f31:[5,17],f:[0,4,5,7,10,12,19],fals:10,fast:[0,12],faster:1,fatal:2,fcsr:5,fdiv:15,featur:[0,2,3,8,12],februari:12,fenc:[2,12,15],fetch:[4,7,8,11,12,15,19],fetch_enable_i:[3,11,18],fethc:14,few:[3,10],fewer:9,ff1:10,fff40413:19,fflag:5,fft:10,field:[0,7],fifo:[9,13],figur:[1,3,9,12,13,18],file:[1,6,8,10,11,12,15,18],find:[16,19],fine:12,first:[0,2,3,10,11,13],fit:12,fix:[0,1,4,8,10],fl1:10,flag:[5,10],flavor:[10,12],flavour:2,flip:[2,12,15],flist:12,flop:[2,12,14,15],flow:1,flush:15,fmt_logic_t:5,folder:12,follow:[0,1,2,3,4,5,6,9,10,12,13,14,15,18,19],footprint:0,forc:[11,12],fork:12,form:[5,10,17],formal:8,format:[1,5,8,12],former:[10,11],forthcom:0,forward:[15,17],found:[0,3,5,8,9,11,12,13],four:[3,4,10,13],fourth:2,fp:[8,12,14,17],fpfmtmask:5,fpga:[6,7,8],fpnew_top:11,fpnew_wrapp:12,fpu:[0,1,4,7,8,11,15,17,18],fpu_:[12,15],fpu_addmul_lat:[1,5,11,15],fpu_others_lat:[1,5,11,15],fr:12,freeli:5,freez:[8,12,19],frequenc:12,frm:5,from:[0,2,3,4,5,8,9,10,11,12,13,15,18,19],frozen:1,fs:[0,5],fsqrt:15,fulli:[1,12,19],funct3:10,funct4:10,funct5:10,funct7:10,further:[0,1,2],fuse:10,futur:[3,4],fv:19,g:[0,1,4,10,15,18,19],gate:[5,7,8,11,12,14,18],gautschi:12,gcc:10,gdb:3,gener:[2,5,8,9,11,13,15,17,19],get:[5,8,12,13],get_design:12,get_object_nam:12,git:1,github:[1,3,5],give:12,given:[1,4,10,11,19],global:[4,18],glossari:[8,12],go:[5,18],gouedo:12,govern:12,gpr:3,grant:[12,13],greater:[1,2],greatli:[2,19],group:[1,5,10,12],guarante:[1,3],guidelin:8,h:[0,8,10,15],ha:[1,2,3,4,5,6,10,11,12,13,15,17,18,19],had:12,half:[5,9,10,11,13],halfword:[7,13,15],halt:3,hand:2,handl:[0,8,9,12,13,15],handler:[0,2,3,4,14],happen:[2,8,11,13,15],hardwar:[4,5,8,11,12,13,14],hardwir:[0,3],hart:[3,11,19],hart_id_i:[0,11],hartid:19,have:[1,2,3,10,12,13,15,18,19],hazard:[8,14],here:[1,5,16,19],hex:19,hidden:15,high:[3,4,9,12,13],higher:[0,2,4,12],highest:[4,15],highli:[5,11],histori:8,hit:0,hold:[9,13],host:5,how:[0,4,12],howev:[0,1,3,4],hpm:0,hpmcounterh31:0,hpmcounterh3:0,http:[1,3,5,7,12],human:19,hw:5,hwloop:[2,8],hypervisor:0,i0:10,i1:10,i2:10,i3:10,i4:10,i5:10,i:[0,2,4,7,10,12,13,14,15],id:[4,7,8,9,11,12,13,14,15,17,19],identifi:[0,1,19],ieee:[5,12],ifdef:19,ifmt_logic_t:5,ignor:[0,3,4,7,9,11,18],ii:[7,12],illeg:[0,2,3,4,5,14],im:10,imaginari:10,imc:19,imiss:14,imm12:10,imm5:10,imm6:10,imm:10,immedi:[8,15,19],impact:[12,14,18],impera:19,imperasdv:19,implement:[1,3,4,6,9,12,13,14,15,18],impli:12,impos:18,improv:12,inact:5,includ:[5,10,12,15,19],increas:[2,10,12,13],increment:[3,8,11,12,14],indentifi:1,independ:4,index:[4,10],indic:[0,12,15,19],individu:[4,5,10,14],industri:12,ineffici:19,inexact:0,influenc:10,info:3,inform:[4,9,12,13,18,19],infrastructur:[9,12,13],inhibit:14,inihibit:0,initi:[0,5,6,11,12,18],inner:2,innermost:2,innov:19,input:[3,4,5,6,9,10,11,12,13,18],insert:[5,10],insertr:10,insid:[0,2,5,6,10,12,14,18],inspect:19,instanc:1,instanti:[1,5,8,12,17,18,19],instead:[1,5,10,11],instr:[14,19],instr_:11,instr_addr_o:[9,11],instr_gnt_i:[9,11,18],instr_rdata_i:[9,11],instr_req_o:[9,11],instr_rvalid_i:[9,11,18],instruct:[1,2,3,4,5,7,8,11,14,17,18,19],intanti:5,integ:[0,3,5,12,15,17],integr:[0,3,4,7,8,12,19],intend:[3,4,6],intent:10,interconnect:[9,13],interfac:[7,8,15,19],intern:[3,9,12,15,18],internet:12,interpret:3,interrupt:[2,5,8,11,18,19],intfmtmask:5,introduct:8,invalid:[0,19],invert:5,invok:[3,10],involv:2,iot:12,ip:[3,5],irq_:11,irq_ack_o:[4,11],irq_i:[0,4,11,18],irq_id:4,irq_id_o:[4,11],is2:10,is3:10,isa:[1,3,4,5,7,10,11,12,19],isr_handle_nested_interrupt:4,iss:19,issu:[1,3,12,13],itali:12,item:[7,13],iter:[0,10],its:[1,2,3,4,5,9,11,12,13,15,18,19],itself:18,iuimm5:10,j:[0,2,10],jalr:15,jedec:0,jmp_stall:14,jtag:3,jump:[0,2,3,4,11,14,15,19],june:[10,12],just:2,k:[0,4,10],keep:[0,2,4,10],kei:3,kept:[12,13],kernel:10,kge:[7,12],kilo:7,kind:12,l:[0,10],lab:12,label:2,lane:[1,5],languag:[0,12,19],larg:[0,12,19],last:[2,5,10,18,19],latenc:[1,5,12,15],later:3,law:12,lb:10,lbu:10,ld:14,ld_stall:14,lead:[10,15],least:[2,4,10,11],left:[4,10],legal:7,less:9,letter:0,level:[2,4,5,7,12],lh:10,lhu:10,li:19,licens:8,life:12,like:19,limit:[0,4,10,12,17],line:[4,12],link:[9,13],lint:19,linter:19,list:[0,1,3,5,12],live:19,llvm:10,load:[0,7,8,9,11,12,14,15,19],local:[9,18],locat:[2,3,17],log:19,logic:[1,5,7,10,14,17,19],longer:[10,18],loop:[8,11,12,13],lost:10,low:[0,3,4,7,11,12,13,18],lower:[0,4,12,14],lowest:[0,2,4,10,13,14],lpcount1:0,lpcount:10,lpend1:0,lpend:10,lpstart1:0,lpstart:10,ls2:10,ls3:10,lsb:[9,10],lsp:10,lsu:[7,8,9,11,12,15],lui:19,luimm2:10,luimm5:10,lw:10,m:[0,4,7,10,12],mac:10,machhsn:10,machhsrn:10,machhun:10,machhurn:10,machin:[4,7,11,12,14],macsn:10,macsrn:10,macun:10,macurn:10,made:12,mai:[0,3,9,10,12,13],main:[3,5,11],mainli:12,maintain:12,make:[2,10,11],manag:2,mani:[12,19],manifest:6,manipul:[0,8],manual:[7,12,19],manufactur:0,map:[2,4,5,8],march:10,marchid:1,mark:0,mask:[5,10],maskmax:0,master:[9,13],match:[0,3,18],materi:12,matrix:2,max:10,maximum:[4,12,15,17],maxu:10,mcaus:[3,15],mcountinhibit:[14,15],mcycl:[14,15],mcycleh:15,md:1,mean:[0,1,2,3,5,10,13,14,15,19],meaningful:2,mechan:[4,18],meet:18,mei:4,meie:0,meip:0,mem16:10,mem32:10,mem8:10,memori:[0,2,4,5,8,9,10,11,13,15,18,19],mention:[0,1,5,9,11,13],mepc:[3,4,15],mepc_bak:4,merg:5,messag:2,met:[15,18],method:[10,19],methodolog:[12,19],mhartid:11,mhpmcounter31:14,mhpmcounter3:14,mhpmcounter:[11,15],mhpmcounterh31:0,mhpmcounterh3:0,mhpmcounterx:14,mhpmevent31:14,mhpmevent3:14,mhpmevent:15,mhpmeventx:14,michael:12,micrel:12,mie:4,mie_bak:4,might:3,mileston:1,min:10,minimum:[3,12,15],minor:1,minstret:[14,15],minstreth:15,minu:10,mip:4,misalign:[8,12,15],miscellan:10,miss:16,mnemon:10,mno:19,mnumer:19,mode:[4,5,7,8,10,11,12,14,18],model:[2,12,19],modif:[1,11],modifi:[2,3,10],modul:[3,5,6,11,12,18,19],monitor:[12,14],month:19,moot:0,more:[1,4,10,12,13,15,19],most:[0,3,10,12,14],move:[1,3,12],mpec:4,mpie:[0,4],mpp:0,mprven:0,mret:[0,2,3,4],mro:0,mrw:0,msb:10,msi:4,msie:0,msip:0,mstatu:[4,5,15,18],mstatus_bak:4,msu:10,mti:4,mtie:0,mtime:14,mtip:0,mtval:3,mtvec:[3,4,11,15],mtvec_addr_i:[0,11],much:12,mul:15,mulh:15,mulhhsn:10,mulhhsrn:10,mulhhun:10,mulhhurn:10,mulhsu:15,mulhu:15,mulsn:10,mulsrn:10,mult:15,multi:8,multicycl:12,multipl:[1,2,4,5,7,8,9,11,12,13,14,15,18],multipli:[0,8,15],multitherman:12,mulun:10,mulurn:10,must:[0,1,2,3,4,10,11,12,13,14,18,19],mutual:3,mxl:0,n:[0,2,10],name:[0,1,3,5,11,12,14,19],nan:5,nand2:7,nativ:0,natur:13,necessari:5,need:[0,2,3,4,9,10,11,12,15],neither:3,nest:[2,8,12],never:[2,13],next:[0,3,9,10,13,18],nicer:1,nmip:0,non:[3,5,7,8,11,13,14,15,19],none:3,nonexist:3,nop:18,nor:12,normal:[3,10,11],norvc:2,note:[0,4,10,12,13,19],notic:[0,10],now:12,num_mhpcount:14,num_mhpmcount:[0,1,11,12,14],numb:14,number:[0,2,3,4,5,8,9,11,13,14,15,19],numer:19,nv:0,nx:0,o:[0,10],obi:[7,9,12,13],objdump:19,observ:3,obtain:12,occupi:12,occur:[3,5,9,11],oct:12,off:[0,1,5,9,13,18],offer:3,offs:10,offset:[10,13],old:1,onc:[1,10,11,12,18],one:[0,1,2,3,4,5,9,10,11,12,13,15,18],ones:[12,15],onespin:19,onli:[0,1,2,3,4,5,6,7,9,10,11,12,13,17,18],op2:10,opcod:10,open:[1,3,7,12,19],opene906:12,openhw:[0,1,12],openhwgroup:[1,3,5,12],openrisc:12,oper:[0,3,5,8,11,12,13,14,17,18],operand:[5,10,15,17],opgrp_fmt_unit_types_t:5,opgrp_fmt_unsigned_t:5,optim:[2,8,9,10,12],option:[2,3,4,9,10,12,13,17,18],or10n:12,order:[2,4,9,12,13,14,15],org:[7,12],organ:18,origin:10,os:12,other:[1,3,4,8,9,10,13,15,18],otherwis:[1,4,11],out:[0,3,10,11],outer:2,outermost:2,output:[3,4,5,6,8,9,12,13,18],outsid:[9,12],outstand:[9,13,15],over:[3,10,12,15],overal:3,overflow:[0,10],overhead:[0,2,13],overrul:5,overview:[3,12],overwrit:14,overwritten:4,own:[9,12,13],p:[0,10],pa:19,pack:[0,5],packhi:10,packlo:10,page:6,parallel:[5,7,18],paramet:[0,2,4,8,9,10,12,14,16,17,18,19],parameter:12,parameteriz:14,parametr:8,pariti:0,part:[4,6,10,11,12,15,19],partial:12,particular:[0,14],pascal:12,pasqual:12,pass:10,patch:1,path:[4,10,15,17],patmo:12,pattern:[10,13],paul:12,pc:[3,7,10,15,19],pdf:12,penalti:[2,15],pend:[4,18],per:[5,9,12,17,19],perfectli:12,perform:[3,4,8,9,10,11,12,13,15,17,18],period:3,permiss:12,perspect:10,phase:13,piec:2,pin:3,pipe_config_t:5,pipe_stal:14,pipeconfig:5,pipel:5,pipelin:[5,8,11,12,14],pipereg:5,place:[5,11,14,18],placement:5,plan:19,platform:[2,7,12,14,18,19],pleas:3,plu:[4,12,19],pmp:12,point:[2,3,7,8,9,10,11,12,13,15],pointer:13,popul:10,port:[3,5,6,12,15,17],portion:1,posit:[10,12],possibl:[0,2,9,12,19],post:[8,11,12],posteriori:3,power:[2,7,12,14,18],pp:12,ppa:8,pre:15,preced:15,precis:[0,5,12,15],prefetch:[9,15],prefetech:15,prefix:19,present:[0,2],preserv:7,previou:[0,10,12],previous:[0,4,12,19],primarili:10,primit:6,prior:10,prioriti:[2,4,12,15],priveleg:3,priviledg:0,privileg:[2,4,5,7,12,14],privilg:0,process:[7,13,18],processor:[7,12],produc:[18,19],professon:19,program:[0,1,2,4,5,7,8,11,19],programm:[7,8],prohibit:3,project:[12,16],properli:3,properti:3,propos:1,protect:8,protocol:8,provid:[0,3,6,10,12,13,14,19],prv:0,pschiavo:12,pseudo:[4,19],pull:1,pulp:[0,1,3,4,7,8,10,11,19],pulp_clock_en_i:[11,14,18],pulp_clust:1,pulp_platform_common_cel:12,pulp_platform_fpnew:12,pulp_platform_fpu_div_sqrt:12,pulp_secur:0,pulp_xpulp:1,pulp_zfinx:1,puls:4,pure:12,purpos:[2,5,10,11,12],put:[2,5],q:0,quad:0,qualiti:[12,19],queri:3,r0:0,r:[0,2,10],race:12,radix:10,rais:[0,4,10,12,13],random:19,rang:[0,5,10,11,14,15],ratifi:[1,12],rational:2,rd:10,rdn:0,re:[1,3,4,8,10,19],reach:12,read:[0,2,3,5,7,9,11,12,13,14,15,17,18,19],readi:[13,18],real:10,reason:[0,1,9],recommend:[14,19],reduc:13,reduct:3,refer:[1,2,3,8,10,19],referenc:13,reflect:[0,3,4],region:9,regist:[2,4,7,8,11,12,15,19],registernam:19,regular:[13,18],reject:1,rel:[2,10],relat:[2,10,11,12,19],releas:[5,8,19],relev:3,remain:[0,1,3],remaind:[3,15],remind:8,remov:[5,10,12,19],renam:1,replac:[0,10,19],replic:[10,17],report:[1,8,10],repositori:5,repres:[0,2,10],represent:10,req:12,request:[1,3,9,12,13,15,18],requir:[0,1,3,6,11,12,13,15,18],reserv:[0,4,7],reset:[0,3,4,5,11,14,18,19],resolv:19,resourc:[2,5],resp:2,respect:[2,3,4,5,10,12],respons:[9,13],rest:10,restart:8,restor:[0,2,4,5],restrict:12,restructuredtext:12,result:[0,3,5,7,9,10,14,15],resum:18,retain:10,retim:12,retir:[3,14],retract:12,reus:[12,15],revers:8,review:19,ri5ci:12,rid:[9,13],right:[10,12],risc:[1,3,4,5,7,8,10,12,14,15,19],riscv:[3,15,19],rm:19,rmm:0,rne:0,ro:0,root:[5,15],ror:10,rotat:10,rotateright:10,round:[5,10],routin:[2,3,4,5],rreadi:[9,13],rs1:10,rs2:10,rs3:10,rs:10,rst_ni:[3,11,18],rtl:[5,6,8,12,17,18],rtl_freeze_v1:1,rtz:0,rule:[2,8,12],run:[0,3,18],rup:0,ruser:[9,13],rv32a:8,rv32c:7,rv32e:0,rv32f:[5,7,8],rv32i:[0,10,12,15],rvalid:12,rvc:[2,15],rvf:4,rvvi:19,rw:0,s:[0,3,10,11,19],sail:19,same:[1,3,4,5,9,10,12,13,15,17],sampl:3,satur:10,save:[0,2,3,4,5],sb:10,sc:10,scalabl:12,scalar:10,scale:12,scan:[6,11],scan_cg_en_i:[6,11],scenario:[1,8,13,18],scheme:[4,10],schiavon:12,sci:10,scontext:0,scr1:10,scratch:3,sd:[0,5],sdc:12,sdotsp:10,sdotup:10,sdotusp:10,second:10,section:[0,2,3,4,10,13,14],secur:8,see:[0,1,3,4,5,10,11,12,14,15,18,19],segment:10,select:[3,6,12,17],selector:8,self:19,semant:18,semaphor:18,sensist:4,sensit:[0,4],sent:[9,13],separ:[2,9,10,13,19],sequenc:10,sequenti:17,serv:[9,13],set:[0,1,2,3,4,5,6,7,8,11,13,14,15,17,18,19],set_optimize_regist:12,setup:2,setupi:10,sever:[3,10,12],sext:10,sh:10,shadow:0,shall:[3,4],share:[17,18],shift:10,shl:12,should:[1,2,3,4,5,6,9,10,11,12,13,14,18],show:[0,1,3,9,12,13,15,18],shuffle2:10,shufflei0:10,shufflei1:10,shufflei2:10,shufflei3:10,side:[0,9,12,13,15],siemen:19,sign:[1,10,19],signal:[5,11,12,17],signific:[4,10],significantli:13,silab:12,simd:[0,5,7,8,12],similar:[0,3],simpl:[10,12],simplifi:[2,3,9,19],simul:[2,6,8,12],simultan:12,sinc:[0,2,5,10,12,19],singl:[0,5,7,8,10,12,13,18],situat:2,size:[0,3],sizelo:0,sleep:[5,8,10,11,12,14],slet:10,sletu:10,slight:11,slightli:12,sll:10,slow:[12,13],small:[2,10],smaller:10,snippet:4,so:[0,4,5,9,10,13,15],softwar:[0,1,2,4,8,12,19],solderpad:12,some:[1,3,11,12,15],soon:13,sourc:[3,4,17,18,19],source:4,space:[2,12],spec:[3,8],special:11,specif:[0,1,3,4,5,6,7,9,10,12,13,14,15,19],specifi:[0,3,5,9,10,13],specul:9,sphinx_github_changelog_token:16,split:10,sqrt:12,squar:[5,15],sra:10,src1:10,src2:10,src:10,srl:10,st:14,stabil:12,stabl:10,stack:[4,17],stage:[5,9,12,15,17],stai:[9,13],stall:[2,14,15],standard:[0,4,5,7,8,19],start:[2,3,4,8,10,12,18,19],starti:[2,10],starto:2,startup:8,startz:2,state:[0,5,8,9,10,13],statu:[2,3,4,5,7,8,11,12,14],steadi:12,step:[0,6,8,12,18,19],stepi:0,still:[1,11],stopcount:0,stoptim:0,store:[0,2,7,8,9,11,12,14,15,19],straight:3,strategi:19,stream:19,strictli:2,structur:12,style:19,sub:10,subgroup:10,subn:10,subnr:10,subrn:10,subrnr:10,subrotmj:10,subsequ:0,substract:10,substractor:2,subtract:10,subun:10,subunr:10,suburn:10,suburnr:10,success:19,successfulli:19,suggest:11,summari:3,supervisor:0,suppli:[4,9,19],support:[0,1,2,3,4,5,9,10,11,12,13,19],suppos:1,sv:[6,9,11,12,17,18],sw:10,swap:10,switzerland:12,swsp:19,symbol:19,symposium:12,synchron:[3,12,18],synopsi:12,synthes:[5,8],synthesi:[5,6,8],synthesiz:[12,19],system:[0,3,12,15],systemverilog:[5,19],t:[0,10],tab:19,tabl:[0,4,5,9,10,13,15,18],tag:[1,5],tagtyp:5,take:[10,13,15],taken:[4,5,9,10,14,15],target:[6,12,15,19],tdata1:3,tdata2:3,tdata:0,team:[12,19],technolog:[6,12],templat:[8,12],tent:0,terminolog:12,test:[11,19],testament:19,testbench:19,testcas:19,than:[0,1,2,9,10,12,15,17,19],thei:[1,2,4,5,9,12,13,14,15],them:[2,12,13,15,19],themselv:19,therebi:18,therefor:[0,1,3,9,13,14,18],thi:[0,1,2,3,4,5,6,9,10,11,12,13,14,15,17,18,19],thing:12,think:3,third:2,those:[0,2,4,5,10,12,15],though:6,thought:[9,13],thread:11,three:[2,3,10,17],threshold:12,through:[3,4,5,10,14,15],thrown:10,thu:[6,9,10,12],ti:[4,9,10,13,18],tie:[11,18],tightli:18,time:[0,1,2,3,4,5,8,9,10,12,13,15,19],timer:[0,4],tinfo:3,todo:19,togeth:[2,10,12,13,18,19],took:19,tool:[10,12,19],toolchain:[2,10],top:[5,12,17],total:[12,19],traber:12,trace:8,trace_core_:19,tracer:8,transact:[0,9,12,13,15,18],transfer:[3,13,15],transit:3,translat:0,transport:3,trap:[4,11,12,14],treat:10,trigger:[4,8,11,12,18],truesimdclass:5,tselect:3,tupl:1,two:[0,2,3,4,5,9,10,12,13,17],type:[0,3,5,11,14,19],typic:[3,13,18],u:[0,12],u_cor:11,uf:0,uhartid:11,uimm:10,uimml:10,ultra:[7,12,18],unaffect:18,unavail:3,uncompress:19,uncondit:14,undefin:[0,2,4,14],under:[12,18],underflow:0,unimpl:[0,14],uniqu:0,unit:[4,7,8,9,11,12,14,15],unittyp:5,univers:12,unknown:19,unless:[0,4,12,17],unmodifi:10,unoffici:19,unprivileg:[0,4],unreproduc:19,unsign:[10,19],unspecifi:3,until:[3,9,12,13,15,18],untouch:10,unwant:9,up:[8,9,10,13,18],updat:[1,2,3],upon:[3,4,5,15,18],upper:[4,14,15],uret:3,uro:0,urw:0,us:[0,2,3,4,5,6,9,10,11,12,13,14,15,17,18,19],usag:18,user:[3,7,11,12,14,19],usual:[6,11],v1:[1,5,8,11,12],v2:[1,8,11],v:[1,3,4,5,7,8,11,12,14,15,19],valid:[4,9,13],valu:[1,2,3,4,5,7,9,10,11,14,15,19],variabl:15,vector:[4,10,11,12],vectori:5,vendor:[5,12],veri:12,verif:[1,2,3,5,8,12],verifi:[8,12,19],verification_openissu:1,version:[3,4,6,8,9,10,11,12,14,18,19],via:[3,4,5,9,11,12,14,15,18,19],view:[9,13],violat:2,virtual:[0,2],visibl:[1,12],visual:4,vlsi:12,vol:12,volatil:2,volum:[7,12],w:0,wa:[0,1,3,5,10,11,12,13,16,19],wai:3,wait:14,waiv:1,wake:18,want:0,warl:[0,7],warranti:12,waveform:18,wb:[7,15,17],wdata:9,we:[0,1,9],well:[4,5,12,13,14,15,18,19],went:19,were:[0,9,13],wfi:[2,8,14],what:[0,8,10,19],whatsov:5,when:[0,1,2,3,4,5,9,10,11,12,13,15,17,18,19],whenev:2,where:[3,5,10,13,15],wherea:[2,14],wherebi:3,whether:[3,5,12],which:[0,1,2,3,4,5,9,10,12,13,14,17,18,19],whole:[0,5,12],wide:[12,14,17,19],width:[5,11],win:12,wip:19,wish:3,within:[4,10],withold:18,without:[1,2,3,10,11,12,13],wlrl:[0,7],word:[3,5,7,9,10,11,13,15],work:[10,13,19],worth:[1,11],would:[2,3,4],wpri:7,wrap:11,wrapper:5,write:[0,1,2,3,4,5,7,9,12,13,14,15,17,19],writeback:15,written:[0,2,10,13,14,19],wuser:[9,13],www:12,x0:[2,17],x18:10,x1:[10,17,19],x20:10,x2:[10,19],x31:17,x3:10,x8:19,x9:19,x:[0,8,12,14,15],xcv:12,xcvelw:12,xdebugv:0,xlen:0,xor:10,xpulp:19,xx:12,y:0,yet:[8,18],you:[0,10,12],your:[0,6,10],z:0,zavalnei:12,zero:[0,2,10,15],zext:10,zfinx:[1,5,11,12,17,19],zicntr:12,zicsr:[12,15],zifencei:[12,15],zurich:12},titles:["Control and Status Registers","Core Versions and RTL Freeze Rules","CORE-V Hardware Loop Extensions","Debug & Trigger","Exceptions and Interrupts","Floating Point Unit (FPU)","Getting Started with CV32E40P","Glossary","OpenHW Group CV32E40P User Manual","Instruction Fetch","CORE-V Instruction Set Custom Extension","Core Integration","Introduction","Load-Store-Unit (LSU)","Performance Counters","Pipeline Details","Changelog","Register File","Sleep Unit","Verification"],titleterms:{"0":[0,1,19],"1":[0,1,3],"16":10,"2":[0,3],"3":[0,3],"32":[0,10],"float":[0,5,17],"long":10,"new":1,"short":10,A:1,access:[9,13],accru:0,accumul:10,address:[0,12],after:1,alu:10,architectur:0,asic:12,backward:1,base:0,behavior:[3,18],bit:[0,10],branch:10,breakdown:19,bu:12,buffer:3,bug:[1,12],caus:0,cell:6,chang:1,changelog:16,classif:19,clean:12,clock:6,cluster:18,code:[3,12],comparison:10,compat:1,complex:10,complianc:12,constraint:2,content:[8,12],context:0,contributor:12,control:[0,14],core:[1,2,3,10,11],count:[0,15],counter:[0,14],csr:[0,5,12],custom:[10,12],cv32e40p:[6,8,12],cv32e40p_v1:1,cv32e40p_v2:1,cvfpu:5,cycl:[0,15],cycleh:0,data:0,dcsr:0,debug:[0,3],descript:0,detail:15,document:12,dot:10,dpc:0,dscratch0:0,dure:3,dynam:0,ebreak:3,enabl:0,encod:10,end:0,enter:3,event:[0,10,14],except:[0,3,4],exit:3,extens:[2,10,12,18],fcsr:0,featur:[1,5],fetch:9,fflag:0,file:[5,17,19],fix:12,formal:19,format:19,found:[1,19],fp:5,fpga:12,fpu:[5,12],freez:1,frm:0,from:14,gate:6,gener:10,get:6,glossari:7,group:8,guidelin:12,h:14,handl:4,happen:1,hardwar:[0,2,10],hazard:15,histori:12,how:19,hpmcounter31:0,hpmcounter31h:0,hpmcounter3:0,hpmcounter3h:0,hwloop:[0,12],id:0,immedi:10,implement:[0,5],increment:[10,13],info:0,inhibit:0,instanti:11,instret:0,instreth:0,instruct:[0,9,10,12,13,15],integr:11,interfac:[3,4,9,11,12,13,18],interrupt:[0,3,4,12],introduct:12,isa:0,issu:19,level:0,licens:12,load:[10,13],loop:[0,2,10],lpcount0:0,lpend0:0,lpstart0:0,lsu:13,machin:0,manipul:10,manual:8,map:[0,12],marchid:0,mcaus:0,mcontext:0,mcountinhibit:0,mcycl:0,mcycleh:0,memori:12,mepc:0,mhartid:0,mhpmcounter31:0,mhpmcounter31h:0,mhpmcounter3:0,mhpmcounter3h:0,mhpmevent31:0,mhpmevent3:0,mie:0,mimpid:[0,1],minstret:0,minstreth:0,mip:0,misa:0,misalign:[9,13],mode:[0,3],monitor:0,mscratch:0,mstatu:0,mtval:0,mtvec:0,multi:15,multipl:10,multipli:10,mvendorid:0,nest:4,non:[0,1],number:10,openhw:8,oper:10,optim:1,other:[0,5],output:19,pack:10,paramet:[1,5,11],parametr:14,pc:0,pend:0,per:15,perform:[0,14],pipelin:15,point:[0,5,17],post:[10,13],ppa:1,privileg:0,privlv:0,product:10,program:3,programm:5,protect:12,protocol:[9,12,13],pulp:[12,18],re:12,refer:12,regist:[0,3,5,10,14,17],releas:1,remind:5,report:19,restart:3,retir:0,revers:10,risc:0,round:0,rtl:[1,19],rule:1,rv32a:12,rv32f:12,scenario:3,scratch:0,secur:12,select:0,selector:[0,14],set:[10,12],setup:10,shuffl:10,signal:[3,4,9,13,18],simd:10,simul:19,singl:[3,15],sleep:18,softwar:14,spec:12,standard:12,start:[0,6],startup:18,state:3,statu:0,step:3,store:[10,13],synthes:12,synthesi:[12,14],tdata1:0,tdata2:0,tdata3:0,templat:11,thread:0,time:14,tinfo:0,trace:19,tracer:19,trap:0,trigger:[0,3],tselect:0,type:15,uhartid:0,unit:[5,13,18],up:12,upper:0,user:[0,8],v1:19,v2:19,v:[0,2,10],valu:0,vector:0,vendor:0,verif:19,verifi:1,version:1,were:19,wfi:18,what:1,x:10,yet:1,zfinx:0}}) \ No newline at end of file diff --git a/docs/html/sleep.html b/docs/html/sleep.html new file mode 100644 index 000000000..a2963a05e --- /dev/null +++ b/docs/html/sleep.html @@ -0,0 +1,286 @@ + + + + + + + Sleep Unit — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Sleep Unit

+

Source File: rtl/cv32e40p_sleep_unit.sv

+

The Sleep Unit contains and controls the instantiated clock gate (see Clock Gating Cell) that gates clk_i and produces a gated clock +for use by the other modules inside CV32E40P. The Sleep Unit is the only place in which clk_i itself is used; all other modules use the gated version of clk_i.

+

The clock gating in the Sleep Unit is impacted by the following:

+
+
    +
  • rst_ni

  • +
  • fetch_enable_i

  • +
  • wfi instruction (only when COREV_CLUSTER = 0)

  • +
  • cv.elw instruction (only when COREV_CLUSTER = 1)

  • +
  • pulp_clock_en_i (only when COREV_CLUSTER = 1)

  • +
+
+

Table 14 describes the Sleep Unit interface.

+ + +++++ + + + + + + + + + + + + + + + + + + + + +
Table 14 Sleep Unit interface signals

Signal

Direction

Description

pulp_clock_en_i

input

COREV_CLUSTER = 0:

+

pulp_clock_en_i is not used. Tie to 0.

+

COREV_CLUSTER = 1:

+

pulp_clock_en_i can be used to gate clk_i +internal to the core when core_sleep_o = 1.

+

See PULP Cluster Extension for details.

+

core_sleep_o

output

COREV_CLUSTER = 0:

+

Core is sleeping because of a wfi instruction. +If core_sleep_o = 1 then clk_i is gated +off internally and it is allowing to gate off +clk_i externally as well (e.g. FPU).

+

See WFI for details.

+

COREV_CLUSTER = 1:

+

Core is sleeping because +of a cv.elw instruction. +If core_sleep_o = 1, +then the pulp_clock_en_i directly +controls the internally instantiated clock gate +and therefore pulp_clock_en_i can be set +to 0 to internally gate off clk_i. If +core_sleep_o = 0, then it is not allowed +to set pulp_clock_en_i to 0.

+

See PULP Cluster Extension for details.

+
+
+

Note

+

The semantics of pulp_clock_en_i and core_sleep_o depend on the COREV_CLUSTER parameter.

+
+
+

Startup behavior

+

clk_i is internally gated off (while signaling core_sleep_o = 0) during CV32E40P startup:

+
+
    +
  • clk_i is internally gated off during rst_ni assertion

  • +
  • clk_i is internally gated off from rst_ni deassertion until fetch_enable_i = 1

  • +
+
+

After initial assertion of fetch_enable_i, the fetch_enable_i signal is ignored until after a next reset assertion.

+
+
+

WFI

+

The wfi instruction can under certain conditions be used to enter sleep mode awaiting a locally enabled +interrupt to become pending. The operation of wfi is unaffected by the global interrupt bits in mstatus.

+

A wfi will not enter sleep mode but will be executed as a regular nop, if any of the following conditions apply:

+
+
    +
  • debug_req_i = 1 or a debug request is pending

  • +
  • The core is in debug mode

  • +
  • The core is performing single stepping (debug)

  • +
  • The core has a trigger match (debug)

  • +
  • COREV_CLUSTER = 1

  • +
+
+

If a wfi causes sleep mode entry, then core_sleep_o is set to 1 and clk_i is gated off internally. +clk_i is allowed to be gated off externally as well in this scenario. A wake-up can be triggered by any of the following:

+
+
    +
  • A locally enabled interrupt is pending

  • +
  • A debug request is pending

  • +
  • Core is in debug mode

  • +
+
+

Upon wake-up core_sleep_o is set to 0, clk_i will no longer be gated internally, must not be gated off externally, and +instruction execution resumes.

+

If one of the above wake-up conditions coincides with the wfi instruction, then sleep mode is not entered and core_sleep_o +will not become 1.

+

Figure 9 shows an example waveform for sleep mode entry because of a wfi instruction.

+
+_images/wfi.svg
+

Figure 9 wfi example

+
+
+
+
+

PULP Cluster Extension

+

CV32E40P has an optional extension to enable its usage in a PULP Cluster in the PULP (Parallel Ultra Low Power) platform. +This extension is enabled by setting the COREV_CLUSTER parameter to 1. The PULP platform is organized as clusters of +multiple (typically 4 or 8) CV32E40P cores that share a tightly-coupled data memory, aimed at running digital signal processing +applications efficiently.

+

The mechanism via which CV32E40P cores in a PULP Cluster synchronize with each other is implemented via the custom cv.elw instruction +that performs a read transaction on an external Event Unit (which for example implements barriers and semaphores). This +read transaction to the Event Unit together with the core_sleep_o signal inform the Event Unit that the CV32E40P is not busy and +ready to go to sleep. Only in that case the Event Unit is allowed to set pulp_clock_en_i to 0, thereby gating off clk_i +internal to the core. Once the CV32E40P core is ready to start again (e.g. when the last core meets the barrier), pulp_clock_en_i is +set to 1 thereby enabling the CV32E40P to run again.

+

If the PULP Cluster extension is not used (COREV_CLUSTER = 0), the pulp_clock_en_i signal is not used and should be tied to 0.

+

Execution of a cv.elw instructions causes core_sleep_o = 1 only if all of the following conditions are met:

+
+
    +
  • The cv.elw did not yet complete (which can be achieved by witholding data_gnt_i and/or data_rvalid_i)

  • +
  • No debug request is pending

  • +
  • The core is not in debug mode

  • +
  • The core is not single stepping (debug)

  • +
  • The core does not have a trigger match (debug)

  • +
+
+

As pulp_clock_en_i can directly impact the internal clock gate, certain requirements are imposed on the environment of CV32E40P +in case COREV_CLUSTER = 1:

+
+
    +
  • If core_sleep_o = 0, then pulp_clock_en_i must be 1

  • +
  • If pulp_clock_en_i = 0, then irq_i[*] must be 0

  • +
  • If pulp_clock_en_i = 0, then debug_req_i must be 0

  • +
  • If pulp_clock_en_i = 0, then instr_rvalid_i must be 0

  • +
  • If pulp_clock_en_i = 0, then instr_gnt_i must be 0

  • +
  • If pulp_clock_en_i = 0, then data_rvalid_i must be 0

  • +
  • If pulp_clock_en_i = 0, then data_gnt_i must be 0

  • +
+
+

Figure 10 shows an example waveform for sleep mode entry because of a cv.elw instruction.

+
+_images/load_event.svg
+

Figure 10 cv.elw example

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/html/verification.html b/docs/html/verification.html new file mode 100644 index 000000000..169a91e74 --- /dev/null +++ b/docs/html/verification.html @@ -0,0 +1,321 @@ + + + + + + + Verification — CORE-V CV32E40P User Manual documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Verification

+

The verification environment (testbenches, testcases, etc.) for the CV32E40P +core can be found at core-v-verif. +It is recommended to start by reviewing the +CORE-V Verification Strategy.

+
+

v1.0.0 verification

+

In early 2021 the CV32E40P achieved Functional RTL Freeze (released with cv32e40p_v1.0.0 version), meaning that is has been fully verified as per its +Verification Plan. +Final functional, code and test coverage reports can be found here.

+

The unofficial start date for the CV32E40P verification effort is 2020-02-27, +which is the date the core-v-verif environment “went live”. Between then and +RTL Freeze, a total of 47 RTL issues and 38 User Manual issues were identified +and resolved 1. A breakdown of the RTL issues is as follows:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5 How RTL Issues Were Found

“Found By”

Count

Note

Simulation

18

See classification below

Inspection

13

Human review of the RTL

Formal Verification

13

This includes both Designer and Verifier use of FV

Lint

2

Unknown

1

+

A classification of the simulation issues by method used to identify them is informative:

+ + +++++ + + + + + + + + + + + + + + + + + + + + +
Table 6 Breakdown of Issues found by Simulation

Simulation Method

Count

Note

Directed, self-checking test

10

Many test supplied by Design team and a couple from the Open Source Community at large

Step & Compare

6

Issues directly attributed to S&C against ISS

Constrained-Random

2

Test generated by corev-dv (extension of riscv-dv)

+

A classification of the issues themselves:

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7 Issue Classification

Issue Type

Count

Note

RTL Functional

40

A bug!

RTL coding style

4

Linter issues, removing TODOs, removing `ifdefs, etc.

Non-RTL functional

1

Issue related to behavioral tracer (not part of the core)

Unreproducible

1

Invalid

1

+

Additional details are available as part of the CV32E40P v1.0.0 Report.

+
+
1
+

It is a testament on the quality of the work done by the PULP platform team +that it took a team of professonal verification engineers more than 9 months +to find all these issues.

+
+
+
+
+

v2.0.0 verification

+
+

Simulation verification

+

core-v-verif verification environment for v1.0.0 was using a step&compare methodology with an instruction set simulator (ISS) from Imperas Software as the reference model. +This strategy was successful, but inefficient because the step&compare logic in the testbench must compensate for the cycle-time effects of events that are asynchronous to the instruction stream such as interrupts, debug resets plus bus errors and random delays on instruction fetch and load/store memory buses. +For verification of v2.0.0 release of the CV32E40P core, the step-and-compare and the ISS have been replaced by a true reference model (RM) called ImperasDV. In addition, the Imperas Reference Model has been extended to support the v2 Xpulp instructions specification.

+

Another innovation for v2.0.0 was the adoption of a standardized tracer interface to the DUT and RM, based on the open-source RISC-V Verification Interface (RVVI). The use of well documented, standardized interfaces greatly simplifies the integration of the DUT with the RM.

+

WIP…

+
+
+

Formal verification

+

To accelerate the verification of more than 300 Xpulp instructions, Formal Verification methodology has been used with Siemens EDA Onespin tools and their RISC-V ISA app.

+

The Xpulp instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and Xpulp extensions. +This has been applied on 5 different core configurations (controlled via SystemVerilog parameters).

+

WIP…

+
+
+

Reports

+

WIP…

+
+
+
+

Tracer

+

TODO: To re-work with ImperasDV tracer.

+

The module cv32e40p_tracer can be used to create a log of the executed instructions. +It is a behavioral, non-synthesizable, module instantiated in the example testbench that is provided for +the cv32e40p_top. It can be enabled during simulation by defining CV32E40P_TRACE_EXECUTION.

+
+

Output file

+

All traced instructions are written to a log file. +The log file is named trace_core_<HARTID>.log, with <HARTID> being the 32 digit hart ID of the core being traced.

+
+
+

Trace output format

+

The trace output is in tab-separated columns.

+
    +
  1. Time: The current simulation time.

  2. +
  3. Cycle: The number of cycles since the last reset.

  4. +
  5. PC: The program counter

  6. +
  7. Instr: The executed instruction (base 16). +32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions.

  8. +
  9. Decoded instruction: The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like objdump -Mnumeric -Mno-aliases -D. +- Unsigned numbers are given in hex (prefixed with 0x), signed numbers are given as decimal numbers. +- Numeric register names are used (e.g. x1). +- Symbolic CSR names are used. +- Jump/branch targets are given as absolute address if possible (PC + immediate).

  10. +
  11. Register and memory contents: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as registername=value, reads as registername:value. For memory accesses, the address and the loaded and stored data are given.

  12. +
+
Time Cycle PC       Instr    Decoded instruction Register and memory contents
+ 130    61 00000150 4481     c.li    x9,0        x9=0x00000000
+ 132    62 00000152 00008437 lui     x8,0x8      x8=0x00008000
+ 134    63 00000156 fff40413 addi    x8,x8,-1    x8:0x00008000 x8=0x00007fff
+ 136    64 0000015a 8c65     c.and   x8,x9       x8:0x00007fff x9:0x00000000 x8=0x00000000
+ 142    67 0000015c c622     c.swsp  x8,12(x2)   x2:0x00002000 x8:0x00000000 PA:0x0000200c
+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/images/CV32E40P_Block_Diagram.png b/docs/images/CV32E40P_Block_Diagram.png old mode 100644 new mode 100755 index 90643caac..919bacdc4 Binary files a/docs/images/CV32E40P_Block_Diagram.png and b/docs/images/CV32E40P_Block_Diagram.png differ diff --git a/docs/images/CV32E40P_Block_Diagram.svg b/docs/images/CV32E40P_Block_Diagram.svg index 83f862ddd..a9865da7c 100644 --- a/docs/images/CV32E40P_Block_Diagram.svg +++ b/docs/images/CV32E40P_Block_Diagram.svg @@ -1,226 +1,225 @@ image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PC - - - - - - - - - - - - - WB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -IFID - - - - - - - - - - - - - IDEX - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXWB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IM - - - - - - - - - - - - - RF - - - - - - - - - - - - - EX - - - - - - - - - - - - - WB - - - - - - - - - - - - - IM - - - - - - - - - - - - - RF - - - - - - - - - - - - - EX - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -RF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CV32E40P - - - - - - - - - - + x="128.71898" + y="473.45087" + style="font-size:19.2px;line-height:1.25;font-family:sans-serif;fill:#00006e;fill-opacity:1;stroke:#00006e;stroke-opacity:1">CV32E40P topCV32E40P core registerfile - + id="tspan1790">file(s) DIA - rB - rA - DA - DB - DC - DIB - rC - - - - - -CSR - OpA - OpB - RD - ALUALU - + id="tspan917">DIV OpB - OpC - RD - OpA - MULT - + x="483.91998" + y="313.07068">MULTDOTP OpA - OpB - RD - OpC - - - - - - - - - - - - - - - - - - - - - - - - -prefetchbuffer - - - - -decoderdecoder +controller - aligner - - - - - - - - - - - - - - - -LSULSU +OpAOpA +OpBOpB +RDRD +OpCOpC +compressdecodercompressdecoder +hwloopregshwloopregs +sleep unitsleep unit +interrupt interfaceinterrupt interface +debug interfacedebug interface +instructioninstructioninterfaceinterface +datadatainterfaceinterface +FPU +OpA +OpB +RD +OpC + + inkscape:connector-curvature="0" /> + diff --git a/docs/images/debug_halted.svg b/docs/images/debug_halted.svg old mode 100755 new mode 100644 diff --git a/docs/images/debug_running.svg b/docs/images/debug_running.svg old mode 100755 new mode 100644 diff --git a/docs/images/image_sources/debug_halted.tim b/docs/images/image_sources/debug_halted.tim old mode 100755 new mode 100644 diff --git a/docs/images/image_sources/debug_running.tim b/docs/images/image_sources/debug_running.tim old mode 100755 new mode 100644 diff --git a/docs/images/image_sources/load_event.tim b/docs/images/image_sources/load_event.tim old mode 100755 new mode 100644 diff --git a/docs/images/image_sources/wfi.tim b/docs/images/image_sources/wfi.tim old mode 100755 new mode 100644 diff --git a/docs/images/load_event.svg b/docs/images/load_event.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_data_back_to_back.svg b/docs/images/obi_data_back_to_back.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_data_basic.svg b/docs/images/obi_data_basic.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_data_multiple_outstanding.svg b/docs/images/obi_data_multiple_outstanding.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_data_slow_response.svg b/docs/images/obi_data_slow_response.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_instruction_basic.svg b/docs/images/obi_instruction_basic.svg old mode 100755 new mode 100644 diff --git a/docs/images/obi_instruction_multiple_outstanding.svg b/docs/images/obi_instruction_multiple_outstanding.svg old mode 100755 new mode 100644 diff --git a/docs/images/wfi.svg b/docs/images/wfi.svg old mode 100755 new mode 100644 diff --git a/docs/source/apu.rst b/docs/source/apu.rst deleted file mode 100644 index 6ee57c6b2..000000000 --- a/docs/source/apu.rst +++ /dev/null @@ -1,86 +0,0 @@ -.. - Copyright (c) 2020 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://solderpad.org/licenses/ - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - -.. _apu: - -Auxiliary Processing Unit (APU) -=============================== - -Auxiliary Processing Unit Interface ------------------------------------ - -:numref:`Auxiliary Processing Unit interface signals` describes the signals of the Auxiliary Processing Unit interface. - -.. table:: Auxiliary Processing Unit interface signals - :name: Auxiliary Processing Unit interface signals - - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | **Signal** | **Direction** | **Description** | - +=================================+===============+==============================================================================================================================+ - | ``apu_req_o`` | output | Request valid, will stay high until ``apu_gnt_i`` is high for one cycle | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_gnt_i`` | input | The other side accepted the request. ``apu_operands_o``, ``apu_op_o``, ``apu_flags_o`` may change in the next cycle. | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_operands_o[2:0][31:0]`` | output | APU's operands | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_op_o[5:0]`` | output | APU's operation | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_flags_o[14:0]`` | output | APU's flags | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_rvalid_i`` | input | ``apu_result_i`` holds valid data when ``apu_valid_i`` is high. This signal will be high for exactly one cycle per request | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_result_i[31:0]`` | input | APU's result | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``apu_flags_i[4:0]`` | input | APU's flag result | - +---------------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------+ - - -Protocol --------- - -The CV32E40P apu interface uses the ``apu_operands_o``, ``apu_op_o``, and ``apu_flags_o`` as the address signal during the Address phase, indicating its validity with the ``apu_req_o`` signal. It uses the ``apu_result_i`` and ``apu_flags_i`` as the rdata of the response phase. It does not implement the OBI signals: we, be, wdata, auser, wuser, aid, -rready, err, ruser, rid. These signals can be thought of as being tied off as -specified in the OBI specification. -The CV32E40P apu interface can cause up to two outstanding transactions. - -Connection with the FPU ------------------------ - -The CV32E40P sends FP operands over the ``apu_operands_o`` bus; the decoded RV32F operation as ADD, SUB, MUL, etc through the ``apu_op_o`` bus; the cast, destination and source formats as well as rounding mode through the ``apu_flags_o`` bus. The respose is the FPU result and relative output flags as Overflow, Underflow, etc. - - -APU Tracer ----------- - -The module ``cv32e40p_apu_tracer`` can be used to create a log of the APU interface. -It is a behavioral, non-synthesizable, module instantiated in the example testbench that is provided for -the ``cv32e40p_core``. It can be enabled during simulation by defining **CV32E40P_APU_TRACE**. - -Output file ------------ - -The APU trace is written to a log file which is named ``apu_trace_core_.log``, with ```` being -the 32 digit hart ID of the core being traced. - -Trace output format -------------------- - -The trace output is in tab-separated columns. - -1. **Time**: The current simulation time. -2. **Register**: The register file write address. -3. **Result**: The register file write data. diff --git a/docs/source/conf.py b/docs/source/conf.py index 0bc083e57..dbb7b0203 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,7 +38,7 @@ # -- Project information ----------------------------------------------------- project = u'CORE-V CV32E40P User Manual' -copyright = u'2022, OpenHW Group' +copyright = u'2023, OpenHW Group' author = u'PULP Platform and OpenHW Group' # The short X.Y version diff --git a/docs/source/control_status_registers.rst b/docs/source/control_status_registers.rst index 66aec6cba..d18727951 100644 --- a/docs/source/control_status_registers.rst +++ b/docs/source/control_status_registers.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -32,16 +32,11 @@ CSR Map :numref:`Control and Status Register Map` lists all implemented CSRs. Two columns in :numref:`Control and Status Register Map` may require additional explanation: -The **Parameter** column identifies those CSRs that are dependent on the value -of specific compile/synthesis parameters. If these parameters are not set as -indicated in :numref:`Control and Status Register Map` then the associated CSR is not implemented. If the -parameter column is empty then the associated CSR is always implemented. - -The **Privilege** column indicates the access mode of a CSR. The first letter -indicates the lowest privilege level required to access the CSR. Attempts to +The **Privilege** column indicates the access mode of a CSR. The first letter +indicates the lowest privilege level required to access the CSR. Attempts to access a CSR with a higher privilege level than the core is currently running in will throw an illegal instruction exception. This is largely a moot point -for the CV32E40P as it only supports machine and debug modes. The remaining +for the CV32E40P as it only supports machine and debug modes. The remaining letters indicate the read and/or write behavior of the CSR when accessed by the indicated or higher privilge level: @@ -56,164 +51,191 @@ Writes of a non-supported value to **WLRL** bitfields of a **RW** CSR do not res instruction exception. The exact bitfield access types, e.g. **WLRL** or **WARL**, can be found in the RISC-V privileged specification. +In the **Description** column there is a specific comment which identifies those CSRs that are dependent on the value +of specific parameters. If these parameters are not set as +indicated in :numref:`Control and Status Register Map` then the associated CSR is not implemented. If the column does not +mention any parameter then the associated CSR is always implemented. + Reads or writes to a CSR that is not implemented will result in an illegal instruction exception. .. table:: Control and Status Register Map :name: Control and Status Register Map - - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | CSR Address | Name | Privilege | Parameter | Description | - +===============+===================+============+=====================+=========================================================+ - | User CSRs | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x001 | ``fflags`` | URW | ``FPU`` = 1 | Floating-point accrued exceptions. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x002 | ``frm`` | URW | ``FPU`` = 1 | Floating-point dynamic rounding mode. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x003 | ``fcsr`` | URW | ``FPU`` = 1 | Floating-point control and status register. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC00 | ``cycle`` | URO | | (HPM) Cycle Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC02 | ``instret`` | URO | | (HPM) Instructions-Retired Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC03 | ``hpmcounter3`` | URO | | (HPM) Performance-Monitoring Counter 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | . . . . . | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC1F | ``hpmcounter31`` | URO | | (HPM) Performance-Monitoring Counter 31 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC80 | ``cycleh`` | URO | | (HPM) Upper 32 Cycle Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC82 | ``instreth`` | URO | | (HPM) Upper 32 Instructions-Retired Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC83 | ``hpmcounterh3`` | URO | | (HPM) Upper 32 Performance-Monitoring Counter 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | . . . . . | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xC9F | ``hpmcounterh31`` | URO | | (HPM) Upper 32 Performance-Monitoring Counter 31 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | User Custom CSRs | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC0 | ``lpstart0`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 0 Start. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC1 | ``lpend0`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 0 End. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC2 | ``lpcount0`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 0 Counter. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC4 | ``lpstart1`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 1 Start. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC5 | ``lpend1`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 1 End. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC6 | ``lpcount1`` | URO | ``PULP_XPULP`` = 1 | Hardware Loop 1 Counter. | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC8 | ``uhartid`` | URO | ``PULP_XPULP`` = 1 & | Hardware Thread ID | - | | | | | | - | | | | ``PULP_SECURE`` = 1 | | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xCC9 | ``privlv`` | URO | ``PULP_XPULP`` = 1 & | Privilege Level | - | | | | | | - | | | | ``PULP_SECURE`` = 1 | | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | Machine CSRs | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x300 | ``mstatus`` | MRW | | Machine Status | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x301 | ``misa`` | MRW | | Machine ISA | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x304 | ``mie`` | MRW | | Machine Interrupt Enable Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x305 | ``mtvec`` | MRW | | Machine Trap-Handler Base Address | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x320 | ``mcountinhibit`` | MRW | | (HPM) Machine Counter-Inhibit Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x323 | ``mhpmevent3`` | MRW | | (HPM) Machine Performance-Monitoring Event Selector 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | . . . . . | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x33F | ``mhpmevent31`` | MRW | | (HPM) Machine Performance-Monitoring Event Selector 31 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x340 | ``mscratch`` | MRW | | Machine Scratch | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x341 | ``mepc`` | MRW | | Machine Exception Program Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x342 | ``mcause`` | MRW | | Machine Trap Cause | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x343 | ``mtval`` | MRW | | Machine Trap Value | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x344 | ``mip`` | MRW | | Machine Interrupt Pending Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A0 | ``tselect`` | MRW | | Trigger Select Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A1 | ``tdata1`` | MRW | | Trigger Data Register 1 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A2 | ``tdata2`` | MRW | | Trigger Data Register 2 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A3 | ``tdata3`` | MRW | | Trigger Data Register 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A4 | ``tinfo`` | MRO | | Trigger Info | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7A8 | ``mcontext`` | MRW | | Machine Context Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7AA | ``scontext`` | MRW | | Machine Context Register | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7B0 | ``dcsr`` | DRW | | Debug Control and Status | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7B1 | ``dpc`` | DRW | | Debug PC | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7B2 | ``dscratch0`` | DRW | | Debug Scratch Register 0 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0x7B3 | ``dscratch1`` | DRW | | Debug Scratch Register 1 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB00 | ``mcycle`` | MRW | | (HPM) Machine Cycle Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB02 | ``minstret`` | MRW | | (HPM) Machine Instructions-Retired Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB03 | ``mhpmcounter3`` | MRW | | (HPM) Machine Performance-Monitoring Counter 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | . . . . . | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB1F | ``mhpmcounter31`` | MRW | | (HPM) Machine Performance-Monitoring Counter 31 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB80 | ``mcycleh`` | MRW | | (HPM) Upper 32 Machine Cycle Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB82 | ``minstreth`` | MRW | | (HPM) Upper 32 Machine Instructions-Retired Counter | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB83 | ``mhpmcounterh3`` | MRW | | (HPM) Upper 32 Machine Performance-Monitoring Counter 3 | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | . . . . . | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xB9F | ``mhpmcounterh31``| MRW | | (HPM) Upper 32 Machine Performance-Monitoring Counter 31| - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xF11 | ``mvendorid`` | MRO | | Machine Vendor ID | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xF12 | ``marchid`` | MRO | | Machine Architecture ID | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xF13 | ``mimpid`` | MRO | | Machine Implementation ID | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ - | 0xF14 | ``mhartid`` | MRO | | Hardware Thread ID | - +---------------+-------------------+-----------+----------------------+---------------------------------------------------------+ + :widths: 13 17 15 55 + :class: no-scrollbar-table + + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **CSR Address** | **Name** | **Privilege** | **Description** | + +=================+===================+===============+==============================================================+ + | **User CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x001 | ``fflags`` | URW | Floating-point accrued exceptions. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x002 | ``frm`` | URW | Floating-point dynamic rounding mode. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x003 | ``fcsr`` | URW | Floating-point control and status register. | + | | | | | + | | | | Only present if ``FPU`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC00 | ``cycle`` | URO | (HPM) Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC02 | ``instret`` | URO | (HPM) Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC03 | ``hpmcounter3`` | URO | (HPM) Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC1F | ``hpmcounter31`` | URO | (HPM) Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC80 | ``cycleh`` | URO | (HPM) Upper 32 bits Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC82 | ``instreth`` | URO | (HPM) Upper 32 bits Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC83 | ``hpmcounterh3`` | URO | (HPM) Upper 32 bits Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xC9F | ``hpmcounterh31`` | URO | (HPM) Upper 32 bits Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **User Custom CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC0 | ``lpstart0`` | URO | Hardware Loop 0 Start. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC1 | ``lpend0`` | URO | Hardware Loop 0 End. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC2 | ``lpcount0`` | URO | Hardware Loop 0 Counter. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC4 | ``lpstart1`` | URO | Hardware Loop 1 Start. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC5 | ``lpend1`` | URO | Hardware Loop 1 End. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCC6 | ``lpcount1`` | URO | Hardware Loop 1 Counter. | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD0 | ``uhartid`` | URO | Hardware Thread ID | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 & ``PULP_SECURE`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD1 | ``privlv`` | URO | Privilege Level | + | | | | | + | | | | Only present if ``COREV_PULP`` = 1 & ``PULP_SECURE`` = 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xCD2 | ``zfinx`` | URO | ``ZFINX`` ISA | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | **Machine CSRs** | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x300 | ``mstatus`` | MRW | Machine Status | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x301 | ``misa`` | MRW | Machine ISA | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x304 | ``mie`` | MRW | Machine Interrupt Enable register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x305 | ``mtvec`` | MRW | Machine Trap-Handler Base Address | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x320 | ``mcountinhibit`` | MRW | (HPM) Machine Counter-Inhibit register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x323 | ``mhpmevent3`` | MRW | (HPM) Machine Performance-Monitoring Event Selector 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x33F | ``mhpmevent31`` | MRW | (HPM) Machine Performance-Monitoring Event Selector 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x340 | ``mscratch`` | MRW | Machine Scratch | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x341 | ``mepc`` | MRW | Machine Exception Program Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x342 | ``mcause`` | MRW | Machine Trap Cause | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x343 | ``mtval`` | MRW | Machine Trap Value | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x344 | ``mip`` | MRW | Machine Interrupt Pending register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A0 | ``tselect`` | MRW | Trigger Select register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A1 | ``tdata1`` | MRW | Trigger Data register 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A2 | ``tdata2`` | MRW | Trigger Data register 2 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A3 | ``tdata3`` | MRW | Trigger Data register 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A4 | ``tinfo`` | MRO | Trigger Info | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7A8 | ``mcontext`` | MRW | Machine Context register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7AA | ``scontext`` | MRW | Machine Context register | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B0 | ``dcsr`` | DRW | Debug Control and Status | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B1 | ``dpc`` | DRW | Debug PC | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B2 | ``dscratch0`` | DRW | Debug Scratch register 0 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0x7B3 | ``dscratch1`` | DRW | Debug Scratch register 1 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB00 | ``mcycle`` | MRW | (HPM) Machine Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB02 | ``minstret`` | MRW | (HPM) Machine Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB03 | ``mhpmcounter3`` | MRW | (HPM) Machine Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB1F | ``mhpmcounter31`` | MRW | (HPM) Machine Performance-Monitoring Counter 31 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB80 | ``mcycleh`` | MRW | (HPM) Upper 32 bits Machine Cycle Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB82 | ``minstreth`` | MRW | (HPM) Upper 32 bits Machine Instructions-Retired Counter | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB83 | ``mhpmcounterh3`` | MRW | (HPM) Upper 32 bits Machine Performance-Monitoring Counter 3 | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | . . . . | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xB9F | ``mhpmcounterh31``| MRW | (HPM) Upper 32 bits Machine Performance-Monitoring Counter 31| + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF11 | ``mvendorid`` | MRO | Machine Vendor ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF12 | ``marchid`` | MRO | Machine Architecture ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF13 | ``mimpid`` | MRO | Machine Implementation ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ + | 0xF14 | ``mhartid`` | MRO | Hardware Thread ID | + +-----------------+-------------------+---------------+--------------------------------------------------------------+ .. only:: USER .. table:: Control and Status Register Map (additional CSRs for User mode) :name: Control and Status Register Map (additional CSRs for User mode) - +-------------------+----------------+------------+------------------------------------------+ - | CSR address | Name | Privilege | Description | - +-------------------+----------------+------------+------------------------------------------+ - | | | | | - +===================+================+============+==========================================+ - | 0x000 | ``ustatus`` | URW | User Status | - +-------------------+----------------+------------+------------------------------------------+ - | 0x005 | ``utvec`` | URW | User Trap-Handler Base Address | - +-------------------+----------------+------------+------------------------------------------+ - | 0x041 | ``uepc`` | URW | User Exception Program Counter | - +-------------------+----------------+------------+------------------------------------------+ - | 0x042 | ``ucause`` | URW | User Trap Cause | - +-------------------+----------------+------------+------------------------------------------+ - | 0x306 | ``mcounteren`` | MRW | Machine Counter Enable | - +-------------------+----------------+------------+------------------------------------------+ + +-------------------+----------------+---------------+------------------------------------------+ + | **CSR address** | **Name** | **Privilege** | **Description** | + +-------------------+----------------+---------------+------------------------------------------+ + | | | | | + +===================+================+===============+==========================================+ + | 0x000 | ``ustatus`` | URW | User Status | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x005 | ``utvec`` | URW | User Trap-Handler Base Address | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x041 | ``uepc`` | URW | User Exception Program Counter | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x042 | ``ucause`` | URW | User Trap Cause | + +-------------------+----------------+---------------+------------------------------------------+ + | 0x306 | ``mcounteren`` | MRW | Machine Counter Enable | + +-------------------+----------------+---------------+------------------------------------------+ CSR Descriptions ----------------- @@ -243,21 +265,27 @@ CSR Address: 0x001 (only present if ``FPU`` = 1) Reset Value: 0x0000_0000 -+-------------+-----------+-------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+=========================================================================+ -| 31:5 | RO | Writes are ignored; reads return 0. | -+-------------+-----------+-------------------------------------------------------------------------+ -| 4 | RW | NV- Invalid Operation | -+-------------+-----------+-------------------------------------------------------------------------+ -| 3 | RW | DZ - Divide by Zero | -+-------------+-----------+-------------------------------------------------------------------------+ -| 2 | RW | OF - Overflow | -+-------------+-----------+-------------------------------------------------------------------------+ -| 1 | RW | UF - Underflow | -+-------------+-----------+-------------------------------------------------------------------------+ -| 0 | RW | NX - Inexact | -+-------------+-----------+-------------------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================+ + | 31:5 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+-------------------------------------------------------------------------+ + | 4 | RW | NV - Invalid Operation | + +-------------+-----------+-------------------------------------------------------------------------+ + | 3 | RW | DZ - Divide by Zero | + +-------------+-----------+-------------------------------------------------------------------------+ + | 2 | RW | OF - Overflow | + +-------------+-----------+-------------------------------------------------------------------------+ + | 1 | RW | UF - Underflow | + +-------------+-----------+-------------------------------------------------------------------------+ + | 0 | RW | NX - Inexact | + +-------------+-----------+-------------------------------------------------------------------------+ .. _csr-frm: @@ -268,14 +296,35 @@ CSR Address: 0x002 (only present if ``FPU`` = 1) Reset Value: 0x0000_0000 -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:3 | RO | Writes are ignored; reads return 0. | -+-------------+-----------+------------------------------------------------------------------------+ -| 2:0 | RW | Rounding mode. 000 = RNE, 001 = RTZ, 010 = RDN, 011 = RUP, 100 = RMM | -| | | 101 = Invalid, 110 = Invalid, 111 = DYN. | -+-------------+-----------+------------------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+--------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+======================================+ + | 31:3 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+--------------------------------------+ + | 2:0 | RW | Rounding mode: | + | | | | + | | | 000 = RNE | + | | | | + | | | 001 = RTZ | + | | | | + | | | 010 = RDN | + | | | | + | | | 011 = RUP | + | | | | + | | | 100 = RMM | + | | | | + | | | 101 = Invalid | + | | | | + | | | 110 = Invalid | + | | | | + | | | 111 = DYN | + +-------------+-----------+--------------------------------------+ .. _csr-fcsr: @@ -286,15 +335,21 @@ CSR Address: 0x003 (only present if ``FPU`` = 1) Reset Value: 0x0000_0000 -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:8 | RO | Reserved. Writes are ignored; reads return 0. | -+-------------+-----------+------------------------------------------------------------------------+ -| 7:5 | RW | Rounding Mode (``frm``) | -+-------------+-----------+------------------------------------------------------------------------+ -| 4:0 | RW | Accrued Exceptions (``fflags``) | -+-------------+-----------+------------------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:8 | RO | Reserved. Writes are ignored; reads return 0. | + +-------------+-----------+------------------------------------------------------------------------+ + | 7:5 | RW | Rounding Mode (``frm``) | + +-------------+-----------+------------------------------------------------------------------------+ + | 4:0 | RW | Accrued Exceptions (``fflags``) | + +-------------+-----------+------------------------------------------------------------------------+ Hardware Loops CSRs ::::::::::::::::::: @@ -302,95 +357,63 @@ Hardware Loops CSRs HWLoop Start Address 0/1 (``lpstart0/1``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSR Address: 0xCC0/0xCC4 (only present if ``PULP_XPULP`` = 1) +CSR Address: 0xCC0/0xCC4 (only present if ``COREV_PULP`` = 1) Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+-------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+===========================================+ -| 31:0 | RW | Start Address of the HWLoop 0/1. | -+-------------+-----------+-------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | Start Address of the HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ HWLoop End Address 0/1 (``lpend0/1``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSR Address: 0xCC1/0xCC5 (only present if ``PULP_XPULP`` = 1) +CSR Address: 0xCC1/0xCC5 (only present if ``COREV_PULP`` = 1) Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+-------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+===========================================+ -| 31:0 | RW | End Address of the HWLoop 0/1. | -+-------------+-----------+-------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | End Address of the HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ HWLoop Count Address 0/1 (``lpcount0/1``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSR Address: 0xCC2/0xCC6 (only present if ``PULP_XPULP`` = 1) +CSR Address: 0xCC2/0xCC6 (only present if ``COREV_PULP`` = 1) Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+-------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+===========================================+ -| 31:0 | RW | Number of iteration of HWLoop 0/1. | -+-------------+-----------+-------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table -.. _csr-uhartid: + +-------------+-----------+-------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===========================================+ + | 31:0 | RW | Number of iteration of HWLoop 0/1. | + +-------------+-----------+-------------------------------------------+ -Misc. CSRs +Other CSRs :::::::::: -User Hardware Thread ID (``uhartid``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0xCC8 (only present if ``PULP_XPULP`` = 1 and ``PULP_SECURE`` = 1) - -Reset Value: Defined - -.. table:: UHARTID - :name: UHARTID - - +-------------+-----------+----------------------------------------------------------------+ - | Bit # | Mode | Description | - +=============+===========+================================================================+ - | 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | - +-------------+-----------+----------------------------------------------------------------+ - -Similar to ``mhartid`` the ``uhartid`` provides the Hardware Thread ID. It differs from ``mhartid`` only in the required privilege level. -On CV32E40P, as it is a machine mode only implementation, this difference is not noticeable. - -Privilege Level (``privlv``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0xCC9 (only present if ``PULP_XPULP`` = 1 and ``PULP_SECURE`` = 1) - -Reset Value: 0x0000_0003 - -.. table:: PRIVLV - :name: PRIVLV - - +-------------+-----------+--------------------------------------------------+ - | Bit # | Mode | Description | - +=============+===========+==================================================+ - | 31:2 | RO | Reads as 0. | - +-------------+-----------+--------------------------------------------------+ - | 1:0 | RO | Current Privilege Level. 11 = Machine, | - | | | 10 = Hypervisor, 01 = Supervisor, 00 = User. | - | | | CV32E40P only supports Machine mode. | - +-------------+-----------+--------------------------------------------------+ - -Machine CSRs -:::::::::::: - Machine Status (``mstatus``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -398,35 +421,55 @@ CSR Address: 0x300 Reset Value: 0x0000_1800 -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+=====================================================================================================================================================================================================================================================================+ -| 31 | RO | **SD:** State Dirty, set to 1 if **FS** = 11 meaning Floating Point state is dirty so save/restore is needed in case of context switch, hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 30:18 | RO | Reserved, hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 17 | RO | **MPRV:** hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 16:15 | RO | Unimplemented, hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 14:13 | RW | **FS:** Floating point State, hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 12:11 | RO | **MPP:** Machine Previous Priviledge mode, hardwired to 11 when the user mode is not enabled. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 10:8 | RO | Unimplemented, hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 7 | RO | **Previous Machine Interrupt Enable:** When an exception is encountered, MPIE will be set to MIE. When the mret instruction is executed, the value of MPIE will be stored to MIE. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 6:5 | RO | Unimplemented, hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 4 | RO | **Previous User Interrupt Enable:** If user mode is enabled, when an exception is encountered, UPIE will be set to UIE. When the uret instruction is executed, the value of UPIE will be stored to UIE. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 3 | RW | **Machine Interrupt Enable:** If you want to enable interrupt handling in your exception handler, set the Interrupt Enable MIE to 1 inside your handler code. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 2:1 | RO | Unimplemented, hardwired to 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 0 | RO | **User Interrupt Enable:** If you want to enable user level interrupt handling in your exception handler, set the Interrupt Enable UIE to 1 inside your handler code. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================================================================+ + | 31 | RO | **SD:** State Dirty | + | | | | + | | | SD set to 1 if **FS** = 11 meaning Floating point State is dirty so save/restore is needed in case of context switch. | + | | | | + | | | Hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 30:15 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 14:13 | RW | **FS:** Floating point State | + | | | | + | | | 00 = Off | + | | | | + | | | 01 = Initial | + | | | | + | | | 10 = Clean | + | | | | + | | | 11 = Dirty | + | | | | + | | | Hardwired to 0 if ``FPU`` = 0 or ``ZFINX`` = 1. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 12:11 | RO | **MPP:** Machine Previous Priviledge mode | + | | | | + | | | Hardwired to 11 when the user mode is not enabled. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 10:8 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 7 | RO | **MPIE:** Machine Previous Interrupt Enable | + | | | | + | | | When an exception is encountered, MPIE will be set to MIE. | + | | | When the mret instruction is executed, the value of MPIE will be stored to MIE. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 6:4 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 3 | RW | **MIE:** Machine Interrupt Enable | + | | | | + | | | If you want to enable interrupt handling in your exception handler, | + | | | set the Interrupt Enable MIE to 1 inside your handler code. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 2:0 | RO | Unimplemented, hardwired to 0. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ .. only:: USER @@ -439,94 +482,17 @@ Reset Value: 0x0000_1800 Detailed: - +-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | Bit # | Mode | Description | - +=============+===========+=====================================================================================================================================================================================================================================================================+ - | 4 | RW | **Previous User Interrupt Enable:** If user mode is enabled, when an exception is encountered, UPIE will be set to UIE. When the uret instruction is executed, the value of UPIE will be stored to UIE. | - +-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | 0 | RW | **User Interrupt Enable:** If you want to enable user level interrupt handling in your exception handler, set the Interrupt Enable UIE to 1 inside your handler code. | - +-------------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Machine ISA (``misa``) -~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0x301 - -Reset Value: defined - -Detailed: - -+-------------+------------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+============+========================================================================+ -| 31:30 | RO (0x1) | **MXL** (Machine XLEN). | -+-------------+------------+------------------------------------------------------------------------+ -| 29:26 | RO (0x0) | (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 25 | RO (0x0) | **Z** (Reserved). Read-only; writes are ignored. | -+-------------+------------+------------------------------------------------------------------------+ -| 24 | RO (0x0) | **Y** (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 23 | RO | **X** (Non-standard extensions present). | -+-------------+------------+------------------------------------------------------------------------+ -| 22 | RO (0x0) | **W** (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 21 | RO (0x0) | **V** (Tentatively reserved for Vector extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 20 | RO (0x0) | **U** (User mode implemented). | -+-------------+------------+------------------------------------------------------------------------+ -| 19 | RO (0x0) | **T** (Tentatively reserved for Transactional Memory extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 18 | RO (0x0) | **S** (Supervisor mode implemented). | -+-------------+------------+------------------------------------------------------------------------+ -| 17 | RO (0x0) | **R** (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 16 | RO (0x0) | **Q** (Quad-precision floating-point extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 15 | RO (0x0) | **P** (Tentatively reserved for Packed-SIMD extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 14 | RO (0x0) | **O** (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 13 | RO (0x0) | **N** (User-level interrupts supported). | -+-------------+------------+------------------------------------------------------------------------+ -| 12 | RO (0x1) | **M** (Integer Multiply/Divide extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 11 | RO (0x0) | **L** (Tentatively reserved for Decimal Floating-Point extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 10 | RO (0x0) | **K** (Reserved). | -+-------------+------------+------------------------------------------------------------------------+ -| 9 | RO (0x0) | **J** (Tentatively reserved for Dynamically Translated Languages | -| | | extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 8 | RO (0x1) | **I** (RV32I/64I/128I base ISA). | -+-------------+------------+------------------------------------------------------------------------+ -| 7 | RO (0x0) | **H** (Hypervisor extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 6 | RO (0x0) | **G** (Additional standard extensions present). | -+-------------+------------+------------------------------------------------------------------------+ -| 5 | RO | **F** (Single-precision floating-point extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 4 | RO (0x0) | **E** (RV32E base ISA). | -+-------------+------------+------------------------------------------------------------------------+ -| 3 | RO (0x0) | **D** (Double-precision floating-point extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 2 | RO (0x1) | **C** (Compressed extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 1 | RO (0x0) | **B** (Tentatively reserved for Bit-Manipulation extension). | -+-------------+------------+------------------------------------------------------------------------+ -| 0 | RO (0x0) | **A** (Atomic extension). | -+-------------+------------+------------------------------------------------------------------------+ - -All bitfields in the ``misa`` CSR read as 0 except for the following: - -* **C** = 1 -* **F** = 1 if ``FPU`` = 1 and ``ZFINX`` = 0 -* **I** = 1 -* **M** = 1 -* **X** = 1 if ``PULP_XPULP`` = 1 or ``PULP_CLUSTER`` = 1 -* **MXL** = 1 (i.e. XLEN = 32) - -Machine Interrupt Enable Register (``mie``) + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=========================================================================================================================+ + | 4 | RW | **Previous User Interrupt Enable:** If user mode is enabled, when an exception is encountered, UPIE will be set to UIE. | + | | | When the uret instruction is executed, the value of UPIE will be stored to UIE. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + | 0 | RW | **User Interrupt Enable:** If you want to enable user level interrupt handling in your exception handler, | + | | | set the Interrupt Enable UIE to 1 inside your handler code. | + +-------------+-----------+-------------------------------------------------------------------------------------------------------------------------+ + +Machine Interrupt Enable register (``mie``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x304 @@ -535,17 +501,37 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+==========================================================================================+ -| 31:16 | RW | Machine Fast Interrupt Enables: Set bit x to enable interrupt irq_i[x]. | -+-------------+-----------+------------------------------------------------------------------------------------------+ -| 11 | RW | **Machine External Interrupt Enable (MEIE)**: If set, irq_i[11] is enabled. | -+-------------+-----------+------------------------------------------------------------------------------------------+ -| 7 | RW | **Machine Timer Interrupt Enable (MTIE)**: If set, irq_i[7] is enabled. | -+-------------+-----------+------------------------------------------------------------------------------------------+ -| 3 | RW | **Machine Software Interrupt Enable (MSIE)**: if set, irq_i[3] is enabled. | -+-------------+-----------+------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==========================================================================================+ + | 31:16 | RW | Machine Fast Interrupt Enables | + | | | | + | | | Set bit x to enable interrupt irq_i[x] (x between 16 and 31). | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 15:12 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 11 | RW | **MEIE:** Machine External Interrupt Enable | + | | | | + | | | If set, irq_i[11] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 10:8 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 7 | RW | **MTIE:** Machine Timer Interrupt Enable | + | | | | + | | | If set, irq_i[7] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 6:4 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 3 | RW | **MSIE:** Machine Software Interrupt Enable | + | | | | + | | | If set, irq_i[3] is enabled. | + +-------------+-----------+------------------------------------------------------------------------------------------+ + | 2:0 | RO | Hardwired to 0. | + +-------------+-----------+------------------------------------------------------------------------------------------+ .. _csr-mtvec: @@ -558,17 +544,31 @@ Reset Value: Defined Detailed: -+-------------+-----------+---------------------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+===============================================================================================================+ -| 31 : 8 | RW | BASE[31:8]: The trap-handler base address, always aligned to 256 bytes. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------+ -| 7 : 2 | RO | BASE[7:2]: The trap-handler base address, always aligned to 256 bytes, i.e., mtvec[7:2] is always set to 0. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------+ -| 1 | RO | MODE[1]: always 0 | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------+ -| 0 | RW | MODE[0]: 0 = direct mode, 1 = vectored mode. | -+-------------+-----------+---------------------------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===============================================================================================================+ + | 31 : 8 | RW | BASE[31:8] | + | | | | + | | | The trap-handler base address, always aligned to 256 bytes. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 7 : 2 | RO | BASE[7:2] | + | | | | + | | | The trap-handler base address, always aligned to 256 bytes, i.e., mtvec[7:2] is always set to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 1 | RO | MODE[1] | + | | | | + | | | 0 | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ + | 0 | RW | MODE[0] | + | | | | + | | | 0 = Direct mode | + | | | | + | | | 1 = Vectored mode. | + +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ The initial value of ``mtvec`` is equal to {**mtvec_addr_i[31:8]**, 6'b0, 2'b01}. @@ -577,83 +577,6 @@ handler using the content of the MTVEC[31:8] as base address. Only 8-byte aligned addresses are allowed. Both direct mode and vectored mode are supported. -.. only:: USER - - Machine Counter Enable (``mcounteren``) - --------------------------------------- - - CSR Address: 0x306 - - Reset Value: 0x0000_0000 - - Detailed: - - Each bit in the machine counter-enable register allows the associated read-only - unprivileged shadow performance register to be read from user mode. If the bit - is clear an attempt to read the register in user mode will trigger an illegal - instruction exception. - - +-------+------+------------------------------------------------------------------+ - | Bit# | Mode | Description | - +=======+======+==================================================================+ - | 31:4 | RW | Dependent on number of counters implemented in design parameter | - +-------+------+------------------------------------------------------------------+ - | 3 | RW | **selectors:** hpmcounter3 enable for user mode | - +-------+------+------------------------------------------------------------------+ - | 2 | RW | instret enable for user mode | - +-------+------+------------------------------------------------------------------+ - | 1 | RO | 0 | - +-------+------+------------------------------------------------------------------+ - | 0 | RW | cycle enable for user mode | - +-------+------+------------------------------------------------------------------+ - -Machine Counter-Inhibit Register (``mcountinhibit``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0x320 - -Reset Value: 0x0000_000D - -The performance counter inhibit control register. The default value is to inihibit counters out of reset. -The bit returns a read value of 0 for non implemented counters. This reset value -shows the result using the default number of performance counters to be 1. - -Detailed: - -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:4 | RW | Dependent on number of counters implemented in design parameter | -+-------+------+------------------------------------------------------------------+ -| 3 | RW | **selectors:** mhpmcounter3 inhibit | -+-------+------+------------------------------------------------------------------+ -| 2 | RW | minstret inhibit | -+-------+------+------------------------------------------------------------------+ -| 1 | RO | 0 | -+-------+------+------------------------------------------------------------------+ -| 0 | RW | mcycle inhibit | -+-------+------+------------------------------------------------------------------+ - -Machine Performance Monitoring Event Selector (``mhpmevent3 .. mhpmevent31``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0x323 - 0x33F - -Reset Value: 0x0000_0000 - -Detailed: - -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:16 | RO | 0 | -+-------+------+------------------------------------------------------------------+ -| 15:0 | RW | **selectors:** Each bit represent a unique event to count | -+-------+------+------------------------------------------------------------------+ - -The event selector fields are further described in Performance Counters section. -Non implemented counters always return a read value of 0. - Machine Scratch (``mscratch``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -663,11 +586,15 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:0 | RW | Scratch value | -+-------------+-----------+------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RW | Scratch value | + +-------------+-----------+------------------------------------------------------------------------+ Machine Exception PC (``mepc``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -676,13 +603,19 @@ CSR Address: 0x341 Reset Value: 0x0000_0000 -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:1 | RW | Machine Expection Program Counter 31:1 | -+-------------+-----------+------------------------------------------------------------------------+ -| 0 | R0 | Always 0 | -+-------------+-----------+------------------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:1 | RW | **MEPC:** Machine Exception Program Counter | + +-------------+-----------+------------------------------------------------------------------------+ + | 0 | R0 | 0 | + +-------------+-----------+------------------------------------------------------------------------+ When an exception is encountered, the current program counter is saved in MEPC, and the core jumps to the exception address. When a mret @@ -696,17 +629,23 @@ CSR Address: 0x342 Reset Value: 0x0000_0000 -+-------------+-----------+----------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+==================================================================================+ -| 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | -+-------------+-----------+----------------------------------------------------------------------------------+ -| 30:5 | RO (0) | Always 0 | -+-------------+-----------+----------------------------------------------------------------------------------+ -| 4:0 | RW | **Exception Code** (See note below) | -+-------------+-----------+----------------------------------------------------------------------------------+ - -**NOTE**: software accesses to `mcause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==================================================================================+ + | 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | + +-------------+-----------+----------------------------------------------------------------------------------+ + | 30:5 | RO (0) | 0 | + +-------------+-----------+----------------------------------------------------------------------------------+ + | 4:0 | RW | **Exception Code** (See note below) | + +-------------+-----------+----------------------------------------------------------------------------------+ + +**NOTE**: software accesses to `mcause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, when `mcause[31]` is set, writing 0x1 to `mcause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. @@ -719,13 +658,17 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:0 | RO (0) | Writes are ignored; reads return 0. | -+-------------+-----------+------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | Writes are ignored; reads return 0. | + +-------------+-----------+------------------------------------------------------------------------+ -Machine Interrupt Pending Register (``mip``) +Machine Interrupt Pending register (``mip``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x344 @@ -734,48 +677,75 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+---------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+===================================================================================================+ -| 31:16 | RO | Machine Fast Interrupts Pending: If bit x is set, interrupt irq_i[x] is pending. | -+-------------+-----------+---------------------------------------------------------------------------------------------------+ -| 11 | RO | **Machine External Interrupt Pending (MEIP)**: If set, irq_i[11] is pending. | -+-------------+-----------+---------------------------------------------------------------------------------------------------+ -| 7 | RO | **Machine Timer Interrupt Pending (MTIP)**: If set, irq_i[7] is pending. | -+-------------+-----------+---------------------------------------------------------------------------------------------------+ -| 3 | RO | **Machine Software Interrupt Pending (MSIP)**: if set, irq_i[3] is pending. | -+-------------+-----------+---------------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+===================================================================================================+ + | 31:16 | RO | Machine Fast Interrupts Pending | + | | | | + | | | If bit x is set, interrupt irq_i[x] is pending (x between 16 and 31). | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 15:12 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 11 | RO | **MEIP:** Machine External Interrupt Pending | + | | | | + | | | If set, irq_i[11] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 10:8 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 7 | RO | **MTIP:** Machine Timer Interrupt Pending | + | | | | + | | | If set, irq_i[7] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 6:4 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 3 | RO | **MSIP:** Machine Software Interrupt Pending | + | | | | + | | | If set, irq_i[3] is pending. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ + | 2:0 | RO | Hardwired to 0. | + +-------------+-----------+---------------------------------------------------------------------------------------------------+ Trigger CSRs :::::::::::: .. _csr-tselect: -Trigger Select Register (``tselect``) +Trigger Select register (``tselect``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7A0 Reset Value: 0x0000_0000 -Accessible in Debug Mode or M-Mode. +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table -+-------------+-----------+----------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================================+ -| 31:0 | RO | CV32E40P implements a single trigger, therefore this register will always read as zero | -+-------------+-----------+----------------------------------------------------------------------------------------+ + +-------------+-----------+----------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================================+ + | 31:0 | RO | CV32E40P implements a single trigger, therefore this register will always read as zero.| + +-------------+-----------+----------------------------------------------------------------------------------------+ +Accessible in Debug Mode or M-Mode. .. _csr-tdata1: -Trigger Data Register 1 (``tdata1``) +Trigger Data register 1 (``tdata1``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7A1 Reset Value: 0x2800_1040 +Detailed: + Accessible in Debug Mode or M-Mode. Since native triggers are not supported, writes to this register from M-Mode will be ignored. @@ -788,48 +758,52 @@ Since native triggers are not supported, writes to this register from M-Mode wil 0.13.2, are therefore implemented as WARL bitfields (corresponding to how these bitfields will be specified in the forthcoming Debug Specification 0.14.0). -+-------+----------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+==========+==================================================================+ -| 31:28 | RO (0x2) | **type:** 2 = Address/Data match trigger type. | -+-------+----------+------------------------------------------------------------------+ -| 27 | RO (0x1) | **dmode:** 1 = Only debug mode can write tdata registers | -+-------+----------+------------------------------------------------------------------+ -| 26:21 | RO (0x0) | **maskmax:** 0 = Only exact matching supported. | -+-------+----------+------------------------------------------------------------------+ -| 20 | RO (0x0) | **hit:** 0 = Hit indication not supported. | -+-------+----------+------------------------------------------------------------------+ -| 19 | RO (0x0) | **select:** 0 = Only address matching is supported. | -+-------+----------+------------------------------------------------------------------+ -| 18 | RO (0x0) | **timing:** 0 = Break before the instruction at the specified | -| | | address. | -+-------+----------+------------------------------------------------------------------+ -| 17:16 | RO (0x0) | **sizelo:** 0 = Match accesses of any size. | -+-------+----------+------------------------------------------------------------------+ -| 15:12 | RO (0x1) | **action:** 1 = Enter debug mode on match. | -+-------+----------+------------------------------------------------------------------+ -| 11 | RO (0x0) | **chain:** 0 = Chaining not supported. | -+-------+----------+------------------------------------------------------------------+ -| 10:7 | RO (0x0) | **match:** 0 = Match the whole address. | -+-------+----------+------------------------------------------------------------------+ -| 6 | RO (0x1) | **m:** 1 = Match in M-Mode. | -+-------+----------+------------------------------------------------------------------+ -| 5 | RO (0x0) | zero. | -+-------+----------+------------------------------------------------------------------+ -| 4 | RO (0x0) | **s:** 0 = S-Mode not supported. | -+-------+----------+------------------------------------------------------------------+ -| 3 | RO (0x0) | **u:** 0 = U-Mode not supported. | -+-------+----------+------------------------------------------------------------------+ -| 2 | RW | **execute:** Enable matching on instruction address. | -+-------+----------+------------------------------------------------------------------+ -| 1 | RO (0x0) | **store:** 0 = Store address / data matching not supported. | -+-------+----------+------------------------------------------------------------------+ -| 0 | RO (0x0) | **load:** 0 = Load address / data matching not supported. | -+-------+----------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:28 | RO (0x2) | **type:** 2 = Address/Data match trigger type. | + +-----------+----------+------------------------------------------------------------------+ + | 27 | RO (0x1) | **dmode:** 1 = Only debug mode can write tdata registers | + +-----------+----------+------------------------------------------------------------------+ + | 26:21 | RO (0x0) | **maskmax:** 0 = Only exact matching supported. | + +-----------+----------+------------------------------------------------------------------+ + | 20 | RO (0x0) | **hit:** 0 = Hit indication not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 19 | RO (0x0) | **select:** 0 = Only address matching is supported. | + +-----------+----------+------------------------------------------------------------------+ + | 18 | RO (0x0) | **timing:** 0 = Break before the instruction at the specified | + | | | address. | + +-----------+----------+------------------------------------------------------------------+ + | 17:16 | RO (0x0) | **sizelo:** 0 = Match accesses of any size. | + +-----------+----------+------------------------------------------------------------------+ + | 15:12 | RO (0x1) | **action:** 1 = Enter debug mode on match. | + +-----------+----------+------------------------------------------------------------------+ + | 11 | RO (0x0) | **chain:** 0 = Chaining not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 10:7 | RO (0x0) | **match:** 0 = Match the whole address. | + +-----------+----------+------------------------------------------------------------------+ + | 6 | RO (0x1) | **m:** 1 = Match in M-Mode. | + +-----------+----------+------------------------------------------------------------------+ + | 5 | RO (0x0) | zero. | + +-----------+----------+------------------------------------------------------------------+ + | 4 | RO (0x0) | **s:** 0 = S-Mode not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RO (0x0) | **u:** 0 = U-Mode not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | **execute:** Enable matching on instruction address. | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO (0x0) | **store:** 0 = Store address / data matching not supported. | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RO (0x0) | **load:** 0 = Load address / data matching not supported. | + +-----------+----------+------------------------------------------------------------------+ .. _csr-tdata2: -Trigger Data Register 2 (``tdata2``) +Trigger Data register 2 (``tdata2``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7A2 @@ -838,16 +812,20 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RW | **data** | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | **data** | + +-----------+----------+------------------------------------------------------------------+ Accessible in Debug Mode or M-Mode. Since native triggers are not supported, writes to this register from M-Mode will be ignored. This register stores the instruction address to match against for a breakpoint trigger. -Trigger Data Register 3 (``tdata3``) +Trigger Data register 3 (``tdata3``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7A3 @@ -856,11 +834,15 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RO | 0 | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ Accessible in Debug Mode or M-Mode. CV32E40P does not support the features requiring this register. Writes are ignored and reads will always return zero. @@ -876,13 +858,17 @@ Reset Value: 0x0000_0004 Detailed: -+-------+----------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+==========+==================================================================+ -| 31:16 | RO (0x0) | 0 | -+-------+----------+------------------------------------------------------------------+ -| 15:0 | RO (0x4) | **info**. Only type 2 is supported. | -+-------+----------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:16 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 15:0 | RO (0x4) | **info**. Only type 2 is supported. | + +-----------+----------+------------------------------------------------------------------+ The **info** field contains one bit for each possible `type` enumerated in `tdata1`. Bit N corresponds to type N. If the bit is set, then that type is @@ -891,7 +877,7 @@ does not exist, this field contains 1. Accessible in Debug Mode or M-Mode. -Machine Context Register (``mcontext``) +Machine Context register (``mcontext``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7A8 @@ -900,34 +886,40 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RO | 0 | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ Accessible in Debug Mode or M-Mode. CV32E40P does not support the features requiring this register. Writes are ignored and reads will always return zero. -Supervisor Context Register (``scontext``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. only:: SUPERVISOR -CSR Address: 0x7AA + Supervisor Context register (``scontext``) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Reset Value: 0x0000_0000 + CSR Address: 0x7AA -Detailed: + Reset Value: 0x0000_0000 -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RO | 0 | -+-------+------+------------------------------------------------------------------+ + Detailed: -Accessible in Debug Mode or M-Mode. -CV32E40P does not support the features requiring this register. Writes are ignored and -reads will always return zero. + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + + Accessible in Debug Mode or M-Mode. + CV32E40P does not support the features requiring this register. Writes are ignored and + reads will always return zero. Debug CSRs :::::::::: @@ -949,39 +941,43 @@ Reset Value: 0x4000_0003 Detailed: -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+==========+===========+=================================================================================================+ -| 31:28 | RO (0x4) | **xdebugver:** returns 4 - External debug support exists as it is described in this document. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 27:16 | RO (0x0) | Reserved | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 15 | RW | **ebreakm** | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 14 | RO (0x0) | Reserved | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 13 | RO (0x0) | **ebreaks**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 12 | RO (0x0) | **ebreaku**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 11 | RW | **stepie** | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 10 | RO (0x0) | **stopcount**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 9 | RO (0x0) | **stoptime**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 8:6 | RO | **cause** | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 5 | RO (0x0) | Reserved | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 4 | RO (0x0) | **mprven**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 3 | RO (0x0) | **nmip**. Always 0. | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 2 | RW | **step** | -+----------+-----------+-------------------------------------------------------------------------------------------------+ -| 1:0 | RO (0x3) | **prv:** returns the current priviledge mode | -+----------+-----------+-------------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+===========+=================================================================================================+ + | 31:28 | RO (0x4) | **xdebugver:** returns 4 - External debug support exists as it is described in this document. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 27:16 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 15 | RW | **ebreakm** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 14 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 13 | RO (0x0) | **ebreaks**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 12 | RO (0x0) | **ebreaku**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 11 | RW | **stepie** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 10 | RO (0x0) | **stopcount**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 9 | RO (0x0) | **stoptime**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 8:6 | RO | **cause** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 5 | RO (0x0) | Reserved | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 4 | RO (0x0) | **mprven**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 3 | RO (0x0) | **nmip**. Always 0. | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 2 | RW | **step** | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ + | 1:0 | RO (0x3) | **prv:** returns the current priviledge mode | + +-----------+-----------+-------------------------------------------------------------------------------------------------+ .. _csr-dpc: @@ -994,18 +990,22 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+-------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+=================================================================================================+ -| 31:1 | RO | zero | -+-------------+-----------+-------------------------------------------------------------------------------------------------+ -| 0 | RO | DPC | -+-------------+-----------+-------------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=================================================================================================+ + | 31:1 | RO | zero | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | 0 | RO | DPC | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ When the core enters in Debug Mode, DPC contains the virtual address of the next instruction to be executed. -Debug Scratch Register 0/1 (``dscratch0/1``) +Debug Scratch register 0/1 (``dscratch0/1``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0x7B2/0x7B3 @@ -1014,15 +1014,104 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+-------------------------------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+=================================================================================================+ -| 31:0 | RW | DSCRATCH0/1 | -+-------------+-----------+-------------------------------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+-------------------------------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+=================================================================================================+ + | 31:0 | RW | DSCRATCH0/1 | + +-------------+-----------+-------------------------------------------------------------------------------------------------+ Performances counters ::::::::::::::::::::: +.. only:: USER + + Machine Counter Enable (``mcounteren``) + --------------------------------------- + + CSR Address: 0x306 + + Reset Value: 0x0000_0000 + + Detailed: + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:4 | RW | Dependent on number of counters implemented in design parameter | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RW | **selectors:** hpmcounter3 enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | instret enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RW | cycle enable for user mode | + +-----------+----------+------------------------------------------------------------------+ + + Each bit in the machine counter-enable register allows the associated read-only + unprivileged shadow performance register to be read from user mode. If the bit + is clear an attempt to read the register in user mode will trigger an illegal + instruction exception. + +Machine Counter-Inhibit register (``mcountinhibit``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x320 + +Reset Value: 0x0000_000D + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:4 | RW | Dependent on number of counters implemented in design parameter | + +-----------+----------+------------------------------------------------------------------+ + | 3 | RW | **selectors:** mhpmcounter3 inhibit | + +-----------+----------+------------------------------------------------------------------+ + | 2 | RW | minstret inhibit | + +-----------+----------+------------------------------------------------------------------+ + | 1 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 0 | RW | mcycle inhibit | + +-----------+----------+------------------------------------------------------------------+ + +The performance counter inhibit control register. The default value is to inihibit counters out of reset. +The bit returns a read value of 0 for non implemented counters. This reset value +shows the result using the default number of performance counters to be 1. + +Machine Performance Monitoring Event Selector (``mhpmevent3 .. mhpmevent31``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x323 - 0x33F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:16 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + | 15:0 | RW | **selectors:** Each bit represent a unique event to count | + +-----------+----------+------------------------------------------------------------------+ + +The event selector fields are further described in Performance Counters section. +Non implemented counters always return a read value of 0. + Machine Cycle Counter (``mcycle``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,11 +1121,15 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RW | The lower 32 bits of the 64 bit machine mode cycle counter. | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | The lower 32 bits of the 64 bit machine mode cycle counter. | + +-----------+----------+------------------------------------------------------------------+ Machine Instructions-Retired Counter (``minstret``) @@ -1048,11 +1141,15 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+---------------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+===========================================================================+ -| 31:0 | RW | The lower 32 bits of the 64 bit machine mode instruction retired counter. | -+-------+------+---------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+---------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+===========================================================================+ + | 31:0 | RW | The lower 32 bits of the 64 bit machine mode instruction retired counter. | + +-----------+----------+---------------------------------------------------------------------------+ Machine Performance Monitoring Counter (``mhpmcounter3 .. mhpmcounter31``) @@ -1064,17 +1161,21 @@ Reset Value: 0x0000_0000 Detailed: -+-------+----------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+==========+==================================================================+ -| 31:0 | RW | Machine performance-monitoring counter | -+-------+----------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | Machine performance-monitoring counter | + +-----------+----------+------------------------------------------------------------------+ The lower 32 bits of the 64 bit machine performance-monitoring counter(s). The number of machine performance-monitoring counters is determined by the parameter ``NUM_MHPMCOUNTERS`` with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0. -Upper 32 Machine Cycle Counter (``mcycleh``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Upper 32 bits Machine Cycle Counter (``mcycleh``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0xB80 @@ -1082,15 +1183,19 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+==================================================================+ -| 31:0 | RW | The upper 32 bits of the 64 bit machine mode cycle counter. | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | The upper 32 bits of the 64 bit machine mode cycle counter. | + +-----------+----------+------------------------------------------------------------------+ -Upper 32 Machine Instructions-Retired Counter (``minstreth``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Upper 32 bits Machine Instructions-Retired Counter (``minstreth``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0xB82 @@ -1098,15 +1203,19 @@ Reset Value: 0x0000_0000 Detailed: -+-------+------+---------------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+======+===========================================================================+ -| 31:0 | RW | The upper 32 bits of the 64 bit machine mode instruction retired counter. | -+-------+------+---------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+---------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+===========================================================================+ + | 31:0 | RW | The upper 32 bits of the 64 bit machine mode instruction retired counter. | + +-----------+----------+---------------------------------------------------------------------------+ -Upper 32 Machine Performance Monitoring Counter (``mhpmcounter3h .. mhpmcounter31h``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Upper 32 bits Machine Performance Monitoring Counter (``mhpmcounter3h .. mhpmcounter31h``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CSR Address: 0xB83 - 0xB9F @@ -1114,17 +1223,232 @@ Reset Value: 0x0000_0000 Detailed: -+-------+----------+------------------------------------------------------------------+ -| Bit# | Mode | Description | -+=======+==========+==================================================================+ -| 31:0 | RW | Machine performance-monitoring counter | -+-------+----------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RW | Machine performance-monitoring counter | + +-----------+----------+------------------------------------------------------------------+ The upper 32 bits of the 64 bit machine performance-monitoring counter(s). The number of machine performance-monitoring counters is determined by the parameter ``NUM_MHPMCOUNTERS`` with a range from 0 to 29 (default value of 1). Non implemented counters always return a read value of 0. -Machine ID CSRs -::::::::::::::: +Cycle Counter (``cycle``) +~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC00 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode cycle counter. + +Instructions-Retired Counter (``instret``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC02 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode instruction retired counter. + +Performance Monitoring Counter (``hpmcounter3 .. hpmcounter31``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC03 - 0xC1F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0. + +Upper 32 bits Cycle Counter (``cycleh``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC80 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode cycle counter. + +Upper 32 bits Instructions-Retired Counter (``instreth``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC82 + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode instruction retired counter. + +Upper 32 bits Performance Monitoring Counter (``hpmcounter3h .. hpmcounter31h``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0xC83 - 0xC9F + +Reset Value: 0x0000_0000 + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-----------+----------+------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +===========+==========+==================================================================+ + | 31:0 | RO | 0 | + +-----------+----------+------------------------------------------------------------------+ + +Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode +performance counter. Non implemented counters always return a read value of 0. + +ID CSRs +::::::: + +Machine ISA (``misa``) +~~~~~~~~~~~~~~~~~~~~~~ + +CSR Address: 0x301 + +Reset Value: defined + +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+------------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+============+========================================================================+ + | 31:30 | RO (0x1) | **MXL** (Machine XLEN) | + +-------------+------------+------------------------------------------------------------------------+ + | 29:26 | RO (0x0) | (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 25 | RO (0x0) | **Z** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 24 | RO (0x0) | **Y** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 23 | RO | **X** (Non-standard extensions present) | + +-------------+------------+------------------------------------------------------------------------+ + | 22 | RO (0x0) | **W** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 21 | RO (0x0) | **V** (Tentatively reserved for Vector extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 20 | RO (0x0) | **U** (User mode implemented) | + +-------------+------------+------------------------------------------------------------------------+ + | 19 | RO (0x0) | **T** (Tentatively reserved for Transactional Memory extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 18 | RO (0x0) | **S** (Supervisor mode implemented) | + +-------------+------------+------------------------------------------------------------------------+ + | 17 | RO (0x0) | **R** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 16 | RO (0x0) | **Q** (Quad-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 15 | RO (0x0) | **P** (Tentatively reserved for Packed-SIMD extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 14 | RO (0x0) | **O** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 13 | RO (0x0) | **N** (User-level interrupts supported) | + +-------------+------------+------------------------------------------------------------------------+ + | 12 | RO (0x1) | **M** (Integer Multiply/Divide extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 11 | RO (0x0) | **L** (Tentatively reserved for Decimal Floating-Point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 10 | RO (0x0) | **K** (Reserved) | + +-------------+------------+------------------------------------------------------------------------+ + | 9 | RO (0x0) | **J** (Tentatively reserved for Dynamically Translated Languages | + | | | extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 8 | RO (0x1) | **I** (RV32I/64I/128I base ISA) | + +-------------+------------+------------------------------------------------------------------------+ + | 7 | RO (0x0) | **H** (Hypervisor extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 6 | RO (0x0) | **G** (Additional standard extensions present) | + +-------------+------------+------------------------------------------------------------------------+ + | 5 | RO | **F** (Single-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 4 | RO (0x0) | **E** (RV32E base ISA) | + +-------------+------------+------------------------------------------------------------------------+ + | 3 | RO (0x0) | **D** (Double-precision floating-point extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 2 | RO (0x1) | **C** (Compressed extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 1 | RO (0x0) | **B** (Tentatively reserved for Bit-Manipulation extension) | + +-------------+------------+------------------------------------------------------------------------+ + | 0 | RO (0x0) | **A** (Atomic extension) | + +-------------+------------+------------------------------------------------------------------------+ + +Writes are ignored and all bitfields in the ``misa`` CSR area read as 0 except for the following: + +* **C** = 1 +* **F** = 1 if ``FPU`` = 1 and ``ZFINX`` = 0 +* **I** = 1 +* **M** = 1 +* **X** = 1 if ``COREV_PULP`` = 1 or ``COREV_CLUSTER`` = 1 +* **MXL** = 1 (i.e. XLEN = 32) Machine Vendor ID (``mvendorid``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1135,13 +1459,17 @@ Reset Value: 0x0000_0602 Detailed: -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:7 | RO | 0xC. Number of continuation codes in JEDEC manufacturer ID. | -+-------------+-----------+------------------------------------------------------------------------+ -| 6:0 | RO | 0x2. Final byte of JEDEC manufacturer ID, discarding the parity bit. | -+-------------+-----------+------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:7 | RO | 0xC. Number of continuation codes in JEDEC manufacturer ID. | + +-------------+-----------+------------------------------------------------------------------------+ + | 6:0 | RO | 0x2. Final byte of JEDEC manufacturer ID, discarding the parity bit. | + +-------------+-----------+------------------------------------------------------------------------+ The ``mvendorid`` encodes the OpenHW JEDEC Manufacturer ID, which is 2 decimal (bank 13). @@ -1154,11 +1482,15 @@ Reset Value: 0x0000_0004 Detailed: -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:0 | RO | Machine Architecture ID of CV32E40P is 4 | -+-------------+-----------+------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | Machine Architecture ID of CV32E40P is 4 | + +-------------+-----------+------------------------------------------------------------------------+ Machine Implementation ID (``mimpid``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1169,11 +1501,15 @@ Reset Value: 0x0000_0000 Detailed: -+-------------+-----------+------------------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+========================================================================+ -| 31:0 | RO | Reads return 0. | -+-------------+-----------+------------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+------------------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+========================================================================+ + | 31:0 | RO | 0 | + +-------------+-----------+------------------------------------------------------------------------+ .. _csr-mhartid: @@ -1184,11 +1520,17 @@ CSR Address: 0xF14 Reset Value: Defined -+-------------+-----------+----------------------------------------------------------------+ -| Bit # | Mode | Description | -+=============+===========+================================================================+ -| 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | -+-------------+-----------+----------------------------------------------------------------+ +Detailed: + +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table + + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | + +-------------+-----------+----------------------------------------------------------------+ .. Comment: no attempt has been made to update these "USER" CSR descriptions .. only:: USER @@ -1199,7 +1541,7 @@ Reset Value: Defined CSR Address: 0x005 +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ - | Bit # | Mode | Description | + | **Bit #** | **Mode** | **Description** | +=============+===========+===============================================================================================================+ | 31 : 2 | RW | BASE: The trap-handler base address, always aligned to 256 bytes, i.e., utvec[7:2] is always set to 0. | +-------------+-----------+---------------------------------------------------------------------------------------------------------------+ @@ -1220,6 +1562,8 @@ Reset Value: Defined Reset Value: 0x0000_0000 + Detailed: + +------+-------+ | 31 | 30: 0 | +======+=======+ @@ -1241,17 +1585,17 @@ Reset Value: Defined Detailed: +-------------+-----------+------------------------------------------------------------------------------------+ - | Bit # | Mode | Description | + | **Bit #** | **Mode** | **Description** | +=============+===========+====================================================================================+ - | 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | + | 31 | RW | **Interrupt:** This bit is set when the exception was triggered by an interrupt. | +-------------+-----------+------------------------------------------------------------------------------------+ | 30:5 | RO (0) | Always 0 | +-------------+-----------+------------------------------------------------------------------------------------+ | 4:0 | RW | **Exception Code** (See note below) | +-------------+-----------+------------------------------------------------------------------------------------+ -**NOTE**: software accesses to `ucause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, -when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. + **NOTE**: software accesses to `ucause[4:0]` must be sensitive to the WLRL field specification of this CSR. For example, + when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interrupt) will result in UNDEFINED behavior. .. only:: PMP @@ -1263,6 +1607,8 @@ when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interr Reset Value: 0x0000_0000 + Detailed: + +----------+ | 31 : 0 | +==========+ @@ -1279,6 +1625,8 @@ when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interr Reset Value: 0x0000_0000 + Detailed: + +----------+ | 31 : 0 | +==========+ @@ -1288,106 +1636,81 @@ when `ucause[31]` is set, writing 0x1 to `ucause[1]` (Supervisor software interr If the PMP is enabled, these sixteen registers contain the addresses of the PMP as specified by the official privileged spec 1.10. -Cycle Counter (``cycle``) -~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0xC00 - -Reset Value: 0x0000_0000 - -Detailed: - -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ - -Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode cycle counter. - -Instructions-Retired Counter (``instret``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0xC02 - -Reset Value: 0x0000_0000 - -Detailed: - -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ +Non-RISC-V CSRs +::::::::::::::: -Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode instruction retired counter. +.. _csr-uhartid: -Performance Monitoring Counter (``hpmcounter3 .. hpmcounter31``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User Hardware Thread ID (``uhartid``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSR Address: 0xC03 - 0xC1F +CSR Address: 0xCD0 (only present if ``COREV_PULP`` = 1 and ``PULP_SECURE`` = 1) -Reset Value: 0x0000_0000 +Reset Value: Defined Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ - -Read-only unprivileged shadow of the lower 32 bits of the 64 bit machine mode -performance counter. Non implemented counters always return a read value of 0. - -Upper 32 Cycle Counter (``cycleh``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CSR Address: 0xC80 +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table -Reset Value: 0x0000_0000 - -Detailed: - -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:0 | RO | Hardware Thread ID **hart_id_i**, see :ref:`core-integration` | + +-------------+-----------+----------------------------------------------------------------+ -Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode cycle counter. +Similar to ``mhartid`` the ``uhartid`` provides the Hardware Thread ID. It differs from ``mhartid`` only in the required privilege level. +On CV32E40P, as it is a machine mode only implementation, this difference is not noticeable. -Upper 32 Instructions-Retired Counter (``instreth``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Privilege Level (``privlv``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CSR Address: 0xC82 +CSR Address: 0xCD1 (only present if ``COREV_PULP`` = 1 and ``PULP_SECURE`` = 1) -Reset Value: 0x0000_0000 +Reset Value: 0x0000_0003 Detailed: -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table -Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode instruction retired counter. + +-------------+-----------+--------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+==================================================+ + | 31:2 | RO | Reads as 0. | + +-------------+-----------+--------------------------------------------------+ + | 1:0 | RO | Current Privilege Level | + | | | | + | | | 00 = User | + | | | | + | | | 01 = Supervisor | + | | | | + | | | 10 = Hypervisor | + | | | | + | | | 11 = Machine | + | | | | + | | | CV32E40P only supports Machine mode. | + +-------------+-----------+--------------------------------------------------+ -Upper 32 Performance Monitoring Counter (``hpmcounter3h .. hpmcounter31h``) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _csr-zfinx: -CSR Address: 0xC83 - 0xC9F +ZFINX ISA (``zfinx``) +~~~~~~~~~~~~~~~~~~~~~ -Reset Value: 0x0000_0000 +CSR Address: 0xCD2 -Detailed: +Reset Value: Defined -+-------+------+------------------------------------------------------------------+ -| Bit# | R/W | Description | -+=======+======+==================================================================+ -| 31:0 | R | 0 | -+-------+------+------------------------------------------------------------------+ +.. table:: + :widths: 15 15 70 + :class: no-scrollbar-table -Read-only unprivileged shadow of the upper 32 bits of the 64 bit machine mode -performance counter. Non implemented counters always return a read value of 0. + +-------------+-----------+----------------------------------------------------------------+ + | **Bit #** | **Mode** | **Description** | + +=============+===========+================================================================+ + | 31:1 | RO | Hardwired to 0. | + +-------------+-----------+----------------------------------------------------------------+ + | 0 | RO | 1 if ``FPU`` = 1 and ``ZFINX`` = 1 else 0. | + +-------------+-----------+----------------------------------------------------------------+ diff --git a/docs/source/core_versions.rst b/docs/source/core_versions.rst index d059ff7af..9af9a71dd 100644 --- a/docs/source/core_versions.rst +++ b/docs/source/core_versions.rst @@ -15,6 +15,8 @@ SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +.. _core_versions: + Core Versions and RTL Freeze Rules ================================== @@ -79,42 +81,103 @@ However, a new GitHub tag should be release and changes documented. Versions control of CV32E40P +.. _backward_compatibility: + +Non-backward compatibility +-------------------------- + +For cv32e40p_v2.0.0, some modifications have been done on ``cv32e40p_top`` and ``cv32e40p_core`` parameters names. + +It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, backward compatibility is still correct as all parameters default values are set to v1 values. + +Parameters +^^^^^^^^^^ + +As RTL has been updated to fully support ratified RISC-V Zfinx, old PULP_ZFINX parameter has been renamed ZFINX in all design and verification files. + +To differentiate v1 to v2 encoding of PULP instructions, old PULP_XPULP and PULP_CLUSTER parameters have been renamed COREV_PULP and COREV_CLUSTER in all design and verification files. + +To easily change FPU instructions latencies, 2 new parameters have been added, FPU_ADDMUL_LAT for Addition/Multiplication lane and FPU_OTHERS_LAT for the other instructions (move, conversion, comparison...). + Released core versions ---------------------- -The verified parameter sets of the core, their implementation version, GitHub tags, -and dates are reported here. +The verified parameter sets of the core, their implementation version, GitHub tags, and dates are reported here. -``mimpid=0`` ------------- +cv32e40p_v1.0.0 +^^^^^^^^^^^^^^^ -The ``mimpid=0`` refers to the CV32E40P core verified with the following parameters: ++--------------------+-------------------+------------+--------------------+---------+ +| Git Tag | Tagged By | Date | Reason for Release | Comment | ++====================+===================+============+====================+=========+ +| cv32e40p_v1.0.0 | Arjan Bink | 2020-12-10 | RTL Freeze | | ++--------------------+-------------------+------------+--------------------+---------+ + +For this release ``mimpid`` value is fixed and is equal to ``0``. + +It refers to the CV32E40P core verified with the following parameters: +---------------------------+-------+ | Name | Value | +===========================+=======+ | ``FPU`` | 0 | +---------------------------+-------+ -| ``ZFINX`` | 0 | +| ``PULP_ZFINX`` | 0 | +---------------------------+-------+ -| ``NUM_MHPMCOUNTERS`` | 1 | +| ``PULP_XPULP`` | 0 | +---------------------------+-------+ | ``PULP_CLUSTER`` | 0 | +---------------------------+-------+ -| ``PULP_XPULP`` | 0 | +| ``NUM_MHPMCOUNTERS`` | 1 | +---------------------------+-------+ -Following, all the GitHub tags related to ``mimpid=0``. +The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at: + +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Design_openissues.md +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Verification_openissues.md +* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Documentation_openissues.md + +cv32e40p_v2.0.0 +^^^^^^^^^^^^^^^ +--------------------+-------------------+------------+--------------------+---------+ | Git Tag | Tagged By | Date | Reason for Release | Comment | +====================+===================+============+====================+=========+ -| cv32e40p_v1.0.0 | Arjan Bink | 2020-12-10 | RTL Freeze | | +| cv32e40p_v2.0.0 | | | RTL Freeze | | +--------------------+-------------------+------------+--------------------+---------+ -The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at: +For this release ``mimpid`` value is depending of parameters value. -* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Design_openissues.md -* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Verification_openissues.md -* https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Documentation_openissues.md +mimpid = 0 +~~~~~~~~~~ + +When parameters are set with the exact same values than for cv32e40p_v1.0.0 release then ``mimpid`` value is equal to ``0``. + ++---------------------------+-------+ +| Name | Value | ++===========================+=======+ +| ``FPU`` | 0 | ++---------------------------+-------+ +| ``ZFINX`` | 0 | ++---------------------------+-------+ +| ``COREV_PULP`` | 0 | ++---------------------------+-------+ +| ``COREV_CLUSTER`` | 0 | ++---------------------------+-------+ +| ``NUM_MHPMCOUNTERS`` | 1 | ++---------------------------+-------+ + +mimpid = 1 +~~~~~~~~~~ + +When one parameter is set with a different value than for cv32e40p_v1.0.0 release then ``mimpid`` value is equal to ``1``. + +This means either ``FPU``, ``ZFINX``, ``COREV_PULP`` or ``COREV_CLUSTER`` is set to 1. +Or ``NUM_MHPMCOUNTERS`` is set to a value greater than 1. + +.. The list of open (waived) issues at the time of applying the cv32e40p_v1.0.0 tag can be found at: + + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Design_openissues.md + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Verification_openissues.md + * https://github.com/openhwgroup/programs/blob/7a72508c90484a7835590a97038eb9dd53bd8c32/milestones/CV32E40P/RTL_Freeze_v1.0.0/Documentation_openissues.md diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 8ed7e65f6..11e422b31 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ CORE-V Hardware Loop Extensions =============================== To increase the efficiency of small loops, CV32E40P supports hardware -loops (HWLoop). They can be enabled by setting the ``PULP_XPULP`` parameter. +loops (HWLoop). They can be enabled by setting the ``COREV_PULP`` parameter. Hardware loops make executing a piece of code multiple times possible, without the overhead of branches penalty or updating a counter. Hardware loops involve zero stall cycles for jumping to the first @@ -111,9 +111,9 @@ Below an assembly code example of a nested HWLoop that computes a matrix additio "startO:;" " cv.count 0, %[N];" " startZ:;" - " addi %[i], x0, 1;" - " addi %[i], x0, 1;" - " addi %[i], x0, 1;" + " addi %[i], %[i], 1;" + " addi %[i], %[i], 1;" + " addi %[i], %[i], 1;" " endZ:;" " addi %[j], %[j], 2;" " addi %[j], %[j], 2;" diff --git a/docs/source/debug.rst b/docs/source/debug.rst index 038a4c43e..654183912 100644 --- a/docs/source/debug.rst +++ b/docs/source/debug.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,7 +20,8 @@ Debug & Trigger =============== -CV32E40P offers support for execution-based debug according to the `RISC-V Debug Specification `_, version 0.13.2. The main requirements for the core are described in Chapter 4: RISC-V Debug, Chapter 5: Trigger Module, and Appendix A.2: Execution Based. +CV32E40P offers support for execution-based debug according to the `RISC-V Debug Specification `_, version 0.13.2. +The main requirements for the core are described in Chapter 4: RISC-V Debug, Chapter 5: Trigger Module, and Appendix A.2: Execution Based. The following list shows the simplified overview of events that occur in the core when debug is requested: @@ -37,7 +38,9 @@ Debug Mode can be entered by one of the following conditions: - Trigger Module match event - ebreak instruction when not in Debug Mode and when DCSR.EBREAKM == 1 (see :ref:`ebreak_behavior` below) -A user wishing to perform an abstract access, whereby the user can observe or control a core’s GPR or CSR register from the hart, is done by invoking debug control code to move values to and from internal registers to an externally addressable Debug Module (DM). Using this execution-based debug allows for the reduction of the overall number of debug interface signals. +A user wishing to perform an abstract access, whereby the user can observe or control a core’s GPR (either integer of floating-point one) or CSR register from the hart, +is done by invoking debug control code to move values to and from internal registers to an externally addressable Debug Module (DM). +Using this execution-based debug allows for the reduction of the overall number of debug interface signals. .. note:: @@ -52,54 +55,64 @@ The CV3240P also supports a Trigger Module to enable entry into Debug Mode on a - Number of trigger register(s) : 1 - Supported trigger types: instruction address match (Match Control) -The CV32E40P will not support the optional debug features 10, 11, & 12 listed in Section 4.1 of the `RISC-V Debug Specification `_. Specifically, a control transfer instruction's destination location being in or out of the Program Buffer and instructions depending on PC value shall **not** cause an illegal instruction. - -Interface ---------- - -+-------------------------------+-----------+--------------------------------------------+ -| Signal | Direction | Description | -+===============================+===========+============================================+ -| ``debug_req_i`` | input | Request to enter Debug Mode | -+-------------------------------+-----------+--------------------------------------------+ -| ``debug_havereset_o`` | output | Debug status: Core has been reset | -+-------------------------------+-----------+--------------------------------------------+ -| ``debug_running_o`` | output | Debug status: Core is running | -+-------------------------------+-----------+--------------------------------------------+ -| ``debug_halted_o`` | output | Debug status: Core is halted | -+-------------------------------+-----------+--------------------------------------------+ -| ``dm_halt_addr_i[31:0]`` | input | Address for debugger entry | -+-------------------------------+-----------+--------------------------------------------+ -| ``dm_exception_addr_i[31:0]`` | input | Address for debugger exception entry | -+-------------------------------+-----------+--------------------------------------------+ - -``debug_req_i`` is the "debug interrupt", issued by the debug module when the core should enter Debug Mode. The ``debug_req_i`` is synchronous to ``clk_i`` and requires a minimum assertion of one clock period to enter Debug Mode. The instruction being decoded during the same cycle that ``debug_req_i`` is first asserted shall not be executed before entering Debug Mode. - -``debug_havereset_o``, ``debug_running_o``, and ``debug_mode_o`` signals provide the operational status of the core to the debug module. The assertion of these -signals is mutually exclusive. - -``debug_havereset_o`` is used to signal that the CV32E40P has been reset. ``debug_havereset_o`` is set high during the assertion of ``rst_ni``. It will be -cleared low a few (unspecified) cycles after ``rst_ni`` has been deasserted **and** ``fetch_enable_i`` has been sampled high. +The CV32E40P will not support the optional debug features 10, 11, & 12 listed in Section 4.1 of the `RISC-V Debug Specification `_. +Specifically, a control transfer instruction's destination location being in or out of the Program Buffer and instructions depending on PC value shall **not** cause an illegal instruction. + +Debug Interface +--------------- + +.. table:: Debug interface signals + :name: Debug interface signals + :widths: 30 15 55 + :class: no-scrollbar-table + + +-------------------------------+---------------+--------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +===============================+===============+============================================+ + | ``debug_req_i`` | input | Request to enter Debug Mode | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_havereset_o`` | output | Debug status: Core has been reset | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_running_o`` | output | Debug status: Core is running | + +-------------------------------+---------------+--------------------------------------------+ + | ``debug_halted_o`` | output | Debug status: Core is halted | + +-------------------------------+---------------+--------------------------------------------+ + | ``dm_halt_addr_i[31:0]`` | input | Address for debugger entry | + +-------------------------------+---------------+--------------------------------------------+ + | ``dm_exception_addr_i[31:0]`` | input | Address for debugger exception entry | + +-------------------------------+---------------+--------------------------------------------+ + +``debug_req_i`` is the "debug interrupt", issued by the debug module when the core should enter Debug Mode. +The ``debug_req_i`` is synchronous to ``clk_i`` and requires a minimum assertion of one clock period to enter Debug Mode. +The instruction being decoded during the same cycle that ``debug_req_i`` is first asserted shall not be executed before entering Debug Mode. + +``debug_havereset_o``, ``debug_running_o`` and ``debug_mode_o`` signals provide the operational status of the core to the debug module. +The assertion of these signals is mutually exclusive. + +``debug_havereset_o`` is used to signal that the CV32E40P has been reset. ``debug_havereset_o`` is set high during the assertion of ``rst_ni``. +It will be cleared low a few (unspecified) cycles after ``rst_ni`` has been deasserted **and** ``fetch_enable_i`` has been sampled high. ``debug_running_o`` is used to signal that the CV32E40P is running normally. ``debug_halted_o`` is used to signal that the CV32E40P is in debug mode. -``dm_halt_addr_i`` is the address where the PC jumps to for a debug entry event. When in Debug Mode, an ebreak instruction will also cause the PC to jump back to this address without affecting status registers. (see :ref:`ebreak_behavior` below) +``dm_halt_addr_i`` is the address where the PC jumps to for a debug entry event. When in Debug Mode, an ebreak instruction will also cause the PC +to jump back to this address without affecting status registers (see :ref:`ebreak_behavior` below). -``dm_exception_addr_i`` is the address where the PC jumps to when an exception occurs during Debug Mode. When in Debug Mode, the mret or uret instruction will also cause the PC to jump back to this address without affecting status registers. +``dm_exception_addr_i`` is the address where the PC jumps to when an exception occurs during Debug Mode. +When in Debug Mode, the mret or uret instruction will also cause the PC to jump back to this address without affecting status registers. Both ``dm_halt_addr_i`` and ``dm_exception_addr_i`` must be word aligned. Core Debug Registers -------------------- -CV32E40P implements four core debug registers, namely :ref:`csr-dcsr`, :ref:`csr-dpc`, and two debug scratch registers. Access to these registers in non Debug Mode results in an illegal instruction. +CV32E40P implements four core debug registers, namely :ref:`csr-dcsr`, :ref:`csr-dpc` and two debug scratch registers. +Access to these registers in non Debug Mode results in an illegal instruction. -Several trigger registers are required to adhere to specification. The following are the most relevant: :ref:`csr-tselect`, :ref:`csr-tdata1`, :ref:`csr-tdata2` and :ref:`csr-tinfo` +Several trigger registers are required to adhere to specification. The following are the most relevant: :ref:`csr-tselect`, :ref:`csr-tdata1`, :ref:`csr-tdata2` and :ref:`csr-tinfo`. -The TDATA1.DMODE is hardwired to a value of 1. In non Debug Mode, -writes to Trigger registers are ignored and reads reflect CSR values. +The TDATA1.DMODE is hardwired to a value of 1. In non Debug Mode, writes to Trigger registers are ignored and reads reflect CSR values. Debug state ----------- @@ -114,7 +127,7 @@ respectively. Therefore, assuming that this core will not be integrated as a ``n when neither ``debug_running_o`` or ``debug_halted_o`` is asserted. Upon ``rst_ni`` assertion the debug state will be ``unavailable`` until some cycle(s) after ``rst_ni`` has been deasserted and ``fetch_enable_i`` has been sampled high. After this point (until a next reset assertion) the core will transition between having its ``debug_halted_o`` or ``debug_running_o`` pin asserted depending whether the core is in debug mode or not. -Exactly one of the ``debug_havereset_o``, ``debug_running_o``, ``debug_halted_o`` is asserted at all times. +Exactly one of the ``debug_havereset_o``, ``debug_running_o`` or ``debug_halted_o`` is asserted at all times. :numref:`debug-running` and show :numref:`debug-halted` show typical examples of transitioning into the ``running`` and ``halted`` states. @@ -145,7 +158,9 @@ The key properties of the debug states are: EBREAK Behavior -------------------- -The EBREAK instruction description is distributed across several RISC-V specifications: `RISC-V Debug Specification `_, `RISC-V Priveleged Specification `_, `RISC-V ISA `_. The following is a summary of the behavior for three common scenarios. +The EBREAK instruction description is distributed across several RISC-V specifications: `RISC-V Debug Specification `_, +`RISC-V Priveleged Specification `_, +`RISC-V ISA `_. The following is a summary of the behavior for three common scenarios. Scenario 1 : Enter Exception """""""""""""""""""""""""""" @@ -155,9 +170,12 @@ Executing the EBREAK instruction when the core is **not** in Debug Mode and the - The core enters the exception handler routine located at MTVEC (Debug Mode is not entered) - MEPC & MCAUSE are updated -To properly return from the exception, the ebreak handler will need to increment the MEPC to the next instruction. This requires querying the size of the ebreak instruction that was used to enter the exception (16 bit c.ebreak or 32 bit ebreak). +To properly return from the exception, the ebreak handler will need to increment the MEPC to the next instruction. +This requires querying the size of the ebreak instruction that was used to enter the exception (16 bit c.ebreak or 32 bit ebreak). -*Note: The CV32E40P does not support MTVAL CSR register which would have saved the value of the instruction for exceptions. This may be supported on a future core.* +.. note:: + + The CV32E40P does not support MTVAL CSR register which would have saved the value of the instruction for exceptions. This may be supported on a future core. Scenario 2 : Enter Debug Mode """"""""""""""""""""""""""""" @@ -169,12 +187,15 @@ Executing the EBREAK instruction when the core is **not** in Debug Mode and the Similar to the exception scenario above, the debugger will need to increment the DPC to the next instruction before returning from Debug Mode. -*Note: The default value of DCSR.EBREAKM is 0 and the DCSR is only accessible in Debug Mode. To enter Debug Mode from EBREAK, the user will first need to enter Debug Mode through some other means, such as from the external ``debug_req_i``, and set DCSR.EBREAKM.* +.. note:: + + The default value of DCSR.EBREAKM is 0 and the DCSR is only accessible in Debug Mode. To enter Debug Mode from EBREAK, + the user will first need to enter Debug Mode through some other means, such as from the external ``debug_req_i``, and set DCSR.EBREAKM. Scenario 3 : Exit Program Buffer & Restart Debug Code """"""""""""""""""""""""""""""""""""""""""""""""""""" -Execuitng the EBREAK instruction when the core is in Debug Mode shall result in the following actions: +Executing the EBREAK instruction when the core is in Debug Mode shall result in the following actions: - The core remains in Debug Mode and execution jumps back to the beginning of the debug code located at ``dm_halt_addr_i`` - none of the CSRs are modified @@ -185,8 +206,9 @@ Execuitng the EBREAK instruction when the core is in Debug Mode shall result in Interrupts during Single-Step Behavior -------------------------------------- -The CV32E40P CPU is not compliant with the intended interpretation of the RISC-V Debug spec 0.13.2 specification when interrupts occur during Single-Steps. +The CV32E40P is not compliant with the intended interpretation of the RISC-V Debug spec 0.13.2 specification when interrupts occur during Single-Steps. However, the intended behavior has been clarified a posteriori only in version 1.0.0. See https://github.com/riscv/riscv-debug-spec/issues/510. -The CV32E40P executes the first instruction of the interrupt handler and retires it before re-entering in Debug Mode, which is prohibited in version 1.0.0 but not specified in 0.13.2. For details about the specific use-case, please refer to https://github.com/openhwgroup/core-v-verif/issues/904. +The CV32E40P executes the first instruction of the interrupt handler and retires it before re-entering in Debug Mode, which is prohibited in version 1.0.0 but not specified in 0.13.2. +For details about the specific use-case, please refer to https://github.com/openhwgroup/core-v-verif/issues/904. diff --git a/docs/source/exceptions_interrupts.rst b/docs/source/exceptions_interrupts.rst index 989d32533..086ce723a 100644 --- a/docs/source/exceptions_interrupts.rst +++ b/docs/source/exceptions_interrupts.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -43,32 +43,41 @@ Interrupt Interface .. table:: Interrupt interface signals :name: Interrupt interface signals - - +-------------------------+-----------+--------------------------------------------------+ - | Signal | Direction | Description | - +=========================+===========+==================================================+ - | ``irq_i[31:0]`` | input | Active high, level sensistive interrupt inputs. | - | | | Not all interrupt inputs can be used on | - | | | CV32E40P. Specifically irq_i[15:12], | - | | | irq_i[10:8], irq_i[6:4] and irq_i[2:0] shall be | - | | | tied to 0 externally as they are reserved for | - | | | future standard use (or for cores which are not | - | | | Machine mode only) in the RISC-V Privileged | - | | | specification. irq_i[11], irq_i[7], and irq_i[3] | - | | | correspond to the Machine External | - | | | Interrupt (MEI), Machine Timer Interrupt (MTI), | - | | | and Machine Software Interrupt (MSI) | - | | | respectively. The irq_i[31:16] interrupts | - | | | are a CV32E40P specific extension to the RISC-V | - | | | Basic (a.k.a. CLINT) interrupt scheme. | - +-------------------------+-----------+--------------------------------------------------+ - | ``irq_ack_o`` | output | Interrupt acknowledge. Set to 1 for one cycle | - | | | when the interrupt with ID ``irq_id_o[4:0]`` is | - | | | taken. | - +-------------------------+-----------+--------------------------------------------------+ - | ``irq_id_o[4:0]`` | output | Interrupt index for taken interrupt. Only valid | - | | | when ``irq_ack_o`` = 1. | - +-------------------------+-----------+--------------------------------------------------+ + :widths: 20 15 65 + :class: no-scrollbar-table + + +-------------------------+---------------+--------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +=========================+===============+==================================================+ + | ``irq_i[31:0]`` | input | Level sensistive active high interrupt inputs. | + | | | Not all interrupt inputs can be used on | + | | | CV32E40P. Specifically irq_i[15:12], | + | | | irq_i[10:8], irq_i[6:4] and irq_i[2:0] shall be | + | | | tied to 0 externally as they are reserved for | + | | | future standard use (or for cores which are not | + | | | Machine mode only) in the RISC-V Privileged | + | | | specification. | + | | | | + | | | irq_i[11], irq_i[7], and irq_i[3] | + | | | correspond to the Machine External | + | | | Interrupt (MEI), Machine Timer Interrupt (MTI), | + | | | and Machine Software Interrupt (MSI) | + | | | respectively. | + | | | | + | | | The irq_i[31:16] interrupts | + | | | are a CV32E40P specific extension to the RISC-V | + | | | Basic (a.k.a. CLINT) interrupt scheme. | + +-------------------------+---------------+--------------------------------------------------+ + | ``irq_ack_o`` | output | Interrupt acknowledge | + | | | | + | | | Set to 1 for one cycle | + | | | when the interrupt with ID ``irq_id_o[4:0]`` is | + | | | taken. | + +-------------------------+---------------+--------------------------------------------------+ + | ``irq_id_o[4:0]`` | output | Interrupt index for taken interrupt | + | | | | + | | | Only valid when ``irq_ack_o`` = 1. | + +-------------------------+---------------+--------------------------------------------------+ Interrupts ---------- @@ -86,7 +95,7 @@ ordered as follows: ``irq_i[31]``, ``irq_i[30]``, ..., ``irq_i[16]``, ``irq_i[11 All interrupt lines are level-sensitive. There are two supported mechanisms by which interrupts can be cleared at the external source. * A software-based mechanism in which the interrupt handler signals completion of the handling routine to the interrupt source, e.g., through a memory-mapped register, which then deasserts the corresponding interrupt line. -* A hardware-based mechanism in which the ``irq_ack_o`` and ``irq_id_o[4:0]`` signals are used to clear the interrupt sourcee, e.g. by an external interrupt controller. ``irq_ack_o`` is a 1 ``clk_i`` cycle pulse during which ``irq_id_o[4:0]`` reflects the index in ``irq_id[]`` of the taken interrupt. +* A hardware-based mechanism in which the ``irq_ack_o`` and ``irq_id_o[4:0]`` signals are used to clear the interrupt sourcee, e.g. by an external interrupt controller. ``irq_ack_o`` is a 1 ``clk_i`` cycle pulse during which ``irq_id_o[4:0]`` reflects the index in ``irq_id[*]`` of the taken interrupt. In Debug Mode, all interrupts are ignored independent of ``mstatus``.MIE and the content of the ``mie`` CSR. @@ -95,19 +104,25 @@ Exceptions CV32E40P can trigger an exception due to the following exception causes: -+----------------+---------------------------------------------------------------+ -| Exception Code | Description | -+----------------+---------------------------------------------------------------+ -| 2 | Illegal instruction | -+----------------+---------------------------------------------------------------+ -| 3 | Breakpoint | -+----------------+---------------------------------------------------------------+ -| 11 | Environment call from M-Mode (ECALL) | -+----------------+---------------------------------------------------------------+ +.. table:: Exceptions + :name: Exceptions + :widths: 20 80 + :class: no-scrollbar-table + + +--------------------+---------------------------------------------------------------+ + | **Exception Code** | **Description** | + +====================+===============================================================+ + | 2 | Illegal instruction | + +--------------------+---------------------------------------------------------------+ + | 3 | Breakpoint | + +--------------------+---------------------------------------------------------------+ + | 11 | Environment call from M-Mode (ECALL) | + +--------------------+---------------------------------------------------------------+ The illegal instruction exception and M-Mode ECALL instruction exceptions cannot be disabled and are always active. -The core raises an illegal instruction exception for any instruction in the RISC-V privileged and unprivileged specifications that is explicitly defined as being illegal according to the ISA implemented by the core, as well as for any instruction that is left undefined in these specifications unless the instruction encoding is configured as a custom CV32E40P instruction for specific parameter settings as defined in (see :ref:custom-isa-extensions). -For example, in case the parameter FPU is set to 0, the CV32E40P raises an illegal instruction exception for any RVF instruction. The same concerns for XPULP extensions everytime the parameter PULP_XPULP is set to 0 (see :ref:core-integration). +The core raises an illegal instruction exception for any instruction in the RISC-V privileged and unprivileged specifications that is explicitly defined as being illegal according to the ISA implemented by the core, as well as for any instruction that is left undefined in these specifications unless the instruction encoding is configured as a custom CV32E40P instruction for specific parameter settings as defined in (see :ref:`custom-isa-extensions`). +For example, in case the parameter ``FPU`` is set to 0, the CV32E40P raises an illegal instruction exception for any RVF instruction or CSR instruction trying to access F CSRs. +The same concerns PULP extensions everytime both parameters ``COREV_PULP`` and ``CORE_CLUSTER`` are set to 0 (see :ref:`core-integration`). .. only:: PMP diff --git a/docs/source/fpu.rst b/docs/source/fpu.rst index e4781e0a5..9dc85aa2e 100644 --- a/docs/source/fpu.rst +++ b/docs/source/fpu.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,24 +21,149 @@ Floating Point Unit (FPU) ========================= The RV32F ISA extension for floating-point support in the form of IEEE-754 single -precision can be enabled by setting the parameter **FPU** of the toplevel file -``cv32e40p_core.sv`` to 1. This will extend the CV32E40P decoder accordingly. -The actual Floating Point Unit (FPU) is instantiated outside the -CV32E40P and is accessed via the APU interface (see :ref:`apu`). -The FPU repository used by the CV32E40P core is available at -https://github.com/openhwgroup/cvfpu -In the core repository, a wrapper showing how the FPU is connected -to the core is available at ``example_tb/core/cv32e40p_fp_wrapper.sv``. +precision can be enabled by setting the parameter **FPU** of the ``cv32e40p_top`` top level module +to 1. This will extend the CV32E40P decoder accordingly and will instantiate the FPU. +The FPU repository used by the CV32E40P is available at `https://github.com/openhwgroup/cvfpu `_ and +its documentation can be found `here `_. +CVFPU v1.0.0 release has been copied in CV32E40P repository inside rtl/vendor (used for verification and implementation) so all core and FPU RTL files should be taken from CV32E40P repository. + +cv32e40p_fpu_manifest file is listing all necessary files for both the Core and CVFPU. + +CVFPU parameters +---------------- + +As CVFPU is an highly configurable IP, here is the list of its parameters and their actual value used when CVFPU is intantiated through a wrapper in ``cv32e40p_top`` module. + +.. table:: CVFPU Features parameter + :name: CVFPU Features parameter + :widths: 17 15 17 51 + :class: no-scrollbar-table + + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+================+==================+==========================================================================+ + | ``Width`` | int | 32 | **Datapath Width** | + | | | | | + | | | | Specifies the width of the input and output data ports and | + | | | | of the datapath. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableVectors`` | logic | 0 | **Vectorial Hardware Generation** | + | | | | | + | | | | Controls the generation of packed-SIMD computation units. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableNanBox`` | logic | 0 | **NaN-Boxing Check Control** | + | | | | | + | | | | Controls whether input value NaN-boxing is enforced. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``FpFmtMask`` | fmt_logic_t | {1, 0, 0, 0, 0} | **Enabled Floating-Point Formats** | + | | | | | + | | | | Enables respectively: | + | | | | | + | | | | IEEE Single-Precision format | + | | | | | + | | | | IEEE Double-Precision format | + | | | | | + | | | | IEEE Half-Precision format | + | | | | | + | | | | Custom Byte-Precision format | + | | | | | + | | | | Custom Alternate Half-Precision format | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``IntFmtMask`` | ifmt_logic_t | {0, 0, 1, 0} | **Enabled Integer Formats** | + | | | | | + | | | | Enables respectively: | + | | | | | + | | | | Byte format | + | | | | | + | | | | Half-Word format | + | | | | | + | | | | Word format | + | | | | | + | | | | Double-Word format | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + +.. table:: CVFPU Implementation parameter + :name: CVFPU Implementation parameter + :widths: 13 21 30 36 + :class: no-scrollbar-table + + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+========================+=====================================+============================================================================+ + | ``PipeRegs`` | opgrp_fmt_unsigned_t | { | **Number of Pipelining Stages** | + | | | | | + | | | {``FPU_ADDMUL_LAT``, 0, 0, 0, 0}, | This parameter sets a number of pipeline stages to be inserted into the | + | | | | computational units per operation group, per FP format. As such, | + | | | {default: 1}, | latencies for different operations and different formats can be freely | + | | | | configured. | + | | | {default: ``FPU_OTHERS_LAT``}, | | + | | | | Respectively: | + | | | {default: ``FPU_OTHERS_LAT``} | | + | | | | ADDition/MULtiplication operation group | + | | | } | | + | | | | DIVision/SQuare RooT operation group | + | | | | | + | | | | NON COMPuting operation group | + | | | | | + | | | | CONVersion operation group | + | | | | | + | | | | ``FPU_ADDMUL_LAT`` and ``FPU_OTHERS_LAT`` are ``cv32e40p_top`` parameters. | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | ``UnitTypes`` | opgrp_fmt_unit_types_t | { | **HW Unit Implementation** | + | | | | | + | | | {default: MERGED}, | This parameter allows to control resources by either removing operation | + | | | | units for certain formats and operations, | + | | | {default: MERGED}, | or merging multiple formats into one. | + | | | | | + | | | {default: PARALLEL}, | Respectively: | + | | | | | + | | | {default: MERGED} | ADDition/MULtiplication operation group | + | | | | | + | | | } | DIVision/SQuare RooT operation group | + | | | | | + | | | | NON COMPuting operation group | + | | | | | + | | | | CONVersion operation group | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + | ``PipeConfig`` | pipe_config_t | AFTER | **Pipeline Register Placement** | + | | | | | + | | | | This parameter controls where pipeling registers (number defined by | + | | | | ``PipeRegs``) are placed in each operational unit. | + | | | | | + | | | | AFTER means they are all placed at the output of each operational unit. | + | | | | | + | | | | See :ref:`synthesis_with_fpu` advices to get best synthesis results. | + +------------------------------+------------------------+-------------------------------------+----------------------------------------------------------------------------+ + +.. table:: Other CVFPU parameters + :name: Other CVFPU parameters + :widths: 20 15 10 55 + :class: no-scrollbar-table + + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Value** | **Description** | + +==============================+================+==================+==========================================================================+ + | ``TagType`` | | logic | The SystemVerilog data type of the operation tag input and output ports. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``TrueSIMDClass`` | int | 0 | Vectorial mode classify operation RISC-V compliancy. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + | ``EnableSIMDMask`` | int | 0 | Inactive vectorial lanes floating-point status flags masking. | + +------------------------------+----------------+------------------+--------------------------------------------------------------------------+ + +FP Register File +---------------- + By default a dedicated register file consisting of 32 floating-point registers, ``f0``-``f31``, is instantiated. This default behavior -can be overruled by setting the parameter **ZFINX** of the toplevel -file ``cv32e40p_core.sv`` to 1, in which case the dedicated register file is +can be overruled by setting the parameter **ZFINX** of the ``cv32e40p_top`` top level +module to 1, in which case the dedicated register file is not included and the general purpose register file is used instead to host the floating-point operands. -The latency of the individual instructions are set by means of parameters in the -FPU repository (see https://github.com/openhwgroup/cvfpu/tree/develop/docs). +The latency of the individual instructions are explained in :ref:`instructions_latency_table` table. +To allow FPU unit to be put in sleep mode at the same time the core is doing so, a clock gating cell is instantiated in ``cv32e40p_top`` top level module as well +with its enable signal being inverted ``core_sleep_o`` core output. FP CSR ------ @@ -48,3 +173,14 @@ floating-point status and control register (:ref:`csr-fcsr`) which contains the exceptions that occurred since it was last reset and the rounding mode. :ref:`csr-fflags` and :ref:`csr-frm` can be accessed directly or via :ref:`csr-fcsr` which is mapped to those two registers. + +Reminder for programmers +------------------------ + +As mentioned in RISC-V Privileged Architecture specification, ``mstatus``.FS should be set to Initial to be able to use FP instructions. +If ``mstatus``.FS = Off (reset value), any instruction that attempts to read or write the Floating-Point state (F registers or F CSRs) will cause an illegal instruction exception. + +Upon interrupt or context switch events, ``mstatus``.SD should be read to see if Floating-Point state has been altered. +If following executed program (interrupt routine or whatsover) is going to use FP instructions and only if ``mstatus``.SD = 1 (means FS = Dirty), +then the whole FP state (F registers and F CSRs) should be saved in memory and program should set ``mstatus``.FS to Clean. +When returning to interrupted or main program, if ``mstatus``.FS = Clean then the whole FP state should be restored from memory. diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 1bd83f27d..4774abe62 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,13 +22,6 @@ Getting Started with CV32E40P This page discusses initial steps and requirements to start using CV32E40P in your design. -Register File -------------- - -CV32E40P comes with two different register file implementations. -Depending on the target technology, either the implementation in ``cv32e40p_register_file_ff.sv`` or the one in ``cv32e40p_register_file_latch.sv`` should be selected in the manifest file. -For more information about the two register file implementations and their trade-offs, check out :ref:`register-file`. - .. _clock-gating-cell: Clock Gating Cell @@ -44,8 +37,7 @@ a module called ``cv32e40p_clock_gate`` that has the following ports: * ``scan_cg_en_i``: Scan Clock Gate Enable Input (activates the clock even though ``en_i`` is not set) * ``clk_o``: Gated Clock Output -Inside CV32E40P, clock gating cells are used both in ``cv32e40p_sleep_unit.sv`` and ``cv32e40p_register_file_latch.sv``. -For more information on the expected behavior of the clock gating cell when using the latch-based register file check out :ref:`register-file`. +Inside CV32E40P, clock gating cells are used in both ``cv32e40p_sleep_unit.sv`` and ``cv32e40p_top.sv``. The ``cv32e40p_sim_clock_gate.sv`` file is not intended for synthesis. For ASIC synthesis and FPGA synthesis the manifest should be adapted to use a customer specific file that implements the ``cv32e40p_clock_gate`` module using design primitives diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index de1ed4ac8..7269f96a9 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -26,7 +26,7 @@ Glossary * **CPU**: Central Processing Unit, processor * **CSR**: Control and Status Register * **Custom extension**: Non-Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA) -* **EXE**: Instruction Execute +* **EX**: Instruction Execute * **FPGA**: Field Programmable Gate Array * **FPU**: Floating Point Unit * **Halfword**: 16-bit data item diff --git a/docs/source/index.rst b/docs/source/index.rst index 357b813d9..5853a12b0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,11 +26,11 @@ OpenHW Group CV32E40P User Manual intro getting_started integration + verification pipeline instruction_fetch load_store_unit register_file - apu fpu sleep corev_hw_loop @@ -38,7 +38,6 @@ OpenHW Group CV32E40P User Manual perf_counters exceptions_interrupts debug - tracer instruction_set_extensions core_versions glossary diff --git a/docs/source/instruction_fetch.rst b/docs/source/instruction_fetch.rst index 90def947b..2e5f77083 100644 --- a/docs/source/instruction_fetch.rst +++ b/docs/source/instruction_fetch.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,19 +20,20 @@ Instruction Fetch ================= -The Instruction Fetch (IF) stage of the CV32E40P is able to supply one instruction to -the Instruction Decode (ID ) stage per cycle if the external bus interface is able -to serve one instruction per cycle. In case of executing compressed instructions, -on average less than one 32-bit instruction fetch will we needed per instruction +The Instruction Fetch (IF) stage of the CV32E40P is able to supply one instruction per cycle to +the Instruction Decode (ID ) stage if the external bus interface is able +to serve one fetch request per cycle. In case of executing compressed instructions, +on average less than one 32-bit fetch request will be needed per instruction in the ID stage. For optimal performance and timing closure reasons, a prefetcher is used which fetches instructions via the external bus interface from for example an externally connected instruction memory or instruction cache. -The prefetch unit performs word-aligned 32-bit prefetches and stores the -fetched words in a FIFO with four entries. As a result of this (speculative) -prefetch, CV32E40P can fetch up to four words outside of the code region +The prefetch buffer performs word-aligned 32-bit prefetches and stores the +fetched words in a FIFO with a number of entries depending of a local parameter. +It is called ``DEPTH`` and can be found in ``cv32e40p_prefetch_buffer.sv`` (default value of 2). +As a result of this (speculative) prefetch, CV32E40P can fetch up to ``DEPTH`` words outside of the code region and care should therefore be taken that no unwanted read side effects occur for such prefetches outside of the actual code region. @@ -43,19 +44,21 @@ are possible and thus it needs fewer signals. .. table:: Instruction Fetch interface signals :name: Instruction Fetch interface signals + :widths: 25 15 60 + :class: no-scrollbar-table +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ | **Signal** | **Direction** | **Description** | +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ - | instr\_req\_o | output | Request valid, will stay high until instr\_gnt\_i is high for one cycle | + | ``instr_addr_o[31:0]`` | output | Address, word aligned | +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ - | instr\_addr\_o[31:0] | output | Address, word aligned | + | ``instr_req_o`` | output | Request valid, will stay high until ``instr_gnt_i`` is high for one cycle | +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ - | instr\_rdata\_i[31:0] | input | Data read from memory | + | ``instr_gnt_i`` | input | The other side accepted the request. ``instr_addr_o`` may change in the next cycle. | +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ - | instr\_rvalid\_i | input | instr\_rdata\_i holds valid data when instr\_rvalid\_i is high. This signal will be high for exactly one cycle per request. | + | ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when ``instr_rvalid_i`` is high. This signal will be high for exactly one cycle per request.| +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ - | instr\_gnt\_i | input | The other side accepted the request. instr\_addr\_o may change in the next cycle. | + | ``instr_rdata_i[31:0]`` | input | Data read from memory | +-------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+ Misaligned Accesses @@ -69,11 +72,15 @@ The LSB of the instruction address is ignored internally. Protocol -------- -The CV32E40P instruction fetch interface does not -implement the following optional OBI signals: we, be, wdata, auser, wuser, aid, -rready, err, ruser, rid. These signals can be thought of as being tied off as -specified in the OBI specification. The CV32E40P instruction fetch interface can -cause up to two outstanding transactions. +The CV32E40P instruction fetch interface does not implement the following optional OBI signals: we, be, wdata, auser, wuser, aid, +rready, err, ruser, rid. These signals can be thought of as being tied off as specified in the OBI specification. + +.. note:: + + **Transactions Ordering** + As mentioned above, instruction fetch interface can generate up to ``DEPTH`` outstanding transactions. + OBI specification states that links are always in-order from master point of view. So as the fetch interface does not generate transaction id (aid), + interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information. :numref:`obi-instruction-basic` and :numref:`obi-instruction-multiple-outstanding` show example timing diagrams of the protocol. diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index c2dcb55c5..82cc76af6 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -1,18 +1,18 @@ .. - Copyright (c) 2020 OpenHW Group - + Copyright (c) 2023 OpenHW Group + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + https://solderpad.org/licenses/ - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _custom-isa-extensions: @@ -20,9 +20,9 @@ CORE-V Instruction Set Custom Extension ======================================= -CV32E40P supports the following CORE-V ISA X Custom Extension, which can be enabled by setting ``PULP_XPULP`` == 1. +CV32E40P supports the following CORE-V ISA X Custom Extension, which can be enabled by setting ``COREV_PULP`` == 1. - * Post-Incrementing load and stores, see :ref:`corev_load_store`, invoked in the tool chain with ``-march=rv32i*_xcvmem``. + * Post-Increment load and stores, see :ref:`corev_load_store`, invoked in the tool chain with ``-march=rv32i*_xcvmem``. * Hardware Loop extension, see :ref:`corev_hardware_loop`, invoked in the tool chain with ``-march=rv32i*_xcvhwlp``. * ALU extensions, see :ref:`corev_alu`, which are divided into three sub-extensions: @@ -33,23 +33,23 @@ CV32E40P supports the following CORE-V ISA X Custom Extension, which can be enab * Multiply-Accumulate extensions, see :ref:`corev_multiply_accumulate`, invoked in the tool chain with ``-march=rv32i*_xcvmac``. * Single Instruction Multiple Data (aka SIMD) extensions, see :ref:`corev_simd`, invoked in the tool chain with ``-march=rv32i*_xcvsimd``. -If not specified, all the operands are signed and immediate values are sign-extended. - -Additionally the event load instruction (**cv.elw**) is supported by setting ``PULP_CLUSTER`` == 1, see :ref:`corev_event_load`. +Additionally the event load instruction (**cv.elw**) is supported by setting ``COREV_CLUSTER`` == 1, see :ref:`corev_event_load`. This is a separate ISA extension, invoked in the tool chain with ``-march=rv32i*_xcvelw``. +If not specified, all the operands are signed and immediate values are sign-extended. + To use such instructions, you need to compile your SW with the CORE-V GCC or Clang/LLVM compiler. -**Note:** As of 31 January 2023, the compiler work is not complete. -It is anticipated that GCC assembler and builtin function support will be complete by 31 March 2023. -Clang/LLVM assembler will be supported by 30 June 2023, with builtin function support by 31 December 2023. +.. note:: + + Clang/LLVM assembler will be supported by 30 June 2023, with builtin function support by 31 December 2023. .. _corev_load_store: -Post-Incrementing Load & Store Instructions and Register-Register Load & Store Instructions -------------------------------------------------------------------------------------------- +Post-Increment Load & Store Instructions and Register-Register Load & Store Instructions +---------------------------------------------------------------------------------------- -Post-Incrementing load and store instructions perform a load, or a +Post-Increment load and store instructions perform a load, or a store, respectively, while at the same time incrementing the address that was used for the memory access. Since it is a post-incrementing scheme, the base address is used for the access and the modified address @@ -57,232 +57,282 @@ is written back to the register-file. There are versions of those instructions that use immediates and those that use registers as offsets. The base address always comes from a register. -The custom post-incrementing load & store instructions and register-register -load & store instructions are only supported if ``PULP_XPULP`` == 1. +The custom post-increment load & store instructions and register-register +load & store instructions are only supported if ``COREV_PULP`` == 1. -Load Operations +Load operations ^^^^^^^^^^^^^^^ -+----------------------------------------------------+-------------------------------+ -| **Mnemonic** | **Description** | -+====================================================+===============================+ -| **Register-Immediate Loads with Post-Increment** | -+----------------------------------------------------+-------------------------------+ -| **cv.lb rD, Imm(rs1!)** | rD = Sext(Mem8(rs1)) | -| | | -| | rs1 += Sext(Imm[11:0]) | -+----------------------------------------------------+-------------------------------+ -| **cv.lbu rD, Imm(rs1!)** | rD = Zext(Mem8(rs1)) | -| | | -| | rs1 += Sext(Imm[11:0]) | -+----------------------------------------------------+-------------------------------+ -| **cv.lh rD, Imm(rs1!)** | rD = Sext(Mem16(rs1)) | -| | | -| | rs1 += Sext(Imm[11:0]) | -+----------------------------------------------------+-------------------------------+ -| **cv.lhu rD, Imm(rs1!)** | rD = Zext(Mem16(rs1)) | -| | | -| | rs1 += Sext(Imm[11:0]) | -+----------------------------------------------------+-------------------------------+ -| **cv.lw rD, Imm(rs1!)** | rD = Mem32(rs1) | -| | | -| | rs1 += Sext(Imm[11:0]) | -+----------------------------------------------------+-------------------------------+ -| **Register-Register Loads with Post-Increment** | -+----------------------------------------------------+-------------------------------+ -| **cv.lb rD, rs2(rs1!)** | rD = Sext(Mem8(rs1)) | -| | | -| | rs1 += rs2 | -+----------------------------------------------------+-------------------------------+ -| **cv.lbu rD, rs2(rs1!)** | rD = Zext(Mem8(rs1)) | -| | | -| | rs1 += rs2 | -+----------------------------------------------------+-------------------------------+ -| **cv.lh rD, rs2(rs1!)** | rD = Sext(Mem16(rs1)) | -| | | -| | rs1 += rs2 | -+----------------------------------------------------+-------------------------------+ -| **cv.lhu rD, rs2(rs1!)** | rD = Zext(Mem16(rs1)) | -| | | -| | rs1 += rs2 | -+----------------------------------------------------+-------------------------------+ -| **cv.lw rD, rs2(rs1!)** | rD = Mem32(rs1) | -| | | -| | rs1 += rs2 | -+----------------------------------------------------+-------------------------------+ -| **Register-Register Loads** | -+----------------------------------------------------+-------------------------------+ -| **cv.lb rD, rs2(rs1)** | rD = Sext(Mem8(rs1 + rs2)) | -+----------------------------------------------------+-------------------------------+ -| **cv.lbu rD, rs2(rs1)** | rD = Zext(Mem8(rs1 + rs2)) | -+----------------------------------------------------+-------------------------------+ -| **cv.lh rD, rs2(rs1)** | rD = Sext(Mem16(rs1 + rs2)) | -+----------------------------------------------------+-------------------------------+ -| **cv.lhu rD, rs2(rs1)** | rD = Zext(Mem16(rs1 + rs2)) | -+----------------------------------------------------+-------------------------------+ -| **cv.lw rD, rs2(rs1)** | rD = Mem32(rs1 + rs2) | -+----------------------------------------------------+-------------------------------+ - -Store Operations +.. table:: Load operations + :name: Load operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------------+-------------------------------+ + | **Mnemonic** | **Description** | + +====================================================+===============================+ + | **Register-Immediate Loads with Post-Increment** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, Imm(rs1!)** | rD = Sext(Mem8(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, Imm(rs1!)** | rD = Zext(Mem8(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, Imm(rs1!)** | rD = Sext(Mem16(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, Imm(rs1!)** | rD = Zext(Mem16(rs1)) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, Imm(rs1!)** | rD = Mem32(rs1) | + | | | + | | rs1 += Sext(Imm[11:0]) | + +----------------------------------------------------+-------------------------------+ + | **Register-Register Loads with Post-Increment** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, rs2(rs1!)** | rD = Sext(Mem8(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, rs2(rs1!)** | rD = Zext(Mem8(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, rs2(rs1!)** | rD = Sext(Mem16(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, rs2(rs1!)** | rD = Zext(Mem16(rs1)) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, rs2(rs1!)** | rD = Mem32(rs1) | + | | | + | | rs1 += rs2 | + +----------------------------------------------------+-------------------------------+ + | **Register-Register Loads** | + +----------------------------------------------------+-------------------------------+ + | **cv.lb rD, rs2(rs1)** | rD = Sext(Mem8(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lbu rD, rs2(rs1)** | rD = Zext(Mem8(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lh rD, rs2(rs1)** | rD = Sext(Mem16(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lhu rD, rs2(rs1)** | rD = Zext(Mem16(rs1 + rs2)) | + +----------------------------------------------------+-------------------------------+ + | **cv.lw rD, rs2(rs1)** | rD = Mem32(rs1 + rs2) | + +----------------------------------------------------+-------------------------------+ + +Store operations ^^^^^^^^^^^^^^^^ -+-----------------------------------------------------+--------------------------+ -| **Mnemonic** | **Description** | -+=====================================================+==========================+ -| **Register-Immediate Stores with Post-Increment** | -+-----------------------------------------------------+--------------------------+ -| **cv.sb rs2, Imm(rs1!)** | Mem8(rs1) = rs2 | -| | | -| | rs1 += Sext(Imm[11:0]) | -+-----------------------------------------------------+--------------------------+ -| **cv.sh rs2, Imm(rs1!)** | Mem16(rs1) = rs2 | -| | | -| | rs1 += Sext(Imm[11:0]) | -+-----------------------------------------------------+--------------------------+ -| **cv.sw rs2, Imm(rs1!)** | Mem32(rs1) = rs2 | -| | | -| | rs1 += Sext(Imm[11:0]) | -+-----------------------------------------------------+--------------------------+ -| **Register-Register Stores with Post-Increment** | -+-----------------------------------------------------+--------------------------+ -| **cv.sb rs2, rs3(rs1!)** | Mem8(rs1) = rs2 | -| | | -| | rs1 += rs3 | -+-----------------------------------------------------+--------------------------+ -| **cv.sh rs2, rs3(rs1!)** | Mem16(rs1) = rs2 | -| | | -| | rs1 += rs3 | -+-----------------------------------------------------+--------------------------+ -| **cv.sw rs2, rs3(rs1!)** | Mem32(rs1) = rs2 | -| | | -| | rs1 += rs3 | -+-----------------------------------------------------+--------------------------+ -| **Register-Register Stores** | -+-----------------------------------------------------+--------------------------+ -| **cv.sb rs2, rs3(rs1)** | Mem8(rs1 + rs3) = rs2 | -+-----------------------------------------------------+--------------------------+ -| **cv.sh rs2 rs3(rs1)** | Mem16(rs1 + rs3) = rs2 | -+-----------------------------------------------------+--------------------------+ -| **cv.sw rs2, rs3(rs1)** | Mem32(rs1 + rs3) = rs2 | -+-----------------------------------------------------+--------------------------+ +.. table:: Store operations + :name: Store operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------------+--------------------------+ + | **Mnemonic** | **Description** | + +=====================================================+==========================+ + | **Register-Immediate Stores with Post-Increment** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, Imm(rs1!)** | Mem8(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2, Imm(rs1!)** | Mem16(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, Imm(rs1!)** | Mem32(rs1) = rs2 | + | | | + | | rs1 += Sext(Imm[11:0]) | + +-----------------------------------------------------+--------------------------+ + | **Register-Register Stores with Post-Increment** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, rs3(rs1!)** | Mem8(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2, rs3(rs1!)** | Mem16(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, rs3(rs1!)** | Mem32(rs1) = rs2 | + | | | + | | rs1 += rs3 | + +-----------------------------------------------------+--------------------------+ + | **Register-Register Stores** | + +-----------------------------------------------------+--------------------------+ + | **cv.sb rs2, rs3(rs1)** | Mem8(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ + | **cv.sh rs2 rs3(rs1)** | Mem16(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ + | **cv.sw rs2, rs3(rs1)** | Mem32(rs1 + rs3) = rs2 | + +-----------------------------------------------------+--------------------------+ Encoding -~~~~~~~~ - -+-------------+--------+----------+--------+------------+---------------------------+ -| 31 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+-------------+--------+----------+--------+------------+---------------------------+ -| imm[11:0] | rs1 | funct3 | rd | opcode | Mnemonic | -+=============+========+==========+========+============+===========================+ -| offset | base | 000 | dest | 000 1011 | **cv.lb rD, Imm(rs1!)** | -+-------------+--------+----------+--------+------------+---------------------------+ -| offset | base | 100 | dest | 000 1011 | **cv.lbu rD, Imm(rs1!)** | -+-------------+--------+----------+--------+------------+---------------------------+ -| offset | base | 001 | dest | 000 1011 | **cv.lh rD, Imm(rs1!)** | -+-------------+--------+----------+--------+------------+---------------------------+ -| offset | base | 101 | dest | 000 1011 | **cv.lhu rD, Imm(rs1!)** | -+-------------+--------+----------+--------+------------+---------------------------+ -| offset | base | 010 | dest | 000 1011 | **cv.lw rD, Imm(rs1!)** | -+-------------+--------+----------+--------+------------+---------------------------+ - -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| funct7 | rs2 | rs1 | funct3 | rd | opcode | Mnemonic | -+============+==========+========+==========+========+============+===========================+ -| 000 0000 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 1000 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 0001 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 1001 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 0010 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ - -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| funct7 | rs2 | rs1 | funct3 | rd | opcode | Mnemonic | -+============+==========+========+==========+========+============+===========================+ -| 000 0100 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 1100 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 0101 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 1101 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 000 0110 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ - -+----------------+-------+--------+----------+---------------+------------+---------------------------+ -| 31 : 25 | 24:20 | 19 :15 | 14 : 12 | 11 : 07 | 06 : 00 | | -+----------------+-------+--------+----------+---------------+------------+---------------------------+ -| imm[11:5] | rs2 | rs1 | funct3 | rd | opcode | Mnemonic | -+================+=======+========+==========+===============+============+===========================+ -| offset[11:5] | src | base | 000 | offset[4:0] | 010 1011 | **cv.sb rs2, Imm(rs1!)** | -+----------------+-------+--------+----------+---------------+------------+---------------------------+ -| offset[11:5] | src | base | 001 | offset[4:0] | 010 1011 | **cv.sh rs2, Imm(rs1!)** | -+----------------+-------+--------+----------+---------------+------------+---------------------------+ -| offset[11:5] | src | base | 010 | offset[4:0] | 010 1011 | **cv.sw rs2, Imm(rs1!)** | -+----------------+-------+--------+----------+---------------+------------+---------------------------+ - -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| funct7 | rs2 | rs1 | funct3 | rd | opcode | Mnemonic | -+============+==========+========+==========+========+============+===========================+ -| 001 0000 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 001 0001 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 001 0010 | src | base | 011 | offset | 010 1011 | **cv.sw rs2, rs3(rs1!)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ - -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| funct7 | rs2 | rs1 | funct3 | rs3 | opcode | Mnemonic | -+============+==========+========+==========+========+============+===========================+ -| 001 0100 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 001 0101 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ -| 001 0110 | src | base | 011 | offset | 010 1011 | **cv.sw rs2, rs3(rs1)** | -+------------+----------+--------+----------+--------+------------+---------------------------+ +^^^^^^^^ + +.. table:: Post-Increment Register-Immediate Load operations encoding + :name: Post-Increment Register-Immediate Load operations encoding + :widths: 25 10 10 15 15 25 + :class: no-scrollbar-table + + +---------------+---------+------------+--------+------------+---------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +---------------+---------+------------+--------+------------+---------------------------+ + | **imm[11:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +===============+=========+============+========+============+===========================+ + | offset | base | 000 | dest | 000 1011 | **cv.lb rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 100 | dest | 000 1011 | **cv.lbu rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 001 | dest | 000 1011 | **cv.lh rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 101 | dest | 000 1011 | **cv.lhu rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + | offset | base | 010 | dest | 000 1011 | **cv.lw rD, Imm(rs1!)** | + +---------------+---------+------------+--------+------------+---------------------------+ + +.. table:: Post-Increment Register-Register Load operations encoding + :name: Post-Increment Register-Register Load operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +============+==========+=========+============+========+============+===========================+ + | 000 0000 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1000 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0001 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1001 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0010 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1!)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + +.. table:: Register-Register Load operations encoding + :name: Register-Register Load operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +============+==========+=========+============+========+============+===========================+ + | 000 0100 | offset | base | 011 | dest | 010 1011 | **cv.lb rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1100 | offset | base | 011 | dest | 010 1011 | **cv.lbu rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0101 | offset | base | 011 | dest | 010 1011 | **cv.lh rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 1101 | offset | base | 011 | dest | 010 1011 | **cv.lhu rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + | 000 0110 | offset | base | 011 | dest | 010 1011 | **cv.lw rD, rs2(rs1)** | + +------------+----------+---------+------------+--------+------------+---------------------------+ + +.. table:: Post-Increment Register-Immediate Store operations encoding + :name: Post-Increment Register-Immediate Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | **imm[11:5]** | **rs2** | **rs1** | **funct3** | **imm[4:0]** | **opcode** | **Mnemonic** | + +================+=========+=========+============+===============+============+===========================+ + | offset[11:5] | src | base | 000 | offset[4:0] | 010 1011 | **cv.sb rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | offset[11:5] | src | base | 001 | offset[4:0] | 010 1011 | **cv.sh rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + | offset[11:5] | src | base | 010 | offset[4:0] | 010 1011 | **cv.sw rs2, Imm(rs1!)** | + +----------------+---------+---------+------------+---------------+------------+---------------------------+ + +.. table:: Post-Increment Register-Register Store operations encoding + :name: Post-Increment Register-Register Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rs3** | **opcode** | **Mnemonic** | + +============+==========+=========+============+=========+============+===========================+ + | 001 0000 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0001 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0010 | src | base | 011 | offse t | 010 1011 | **cv.sw rs2, rs3(rs1!)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + +.. table:: Register-Register Store operations encoding + :name: Register-Register Store operations encoding + :widths: 15 10 10 10 15 15 25 + :class: no-scrollbar-table + + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rs3** | **opcode** | **Mnemonic** | + +============+==========+=========+============+=========+============+===========================+ + | 001 0100 | src | base | 011 | offset | 010 1011 | **cv.sb rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0101 | src | base | 011 | offset | 010 1011 | **cv.sh rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ + | 001 0110 | src | base | 011 | offset | 010 1011 | **cv.sw rs2, rs3(rs1)** | + +------------+----------+---------+------------+---------+------------+---------------------------+ .. _corev_event_load: -Event Load Instructions ------------------------ +Event Load Instruction +---------------------- -The event load instruction **cv.elw** is only supported if the ``PULP_CLUSTER`` parameter is set to 1. +The event load instruction **cv.elw** is only supported if the ``COREV_CLUSTER`` parameter is set to 1. The event load performs a load word and can cause the CV32E40P to enter a sleep state as explained in :ref:`pulp_cluster`. -Load Operations -^^^^^^^^^^^^^^^ +Event Load operation +^^^^^^^^^^^^^^^^^^^^ + +.. table:: Event Load operation + :name: Event Load operation + :widths: 30 70 + :class: no-scrollbar-table -+----------------------------------------------------+-------------------------------+ -| **Mnemonic** | **Description** | -+====================================================+===============================+ -| **Event Load** | -+----------------------------------------------------+-------------------------------+ -| **cv.elw rD, Imm(rs1)** | rD = Mem32(Sext(Imm)+rs1) | -+----------------------------------------------------+-------------------------------+ + +----------------------------------------------------+-------------------------------+ + | **Mnemonic** | **Description** | + +====================================================+===============================+ + | **Event Load** | + +----------------------------------------------------+-------------------------------+ + | **cv.elw rD, Imm(rs1)** | rD = Mem32(Sext(Imm) + rs1) | + +----------------------------------------------------+-------------------------------+ Encoding -~~~~~~~~ +^^^^^^^^ -+-------------+--------+----------+--------+------------+---------------------------+ -| 31 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+-------------+--------+----------+--------+------------+---------------------------+ -| imm[11:0] | rs1 | funct3 | rd | opcode | Mnemonic | -+=============+========+==========+========+============+===========================+ -| offset | base | 011 | dest | 000 1011 | **cv.elw rD, Imm(rs1)** | -+-------------+--------+----------+--------+------------+---------------------------+ +.. table:: Event Load operation encoding + :name: Event Load operation encoding + :widths: 25 10 10 15 15 25 + :class: no-scrollbar-table + + +---------------+---------+------------+--------+------------+---------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +---------------+---------+------------+--------+------------+---------------------------+ + | **imm[11:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +===============+=========+============+========+============+===========================+ + | offset | base | 011 | dest | 000 1011 | **cv.elw rD, Imm(rs1)** | + +---------------+---------+------------+--------+------------+---------------------------+ .. _corev_hardware_loop: @@ -297,76 +347,87 @@ has a limited range for the number of instructions contained in the loop and the loop must start in the next instruction after the setup instruction. -Hardware loop instructions and related CSRs are only supported if ``PULP_XPULP`` == 1. +Hardware loop instructions and related CSRs are only supported if ``COREV_PULP`` == 1. Details about the hardware loop constraints are provided in :ref:`hwloop-specs`. In the following tables, the hardware loop instructions are reported. -In assembly, **L** is referred by x0 or x1. - -Operations -^^^^^^^^^^ - -**Long Hardware Loop Setup instructions** - -+----------------------------------------------+-----------------------+----------------------------------+ -| **Mnemonic** | **Description** | | -+==============================================+=======================+==================================+ -| **cv.starti** | **L, uimmL** | lpstart[L] = PC + (uimmL << 2) | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.start** | **L, rs1** | lpstart[L] = rs1 | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.endi** | **L, uimmL** | lpend[L] = PC + (uimmL << 2) | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.end** | **L, rs1** | lpend[L] = rs1 | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.counti** | **L, uimmL** | lpcount[L] = uimmL | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.count** | **L, rs1** | lpcount[L] = rs1 | -+----------------------------------------------+-----------------------+----------------------------------+ - -**Short Hardware Loop Setup Instructions** - -+----------------------------------------------+-----------------------+----------------------------------+ -| **Mnemonic** | **Description** | | -+==============================================+=======================+==================================+ -| **cv.setupi** | **L, uimmL, uimmS** | lpstart[L] = PC + 4 | -| | | | -| | | lpend[L] = PC + (uimmS << 2) | -| | | | -| | | lpcount[L] = uimmL | -+----------------------------------------------+-----------------------+----------------------------------+ -| **cv.setup** | **L, rs1, uimmL** | lpstart[L] = PC + 4 | -| | | | -| | | lpend[L] = PC + (uimmL << 2) | -| | | | -| | | lpcount[L] = rs1 | -+----------------------------------------------+-----------------------+----------------------------------+ +In assembly, **L** is referred by 0 or 1. + +Hardware Loops operations +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: Long Hardware Loop Setup operations + :name: Long Hardware Loop Setup operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------+----------------------------------------------------------+ + | **Mnemonic** | **Description** | + +==============================================+==========================================================+ + | **cv.starti L, uimmL** | lpstart[L] = PC + (uimmL << 2) | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.start L, rs1** | lpstart[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.endi L, uimmL** | lpend[L] = PC + (uimmL << 2) | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.end L, rs1** | lpend[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.counti L, uimmL** | lpcount[L] = uimmL | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.count L, rs1** | lpcount[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ + +.. table:: Short Hardware Loop Setup operations + :name: Short Hardware Loop Setup operations + :widths: 30 70 + :class: no-scrollbar-table + + +----------------------------------------------+----------------------------------------------------------+ + | **Mnemonic** | **Description** | + +==============================================+==========================================================+ + | **cv.setupi L, uimmL, uimmS** | lpstart[L] = PC + 4 | + | | | + | | lpend[L] = PC + (uimmS << 2) | + | | | + | | lpcount[L] = uimmL | + +----------------------------------------------+----------------------------------------------------------+ + | **cv.setup L, rs1, uimmL** | lpstart[L] = PC + 4 | + | | | + | | lpend[L] = PC + (uimmL << 2) | + | | | + | | lpcount[L] = rs1 | + +----------------------------------------------+----------------------------------------------------------+ Encoding -~~~~~~~~ - -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| 31 : 20 | 19 :15 | 14 : 12 | 11 :08 | 07 | 06 : 00 | | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| uimmL[11:0] | rs1 | funct3 | funct4 | L | opcode | Mnemonic | -+=================+============+==========+========+====+============+===============================+ -| uimmL[11:0] | 00000 | 100 | 0000 | L | 010 1011 | **cv.starti L, uimmL** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| 0000 0000 0000 | src1 | 100 | 0001 | L | 010 1011 | **cv.start L, rs1** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| uimmL[11:0] | 00000 | 100 | 0010 | L | 010 1011 | **cv.endi L, uimmL** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| 0000 0000 0000 | src1 | 100 | 0011 | L | 010 1011 | **cv.end L, rs1** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| uimmL[11:0] | 00000 | 100 | 0100 | L | 010 1011 | **cv.counti L, uimmL** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| 0000 0000 0000 | src1 | 100 | 0101 | L | 010 1011 | **cv.count L, rs1** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| uimmL[11:0] | uimmS[4:0] | 100 | 0110 | L | 010 1011 | **cv.setupi L, uimmL, uimmS** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ -| uimmL[11:0] | src1 | 100 | 0111 | L | 010 1011 | **cv.setup L, rs1, uimmL** | -+-----------------+------------+----------+--------+----+------------+-------------------------------+ +^^^^^^^^ + +.. table:: Hardware Loops operations encoding + :name: Hardware Loops operations encoding + :widths: 17 15 10 10 5 15 28 + :class: no-scrollbar-table + + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 31 : 20 | 19 : 15 | 14 : 12 | 11 : 8 | 7 | 6 : 0 | | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | **uimmL[11:0]** | **rs1** | **funct3** | **funct4** | **L** | **opcode** | **Mnemonic** | + +=================+============+============+============+=======+============+===============================+ + | uimmL[11:0] | 00000 | 100 | 0000 | L | 010 1011 | **cv.starti L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0001 | L | 010 1011 | **cv.start L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | 00000 | 100 | 0010 | L | 010 1011 | **cv.endi L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0011 | L | 010 1011 | **cv.end L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | 00000 | 100 | 0100 | L | 010 1011 | **cv.counti L, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | 0000 0000 0000 | src1 | 100 | 0101 | L | 010 1011 | **cv.count L, rs1** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | uimmS[4:0] | 100 | 0110 | L | 010 1011 | **cv.setupi L, uimmL, uimmS** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ + | uimmL[11:0] | src1 | 100 | 0111 | L | 010 1011 | **cv.setup L, rs1, uimmL** | + +-----------------+------------+------------+------------+-------+------------+-------------------------------+ .. _corev_alu: @@ -379,23 +440,23 @@ single instruction and thus increases efficiency of the core. For example, those instructions include zero-/sign-extension instructions for 8-bit and 16-bit operands, simple bit manipulation/counting instructions and min/max/avg instructions. The ALU does also support -saturating, clipping, and normalizing instructions which make fixed-point +saturating, clipping and normalizing instructions which make fixed-point arithmetic more efficient. -The custom ALU extensions are only supported if ``PULP_XPULP`` == 1. +The custom ALU extensions are only supported if ``COREV_PULP`` == 1. The custom extensions to the ALU are split into several subgroups that belong together. -- Bit manipulation instructions are useful to work on single bits or - groups of bits within a word, see :ref:`corev_bit_manipulation`. +- Bit manipulation instructions are useful to work on single bits or + groups of bits within a word, see :ref:`corev_bit_manipulation`. -- General ALU instructions try to fuse common used sequences into a - single instruction and thus increase the performance of small kernels - that use those sequence, see :ref:`corev_general_alu`. +- General ALU instructions try to fuse common used sequences into a + single instruction and thus increase the performance of small kernels + that use those sequence, see :ref:`corev_general_alu`. -- Immediate branching instructions are useful to compare a register - with an immediate value before taking or not a branch, see see :ref:`corev_immediate_branching`. +- Immediate branching instructions are useful to compare a register + with an immediate value before taking or not a branch, see see :ref:`corev_immediate_branching`. Extract, Insert, Clear and Set instructions have the following meaning: @@ -494,405 +555,462 @@ this case care should be taken to set *Is2* appropriately. .. _corev_bit_manipulation: -Bit Manipulation Operations +Bit Manipulation operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **Mnemonic** | | **Description** | -+===================+=========================+==========================================================================================================================================+ -| **cv.extract** | **rD, rs1, Is3, Is2** | rD = Sext(rs1[min(Is3+Is2,31):Is2]) | -| | | | -| | | Note: Sign extension is done over the MSB of the extracted part. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.extractu** | **rD, rs1, Is3, Is2** | rD = Zext(rs1[min(Is3+Is2,31):Is2]) | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.extractr** | **rD, rs1, rs2** | rD = Sext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | -| | | | -| | | Note: Sign extension is done over the MSB of the extracted part. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.extractur** | **rD, rs1, rs2** | rD = Zext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.insert** | **rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] = rs1[Is3-(max(Is3+Is2,31)-31):0] | -| | | | -| | | The rest of the bits of rD are untouched and keep their previous value. | -| | | | -| | | Is3 + Is2 must be < 32. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.insertr** | **rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] = rs1[rs2[9:5]-(max(rs2[9:5]+rs2[4:0],31)-31):0] | -| | | | -| | | The rest of the bits of rD are untouched and keep their previous value. | -| | | | -| | | Is3 + Is2 must be < 32. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.bclr** | **rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 0 | -| | | | -| | | The rest of the bits of rD are passed through from rs1 and are not modified. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.bclrr** | **rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 0 | -| | | | -| | | The rest of the bits of rD are passed through from rs1 and are not modified. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.bset** | **rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 1 | -| | | | -| | | The rest of the bits of rD are passed through from rs1 and are not modified. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.bsetr** | **rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 1 | -| | | | -| | | The rest of the bits of rD are passed through from rs1 and are not modified. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.ff1** | **rD, rs1** | rD = bit position of the first bit set in rs1, starting from LSB. | -| | | | -| | | If bit 0 is set, rD will be 0. If only bit 31 is set, rD will be 31. If rs1 is 0, rD will be 32. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.fl1** | **rD, rs1** | rD = bit position of the last bit set in rs1, starting from MSB. | -| | | | -| | | If bit 31 is set, rD will be 31. If only bit 0 is set, rD will be 0. If rs1 is 0, rD will be 32. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.clb** | **rD, rs1** | rD = count leading bits of rs1 | -| | | | -| | | Number of consecutive 1's or 0's starting from MSB. | -| | | | -| | | If rs1 is 0, rD will be 0. If rs1 is different than 0, returns (number - 1). | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.cnt** | **rD, rs1** | rD = Population count of rs1 | -| | | | -| | | Number of bits set in rs1. | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.ror** | **rD, rs1, rs2** | rD = RotateRight(rs1, rs2) | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| **cv.bitrev** | **rD, rs1, Is3, Is2** | Given an input rs1 it returns a bit reversed representation assuming | -| | | | -| | | FFT on 2^Is2 points in Radix 2^(Is3+1). | -| | | | -| | | Is3 can be either 0 (radix-2), 1 (radix-4) or 2 (radix-8). | -| | | | -| | | Note: When Is3 = 3, instruction has the same bahavior as if it was 0 (radix-2). | -+-------------------+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ +.. table:: Bit Manipulation operations + :name: Bit Manipulation operations + :widths: 30 70 + :class: no-scrollbar-table + + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=============================================+==========================================================================================================================================+ + | **cv.extract rD, rs1, Is3, Is2** | rD = Sext(rs1[min(Is3+Is2,31):Is2]) | + | | | + | | Note: Sign extension is done over the MSB of the extracted part. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractu rD, rs1, Is3, Is2** | rD = Zext(rs1[min(Is3+Is2,31):Is2]) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractr rD, rs1, rs2** | rD = Sext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | + | | | + | | Note: Sign extension is done over the MSB of the extracted part. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.extractur rD, rs1, rs2** | rD = Zext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]]) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.insert rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] = rs1[Is3-(max(Is3+Is2,31)-31):0] | + | | | + | | The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Is3 + Is2 must be < 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.insertr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] = | + | | | + | | rs1[rs2[9:5]-(max(rs2[9:5]+rs2[4:0],31)-31):0] | + | | | + | | The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Is3 + Is2 must be < 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bclr rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 0 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bclrr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 0 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bset rD, rs1, Is3, Is2** | rD[min(Is3+Is2,31):Is2] bits set to 1 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bsetr rD, rs1, rs2** | rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] bits set to 1 | + | | | + | | The rest of the bits of rD are passed through from rs1 and are not modified. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.ff1 rD, rs1** | rD = bit position of the first bit set in rs1, starting from LSB. | + | | | + | | If bit 0 is set, rD will be 0. If only bit 31 is set, rD will be 31. | + | | | + | | If rs1 is 0, rD will be 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.fl1 rD, rs1** | rD = bit position of the last bit set in rs1, starting from MSB. | + | | | + | | If bit 31 is set, rD will be 31. If only bit 0 is set, rD will be 0. | + | | | + | | If rs1 is 0, rD will be 32. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.clb rD, rs1** | rD = count leading bits of rs1 | + | | | + | | Number of consecutive 1's or 0's starting from MSB. | + | | | + | | If rs1 is 0, rD will be 0. If rs1 is different than 0, returns (number - 1). | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.cnt rD, rs1** | rD = Population count of rs1 | + | | | + | | Number of bits set in rs1. | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.ror rD, rs1, rs2** | rD = RotateRight(rs1, rs2) | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + | **cv.bitrev rD, rs1, Is3, Is2** | Given an input rs1 it returns a bit reversed representation assuming | + | | | + | | FFT on 2^Is2 points in Radix 2^(Is3+1). | + | | | + | | Is3 can be either 0 (radix-2), 1 (radix-4) or 2 (radix-8). | + | | | + | | Note: When Is3 = 3, instruction has the same bahavior as if it was 0 (radix-2). | + +---------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ Bit Manipulation Encoding ^^^^^^^^^^^^^^^^^^^^^^^^^ -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 31:30 | 29 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 :07 | 06 : 00 | | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| f2 | ls3[4:0] | ls2[4:0] | rs1 | funct3 | rd | opcode | Mnemonic | -+=======+======================+===============+========+==========+========+============+====================================+ -| 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extract rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extractu rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 10 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.insert rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bclr rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bset rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ -| 11 | {3'b000,Luimm2[1:0]} | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bitrev rD, rs1, Is3, Is2** | -+-------+----------------------+---------------+--------+----------+--------+------------+------------------------------------+ - -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| funct7 | rs2 | rs1 | funct3 | rD | opcode | | -+============+=========+========+==========+========+============+================================+ -| 001 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractr rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 001 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractur rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 001 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.insertr rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 001 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.bclrr rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 001 1101 | src2 | scr1 | 011 | dest | 010 1011 | **cv.bsetr rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 010 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.ror rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 010 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.ff1 rD, rs1** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 010 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.fl1 rD, rs1** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 010 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.clb rD, rs1** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ -| 010 0100 | 00000 | src1 | 011 | dest | 010 1011 | **cv.cnt rD, rs1** | -+------------+---------+--------+----------+--------+------------+--------------------------------+ +.. table:: Immediate Bit Manipulation operations encoding + :name: Immediate Bit Manipulation operations encoding + :width: 50 + :widths: 5 14 13 5 8 6 16 33 + :class: no-scrollbar-table + + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **ls3[4:0]** | **ls2[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | **Mnemonic** | + +========+======================+===============+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extract rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.extractu rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | Iuimm5[4:0] | src | 000 | dest | 101 1011 | **cv.insert rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bclr rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bset rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + | 11 | 000, Luimm2[1:0] | Iuimm5[4:0] | src | 001 | dest | 101 1011 | **cv.bitrev rD, rs1, Is3, Is2** | + +--------+----------------------+---------------+---------+------------+--------+------------+------------------------------------+ + +.. table:: Register Bit Manipulation operations encoding + :name: Register Bit Manipulation operations encoding + :width: 50 + :widths: 19 13 5 8 6 16 33 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+================================+ + | 001 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.extractur rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.insertr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.bclrr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 001 1101 | src2 | scr1 | 011 | dest | 010 1011 | **cv.bsetr rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.ror rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.ff1 rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.fl1 rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.clb rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ + | 010 0100 | 00000 | src1 | 011 | dest | 010 1011 | **cv.cnt rD, rs1** | + +------------+---------+---------+------------+--------+------------+--------------------------------+ .. _corev_general_alu: -General ALU Operations +General ALU operations ^^^^^^^^^^^^^^^^^^^^^^ -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **Mnemonic** | | **Description** | -+=================+=========================+========================================================================+ -| **cv.abs** | **rD, rs1** | rD = rs1 < 0 ? -rs1 : rs1 | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.slet** | **rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | -| | | | -| | | Note: Comparison is signed. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.sletu** | **rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | -| | | | -| | | Note: Comparison is unsigned. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.min** | **rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | -| | | | -| | | Note: Comparison is signed. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.minu** | **rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | -| | | | -| | | Note: Comparison is unsigned. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.max** | **rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | -| | | | -| | | Note: Comparison is signed. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.maxu** | **rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | -| | | | -| | | Note: Comparison is unsigned. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.exths** | **rD, rs1** | rD = Sext(rs1[15:0]) | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.exthz** | **rD, rs1** | rD = Zext(rs1[15:0]) | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.extbs** | **rD, rs1** | rD = Sext(rs1[7:0]) | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.extbz** | **rD, rs1** | rD = Zext(rs1[7:0]) | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.clip** | **rD, rs1, Is2** | if rs1 <= -2^(Is2-1), rD = -2^(Is2-1), | -| | | | -| | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | -| | | | -| | | else rD = rs1 | -| | | | -| | | Note: If ls2 is equal to 0, | -| | | | -| | | -2^(Is2-1) is equivalent to -1 while (2^(Is2-1)-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.clipu** | **rD, rs1, Is2** | if rs1 <= 0, rD = 0, | -| | | | -| | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | -| | | | -| | | else rD = rs1 | -| | | | -| | | Note: If ls2 is equal to 0, (2^(Is2-1)-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.clipr** | **rD, rs1, rs2** | if rs1 <= -(rs2+1), rD = -(rs2+1), | -| | | | -| | | else if rs1 >=rs2, rD = rs2, | -| | | | -| | | else rD = rs1 | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.clipur** | **rD, rs1, rs2** | if rs1 <= 0, rD = 0, | -| | | | -| | | else if rs1 >= rs2, rD = rs2, | -| | | | -| | | else rD = rs1 | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.addN** | **rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | Setting Is3 to 2 replaces former cv.avg. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.adduN** | **rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | Setting Is3 to 2 replaces former cv.avg. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.addRN** | **rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.adduRN** | **rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1))) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subN** | **rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subuN** | **rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >> Is3 | -| | | | -| | | Note: Logical shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subRN** | **rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subuRN** | **rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1))) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.addNr** | **rD, rs1, rs2** | rD = (rD + rs1) >>> rs2[4:0] | -| | | | -| | | Note: Arithmetic shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.adduNr** | **rD, rs1, rs2** | rD = (rD + rs1) >> rs2[4:0] | -| | | | -| | | Note: Logical shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.addRNr** | **rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1)) >>> rs2[4:0] | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.adduRNr** | **rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1))) >> rs2[4:0] | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subNr** | **rD, rs1, rs2** | rD = (rD - rs1) >>> rs2[4:0] | -| | | | -| | | Note: Arithmetic shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subuNr** | **rD, rs1, rs2** | rD = (rD - rs1) >> rs2[4:0] | -| | | | -| | | Note: Logical shift right. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subRNr** | **rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1)) >>> rs2[4:0] | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ -| **cv.subuRNr** | **rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1))) >> rs2[4:0] | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | -+-----------------+-------------------------+------------------------------------------------------------------------+ +.. table:: General ALU operations + :name: General ALU operations + :widths: 30 70 + :class: no-scrollbar-table + + +-------------------------------------------+------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===========================================+========================================================================+ + | **cv.abs rD, rs1** | rD = rs1 < 0 ? -rs1 : rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.slet rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.sletu rD, rs1, rs2** | rD = rs1 <= rs2 ? 1 : 0 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.min rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.minu rD, rs1, rs2** | rD = rs1 < rs2 ? rs1 : rs2 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.max rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | + | | | + | | Note: Comparison is signed. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.maxu rD, rs1, rs2** | rD = rs1 < rs2 ? rs2 : rs1 | + | | | + | | Note: Comparison is unsigned. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.exths rD, rs1** | rD = Sext(rs1[15:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.exthz rD, rs1** | rD = Zext(rs1[15:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.extbs rD, rs1** | rD = Sext(rs1[7:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.extbz rD, rs1** | rD = Zext(rs1[7:0]) | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clip rD, rs1, Is2** | if rs1 <= -2^(Is2-1), rD = -2^(Is2-1), | + | | | + | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | + | | | + | | else rD = rs1 | + | | | + | | Note: If ls2 is equal to 0, | + | | | + | | -2^(Is2-1) is equivalent to -1 while (2^(Is2-1)-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipu rD, rs1, Is2** | if rs1 <= 0, rD = 0, | + | | | + | | else if rs1 >= 2^(Is2-1)-1, rD = 2^(Is2-1)-1, | + | | | + | | else rD = rs1 | + | | | + | | Note: If ls2 is equal to 0, (2^(Is2-1)-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipr rD, rs1, rs2** | if rs1 <= -(rs2+1), rD = -(rs2+1), | + | | | + | | else if rs1 >=rs2, rD = rs2, | + | | | + | | else rD = rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.clipur rD, rs1, rs2** | if rs1 <= 0, rD = 0, | + | | | + | | else if rs1 >= rs2, rD = rs2, | + | | | + | | else rD = rs1 | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | Setting Is3 to 2 replaces former cv.avg. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | Setting Is3 to 2 replaces former cv.avg. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addRN rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduRN rD, rs1, rs2, Is3** | rD = (rs1 + rs2 + 2^(Is3-1))) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subN rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuN rD, rs1, rs2, Is3** | rD = (rs1 - rs2) >> Is3 | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subRN rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuRN rD, rs1, rs2, Is3** | rD = (rs1 - rs2 + 2^(Is3-1))) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addNr rD, rs1, rs2** | rD = (rD + rs1) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduNr rD, rs1, rs2** | rD = (rD + rs1) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.addRNr rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1)) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.adduRNr rD, rs1, rs2** | rD = (rD + rs1 + 2^(rs2[4:0]-1))) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subNr rD, rs1, rs2** | rD = (rD - rs1) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuNr rD, rs1, rs2** | rD = (rD - rs1) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subRNr rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1)) >>> rs2[4:0] | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ + | **cv.subuRNr rD, rs1, rs2** | rD = (rD - rs1+ 2^(rs2[4:0]-1))) >> rs2[4:0] | + | | | + | | Note: Logical shift right. | + | | | + | | If rs2[4:0] is equal to 0, 2^(rs2[4:0]-1) is equivalent to 0. | + +-------------------------------------------+------------------------------------------------------------------------+ General ALU Encoding ^^^^^^^^^^^^^^^^^^^^ -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| funct7 | rs2 | rs1 | funct | rD | opcode | | -+============+=========+========+==========+========+============+===========================+ -| 010 1000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.abs rD, rs1** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.slet rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.sletu rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.min rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.minu rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1101 | src2 | src1 | 011 | dest | 010 1011 | **cv.max rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 010 1110 | src2 | src1 | 011 | dest | 010 1011 | **cv.maxu rD, rs1, rs2** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 011 0000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exths rD, rs1** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 011 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exthz rD, rs1** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 011 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbs rD, rs1** | -+------------+---------+--------+----------+--------+------------+---------------------------+ -| 011 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbz rD, rs1** | -+------------+---------+--------+----------+--------+------------+---------------------------+ - - -+------------+---------------+--------+----------+--------+------------+-----------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+------------+---------------+--------+----------+--------+------------+-----------------------------+ -| funct7 | Is2[4:0] | rs1 | funct3 | rD | opcode | | -+============+===============+========+==========+========+============+=============================+ -| 011 1000 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clip rD, rs1, Is2** | -+------------+---------------+--------+----------+--------+------------+-----------------------------+ -| 011 1001 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clipu rD, rs1, Is2** | -+------------+---------------+--------+----------+--------+------------+-----------------------------+ -| 011 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipr rD, rs1, rs2** | -+------------+---------------+--------+----------+--------+------------+-----------------------------+ -| 011 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipur rD, rs1, rs2** | -+------------+---------------+--------+----------+--------+------------+-----------------------------+ - -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 31:30 | 29 : 25 | 24 :20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| f2 | Is3[4:0] | rs2 | rs1 | funct3 | rD | opcode | | -+=======+===============+========+========+==========+========+============+==================================+ -| 00 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 00 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+----------------------------------+ - -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 31 : 25 | 24 : 20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| funct7 | Is3[4:0] | rs1 | funct3 | rD | opcode | | -+============+==========+========+==========+========+============+=============================+ -| 100 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.addNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0001 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduNr rD, rs1, rs** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0010 | src2 | src1 | 011 | dest | 010 1011 | **cv.addRNr rD, rs1, rs** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0011 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduRNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0100 | src2 | src1 | 011 | dest | 010 1011 | **cv.subNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0101 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0110 | src2 | src1 | 011 | dest | 010 1011 | **cv.subRNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ -| 100 0111 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuRNr rD, rs1, rs2** | -+------------+----------+--------+----------+--------+------------+-----------------------------+ +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+===========================+ + | 010 1000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.abs rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.slet rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.sletu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.min rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1100 | src2 | src1 | 011 | dest | 010 1011 | **cv.minu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1101 | src2 | src1 | 011 | dest | 010 1011 | **cv.max rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 010 1110 | src2 | src1 | 011 | dest | 010 1011 | **cv.maxu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0000 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exths rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0001 | 00000 | src1 | 011 | dest | 010 1011 | **cv.exthz rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0010 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbs rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + | 011 0011 | 00000 | src1 | 011 | dest | 010 1011 | **cv.extbz rD, rs1** | + +------------+---------+---------+------------+--------+------------+---------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | **funct7** | **Is2[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+===============+=========+============+========+============+=============================+ + | 011 1000 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clip rD, rs1, Is2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1001 | Iuimm5[4:0] | src1 | 011 | dest | 010 1011 | **cv.clipu rD, rs1, Is2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1010 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipr rD, rs1, rs2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + | 011 1011 | src2 | src1 | 011 | dest | 010 1011 | **cv.clipur rD, rs1, rs2** | + +------------+---------------+---------+------------+--------+------------+-----------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 5 16 13 9 9 9 11 28 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+==================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.addRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 010 | dest | 101 1011 | **cv.adduRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 011 | dest | 101 1011 | **cv.subuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+----------------------------------+ + +.. table:: General ALU operations encoding + :name: General ALU operations encoding + :widths: 21 13 9 9 9 11 28 + :class: no-scrollbar-table + + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | **funct7** | **Is3[4:0]** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+==============+=========+============+========+============+=============================+ + | 100 0000 | src2 | src1 | 011 | dest | 010 1011 | **cv.addNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0001 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduNr rD, rs1, rs** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0010 | src2 | src1 | 011 | dest | 010 1011 | **cv.addRNr rD, rs1, rs** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0011 | src2 | src1 | 011 | dest | 010 1011 | **cv.adduRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0100 | src2 | src1 | 011 | dest | 010 1011 | **cv.subNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0101 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0110 | src2 | src1 | 011 | dest | 010 1011 | **cv.subRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ + | 100 0111 | src2 | src1 | 011 | dest | 010 1011 | **cv.subuRNr rD, rs1, rs2** | + +------------+--------------+---------+------------+--------+------------+-----------------------------+ .. _corev_immediate_branching: -Immediate Branching Operations +Immediate Branching operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+---------------------------------+------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=================================+========================================================================+ -| **cv.beqimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is equal to Imm5. | -| | | -| | Note: Imm5 is signed. | -+---------------------------------+------------------------------------------------------------------------+ -| **cv.bneimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is not equal to Imm5. | -| | | -| | Note: Imm5 is signed. | -+---------------------------------+------------------------------------------------------------------------+ +.. table:: Immediate Branching operations + :name: Immediate Branching operations + :widths: 30 70 + :class: no-scrollbar-table + + +---------------------------------+------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=================================+========================================================================+ + | **cv.beqimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is equal to Imm5. | + | | | + | | Note: Imm5 is signed. | + +---------------------------------+------------------------------------------------------------------------+ + | **cv.bneimm rs1, Imm5, Imm12** | Branch to PC + (Imm12 << 1) if rs1 is not equal to Imm5. | + | | | + | | Note: Imm5 is signed. | + +---------------------------------+------------------------------------------------------------------------+ Immediate Branching Encoding ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+------------+--------------+---------+----------+---------+-------------+------------+------------+---------------------------------+ -| 31 | 30 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 8 | 7 | 6 : 0 | | -+------------+--------------+---------+----------+---------+-------------+------------+------------+---------------------------------+ -| Imm12[12] | Imm12[10:5] | rs2 | rs1 | funct3 | Imm12 | Imm12 | opcode | | -+============+==============+=========+==========+=========+=============+============+============+=================================+ -| Imm12[12] | Imm12[10:5] | Imm5 | src1 | 110 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.beqimm rs1, Imm5, Imm12** | -+------------+--------------+---------+----------+---------+-------------+------------+------------+---------------------------------+ -| Imm12[12] | Imm12[10:5] | Imm5 | src1 | 111 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.bneimm rs1, Imm5, Imm12** | -+------------+--------------+---------+----------+---------+-------------+------------+------------+---------------------------------+ +.. table:: Immediate Branching encoding + :name: General ALU operations encoding + :widths: 13 14 8 6 8 12 12 11 16 + :class: no-scrollbar-table + + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | 31 | 30 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 8 | 7 | 6 : 0 | | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | **Imm12[12]** | **Imm12[10:5]** | **Imm5** | **rs1** | **funct3** | **Imm12** | **Imm12** | **opcode** | | + +===============+=================+==========+==========+============+=============+============+============+=================================+ + | Imm12[12] | Imm12[10:5] | Imm5 | src1 | 110 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.beqimm rs1, Imm5, Imm12** | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ + | Imm12[12] | Imm12[10:5] | Imm5 | src1 | 111 | Imm12[4:1] | Imm12[11] | 000 1011 | **cv.bneimm rs1, Imm5, Imm12** | + +---------------+-----------------+----------+----------+------------+-------------+------------+------------+---------------------------------+ .. _corev_multiply_accumulate: @@ -902,182 +1020,215 @@ Multiply-Accumulate CV32E40P supports custom extensions for multiply-accumulate and half-word multiplications with an optional post-multiplication shift. -The custom multiply-accumulate extensions are only supported if ``PULP_XPULP`` == 1. - -MAC Operations -^^^^^^^^^^^^^^ - -32-Bit x 32-Bit Multiplication Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+-------------------+-------------------------+------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | | -+===================+=========================+==============================================================================+ -| **cv.mac** | **rD, rs1, rs2** | rD = rD + rs1 \* rs2 | -+-------------------+-------------------------+------------------------------------------------------------------------------+ -| **cv.msu** | **rD, rs1, rs2** | rD = rD - rs1 \* rs2 | -+-------------------+-------------------------+------------------------------------------------------------------------------+ - -16-Bit x 16-Bit Multiplication -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | | -+===================+===========================+==============================================================================+ -| **cv.muluN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0])) >> Is3 | -| | | | -| | | Note: Logical shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulhhuN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16])) >> Is3 | -| | | | -| | | Note: Logical shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulsN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0])) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulhhsN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16])) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.muluRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + 2^(Is3-1)) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulhhuRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + 2^(Is3-1)) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulsRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.mulhhsRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ - -16-Bit x 16-Bit Multiply-Accumulate -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | | -+===================+===========================+==============================================================================+ -| **cv.macuN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD) >> Is3 | -| | | | -| | | Note: Logical shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.machhuN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD) >> Is3 | -| | | | -| | | Note: Logical shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.macsN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.machhsN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.macuRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD + 2^(Is3-1)) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.machhuRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD + 2^(Is3-1)) >> Is3 | -| | | | -| | | Note: Logical shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.macsRN** | **rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ -| **cv.machhsRN** | **, rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD + 2^(Is3-1)) >>> Is3 | -| | | | -| | | Note: Arithmetic shift right. | -| | | | -| | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | -+-------------------+---------------------------+------------------------------------------------------------------------------+ - -MAC Encoding -^^^^^^^^^^^^ - -+------------+--------+--------+----------+--------+------------+--------------------------+ -| 31 : 25 | 24 :20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+------------+--------+--------+----------+--------+------------+--------------------------+ -| funct7 | rs2 | rs1 | funct3 | rD | opcode | | -+============+========+========+==========+========+============+==========================+ -| 100 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.mac rD, rs1, rs2** | -+------------+--------+--------+----------+--------+------------+--------------------------+ -| 100 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.msu rD, rs1, rs2** | -+------------+--------+--------+----------+--------+------------+--------------------------+ - -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 31:30 | 29 : 25 | 24 :20 | 19 :15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| f2 | Is3[4:0] | rs2 | rs1 | funct3 | rD | opcode | | -+=======+===============+========+========+==========+========+============+====================================+ -| 00 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 00 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 00 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 00 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 01 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 10 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ -| 11 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsRN rD, rs1, rs2, Is3** | -+-------+---------------+--------+--------+----------+--------+------------+------------------------------------+ +The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` == 1. + +16-Bit x 16-Bit Multiplication operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 16-Bit Multiplication operations + :name: 16-Bit Multiplication operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===============================================+==============================================================================+ + | **cv.muluN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0])) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16])) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0])) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16])) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.muluRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.mulhhsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + +16-Bit x 16-Bit Multiply-Accumulate operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 16-Bit Multiply-Accumulate operations + :name: 16-Bit Multiply-Accumulate operations + :widths: 30 70 + :class: no-scrollbar-table + + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +===============================================+==============================================================================+ + | **cv.macuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhuN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD) >> Is3 | + | | | + | | Note: Logical shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhsN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[15:0]) \* Zext(rs2[15:0]) + rD + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhuRN rD, rs1, rs2, Is3** | rD[31:0] = (Zext(rs1[31:16]) \* Zext(rs2[31:16]) + rD + 2^(Is3-1)) >> Is3 | + | | | + | | Note: Logical shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.macsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[15:0]) \* Sext(rs2[15:0]) + rD + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + | **cv.machhsRN rD, rs1, rs2, Is3** | rD[31:0] = (Sext(rs1[31:16]) \* Sext(rs2[31:16]) + rD + 2^(Is3-1)) >>> Is3 | + | | | + | | Note: Arithmetic shift right. | + | | | + | | If Is3 is equal to 0, 2^(Is3-1) is equivalent to 0. | + +-----------------------------------------------+------------------------------------------------------------------------------+ + +32-Bit x 32-Bit Multiply-Accumulate operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. table:: 32-Bit Multiply-Accumulate operations + :name: 32-Bit Multiply-Accumulate operations + :widths: 30 70 + :class: no-scrollbar-table + + +--------------------------------+-------------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +================================+===========================================================================================+ + | **cv.mac rD, rs1, rs2** | rD = rD + rs1 \* rs2 | + +--------------------------------+-------------------------------------------------------------------------------------------+ + | **cv.msu rD, rs1, rs2** | rD = rD - rs1 \* rs2 | + +--------------------------------+-------------------------------------------------------------------------------------------+ + +Encoding +^^^^^^^^ + +.. table:: 16-Bit Multiplication operations + :name: 16-Bit Multiplication operations + :widths: 5 16 6 6 9 6 11 39 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.muluRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 101 | dest | 101 1011 | **cv.mulhhuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + +.. table:: 16-Bit Multiply-Accumulate operations + :name: 16-Bit Multiply-Accumulate operations + :widths: 5 16 6 6 9 6 11 39 + :class: no-scrollbar-table + + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 31: 30 | 29 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | **f2** | **Is3[4:0]** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +========+===============+=========+=========+============+========+============+====================================+ + | 00 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 00 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 01 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.macuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 111 | dest | 101 1011 | **cv.machhuRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 10 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.macsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + | 11 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsRN rD, rs1, rs2, Is3** | + +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ + +.. table:: 32-Bit Multiply-Accumulate operations + :name: 32-Bit Multiply-Accumulate operations + :widths: 21 6 6 9 6 11 39 + :class: no-scrollbar-table + + +------------+---------+---------+------------+--------+------------+--------------------------+ + | 31 : 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+---------+---------+------------+--------+------------+--------------------------+ + | **funct7** | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=========+=========+============+========+============+==========================+ + | 100 1000 | src2 | src1 | 011 | dest | 010 1011 | **cv.mac rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------+ + | 100 1001 | src2 | src1 | 011 | dest | 010 1011 | **cv.msu rD, rs1, rs2** | + +------------+---------+---------+------------+--------+------------+--------------------------+ .. _corev_simd: SIMD ---- -The SIMD instructions perform operations on -multiple sub-word elements at the same time. This is done by segmenting -the data path into smaller parts when 8 or 16-bit operations should be -performed. +The SIMD instructions perform operations on multiple sub-word elements at the same time. This is done by segmenting +the data path into smaller parts when 8- or 16-bit operations should be performed. -The custom SIMD extensions are only supported if ``PULP_XPULP`` == 1. +The custom SIMD extensions are only supported if ``COREV_PULP`` == 1. -**Note:** See the comments at the start of :ref:`custom-isa-extensions` on availability of the compiler tool chains. -Support for SIMD will be primarily through assembly code and builtin functions, with no auto-vectorization and limited other optimization. -Simple auto-vectorization (add, sub...) and optimization will be evaluated once a stable GCC toolchain is available. +.. note:: + + See the comments at the start of :ref:`custom-isa-extensions` on availability of the compiler tool chains. + Support for SIMD will be primarily through assembly code and builtin functions, with no auto-vectorization and limited other optimization. + Simple auto-vectorization (add, sub...) and optimization will be evaluated once a stable GCC toolchain is available. SIMD instructions are available in two flavors: @@ -1115,7 +1266,8 @@ Additionally, there are three modes that influence the second operand: 3. Immediate scalar replication mode (.sci), vector-scalar operation. Operand 1 is treated as vector, while operand 2 is treated as a - scalar and comes from an immediate.
+ scalar and comes from a 6-bit immediate. + The immediate is either sign- or zero-extended depending on the operation. If not specified, the immediate is sign-extended with the exception of all cv.shuffle* where it is always unsigned. @@ -1126,524 +1278,564 @@ Additionally, there are three modes that influence the second operand: x3[15: 0] = x2[15: 0] + 0xFFEA -In the following table, the index i ranges from 0 to 1 for 16-Bit -operations and from 0 to 3 for 8-Bit operations: -- The index 0 is 15:0 for 16-Bit operations or 7:0 for 8-Bit operations. +In the following tables, the index i ranges from 0 to 1 for 16-Bit operations and from 0 to 3 for 8-Bit operations: + +- The index 0 is 15:0 for 16-Bit operations or 7:0 for 8-Bit operations. + - The index 1 is 31:16 for 16-Bit operations or 15:8 for 8-Bit operations. -- The index 2 is 23:16 for 8-Bit operations. -- The index 3 is 31:24 for 8-Bit operations. + +- The index 2 is 23:16 for 8-Bit operations. + +- The index 3 is 31:24 for 8-Bit operations. And I5, I4, I3, I2, I1 and I0 respectively represent bits 5, 4, 3, 2, 1 and 0 of the immediate value. -SIMD ALU Operations +SIMD ALU operations ^^^^^^^^^^^^^^^^^^^ -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=======================================+=======================================================================================+ -| **cv.add[.sc,.sci]{.h,.b}** | rD[i] = (rs1[i] + op2[i]) & 0xFFFF | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sub[.sc,.sci]{.h,.b}** | rD[i] = (rs1[i] - op2[i]) & 0xFFFF | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.avg[.sc,.sci]{.h,.b}** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | -| | | -| | Note: Arithmetic right shift. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.avgu[.sc,.sci]{.h,.b}** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | -| | | -| | Note: Logical shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.min[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.minu[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | -| | | -| | Note: Immediate is zero-extended, comparison is unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.max[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.maxu[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | -| | | -| | Note: Immediate is zero-extended, comparison is unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.srl[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] >> op2[i] | -| | | -| | Note: Immediate is zero-extended, shift is logical. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sra[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] >>> op2[i] | -| | | -| | Note: Immediate is zero-extended, shift is arithmetic. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sll[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] << op2[i] | -| | | -| | Note: Immediate is zero-extended, shift is logical. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.or[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] \| op2[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.xor[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] ^ op2[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.and[.sc,.sci]{.h,.b}** | rD[i] = rs1[i] & op2[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.abs{.h,.b}** | rD[i] = rs1[i] < 0 ? -rs1[i] : rs1[i] | -+---------------------------------------+---------------------------------------------------------------------------------------+ - -SIMD Bit Manipulation Operations -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=======================================+=======================================================================================+ -| **cv.extract.h** | rD = Sext(rs1[I0\*16+15:I0\*16]) | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.extract.b** | rD = Sext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.extractu.h** | rD = Zext(rs1[I0\*16+15:I0\*16]) | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.extractu.b** | rD = Zext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.insert.h** | rD[I0\*16+15:I0\*16] = rs1[15:0] | -| | | -| | Note: The rest of the bits of rD are untouched and keep their previous value. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.insert.b** | rD[(I1:I0)\*8+7:(I1:I0)\*8] = rs1[7:0] | -| | | -| | Note: The rest of the bits of rD are untouched and keep their previous value. | -+---------------------------------------+---------------------------------------------------------------------------------------+ - -SIMD Dot Product Instructions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=======================================+=======================================================================================+ -| **cv.dotup[.sc,.sci].h** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: All operands are unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.dotup[.sc,.sci].b** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: All operands are unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.dotusp[.sc,.sci].h** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: rs1 is treated as unsigned, while op2 is treated as signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.dotusp[.sc,.sci].b** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: rs1 is treated as unsigned, while op2 is treated as signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.dotsp[.sc,.sci].h** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: All operands are signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.dotsp[.sc,.sci].b** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: All operands are signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotup[.sc,.sci].h** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: All operands are unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotup[.sc,.sci].b** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: All operands are unsigned. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotusp[.sc,.sci].h** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: rs1 is treated as unsigned while op2 is treated as signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotusp[.sc,.sci].b** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: rs1 is treated as unsigned while op2 is treated as signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotsp[.sc,.sci].h** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | -| | | -| | Note: All operands are signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sdotsp[.sc,.sci].b** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + rs1[2] \* op2[2] + rs1[3] \* op2[3] | -| | | -| | Note: All operands are signed. | -+---------------------------------------+---------------------------------------------------------------------------------------+ - -SIMD Shuffle and Pack Instructions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=======================================+=======================================================================================+ -| **cv.shuffle.h** | rD[31:16] = rs1[rs2[16]\*16+15:rs2[16]\*16] | -| | | -| | rD[15:0] = rs1[rs2[0]\*16+15:rs2[0]\*16] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffle.sci.h** | rD[31:16] = rs1[I1\*16+15:I1\*16] | -| | | -| | rD[15:0] = rs1[I0\*16+15:I0\*16] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffle.b** | rD[31:24] = rs1[rs2[25:24]\*8+7:rs2[25:24]\*8] | -| | | -| | rD[23:16] = rs1[rs2[17:16]\*8+7:rs2[17:16]\*8] | -| | | -| | rD[15:8] = rs1[rs2[9:8]\*8+7:rs2[9:8]\*8] | -| | | -| | rD[7:0] = rs1[rs2[1:0]\*8+7:rs2[1:0]\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffleI0.sci.b** | rD[31:24] = rs1[7:0] | -| | | -| | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | -| | | -| | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | -| | | -| | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffleI1.sci.b** | rD[31:24] = rs1[15:8] | -| | | -| | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | -| | | -| | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | -| | | -| | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffleI2.sci.b** | rD[31:24] = rs1[23:16] | -| | | -| | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | -| | | -| | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | -| | | -| | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffleI3.sci.b** | rD[31:24] = rs1[31:24] | -| | | -| | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | -| | | -| | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | -| | | -| | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffle2.h** | rD[31:16] = ((rs2[17] == 1) ? rs1 : rD)[rs2[16]\*16+15:rs2[16]\*16] | -| | | -| | rD[15:0] = ((rs2[1] == 1) ? rs1 : rD)[rs2[0]\*16+15:rs2[0]\*16] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.shuffle2.b** | rD[31:24] = ((rs2[26] == 1) ? rs1 : rD)[rs2[25:24]\*8+7:rs2[25:24]\*8] | -| | | -| | rD[23:16] = ((rs2[18] == 1) ? rs1 : rD)[rs2[17:16]\*8+7:rs2[17:16]\*8] | -| | | -| | rD[15:8] = ((rs2[10] == 1) ? rs1 : rD)[rs2[9:8]\*8+7:rs2[9:8]\*8] | -| | | -| | rD[7:0] = ((rs2[2] == 1) ? rs1 : rD)[rs2[1:0]\*8+7:rs2[1:0]\*8] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.pack** | rD[31:16] = rs1[15:0] | -| | | -| | rD[15:0] = rs2[15:0] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.pack.h** | rD[31:16] = rs1[31:16] | -| | | -| | rD[15:0] = rs2[31:16] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.packhi.b** | rD[31:24] = rs1[7:0] | -| | | -| | rD[23:16] = rs2[7:0] | -| | | -| | Note: The rest of the bits of rD are untouched and keep their previous value. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.packlo.b** | rD[15:8] = rs1[7:0] | -| | | -| | rD[7:0] = rs2[7:0] | -| | | -| | Note: The rest of the bits of rD are untouched and keep their previous value. | -+---------------------------------------+---------------------------------------------------------------------------------------+ +.. table:: SIMD ALU operations + :name: SIMD ALU operations + :widths: 50 50 + :class: no-scrollbar-table + + +------------------------------------------------------------+------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +============================================================+==================================================================+ + | **cv.add[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] + op2[i]) & 0xFFFF | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sub[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = (rs1[i] - op2[i]) & 0xFFFF | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.avg[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | + | | | + | | Note: Arithmetic right shift. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.avgu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 | + | | | + | | Note: Logical shift right. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.min[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.minu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] | + | | | + | | Note: Immediate is zero-extended, comparison is unsigned. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.max[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.maxu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] | + | | | + | | Note: Immediate is zero-extended, comparison is unsigned. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.srl[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >> op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is logical. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sra[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >>> op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is arithmetic. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.sll[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] << op2[i] | + | | | + | | Note: Immediate is zero-extended, shift is logical. | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.or[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] \| op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.xor[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] ^ op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.and[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] & op2[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + | **cv.abs{.h,.b} rD, rs1** | rD[i] = rs1[i] < 0 ? -rs1[i] : rs1[i] | + +------------------------------------------------------------+------------------------------------------------------------------+ + +SIMD Bit Manipulation operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Bit Manipulation operations + :name: SIMD Bit Manipulation operations + :widths: 50 50 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.extract.h rD, rs1, Imm6** | rD = Sext(rs1[I0\*16+15:I0\*16]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extract.b rD, rs1, Imm6** | rD = Sext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extractu.h rD, rs1, Imm6** | rD = Zext(rs1[I0\*16+15:I0\*16]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.extractu.b rD, rs1, Imm6** | rD = Zext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.insert.h rD, rs1, Imm6** | rD[I0\*16+15:I0\*16] = rs1[15:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.insert.b rD, rs1, Imm6** | rD[(I1:I0)\*8+7:(I1:I0)\*8] = rs1[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD Dot Product operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Dot Product operations + :name: SIMD Dot Product operations + :widths: 50 50 + :class: no-scrollbar-table + + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +============================================================+=======================================================================================+ + | **cv.dotup[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotup[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: rs1 is treated as unsigned, while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: rs1 is treated as unsigned, while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.dotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotup[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotup[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are unsigned. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotusp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: rs1 is treated as unsigned while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotusp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: rs1 is treated as unsigned while op2 is treated as signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotsp[.sc,.sci].h rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sdotsp[.sc,.sci].b rD, rs1, [rs2, Imm6]** | rD = rD + rs1[0] \* op2[0] + rs1[1] \* op2[1] + | + | | | + | | rs1[2] \* op2[2] + rs1[3] \* op2[3] | + | | | + | | Note: All operands are signed. | + +------------------------------------------------------------+---------------------------------------------------------------------------------------+ + +SIMD Shuffle and Pack operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. table:: SIMD Shuffle and Pack operations + :name: SIMD Shuffle and Pack operations + :widths: 35 65 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.shuffle.h rD, rs1, rs2** | rD[31:16] = rs1[rs2[16]\*16+15:rs2[16]\*16] | + | | | + | | rD[15:0] = rs1[rs2[0]\*16+15:rs2[0]\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle.sci.h rD, rs1, Imm6** | rD[31:16] = rs1[I1\*16+15:I1\*16] | + | | | + | | rD[15:0] = rs1[I0\*16+15:I0\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle.b rD, rs1, rs2** | rD[31:24] = rs1[rs2[25:24]\*8+7:rs2[25:24]\*8] | + | | | + | | rD[23:16] = rs1[rs2[17:16]\*8+7:rs2[17:16]\*8] | + | | | + | | rD[15:8] = rs1[rs2[9:8]\*8+7:rs2[9:8]\*8] | + | | | + | | rD[7:0] = rs1[rs2[1:0]\*8+7:rs2[1:0]\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI0.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[7:0] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI1.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[15:8] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI2.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[23:16] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffleI3.sci.b rD, rs1, Imm6** | rD[31:24] = rs1[31:24] | + | | | + | | rD[23:16] = rs1[(I5:I4)\*8+7: (I5:I4)\*8] | + | | | + | | rD[15:8] = rs1[(I3:I2)\*8+7: (I3:I2)\*8] | + | | | + | | rD[7:0] = rs1[(I1:I0)\*8+7:(I1:I0)\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle2.h rD, rs1, rs2** | rD[31:16] = ((rs2[17] == 1) ? rs1 : rD)[rs2[16]\*16+15:rs2[16]\*16] | + | | | + | | rD[15:0] = ((rs2[1] == 1) ? rs1 : rD)[rs2[0]\*16+15:rs2[0]\*16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.shuffle2.b rD, rs1, rs2** | rD[31:24] = ((rs2[26] == 1) ? rs1 : rD)[rs2[25:24]\*8+7:rs2[25:24]\*8] | + | | | + | | rD[23:16] = ((rs2[18] == 1) ? rs1 : rD)[rs2[17:16]\*8+7:rs2[17:16]\*8] | + | | | + | | rD[15:8] = ((rs2[10] == 1) ? rs1 : rD)[rs2[9:8]\*8+7:rs2[9:8]\*8] | + | | | + | | rD[7:0] = ((rs2[2] == 1) ? rs1 : rD)[rs2[1:0]\*8+7:rs2[1:0]\*8] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.pack rD, rs1, rs2** | rD[31:16] = rs1[15:0] | + | | | + | | rD[15:0] = rs2[15:0] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.pack.h rD, rs1, rs2** | rD[31:16] = rs1[31:16] | + | | | + | | rD[15:0] = rs2[31:16] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.packhi.b rD, rs1, rs2** | rD[31:24] = rs1[7:0] | + | | | + | | rD[23:16] = rs2[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.packlo.b rD, rs1, rs2** | rD[15:8] = rs1[7:0] | + | | | + | | rD[7:0] = rs2[7:0] | + | | | + | | Note: The rest of the bits of rD are untouched and keep their previous value. | + +---------------------------------------+---------------------------------------------------------------------------------------+ SIMD ALU Encoding -^^^^^^^^^^^^^^^^^ - -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 :12 | 11 : 7 | 6 : 0 | | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| funct5 | F | | rs2 | rs1 | funct3 | rD | opcode | | -+==========+=====+====+=========+=========+========+==========+==========+======================================+ -| 0 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.add.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.add.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.add.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.add.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.add.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sub.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sub.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sub.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sub.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sub.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avg.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avg.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avg.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avg.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avg.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avg.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avgu.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avgu.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avgu.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avgu.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avgu.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avgu.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.min.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.min.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.min.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.min.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.min.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.min.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.minu.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.minu.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.minu.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.minu.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.minu.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.minu.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.max.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.max.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.max.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.max.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.max.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0110 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.max.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.maxu.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.maxu.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.maxu.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.maxu.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.maxu.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 0111 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.maxu.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.srl.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.srl.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.srl.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.srl.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.srl.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.srl.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sra.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sra.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sra.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sra.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sra.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sra.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sll.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sll.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sll.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sll.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sll.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sll.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.or.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.or.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.or.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.or.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.or.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.or.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.xor.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.xor.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.xor.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.xor.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.xor.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.xor.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.and.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.and.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.and.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.and.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.and.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.and.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1110 | 0 | 0 | 0 | src1 | 000 | dest | 111 1011 | **cv.abs.h rD, rs1** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 0 1110 | 0 | 0 | 0 | src1 | 001 | dest | 111 1011 | **cv.abs.b rD, rs1** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 000 | dest | 111 1011 | **cv.extract.h rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 001 | dest | 111 1011 | **cv.extract.b rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 010 | dest | 111 1011 | **cv.extractu.h rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 011 | dest | 111 1011 | **cv.extractu.b rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 100 | dest | 111 1011 | **cv.insert.h rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 0111 | 0 | Imm6[0\|5:1] | src1 | 101 | dest | 111 1011 | **cv.insert.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotup.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotup.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotup.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotup.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotup.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotup.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotusp.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotusp.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotusp.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotusp.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotusp.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotusp.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotsp.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotsp.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotsp.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotsp.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotsp.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotsp.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotup.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotup.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotup.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotup.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotup.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotup.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotusp.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotusp.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotusp.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotusp.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotusp.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotusp.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotsp.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotsp.sc.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotsp.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotsp.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotsp.sc.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotsp.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.shuffle.sci.h rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI0.sci.b rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI1.sci.b rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI2.sci.b rD, rs1, Imm6** | -+----------+-----+--------------+---------+--------+----------+----------+--------------------------------------+ -| 1 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI3.sci.b rD, rs1, Imm6** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle2.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle2.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1110 | 0 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack.h rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1111 | 0 | 1 | src2 | src1 | 001 | dest | 111 1011 | **cv.packhi.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ -| 1 1111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.packlo.b rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+--------------------------------------+ - - -SIMD Comparison Operations +~~~~~~~~~~~~~~~~~ + +.. table:: SIMD ALU encoding + :name: SIMD ALU encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+======================================+ + | 0 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.add.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.add.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.add.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.add.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.add.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sub.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sub.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sub.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sub.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sub.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avg.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avg.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avg.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avg.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avg.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avg.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avgu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avgu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avgu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avgu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avgu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avgu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.min.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.min.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.min.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.min.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.min.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.min.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.minu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.minu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.minu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.minu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.minu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.minu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.max.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.max.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.max.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.max.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.max.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.max.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.maxu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.maxu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.maxu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.maxu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.maxu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.maxu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.srl.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.srl.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.srl.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.srl.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.srl.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.srl.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sra.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sra.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sra.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sra.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sra.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sra.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sll.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sll.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sll.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sll.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sll.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sll.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.or.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.or.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.or.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.or.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.or.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.or.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.xor.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.xor.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.xor.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.xor.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.xor.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.xor.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.and.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.and.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.and.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.and.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.and.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.and.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 000 | dest | 111 1011 | **cv.abs.h rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 001 | dest | 111 1011 | **cv.abs.b rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 000 | dest | 111 1011 | **cv.extract.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 001 | dest | 111 1011 | **cv.extract.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 010 | dest | 111 1011 | **cv.extractu.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 011 | dest | 111 1011 | **cv.extractu.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 100 | dest | 111 1011 | **cv.insert.h rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 101 | dest | 111 1011 | **cv.insert.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotup.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotup.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotup.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotup.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotusp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotusp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotsp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotsp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotup.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotup.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotup.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotup.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotusp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotusp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotsp.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotsp.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.shuffle.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI0.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI1.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI2.sci.b rD, rs1, Imm6** | + +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI3.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle2.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle2.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 1 | src2 | src1 | 001 | dest | 111 1011 | **cv.packhi.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.packlo.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + + +SIMD Comparison operations ^^^^^^^^^^^^^^^^^^^^^^^^^^ SIMD comparisons are done on individual bytes (.b) or half-words @@ -1659,168 +1851,178 @@ thus instead of a vector comparison a scalar comparison is performed. In the immediate scalar replication mode (.sci), the immediate given to the instruction is used for the comparison. -+----------------------------------+----------------------------+-----------------------------------+ -| **Mnemonic** | | **Description** | -+==================================+============================+===================================+ -| **cv.cmpeq[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] == op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpne[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] != op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpgt[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] > op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpge[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] >=op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmplt[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] < op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmple[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] <= op2 ? '1 : '0 | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpgtu[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] > op2 ? '1 : '0 | -| | | | -| | | Note: Unsigned comparison. | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpgeu[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] >= op2 ? '1 : '0 | -| | | | -| | | Note: Unsigned comparison. | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpltu[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] < op2 ? '1 : '0 | -| | | | -| | | Note: Unsigned comparison. | -+----------------------------------+----------------------------+-----------------------------------+ -| **cv.cmpleu[.sc,.sci]{.h,.b}** | **rD, rs1, {rs2, Imm6}** | rD[i] = rs1[i] <= op2 ? '1 : '0 | -| | | | -| | | Note: Unsigned comparison. | -+----------------------------------+----------------------------+-----------------------------------+ +.. table:: SIMD Comparison operations + :name: SIMD Comparison operations + :widths: 50 50 + :class: no-scrollbar-table + + +---------------------------------------------------------------+-----------------------------------+ + | **Mnemonic** | **Description** | + +===============================================================+===================================+ + | **cv.cmpeq[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] == op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpne[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] != op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpge[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >=op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmplt[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmple[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] <= op2 ? '1 : '0 | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgtu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] > op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpgeu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >= op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpltu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] < op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ + | **cv.cmpleu[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] <= op2 ? '1 : '0 | + | | | + | | Note: Unsigned comparison. | + +---------------------------------------------------------------+-----------------------------------+ SIMD Comparison Encoding ^^^^^^^^^^^^^^^^^^^^^^^^ -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| funct5 | F | | rs2 | rs1 | funct3 | rD | opcode | | -+==========+====+====+=============+==========+=========+==========+============+===================================+ -| 0 0000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpeq.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpeq.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpeq.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpeq.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpeq.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpeq.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpne.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpne.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpne.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpne.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpne.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpne.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgt.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgt.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgt.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgt.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgt.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0010 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgt.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpge.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpge.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpge.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpge.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpge.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0011 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpge.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmplt.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmplt.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmplt.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmplt.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmplt.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0100 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmplt.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmple.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmple.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmple.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmple.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmple.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0101 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmple.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgtu.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgtu.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgtu.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgtu.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgtu.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0110 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgtu.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgeu.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgeu.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgeu.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgeu.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgeu.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 0111 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgeu.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpltu.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpltu.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpltu.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpltu.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpltu.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpltu.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpleu.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpleu.sc.h rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpleu.sci.h rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpleu.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpleu.sc.b rD, rs1, rs2** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ -| 0 1001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpleu.sci.b rD, rs1, Imm6** | -+----------+----+----+-------------+----------+---------+----------+------------+-----------------------------------+ - -SIMD Complex-number Operations +.. table:: SIMD Comparison encoding + :name: SIMD Comparison encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+===================================+ + | 0 0000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpeq.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpeq.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpeq.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpeq.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpeq.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpeq.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpne.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpne.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpne.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpne.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpne.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpne.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgt.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgt.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgt.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgt.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgt.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0010 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgt.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpge.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpge.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpge.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpge.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpge.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0011 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpge.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmplt.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmplt.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmplt.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmplt.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmplt.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0100 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmplt.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmple.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmple.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmple.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmple.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmple.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0101 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmple.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgtu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgtu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgtu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgtu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgtu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0110 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgtu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpgeu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpgeu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpgeu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpgeu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpgeu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 0111 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpgeu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpltu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpltu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpltu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpltu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpltu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1000 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpltu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cmpleu.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cmpleu.sc.h rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.cmpleu.sci.h rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.cmpleu.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.cmpleu.sc.b rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + | 0 1001 | 1 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.cmpleu.sci.b rD, rs1, Imm6** | + +------------+-------+----+---------+---------+------------+----------+------------+-----------------------------------+ + +SIMD Complex-number operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIMD Complex-number operations are extra instructions @@ -1838,87 +2040,97 @@ and one to compute the imaginary part. As for all the other SIMD instructions, no flags are raised and CSR register are unmodified. No carry, overflow is generated. Instructions are rounded up as the mask & 0xFFFF explicits. -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **Mnemonic** | **Description** | -+=======================================+=======================================================================================+ -| **cv.cplxmul.r{/,.div2,.div4,.div8}** | rD[1] = rD[1] | -| | | -| | rD[0] = (rs1[0]\*rs2[0] - rs1[1]\*rs2[1]) >> {15,16,17,18} | -| | | -| | Note: Arithmetic shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.cplxmul.i{/,.div2,.div4,.div8}** | rD[1] = (rs1[0]\*rs2[1] + rs1[1]\*rs2[0]) >> {15,16,17,18} | -| | | -| | rD[0] = rD[0] | -| | | -| | Note: Arithmetic shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.cplxconj** | rD[1] = -rs1[1] | -| | | -| | rD[0] = rs1[0] | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.subrotmj{/,.div2,.div4,.div8}** | rD[1] = ((rs2[0] - rs1[0]) & 0xFFFF) >> {0,1,2,3} | -| | | -| | rD[0] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {0,1,2,3} | -| | | -| | Note: Arithmetic shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.add{.div2,.div4,.div8}** | rD[1] = ((rs1[1] + rs2[1]) & 0xFFFF) >> {1,2,3} | -| | | -| | rD[0] = ((rs1[0] + rs2[0]) & 0xFFFF) >> {1,2,3} | -| | | -| | Note: Arithmetic shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ -| **cv.sub{.div2,.div4,.div8}** | rD[1] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {1,2,3} | -| | | -| | rD[0] = ((rs1[0] - rs2[0]) & 0xFFFF) >> {1,2,3} | -| | | -| | Note: Arithmetic shift right. | -+---------------------------------------+---------------------------------------------------------------------------------------+ +.. table:: SIMD Complex-number operations + :name: SIMD Complex-number operations + :widths: 35 65 + :class: no-scrollbar-table + + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **Mnemonic** | **Description** | + +=======================================+=======================================================================================+ + | **cv.cplxmul.r{/,.div2,.div4,.div8}** | rD[1] = rD[1] | + | | | + | | rD[0] = (rs1[0]\*rs2[0] - rs1[1]\*rs2[1]) >> {15,16,17,18} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.cplxmul.i{/,.div2,.div4,.div8}** | rD[1] = (rs1[0]\*rs2[1] + rs1[1]\*rs2[0]) >> {15,16,17,18} | + | | | + | | rD[0] = rD[0] | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.cplxconj** | rD[1] = -rs1[1] | + | | | + | | rD[0] = rs1[0] | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.subrotmj{/,.div2,.div4,.div8}** | rD[1] = ((rs2[0] - rs1[0]) & 0xFFFF) >> {0,1,2,3} | + | | | + | | rD[0] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {0,1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.add{.div2,.div4,.div8}** | rD[1] = ((rs1[1] + rs2[1]) & 0xFFFF) >> {1,2,3} | + | | | + | | rD[0] = ((rs1[0] + rs2[0]) & 0xFFFF) >> {1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ + | **cv.sub{.div2,.div4,.div8}** | rD[1] = ((rs1[1] - rs2[1]) & 0xFFFF) >> {1,2,3} | + | | | + | | rD[0] = ((rs1[0] - rs2[0]) & 0xFFFF) >> {1,2,3} | + | | | + | | Note: Arithmetic shift right. | + +---------------------------------------+---------------------------------------------------------------------------------------+ SIMD Complex-numbers Encoding ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 :12 | 11 : 7 | 6 : 0 | | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| funct5 | F | | rs2 | rs1 | funct3 | rD | opcode | | -+==========+=====+====+=========+=========+========+==========+==========+====================================+ -| 0 1010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.r rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.r.div2 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.r.div4 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.r.div8 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.i rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 1 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.i.div2 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 1 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.i.div4 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1010 | 1 | 1 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.i.div8 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1011 | 1 | 0 | 00000 | src1 | 000 | dest | 111 1011 | **cv.cplxconj rD, rs1** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.subrotmj rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1100 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.subrotmj.div2 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.subrotmj.div4 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1100 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.subrotmj.div8 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1101 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.add.div2 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.div4 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1101 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.add.div8 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1110 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.sub.div2 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.div4 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ -| 0 1110 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.sub.div8 rD, rs1, rs2** | -+----------+-----+----+---------+---------+--------+----------+----------+------------------------------------+ +.. table:: SIMD ALU encoding + :name: SIMD ALU encoding + :widths: 11 4 4 9 7 8 8 13 36 + :class: no-scrollbar-table + + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+=========+=========+============+==========+============+====================================+ + | 0 1010 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.r rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.r.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.r.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.r.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.cplxmul.i rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 010 | dest | 111 1011 | **cv.cplxmul.i.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 100 | dest | 111 1011 | **cv.cplxmul.i.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1010 | 1 | 1 | src2 | src1 | 110 | dest | 111 1011 | **cv.cplxmul.i.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1011 | 1 | 0 | 00000 | src1 | 000 | dest | 111 1011 | **cv.cplxconj rD, rs1** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.subrotmj rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.subrotmj.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.subrotmj.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1100 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.subrotmj.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.add.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1101 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.add.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 010 | dest | 111 1011 | **cv.sub.div2 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.div4 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ + | 0 1110 | 1 | 0 | src2 | src1 | 110 | dest | 111 1011 | **cv.sub.div8 rD, rs1, rs2** | + +------------+-------+----+---------+---------+------------+----------+------------+------------------------------------+ diff --git a/docs/source/integration.rst b/docs/source/integration.rst index a6dc645ad..253ae77fd 100644 --- a/docs/source/integration.rst +++ b/docs/source/integration.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,26 +20,43 @@ Core Integration ================ -The main module is named ``cv32e40p_core`` and can be found in ``cv32e40p_core.sv``. +The main module is named ``cv32e40p_top`` and can be found in ``cv32e40p_top.sv``. Below, the instantiation template is given and the parameters and interfaces are described. +.. note:: + + ``cv32e40p_top`` instantiates former ``cv32e40p_core`` and a wrapped ``fpnew_top``. + It is highly suggested to use ``cv32e40p_top`` in place of ``cv32e40p_core`` as + it allows to easily enable/disable FPU parameter with no interface change. + As mentioned in :ref:`backward_compatibility`, v2.0.0 ``cv32e40p_core`` has **slight** + modifications that makes it not backward compatible with v1.0.0 one in some cases. + It is worth mentioning that if the core in its v1 version was/is instantiated without parameters setting, + there is still backward compatibility as all parameters default value are set to v1 values. + Instantiation Template ---------------------- .. code-block:: verilog - cv32e40p_core #( + cv32e40p_top #( .FPU ( 0 ), + .FPU_ADDMUL_LAT ( 0 ), + .FPU_OTHERS_LAT ( 0 ), .ZFINX ( 0 ), - .NUM_MHPMCOUNTERS ( 1 ), - .PULP_CLUSTER ( 0 ), - .PULP_XPULP ( 0 ) + .COREV_PULP ( 0 ), + .COREV_CLUSTER ( 0 ), + .NUM_MHPMCOUNTERS ( 1 ) ) u_core ( // Clock and reset - .clk_i (), .rst_ni (), + .clk_i (), .scan_cg_en_i (), + // Special control signals + .fetch_enable_i (), + .pulp_clock_en_i (), + .core_sleep_o (), + // Configuration .boot_addr_i (), .mtvec_addr_i (), @@ -48,32 +65,22 @@ Instantiation Template .hart_id_i (), // Instruction memory interface + .instr_addr_o (), .instr_req_o (), .instr_gnt_i (), .instr_rvalid_i (), - .instr_addr_o (), .instr_rdata_i (), // Data memory interface + .data_addr_o (), .data_req_o (), .data_gnt_i (), - .data_rvalid_i (), - .data_addr_o (), + .data_we_o (), .data_be_o (), .data_wdata_o (), - .data_we_o (), + .data_rvalid_i (), .data_rdata_i (), - // Auxiliary Processing Unit (APU) interface - .apu_req_o (), - .apu_gnt_i (), - .apu_operands_o (), - .apu_op_o (), - .apu_flags_o (), - .apu_rvalid_i (), - .apu_result_i (), - .apu_flags_i (), - // Interrupt interface .irq_i (), .irq_ack_o (), @@ -83,117 +90,116 @@ Instantiation Template .debug_req_i (), .debug_havereset_o (), .debug_running_o (), - .debug_halted_o (), - - // Special control signals - .fetch_enable_i (), - .core_sleep_o (), - .pulp_clock_en_i () + .debug_halted_o () ); Parameters ---------- -.. note:: - The non-default (i.e. non-zero) settings of ``FPU``, ``ZFINX``, ``PULP_CLUSTER`` and ``PULP_XPULP`` have not - been verified yet. The default parameter value for ``PULP_XPULP`` will be changed to 1 once it has been verified. - The default configuration reflected below is currently under verification and this verification effort will be - completed first. - -.. note:: - The instruction encodings for the PULP instructions is expected to change in a non-backward-compatible manner, - see https://github.com/openhwgroup/cv32e40p/issues/452. - -+------------------------------+-------------+------------+------------------------------------------------------------------+ -| Name | Type/Range | Default | Description | -+==============================+=============+============+==================================================================+ -| ``FPU`` | bit | 0 | Enable Floating Point Unit (FPU) support, see :ref:`fpu` | -+------------------------------+-------------+------------+------------------------------------------------------------------+ -| ``ZFINX`` | bit | 0 | Enable Floating Point instructions to use the General Purpose | -| | | | register file instead of requiring a dedicated Floating Point | -| | | | register file, see :ref:`fpu`. Only allowed to be set to 1 | -| | | | if ``FPU`` = 1 | -+------------------------------+-------------+------------+------------------------------------------------------------------+ -| ``NUM_MHPMCOUNTERS`` | int (0..29) | 1 | Number of MHPMCOUNTER performance counters, see | -| | | | :ref:`performance-counters` | -+------------------------------+-------------+------------+------------------------------------------------------------------+ -| ``PULP_CLUSTER`` | bit | 0 | Enable PULP Cluster support, see :ref:`pulp_cluster` | -+------------------------------+-------------+------------+------------------------------------------------------------------+ -| ``PULP_XPULP`` | bit | 0 | Enable all of the custom PULP ISA extensions (except **cv.elw**) | -| | | | (see :ref:`custom-isa-extensions`) and all custom CSRs | -| | | | (see :ref:`cs-registers`). | -| | | | | -| | | | Examples of PULP ISA | -| | | | extensions are post-incrementing load and stores | -| | | | (see :ref:`corev_load_store`) and hardware loops | -| | | | (see :ref:`corev_hardware_loop`). | -| | | | | -+------------------------------+-------------+------------+------------------------------------------------------------------+ +.. table:: Parameters + :name: Parameters + :widths: 25 15 11 49 + :class: no-scrollbar-table + + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | **Name** | **Type/Range** | **Default** | **Description** | + +==============================+================+=============+==================================================================+ + | ``FPU`` | bit | 0 | Enable Floating Point Unit (FPU) support, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``FPU_ADDMUL_LAT`` | int | 0 | Number of pipeline registers for Floating-Point | + | | | | addition and multiplication instructions, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``FPU_OTHERS_LAT`` | int | 0 | Number of pipeline registers for Floating-Point | + | | | | comparison, conversion and classify instructions, see :ref:`fpu` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``ZFINX`` | bit | 0 | Enable Floating Point instructions to use the General Purpose | + | | | | register file instead of requiring a dedicated Floating Point | + | | | | register file, see :ref:`fpu`. Only allowed to be set to 1 | + | | | | if ``FPU`` = 1 | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``COREV_PULP`` | bit | 0 | Enable all of the custom PULP ISA extensions (except **cv.elw**) | + | | | | (see :ref:`custom-isa-extensions`) and all custom CSRs | + | | | | (see :ref:`cs-registers`). | + | | | | | + | | | | Examples of PULP ISA | + | | | | extensions are post-incrementing load and stores | + | | | | (see :ref:`corev_load_store`) and hardware loops | + | | | | (see :ref:`corev_hardware_loop`). | + | | | | | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``COREV_CLUSTER`` | bit | 0 | Enable PULP Cluster support (**cv.elw**), see :ref:`pulp_cluster`| + +------------------------------+----------------+-------------+------------------------------------------------------------------+ + | ``NUM_MHPMCOUNTERS`` | int (0..29) | 1 | Number of MHPMCOUNTER performance counters, see | + | | | | :ref:`performance-counters` | + +------------------------------+----------------+-------------+------------------------------------------------------------------+ Interfaces ---------- -+-------------------------+-------------------------+-----+--------------------------------------------+ -| Signal(s) | Width | Dir | Description | -+=========================+=========================+=====+============================================+ -| ``clk_i`` | 1 | in | Clock signal | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``rst_ni`` | 1 | in | Active-low asynchronous reset | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``scan_cg_en_i`` | 1 | in | Scan clock gate enable. Design for test | -| | | | (DfT) related signal. Can be used during | -| | | | scan testing operation to force | -| | | | instantiated clock gate(s) to be enabled. | -| | | | This signal should be 0 during normal / | -| | | | functional operation. | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``boot_addr_i`` | 32 | in | Boot address. First program counter after | -| | | | reset = ``boot_addr_i``. Must be half-word | -| | | | aligned. Do not change after enabling core | -| | | | via ``fetch_enable_i`` | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``mtvec_addr_i`` | 32 | in | ``mtvec`` address. Initial value for the | -| | | | address part of :ref:`csr-mtvec`. | -| | | | Do not change after enabling core | -| | | | via ``fetch_enable_i`` | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``dm_halt_addr_i`` | 32 | in | Address to jump to when entering Debug | -| | | | Mode, see :ref:`debug-support`. Must be | -| | | | word-aligned. Do not change after enabling | -| | | | core via ``fetch_enable_i`` | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``dm_exception_addr_i`` | 32 | in | Address to jump to when an exception | -| | | | occurs when executing code during Debug | -| | | | Mode, see :ref:`debug-support`. Must be | -| | | | word-aligned. Do not change after enabling | -| | | | core via ``fetch_enable_i`` | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``hart_id_i`` | 32 | in | Hart ID, usually static, can be read from | -| | | | :ref:`csr-mhartid` and :ref:`csr-uhartid` | -| | | | CSRs | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` | -+-------------------------+----------------------------------------------------------------------------+ -| ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` | -+-------------------------+----------------------------------------------------------------------------+ -| ``apu_*`` | Auxiliary Processing Unit (APU) interface, see :ref:`apu` | -+-------------------------+----------------------------------------------------------------------------+ -| ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` | -+-------------------------+----------------------------------------------------------------------------+ -| ``debug_*`` | Debug interface, see :ref:`debug-support` | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``fetch_enable_i`` | 1 | in | Enable the instruction fetch of CV32E40P. | -| | | | The first instruction fetch after reset | -| | | | de-assertion will not happen as long as | -| | | | this signal is 0. ``fetch_enable_i`` needs | -| | | | to be set to 1 for at least one cycle | -| | | | while not in reset to enable fetching. | -| | | | Once fetching has been enabled the value | -| | | | ``fetch_enable_i`` is ignored. | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``core_sleep_o`` | 1 | out | Core is sleeping, see :ref:`sleep_unit`. | -+-------------------------+-------------------------+-----+--------------------------------------------+ -| ``pulp_clock_en_i`` | 1 | in | PULP clock enable (only used when | -| | | | ``PULP_CLUSTER`` = 1, tie to 0 otherwise), | -| | | | see :ref:`sleep_unit` | -+-------------------------+-------------------------+-----+--------------------------------------------+ +.. table:: Interfaces + :name: Interfaces + :widths: 25 10 7 58 + :class: no-scrollbar-table + + +-------------------------+-------------------------+---------+--------------------------------------------+ + | **Signal** | **Width** | **Dir** | **Description** | + +=========================+=========================+=========+============================================+ + | ``rst_ni`` | 1 | in | Active-low asynchronous reset | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``clk_i`` | 1 | in | Clock signal | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``scan_cg_en_i`` | 1 | in | Scan clock gate enable. Design for test | + | | | | (DfT) related signal. Can be used during | + | | | | scan testing operation to force | + | | | | instantiated clock gate(s) to be enabled. | + | | | | This signal should be 0 during normal / | + | | | | functional operation. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``fetch_enable_i`` | 1 | in | Enable the instruction fetch of CV32E40P. | + | | | | The first instruction fetch after reset | + | | | | de-assertion will not happen as long as | + | | | | this signal is 0. ``fetch_enable_i`` needs | + | | | | to be set to 1 for at least one cycle | + | | | | while not in reset to enable fetching. | + | | | | Once fetching has been enabled the value | + | | | | ``fetch_enable_i`` is ignored. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``core_sleep_o`` | 1 | out | Core is sleeping, see :ref:`sleep_unit`. | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``pulp_clock_en_i`` | 1 | in | PULP clock enable (only used when | + | | | | ``COREV_CLUSTER`` = 1, tie to 0 otherwise),| + | | | | see :ref:`sleep_unit` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``boot_addr_i`` | 32 | in | Boot address. First program counter after | + | | | | reset = ``boot_addr_i``. Must be half-word | + | | | | aligned. Do not change after enabling core | + | | | | via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``mtvec_addr_i`` | 32 | in | ``mtvec`` address. Initial value for the | + | | | | address part of :ref:`csr-mtvec`. | + | | | | Do not change after enabling core | + | | | | via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``dm_halt_addr_i`` | 32 | in | Address to jump to when entering Debug | + | | | | Mode, see :ref:`debug-support`. Must be | + | | | | word-aligned. Do not change after enabling | + | | | | core via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``dm_exception_addr_i`` | 32 | in | Address to jump to when an exception | + | | | | occurs when executing code during Debug | + | | | | Mode, see :ref:`debug-support`. Must be | + | | | | word-aligned. Do not change after enabling | + | | | | core via ``fetch_enable_i`` | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``hart_id_i`` | 32 | in | Hart ID, usually static, can be read from | + | | | | :ref:`csr-mhartid` and :ref:`csr-uhartid` | + | | | | CSRs | + +-------------------------+-------------------------+---------+--------------------------------------------+ + | ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` | + +-------------------------+--------------------------------------------------------------------------------+ + | ``debug_*`` | Debug interface, see :ref:`debug-support` | + +-------------------------+-------------------------+---------+--------------------------------------------+ diff --git a/docs/source/intro.rst b/docs/source/intro.rst index 4b1d24fc9..372dfdef5 100644 --- a/docs/source/intro.rst +++ b/docs/source/intro.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,9 +21,9 @@ Introduction CV32E40P is a 4-stage in-order 32-bit RISC-V processor core. The ISA of CV32E40P has been extended to support multiple additional instructions including -hardware loops, post-increment load and store instructions and -additional ALU instructions that are not part of the standard RISC-V -ISA. :numref:`blockdiagram` shows a block diagram of the core. +hardware loops, post-increment load and store instructions, +additional ALU instructions and SIMD instructions that are not part of the standard RISC-V +ISA. :numref:`blockdiagram` shows a block diagram of the top level with the core and the FPU. .. figure:: ../images/CV32E40P_Block_Diagram.png :name: blockdiagram @@ -34,7 +34,7 @@ ISA. :numref:`blockdiagram` shows a block diagram of the core. License ------- -Copyright 2020 OpenHW Group. +Copyright 2023 OpenHW Group. Copyright 2018 ETH Zurich and University of Bologna. @@ -55,8 +55,6 @@ The Instruction Fetch and Load/Store data bus interfaces are compliant to the ** See `OBI-v1.2.pdf `_ for details about the protocol. Additional information can be found in the :ref:`instruction-fetch` and :ref:`load-store-unit` chapters of this document. -The Auxiliary Processing Unit bus interface is derived from to the OBI (Open Bus Interface) protocol, see the :ref:`apu` chapter of this document. - Standards Compliance -------------------- @@ -69,7 +67,7 @@ It follows these specifications: Many features in the RISC-V specification are optional, and CV32E40P can be parameterized to enable or disable some of them. -CV32E40P supports the following base instruction set. +CV32E40P supports the following base integer instruction set. * The RV32I Base Integer Instruction Set, version 2.1 @@ -77,10 +75,12 @@ In addition, the following standard instruction set extensions are available. .. list-table:: CV32E40P Standard Instruction Set Extensions :header-rows: 1 + :widths: 55 12 33 + :class: no-scrollbar-table - * - Standard Extension - - Version - - Configurability + * - **Standard Extension** + - **Version** + - **Configurability** * - **C**: Standard Extension for Compressed Instructions - 2.0 @@ -114,18 +114,20 @@ The following custom instruction set extensions are available. .. list-table:: CV32E40P Custom Instruction Set Extensions :header-rows: 1 + :widths: 40 12 48 + :class: no-scrollbar-table - * - Custom Extension - - Version - - Configurability + * - **Custom Extension** + - **Version** + - **Configurability** - * - **Xcorev**: CORE-V ISA Extensions (excluding **cv.elw**) + * - **Xcv**: CORE-V PULP ISA Extensions - 1.0 - - optionally enabled with the ``PULP_XPULP`` parameter + - optionally enabled with the ``COREV_PULP`` parameter - * - **Xpulpcluster**: PULP Cluster Extension + * - **Xcvelw**: CORE-V PULP Cluster ISA Extension - 1.0 - - optionally enabled with the ``PULP_CLUSTER`` parameter + - optionally enabled with the ``COREV_CLUSTER`` parameter Most content of the RISC-V privileged specification is optional. CV32E40P currently supports the following features according to the RISC-V Privileged Specification, version 1.11. @@ -136,18 +138,22 @@ CV32E40P currently supports the following features according to the RISC-V Privi * Trap handling supporting direct mode or vectored mode as described at :ref:`exceptions-interrupts` +.. _synthesis_guidelines: + Synthesis guidelines -------------------- The CV32E40P core is fully synthesizable. -It has been designed mainly for ASIC designs, but FPGA synthesis -is supported as well. +It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well. + +The top level module is called cv32e40p_top and includes both the core and the FPU. +All the core files are in ``rtl`` and ``rtl/include`` folders (all synthesizable) +while all the FPU files are in ``rtl/vendor/pulp_platform_common_cells``, ``rtl/vendor/pulp_platform_fpnew`` and ``rtl/vendor/pulp_platform_fpu_div_sqrt``. +.. while all the FPU files are in ``rtl/vendor/pulp_platform_common_cells``, ``rtl/vendor/pulp_platform_fpnew`` and ``rtl/vendor/opene906``. +cv32e40p_fpu_manifest.flist is listing all the required files. -All the files in the ``rtl`` and ``rtl/include`` folders are synthesizable. -The user should first decide whether to use the flip-flop or latch-based register-file ( see :ref:`register-file`). -However, the use of the flip-flop-based register-file is the one suggested and used by default as it has been verified. -Secondly, the user must provide a clock-gating module that instantiates the clock-gating cells of the target technology. This file must have the same interface and module name of the one provided for simulation-only purposes -at ``bhv/cv32e40p_sim_clock_gate.sv`` (see :ref:`clock-gating-cell`). +The user must provide a clock-gating module that instantiates the functionally equivalent clock-gating cell of the target technology. +This file must have the same interface and module name as the one provided for simulation-only purposes at ``bhv/cv32e40p_sim_clock_gate.sv`` (see :ref:`clock-gating-cell`). The ``constraints/cv32e40p_core.sdc`` file provides an example of synthesis constraints. @@ -156,103 +162,43 @@ ASIC Synthesis ^^^^^^^^^^^^^^ ASIC synthesis is supported for CV32E40P. The whole design is completely -synchronous and uses positive-edge triggered flip-flops, except for the -register file, which can be implemented either with latches or with -flip-flops. See :ref:`register-file` for more details. The -core occupies an area of about 50 kGE when the latch based register file -is used. With the FPU, the area increases to about 90 kGE (30 kGE -FPU, 10 kGE additional register file). A technology specific implementation +synchronous and uses positive-edge triggered flip-flops. The +core occupies an area of about XX kGE. +With the FPU, the area increases to about XX kGE (XX kGE +FPU, XX kGE additional register file). A technology specific implementation of a clock gating cell as described in :ref:`clock-gating-cell` needs to be provided. FPGA Synthesis ^^^^^^^^^^^^^^^ -FPGA synthesis is only supported for CV32E40P when the flip-flop based register -file is used as latches are not well supported on FPGAs. +FPGA synthesis is only supported for CV32E40P. The user needs to provide a technology specific implementation of a clock gating cell as described in :ref:`clock-gating-cell`. -Verification ------------- +.. _synthesis_with_fpu: + +Synthesizing with the FPU +^^^^^^^^^^^^^^^^^^^^^^^^^ -The verification environment (testbenches, testcases, etc.) for the CV32E40P -core can be found at `core-v-verif `_. -It is recommended that you start by reviewing the -`CORE-V Verification Strategy `_. - -In early 2021 the CV32E40P achieved Functional RTL Freeze, meaning that is has -been fully verified as per its -`Verification Plan `_. -Final functional, code and test coverage reports can be found `here `_. - -The unofficial start date for the CV32E40P verification effort is 2020-02-27, -which is the date the core-v-verif environment "went live". Between then and -RTL Freeze, a total of 47 RTL issues and 38 User Manual issues were identified -and resolved [1]_. A breakdown of the RTL issues is as follows: - -.. table:: How RTL Issues Were Found - :name: How RTL Issues Were Found - - +---------------------+-------+----------------------------------------------------+ - | "Found By" | Count | Note | - +=====================+=======+====================================================+ - | Simulation | 18 | See classification below | - +---------------------+-------+----------------------------------------------------+ - | Inspection | 13 | Human review of the RTL | - +---------------------+-------+----------------------------------------------------+ - | Formal Verification | 13 | This includes both Designer and Verifier use of FV | - +---------------------+-------+----------------------------------------------------+ - | Lint | 2 | | - +---------------------+-------+----------------------------------------------------+ - | Unknown | 1 | | - +---------------------+-------+----------------------------------------------------+ - -A classification of the simulation issues by method used to identify them is informative: - -.. table:: Breakdown of Issues found by Simulation - :name: Breakdown of Issues found by Simulation - - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Simulation Method | Count | Note | - +==============================+=======+========================================================================================+ - | Directed, self-checking test | 10 | Many test supplied by Design team and a couple from the Open Source Community at large | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Step & Compare | 6 | Issues directly attributed to S&C against ISS | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Constrained-Random | 2 | Test generated by corev-dv (extension of riscv-dv) | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - -A classification of the issues themselves: - -.. table:: Issue Classification - :name: Issue Classification - - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Issue Type | Count | Note | - +==============================+=======+========================================================================================+ - | RTL Functional | 40 | A bug! | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | RTL coding style | 4 | Linter issues, removing TODOs, removing \`ifdefs, etc. | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Non-RTL functional | 1 | Issue related to behavioral tracer (not part of the core) | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Unreproducible | 1 | | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - | Invalid | 1 | | - +------------------------------+-------+----------------------------------------------------------------------------------------+ - -Additional details are available as part of the `CV32E40P v1.0.0 Report `_. +By default the pipeline of the FPU is purely combinatorial (FPU_*_LAT = 0). In this case FPU instructions latency is the same than simple ALU operations (except FP multicycle DIV/SQRT ones). +But as FPU operations are much more complex than ALU ones, maximum achievable frequency is much lower than ALU one when FPU is enabled. +If this can be fine for low frequency systems, it is possible to indicate how many pipeline registers are instantiated in the FPU to reach higher target frequency. +This is done with FPU_*_LAT CV32E40P parameters setting to perfectly fit target frequency. +It should be noted that any additional pipeline register is impacting FPU instructions latency and could cause performances degradation depending of applications using Floating-Point operations. +Those pipeline registers are all added at the end of the FPU pipeline with all operators before them. Optimal frequency is only achievable using automatic retiming commands in implementation tools. +This can be achieved with the following command for Synopsys Design Compiler: +“set_optimize_registers true -designs [get_object_name [get_designs "*fpnew_wrapper*"]]”. Contents -------- * :ref:`getting-started` discusses the requirements and initial steps to start using CV32E40P. * :ref:`core-integration` provides the instantiation template and gives descriptions of the design parameters as well as the input and output ports. + * :ref:`verification` gives a brief overview of the verification methodology. * :ref:`pipeline-details` described the overal pipeline structure. * The instruction and data interfaces of CV32E40P are explained in :ref:`instruction-fetch` and :ref:`load-store-unit`, respectively. * The two register-file flavors are described in :ref:`register-file`. - * :ref:`apu` describes the Auxiliary Processing Unit (APU). * :ref:`fpu` describes the Floating Point Unit (FPU). * :ref:`sleep_unit` describes the Sleep unit including the PULP Cluster extension. * :ref:`hwloop-specs` describes the PULP Hardware Loop extension. @@ -260,14 +206,15 @@ Contents * :ref:`performance-counters` gives an overview of the performance monitors and event counters available in CV32E40P. * :ref:`exceptions-interrupts` deals with the infrastructure for handling exceptions and interrupts. * :ref:`debug-support` gives a brief overview on the debug infrastructure. - * :ref:`tracer` gives a brief overview of the tracer module. * :ref:`custom-isa-extensions` describes the custom instruction set extensions. + * :ref:`core_versions` describes the core versioning. * :ref:`glossary` provides definitions of used terminology. History ------- -CV32E40P started its life as a fork of the OR10N CPU core based on the OpenRISC ISA. Then, under the name of RI5CY, it became a RISC-V core (2016), and it has been maintained by the PULP platform team until February 2020, when it has been contributed to OpenHW Group https://www.openhwgroup.org. +CV32E40P started its life as a fork of the OR10N CPU core based on the OpenRISC ISA. Then, under the name of RI5CY, it became a RISC-V core (2016), +and it has been maintained by the PULP platform team until February 2020, when it has been contributed to OpenHW Group https://www.openhwgroup.org. As RI5CY has been used in several projects, a list of all the changes made by OpenHW Group since February 2020 follows: @@ -280,8 +227,9 @@ Such memory interface is slightly different from the one used by RI5CY as: the g RV32F Extensions ^^^^^^^^^^^^^^^^ -The FPU is not instantiated in the core EX stage anymore, and it must be attached to the APU interface. -Previously, RI5CY could select with a parameter whether the FPU was instantiated inside the EX stage or via the APU interface. +Previously, RI5CY could select with a parameter whether the FPU was instantiated inside the EX stage or via the APU interface. Now in CV32E40P, the FPU is not instantiated in the core EX stage anymore. +A new file called cv32e40p_top.sv is instantiating the core together with the FPU and APU interface is not visible on I/Os. +This is this new top level which has been used for Verification and Implementation. RV32A Extensions, Security and Memory Protection ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -292,15 +240,14 @@ Most of the previous RTL descriptions of these features have been kept but not m CSR Address Re-Mapping ^^^^^^^^^^^^^^^^^^^^^^ -CV32E40P is fully compliant with RISC-V. -RI5CY used to have custom performance counters 32b wide (not compliant with RISC-V) in the CSR address space -{0x7A0, 0x7A1, 0x780-0x79F}. CV32E40P is fully compliant with the RISC-V spec. -The custom PULP HWLoop CSRs moved from the 0x7C* to RISC-V user custom read-only 0xCC0-0xCFF address space. +RI5CY used to have custom performance counters 32b wide (not compliant with RISC-V) in the CSR address space {0x7A0, 0x7A1, 0x780-0x79F}. +CV32E40P is now fully compliant with the RISC-V spec on performance counters side. +And the custom PULP HWLoop CSRs have been moved from the 0x7C* to RISC-V user custom read-only 0xCC0-0xCFF address space. Interrupts ^^^^^^^^^^ -RI5CY used to have a req plus a 5bits ID interrupt interface, supporting up to 32 interrupt requests (only one active at a time), with the priority defined outside in an interrupt controller. CV32E40P is now compliant with the CLINT RISC-V spec, extended with 16 custom interrupts lines called fast, for a total of 19 interrupt lines. They can be all active simultaneously, and priority and per-request interrupt enable bit is controlled by the core CLINT definition. +RI5CY used to have a req plus a 5 bits ID interrupt interface, supporting up to 32 interrupt requests (only one active at a time), with the priority defined outside in an interrupt controller. CV32E40P is now compliant with the CLINT RISC-V spec, extended with 16 custom interrupts lines called fast, for a total of 19 interrupt lines. They can be all active simultaneously, and priority and per-request interrupt enable bit is controlled by the core CLINT definition. PULP HWLoop Spec ^^^^^^^^^^^^^^^^ @@ -326,14 +273,14 @@ References Contributors ------------ -| Andreas Traber (`*atraber@iis.ee.ethz.ch* `__) -| Michael Gautschi (`*gautschi@iis.ee.ethz.ch* `__) -| Pasquale Davide Schiavone (`*pschiavo@iis.ee.ethz.ch* `__) +| Andreas Traber (`atraber@iis.ee.ethz.ch `__) +| Michael Gautschi (`gautschi@iis.ee.ethz.ch `__) +| Pasquale Davide Schiavone (`pschiavo@iis.ee.ethz.ch `__) -| Arjan Bink (`*arjan.bink@silabs.com* `__) -| Paul Zavalney (`*paul.zavalney@silabs.com* `__) +| Arjan Bink (`arjan.bink@silabs.com `__) +| Paul Zavalney (`paul.zavalney@silabs.com `__) -| Pascal Gouédo (`*pascal.gouedo@dolphin.fr* `__) +| Pascal Gouédo (`pascal.gouedo@dolphin.fr `__) | Micrel Lab and Multitherman Lab | University of Bologna, Italy @@ -341,8 +288,3 @@ Contributors | Integrated Systems Lab | ETH Zürich, Switzerland - -.. [1] - It is a testament on the quality of the work done by the PULP platform team - that it took a team of professonal verification engineers more than 9 months - to find all these issues. diff --git a/docs/source/load_store_unit.rst b/docs/source/load_store_unit.rst index a5dd8de13..ebaf837cc 100644 --- a/docs/source/load_store_unit.rst +++ b/docs/source/load_store_unit.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,19 +22,24 @@ Load-Store-Unit (LSU) The Load-Store Unit (LSU) of the core takes care of accessing the data memory. Load and stores on words (32 bit), half words (16 bit) and bytes (8 bit) are -supported. +supported. The CV32E40P data interface can cause up to 2 outstanding +transactions and there is no FIFO to allow more outstanding requests. :numref:`LSU interface signals` describes the signals that are used by the LSU. .. table:: LSU interface signals :name: LSU interface signals + :widths: 25 15 60 + :class: no-scrollbar-table +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ | **Signal** | **Direction** | **Description** | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ + | ``data_addr_o[31:0]`` | output | Address | + +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ | ``data_req_o`` | output | Request valid, will stay high until ``data_gnt_i`` is high for one cycle | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``data_addr_o[31:0]`` | output | Address | + | ``data_gnt_i`` | input | The other side accepted the request. ``data_addr_o`` may change in the next cycle. | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ | ``data_we_o`` | output | Write Enable, high for writes, low for reads. Sent together with ``data_req_o`` | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ @@ -42,12 +47,10 @@ supported. +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ | ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together with ``data_req_o`` | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``data_rdata_i[31:0]`` | input | Data read from memory | - +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ | ``data_rvalid_i`` | input | ``data_rvalid_i`` will be high for exactly one cycle to signal the end of the response phase of for both read and write | | | | transactions. For a read transaction ``data_rdata_i`` holds valid data when ``data_rvalid_i`` is high. | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ - | ``data_gnt_i`` | input | The other side accepted the request. ``data_addr_o`` may change in the next cycle. | + | ``data_rdata_i[31:0]`` | input | Data read from memory | +------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------+ Misaligned Accesses @@ -66,11 +69,15 @@ In both cases the transfer corresponding to the lowest address is performed firs Protocol -------- -The CV32E40P data interface does not implement -the following optional OBI signals: auser, wuser, aid, rready, err, ruser, rid. -These signals can be thought of as being tied off as specified in the OBI -specification. The CV32E40P data interface can cause up to two outstanding -transactions. +The CV32E40P data interface does not implement the following optional OBI signals: auser, wuser, aid, rready, err, ruser, rid. +These signals can be thought of as being tied off as specified in the OBI specification. + +.. note:: + + **Transactions Ordering** + As mentioned above, data interface can generate up to 2 outstanding transactions. + OBI specification states that links are always in-order from master point of view. So as the data interface does not generate transaction id (aid), + interconnect infrastructure should ensure that transaction responses come back in the same order they were sent by adding its own additional information. The OBI protocol that is used by the LSU to communicate with a memory works as follows. @@ -125,7 +132,7 @@ one ``data_rvalid_i`` will be signalled for each of them, in the order they were Post-Incrementing Load and Store Instructions --------------------------------------------- -This section is only valid if ``PULP_XPULP=1`` +This section is only valid if ``COREV_PULP = 1`` Post-incrementing load and store instructions perform a load/store operation from/to the data memory while at the same time increasing the diff --git a/docs/source/perf_counters.rst b/docs/source/perf_counters.rst index 9cf4d71cc..bbed0c545 100644 --- a/docs/source/perf_counters.rst +++ b/docs/source/perf_counters.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,7 +23,8 @@ Performance Counters CV32E40P implements performance counters according to the RISC-V Privileged Specification, version 1.11 (see Hardware Performance Monitor, Section 3.1.11). The performance counters are placed inside the Control and Status Registers (CSRs) and can be accessed with the ``CSRRW(I)`` and ``CSRRS/C(I)`` instructions. -CV32E40P implements the clock cycle counter ``mcycle(h)``, the retired instruction counter ``minstret(h)``, as well as the parameterizable number of event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)`` and the corresponding event selector CSRs ``mhpmevent3`` - ``mhpmevent31``, and the ``mcountinhibit`` CSR to individually enable/disable the counters. +CV32E40P implements the clock cycle counter ``mcycle(h)``, the retired instruction counter ``minstret(h)``, as well as the parameterizable number of event counters +``mhpmcounter3(h)`` - ``mhpmcounter31(h)`` and the corresponding event selector CSRs ``mhpmevent3`` - ``mhpmevent31``, and the ``mcountinhibit`` CSR to individually enable/disable the counters. ``mcycle(h)`` and ``minstret(h)`` are always available. All counters are 64 bit wide. @@ -45,43 +46,47 @@ Event Selector The following events can be monitored using the performance counters of CV32E40P. - -+-------------+-----------------+-------------------------------------------+ -| Bit # | Event Name | | -+=============+=================+===========================================+ -| 0 | CYCLES | Number of cycles | -+-------------+-----------------+-------------------------------------------+ -| 1 | INSTR | Number of instructions retired | -+-------------+-----------------+-------------------------------------------+ -| 2 | LD_STALL | Number of load use hazards | -+-------------+-----------------+-------------------------------------------+ -| 3 | JMP_STALL | Number of jump register hazards | -+-------------+-----------------+-------------------------------------------+ -| 4 | IMISS | Cycles waiting for instruction fethces, | -| | | excluding jumps and branches | -+-------------+-----------------+-------------------------------------------+ -| 5 | LD | Number of load instructions | -+-------------+-----------------+-------------------------------------------+ -| 6 | ST | Number of store instructions | -+-------------+-----------------+-------------------------------------------+ -| 7 | JUMP | Number of jumps (unconditional) | -+-------------+-----------------+-------------------------------------------+ -| 8 | BRANCH | Number of branches (conditional) | -+-------------+-----------------+-------------------------------------------+ -| 9 | BRANCH_TAKEN | Number of branches taken (conditional) | -+-------------+-----------------+-------------------------------------------+ -| 10 | COMP_INSTR | Number of compressed instructions retired | -+-------------+-----------------+-------------------------------------------+ -| 11 | PIPE_STALL | Cycles from stalled pipeline | -+-------------+-----------------+-------------------------------------------+ -| 12 | APU_TYPE | Numbe of type conflicts on APU/FP | -+-------------+-----------------+-------------------------------------------+ -| 13 | APU_CONT | Number of contentions on APU/FP | -+-------------+-----------------+-------------------------------------------+ -| 14 | APU_DEP | Number of dependency stall on APU/FP | -+-------------+-----------------+-------------------------------------------+ -| 15 | APU_WB | Number of write backs on APUB/FP | -+-------------+-----------------+-------------------------------------------+ +.. table:: Event Selector + :name: Event Selector + :widths: 10 20 65 + :class: no-scrollbar-table + + +-------------+-----------------+-------------------------------------------+ + | **Bit #** | **Event Name** | **Description** | + +=============+=================+===========================================+ + | 0 | CYCLES | Number of cycles | + +-------------+-----------------+-------------------------------------------+ + | 1 | INSTR | Number of instructions retired | + +-------------+-----------------+-------------------------------------------+ + | 2 | LD_STALL | Number of load use hazards | + +-------------+-----------------+-------------------------------------------+ + | 3 | JMP_STALL | Number of jump register hazards | + +-------------+-----------------+-------------------------------------------+ + | 4 | IMISS | Cycles waiting for instruction fethces, | + | | | excluding jumps and branches | + +-------------+-----------------+-------------------------------------------+ + | 5 | LD | Number of load instructions | + +-------------+-----------------+-------------------------------------------+ + | 6 | ST | Number of store instructions | + +-------------+-----------------+-------------------------------------------+ + | 7 | JUMP | Number of jumps (unconditional) | + +-------------+-----------------+-------------------------------------------+ + | 8 | BRANCH | Number of branches (conditional) | + +-------------+-----------------+-------------------------------------------+ + | 9 | BRANCH_TAKEN | Number of branches taken (conditional) | + +-------------+-----------------+-------------------------------------------+ + | 10 | COMP_INSTR | Number of compressed instructions retired | + +-------------+-----------------+-------------------------------------------+ + | 11 | PIPE_STALL | Cycles from stalled pipeline | + +-------------+-----------------+-------------------------------------------+ + | 12 | APU_TYPE | Numbe of type conflicts on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 13 | APU_CONT | Number of contentions on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 14 | APU_DEP | Number of dependency stall on APU/FP | + +-------------+-----------------+-------------------------------------------+ + | 15 | APU_WB | Number of write backs on APUB/FP | + +-------------+-----------------+-------------------------------------------+ The event selector CSRs ``mhpmevent3`` - ``mhpmevent31`` define which of these events are counted by the event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)``. If a specific bit in an event selector CSR is set to 1, this means that events with this ID are being counted by the counter associated with that selector CSR. @@ -97,7 +102,8 @@ Controlling the counters from software By default, all available counters are disabled after reset in order to provide the lowest power consumption. -They can be individually enabled/disabled by overwriting the corresponding bit in the ``mcountinhibit`` CSR at address ``0x320`` as described in the RISC-V Privileged Specification, version 1.11 (see Machine Counter-Inhibit CSR, Section 3.1.13). +They can be individually enabled/disabled by overwriting the corresponding bit in the ``mcountinhibit`` CSR at address ``0x320`` as described in the RISC-V Privileged Specification, +version 1.11 (see Machine Counter-Inhibit CSR, Section 3.1.13). In particular, to enable/disable ``mcycle(h)``, bit 0 must be written. For ``minstret(h)``, it is bit 2. For event counter ``mhpmcounterX(h)``, it is bit X. The lower 32 bits of all counters can be accessed through the base register, whereas the upper 32 bits are accessed through the ``h``-register. diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 173672f21..8ee1231cc 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -29,85 +29,118 @@ Pipeline Details CV32E40P has a 4-stage in-order completion pipeline, the 4 stages are: Instruction Fetch (IF) - Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. The IF stage also pre-decodes RVC instructions into RV32I base instructions. See :ref:`instruction-fetch` for details. + Fetches instructions from memory via an aligning prefetch buffer, capable of fetching 1 instruction per cycle if the instruction side memory system allows. This prefetech buffer is able to store 2 32-b data. The IF stage also pre-decodes RVC instructions into RV32I base instructions. See :ref:`instruction-fetch` for details. Instruction Decode (ID) Decodes fetched instruction and performs required register file reads. Jumps are taken from the ID stage. Execute (EX) Executes the instructions. The EX stage contains the ALU, Multiplier and Divider. Branches (with their condition met) are taken from the EX stage. Multi-cycle instructions will stall this stage until they are complete. The ALU, Multiplier and Divider instructions write back their result to the register file from the EX stage. The address generation part of the load-store-unit (LSU) is contained in EX as well. + + The FPU writes back its result from EX stage as well when FPU_*_LAT is either 0 cycle or more than 1 cycle. It is reusing register file ALU/Mult/Div write port and it has the highest priority so it will stall EX stage if there is a conflict (when FPU_*_LAT > 1). Writeback (WB) Writes the result of Load instructions back to the register file. + + The FPU writes back its result from WB stage as well when FPU_*_LAT is 1 cycle. It is reusing register file LSU write port but LSU has the highest priority over FPU if there is a conflict. -Multi- and Single-Cycle Instructions ------------------------------------- +Hazards +------- -:numref:`Cycle counts per instruction type` shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means -that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. The cycle counts assume zero stall on the instruction-side interface -and zero stall on the data-side memory interface. +There is a forwarding path betwen ALU, Multiplier and Divider result in EX stage and ID stage flip-flops to avoid the need of a write-through register file. +This allows to have 0-cycle penalty between those instructions and immediately following one when using result. +This is the same with 0-cycle latency FPU instructions. -.. table:: Cycle counts per instruction type - :name: Cycle counts per instruction type +But the CV32E40P experiences a 1-cycle penalty on the following hazards: - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Instruction Type | Cycles | Description | - +=======================+======================================+=============================================================+ - | Integer Computational | 1 | Integer Computational Instructions are defined in the | - | | | RISCV-V RV32I Base Integer Instruction Set. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | CSR Access | 4 (mstatus, mepc, mtvec, mcause, | CSR Access Instruction are defined in 'Zicsr' of the | - | | mcycle, minstret, mhpmcounter*, | RISC-V specification. | - | | mcycleh, minstreth, mhpmcounter*h, | | - | | mcountinhibit, mhpmevent*, dscr, | | - | | dpc, dscratch0, dscratch1) | | - | | | | - | | 1 (all the other CSRs) | | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Load/Store | 1 | Load/Store is handled in 1 bus transaction using both EX | - | | | and WB stages for 1 cycle each. For misaligned word | - | | 2 (non-word aligned word | transfers and for halfword transfers that cross a word | - | | transfer) | boundary 2 bus transactions are performed using EX and WB | - | | | stages for 2 cycles each. | - | | 2 (halfword transfer crossing | A **cv.elw** takes 4 cycles. | - | | word boundary) | | - | | | | - | | 4 (cv.elw) | | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Multiplication | 1 (mul) | CV32E40P uses a single-cycle 32-bit x 32-bit multiplier | - | | | with a 32-bit result. The multiplications with upper-word | - | | 5 (mulh, mulhsu, mulhu) | result take 5 cycles to compute. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Division | 3 - 35 | The number of cycles depends on the divider operand value | - | | | (operand b), i.e. in the number of leading bits at 0. | - | Remainder | 3 - 35 | The minimum number of cycles is 3 when the divider has zero | - | | | leading bits at 0 (e.g., 0x8000000). | - | | | The maximum number of cycles is 35 when the divider is 0 | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Jump | 2 | Jumps are performed in the ID stage. Upon a jump the IF | - | | | stage (including prefetch buffer) is flushed. The new PC | - | | 3 (target is a non-word-aligned | request will appear on the instruction-side memory | - | | non-RVC instruction) | interface the same cycle the jump instruction is in the ID | - | | | stage. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Branch (Not-Taken) | 1 | Any branch where the condition is not met will | - | | | not stall. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Branch (Taken) | 3 | The EX stage is used to compute the branch decision. Any | - | | | branch where the condition is met will be taken from the | - | | 4 (target is a non-word-aligned | EX stage and will cause a flush of the IF stage (including | - | | non-RVC instruction) | prefetch buffer) and ID stage. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ - | Instruction Fence | 2 | The FENCE.I instruction as defined in 'Zifencei' of the | - | | | RISC-V specification. Internally it is implemented as a | - | | 3 (target is a non-word-aligned | jump to the instruction following the fence. The jump | - | | non-RVC instruction) | performs the required flushing as described above. | - +-----------------------+--------------------------------------+-------------------------------------------------------------+ + * Load data hazard in case the instruction immediately following a load uses the result of that load + * Jump register (jalr) data hazard in case that a jalr depends on the result of an immediately preceding instruction + * FPU data hazard when FPU_*_LAT = 1 in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU -Hazards -------- +More than 1-cycle penalty will happen when: + + * FPU data hazard of FPU_*_LAT cycles (FPU_*_LAT > 1) in case the instruction immediately following a FPU one (except FDIV/FSQRT) uses the result of the FPU + * FPU data hazard in case the instruction immediately following FDIV/FSQRT uses the result of those instructions + + +Those cycles penalty can be hidden if the compiler is able to add instructions between the instructions causing this data hazard. -The CV32E40P experiences a 1 cycle penalty on the following hazards. +Single- and Multi-Cycle Instructions +------------------------------------ + +:numref:`Cycle counts per instruction type` shows the cycle count per instruction type. Some instructions have a variable time, this is indicated as a range e.g. 1..32 means that the instruction takes a minimum of 1 cycle and a maximum of 32 cycles. The cycle counts assume zero stall on the instruction-side interface and zero stall on the data-side memory interface. - * Load data hazard (in case the instruction immediately following a load uses the result of that load) - * Jump register (jalr) data hazard (in case that a jalr depends on the result of an immediately preceding instruction) +.. _instructions_latency_table: +.. table:: Cycle counts per instruction type + :name: Cycle counts per instruction type + :widths: 20 30 50 + :class: no-scrollbar-table + + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | **Instruction Type** | **Cycles** | **Description** | + +========================+======================================+=============================================================+ + | Integer | 1 | Integer Computational Instructions are defined in the | + | | | RISCV-V RV32I Base Integer Instruction Set. | + | Computational | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Multiplication | 1 (mul) | CV32E40P uses a single-cycle 32-bit x 32-bit multiplier | + | | | with a 32-bit result. The multiplications with upper-word | + | | 5 (mulh, mulhsu, mulhu) | result take 5 cycles to compute. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Division | 3..35 | The number of cycles depends on the divider operand value | + | | | (operand b), i.e. in the number of leading bits at 0. | + | Remainder | 3..35 | The minimum number of cycles is 3 when the divider has zero | + | | | leading bits at 0 (e.g., 0x8000000). | + | | | The maximum number of cycles is 35 when the divider is 0. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Load/Store | 1 | Load/Store is handled in 1 bus transaction using both EX | + | | | and WB stages for 1 cycle each. For misaligned word | + | | 2 (non-word aligned word | transfers and for halfword transfers that cross a word | + | | transfer) | boundary 2 bus transactions are performed using EX and WB | + | | | stages for 2 cycles each. | + | | 2 (halfword transfer crossing | A **cv.elw** takes 4 cycles. | + | | word boundary) | | + | | | | + | | 4 (cv.elw) | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Jump | 2 | Jumps are performed in the ID stage. Upon a jump the IF | + | | | stage (including prefetch buffer) is flushed. The new PC | + | | 3 (target is a non-word-aligned | request will appear on the instruction-side memory | + | | non-RVC instruction) | interface the same cycle the jump instruction is in the ID | + | | | stage. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Branch | 1 | Any branch where the condition is not met will | + | | | not stall. | + | (Not-Taken) | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Branch | 3 | The EX stage is used to compute the branch decision. Any | + | | | branch where the condition is met will be taken from the | + | (Taken) | 4 (target is a non-word-aligned | EX stage and will cause a flush of the IF stage (including | + | | non-RVC instruction) | prefetch buffer) and ID stage. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | CSR Access | 4 (mstatus, mepc, mtvec, mcause, | CSR Access Instruction are defined in 'Zicsr' of the | + | | mcycle, minstret, mhpmcounter*, | RISC-V specification. | + | | mcycleh, minstreth, mhpmcounter*h, | | + | | mcountinhibit, mhpmevent*, dscr, | | + | | dpc, dscratch0, dscratch1) | | + | | | | + | | 1 (all the other CSRs) | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Instruction Fence | 2 | The FENCE.I instruction as defined in 'Zifencei' of the | + | | | RISC-V specification. Internally it is implemented as a | + | | 3 (target is a non-word-aligned | jump to the instruction following the fence. The jump | + | | non-RVC instruction) | performs the required flushing as described above. | + +------------------------+--------------------------------------+-------------------------------------------------------------+ + | Floating-Point | 1..FPU_ADDMUL_LAT + 1 | Floating-Point instructions are dispatched to the FPU. | + | Addition or | | Following instructions can be executed by the Core as long | + | Multiplication | | as they are not FPU ones and there are no Read-After-Write | + +------------------------+--------------------------------------+ or Write-After-Write data hazard between them and the | + | Floating-Point | 1..FPU_OTHERS_LAT + 1 | destination register of the outstanding FPU instruction. | + | Comparison, Conversion | | If there are enough instructions between FPU one and | + | or Classify | | the instruction using the result then cycle number is 1. | + +------------------------+--------------------------------------+ "Enough instruction" number is either FPU_ADDMUL_LAT, | + | Single Precision | 1..12 | FPU_OTHERS_LAT or 11. | + | Floating-Point | | If there are no instruction in between then cycle number is | + | Division and | | the maximum value for each category. | + | Square-Root | | | + +------------------------+--------------------------------------+-------------------------------------------------------------+ diff --git a/docs/source/register_file.rst b/docs/source/register_file.rst index 041f56a84..2c16e90e7 100644 --- a/docs/source/register_file.rst +++ b/docs/source/register_file.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ Register File ============= -Source files: :file:`rtl/cv32e40p_register_file_ff.sv` :file:`rtl/cv32e40p_register_file_latch.sv` +Source files: :file:`rtl/cv32e40p_register_file_ff.sv` CV32E40P has 31 32-bit wide registers which form registers ``x1`` to ``x31``. Register ``x0`` is statically bound to 0 and can only be read, it does not @@ -29,48 +29,10 @@ contain any sequential logic. The register file has three read ports and two write ports. Register file reads are performed in the ID stage. Register file writes are performed in the WB stage. -There are two flavors of register file available. +Floating-Point Register File +---------------------------- - * Flip-flop based (:file:`rtl/cv32e40p_register_file_ff.sv`) - * Latch-based (:file:`rtl/cv32e40p_register_file_latch.sv`) - -Both flavors have their own benefits and trade-offs. -While the latch-based register file is recommended for ASICs, the -flip-flop based register file is recommended for FPGA synthesis, -although both are compatible with either synthesis target. Note the -flip-flop based register file is significantly larger than the -latch-based register-file for an ASIC implementation. - - -Flip-Flop-Based Register File ------------------------------ - -The flip-flop-based register file uses regular, positive-edge-triggered flip-flops to implement the registers. -This makes it the **first choice when simulating the design using Verilator**. -To select the flip-flop-based register file, make sure to use the source file ``cv32e40p_register_file_ff.sv`` in your project. - -Latch-based Register File -------------------------- - -The latch-based register file uses level-sensitive latches to implement the registers. - -This allows for significant area savings compared to an implementation using regular flip-flops and -thus makes the latch-based register file the **first choice for ASIC implementations**. -Simulation of the latch-based register file is possible using commercial tools. - -.. note:: The latch-based register file cannot be simulated using Verilator. - -The latch-based register file can also be used for FPGA synthesis, but this is not recommended as FPGAs may not support latches. - -To select the latch-based register file, make sure to use the source file ``cv32e40p_register_file_latch.sv`` in your project. -In addition, a technology-specific clock gating cell must be provided to keep the clock inactive when the latches are not written. -This cell must be wrapped in a module called ``cv32e40p_clock_gate``. -For more information regarding the clock gating cell, checkout :ref:`getting-started`. - -FPU Register File ------------------ - -If the optional FPU is instantiated, unless ZFINX is configured, the register file is extended +If the optional FPU is instantiated, unless ``ZFINX`` is configured, the register file is extended with an additional register bank of 32 registers ``f0``-``f31``. These registers are stacked on top of the existing register file and can be accessed concurrently with the limitation that a maximum of three operands per @@ -82,3 +44,6 @@ file. Forwarding paths, and write-back logic are shared for the integer and floating point operations and are not replicated. + +If ``ZFINX`` parameter is set, there is no additional register bank and FPU instructions are using +the same register file than for integer instructions. diff --git a/docs/source/sleep.rst b/docs/source/sleep.rst index 5dbb71194..cc01f4c65 100644 --- a/docs/source/sleep.rst +++ b/docs/source/sleep.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2020 OpenHW Group + Copyright (c) 2023 OpenHW Group Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,56 +22,65 @@ Sleep Unit Source File: :file:`rtl/cv32e40p_sleep_unit.sv` -The Sleep Unit contains and controls the instantiated clock gate, see :ref:`clock-gating-cell`, that gates ``clk_i`` and produces a gated clock -for use by the other modules inside CV32E40P. The Sleep Unit is the only place in which ``clk_i`` itself is used; all -other modules use the gated version of ``clk_i``. +The Sleep Unit contains and controls the instantiated clock gate (see :ref:`clock-gating-cell`) that gates ``clk_i`` and produces a gated clock +for use by the other modules inside CV32E40P. The Sleep Unit is the only place in which ``clk_i`` itself is used; all other modules use the gated version of ``clk_i``. The clock gating in the Sleep Unit is impacted by the following: * ``rst_ni`` * ``fetch_enable_i`` - * **wfi** instruction (only when ``PULP_CLUSTER`` = 0) - * **cv.elw** instruction (only when ``PULP_CLUSTER`` = 1) - * ``pulp_clock_en_i`` (only when ``PULP_CLUSTER`` = 1) + * **wfi** instruction (only when ``COREV_CLUSTER`` = 0) + * **cv.elw** instruction (only when ``COREV_CLUSTER`` = 1) + * ``pulp_clock_en_i`` (only when ``COREV_CLUSTER`` = 1) :numref:`Sleep Unit interface signals` describes the Sleep Unit interface. .. table:: Sleep Unit interface signals :name: Sleep Unit interface signals - - +--------------------------------------+-----------+--------------------------------------------------+ - | Signal | Direction | Description | - +======================================+===========+==================================================+ - | ``pulp_clock_en_i`` | input | ``PULP_CLUSTER`` = 0: ``pulp_clock_en_i`` is not | - | | | used. Tie to 0. | - | | +--------------------------------------------------+ - | | | ``PULP_CLUSTER`` = 1: ``pulp_clock_en_i`` | - | | | can be used to gate ``clk_i`` internal to | - | | | the core when ``core_sleep_o`` = 1. See | - | | | :ref:`pulp_cluster` for details. | - +--------------------------------------+-----------+--------------------------------------------------+ - | ``core_sleep_o`` | output | ``PULP_CLUSTER`` = 0: Core is sleeping because | - | | | of a **wfi** instruction. If | - | | | ``core_sleep_o`` = 1, then ``clk_i`` is gated | - | | | off internally and it is allowed to gate off | - | | | ``clk_i`` externally as well. See | - | | | :ref:`wfi` for details. | - | | +--------------------------------------------------+ - | | | ``PULP_CLUSTER`` = 1: Core is sleeping because | - | | | of a **cv.elw** instruction. | - | | | If ``core_sleep_o`` = 1, | - | | | then the ``pulp_clock_en_i`` directly | - | | | controls the internally instantiated clock gate | - | | | and therefore ``pulp_clock_en_i`` can be set | - | | | to 0 to internally gate off ``clk_i``. If | - | | | ``core_sleep_o`` = 0, then it is not allowed | - | | | to set ``pulp_clock_en_i`` to 0. | - | | | See :ref:`pulp_cluster` for details. | - +--------------------------------------+-----------+--------------------------------------------------+ + :widths: 20 15 65 + :class: no-scrollbar-table + + +--------------------------------------+---------------+----------------------------------------------------+ + | **Signal** | **Direction** | **Description** | + +======================================+===============+====================================================+ + | ``pulp_clock_en_i`` | input | ``COREV_CLUSTER`` = 0: | + | | | | + | | | ``pulp_clock_en_i`` is not used. Tie to 0. | + | | +----------------------------------------------------+ + | | | ``COREV_CLUSTER`` = 1: | + | | | | + | | | ``pulp_clock_en_i`` can be used to gate ``clk_i`` | + | | | internal to the core when ``core_sleep_o`` = 1. | + | | | | + | | | See :ref:`pulp_cluster` for details. | + +--------------------------------------+---------------+----------------------------------------------------+ + | ``core_sleep_o`` | output | ``COREV_CLUSTER`` = 0: | + | | | | + | | | Core is sleeping because of a **wfi** instruction. | + | | | If ``core_sleep_o`` = 1 then ``clk_i`` is gated | + | | | off internally and it is allowing to gate off | + | | | ``clk_i`` externally as well (e.g. FPU). | + | | | | + | | | See :ref:`wfi` for details. | + | | +----------------------------------------------------+ + | | | ``COREV_CLUSTER`` = 1: | + | | | | + | | | Core is sleeping because | + | | | of a **cv.elw** instruction. | + | | | If ``core_sleep_o`` = 1, | + | | | then the ``pulp_clock_en_i`` directly | + | | | controls the internally instantiated clock gate | + | | | and therefore ``pulp_clock_en_i`` can be set | + | | | to 0 to internally gate off ``clk_i``. If | + | | | ``core_sleep_o`` = 0, then it is not allowed | + | | | to set ``pulp_clock_en_i`` to 0. | + | | | | + | | | See :ref:`pulp_cluster` for details. | + +--------------------------------------+---------------+----------------------------------------------------+ .. note:: - The semantics of ``pulp_clock_en_i`` and ``core_sleep_o`` depend on the ``PULP_CLUSTER`` parameter. + The semantics of ``pulp_clock_en_i`` and ``core_sleep_o`` depend on the ``COREV_CLUSTER`` parameter. Startup behavior ---------------- @@ -91,16 +100,16 @@ WFI The **wfi** instruction can under certain conditions be used to enter sleep mode awaiting a locally enabled interrupt to become pending. The operation of **wfi** is unaffected by the global interrupt bits in **mstatus**. -A **wfi** will not enter sleep mode, but will be executed as a regular **nop**, if any of the following conditions apply: +A **wfi** will not enter sleep mode but will be executed as a regular **nop**, if any of the following conditions apply: * ``debug_req_i`` = 1 or a debug request is pending * The core is in debug mode * The core is performing single stepping (debug) * The core has a trigger match (debug) - * ``PULP_CLUSTER`` = 1 + * ``COREV_CLUSTER`` = 1 -If a **wfi** causes sleep mode entry, then ``core_sleep_o`` is set to 1 and ``clk_i`` is gated off internally. ``clk_i`` is -allowed to be gated off externally as well in this scenario. A wake-up can be triggered by any of the following: +If a **wfi** causes sleep mode entry, then ``core_sleep_o`` is set to 1 and ``clk_i`` is gated off internally. +``clk_i`` is allowed to be gated off externally as well in this scenario. A wake-up can be triggered by any of the following: * A locally enabled interrupt is pending * A debug request is pending @@ -126,7 +135,7 @@ PULP Cluster Extension ---------------------- CV32E40P has an optional extension to enable its usage in a PULP Cluster in the PULP (Parallel Ultra Low Power) platform. -This extension is enabled by setting the ``PULP_CLUSTER`` parameter to 1. The PULP platform is organized as clusters of +This extension is enabled by setting the ``COREV_CLUSTER`` parameter to 1. The PULP platform is organized as clusters of multiple (typically 4 or 8) CV32E40P cores that share a tightly-coupled data memory, aimed at running digital signal processing applications efficiently. @@ -137,7 +146,7 @@ ready to go to sleep. Only in that case the Event Unit is allowed to set ``pulp_ internal to the core. Once the CV32E40P core is ready to start again (e.g. when the last core meets the barrier), ``pulp_clock_en_i`` is set to 1 thereby enabling the CV32E40P to run again. -If the PULP Cluster extension is not used (``PULP_CLUSTER`` = 0), the ``pulp_clock_en_i`` signal is not used and should be tied to 0. +If the PULP Cluster extension is not used (``COREV_CLUSTER`` = 0), the ``pulp_clock_en_i`` signal is not used and should be tied to 0. Execution of a **cv.elw** instructions causes ``core_sleep_o`` = 1 only if all of the following conditions are met: @@ -148,10 +157,10 @@ Execution of a **cv.elw** instructions causes ``core_sleep_o`` = 1 only if all o * The core does not have a trigger match (debug) As ``pulp_clock_en_i`` can directly impact the internal clock gate, certain requirements are imposed on the environment of CV32E40P -in case ``PULP_CLUSTER`` = 1: +in case ``COREV_CLUSTER`` = 1: * If ``core_sleep_o`` = 0, then ``pulp_clock_en_i`` must be 1 - * If ``pulp_clock_en_i`` = 0, then ``irq_i[]`` must be 0 + * If ``pulp_clock_en_i`` = 0, then ``irq_i[*]`` must be 0 * If ``pulp_clock_en_i`` = 0, then ``debug_req_i`` must be 0 * If ``pulp_clock_en_i`` = 0, then ``instr_rvalid_i`` must be 0 * If ``pulp_clock_en_i`` = 0, then ``instr_gnt_i`` must be 0 diff --git a/docs/source/tracer.rst b/docs/source/tracer.rst deleted file mode 100644 index 80f805ad5..000000000 --- a/docs/source/tracer.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. - Copyright (c) 2020 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://solderpad.org/licenses/ - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - -.. _tracer: - -Tracer -====== - -The module ``cv32e40p_tracer`` can be used to create a log of the executed instructions. -It is a behavioral, non-synthesizable, module instantiated in the example testbench that is provided for -the ``cv32e40p_core``. It can be enabled during simulation by defining **CV32E40P_TRACE_EXECUTION**. - -Output file ------------ - -All traced instructions are written to a log file. -The log file is named ``trace_core_.log``, with ```` being the 32 digit hart ID of the core being traced. - -Trace output format -------------------- - -The trace output is in tab-separated columns. - -1. **Time**: The current simulation time. -2. **Cycle**: The number of cycles since the last reset. -3. **PC**: The program counter -4. **Instr**: The executed instruction (base 16). - 32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions. -5. **Decoded instruction**: The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like ``objdump -Mnumeric -Mno-aliases -D``. - - Unsigned numbers are given in hex (prefixed with ``0x``), signed numbers are given as decimal numbers. - - Numeric register names are used (e.g. ``x1``). - - Symbolic CSR names are used. - - Jump/branch targets are given as absolute address if possible (PC + immediate). -6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the address and the loaded and stored data are given. - -.. code-block:: text - - Time Cycle PC Instr Decoded instruction Register and memory contents - 130 61 00000150 4481 c.li x9,0 x9=0x00000000 - 132 62 00000152 00008437 lui x8,0x8 x8=0x00008000 - 134 63 00000156 fff40413 addi x8,x8,-1 x8:0x00008000 x8=0x00007fff - 136 64 0000015a 8c65 c.and x8,x9 x8:0x00007fff x9:0x00000000 x8=0x00000000 - 142 67 0000015c c622 c.swsp x8,12(x2) x2:0x00002000 x8:0x00000000 PA:0x0000200c store:0x00000000 load:0xffffffff diff --git a/docs/source/verification.rst b/docs/source/verification.rst new file mode 100644 index 000000000..afb4b3490 --- /dev/null +++ b/docs/source/verification.rst @@ -0,0 +1,200 @@ +.. + Copyright (c) 2023 OpenHW Group + + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://solderpad.org/licenses/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +.. _verification: + +Verification +============ + +The verification environment (testbenches, testcases, etc.) for the CV32E40P +core can be found at `core-v-verif `_. +It is recommended to start by reviewing the +`CORE-V Verification Strategy `_. + +v1.0.0 verification +------------------- + +In early 2021 the CV32E40P achieved Functional RTL Freeze (released with cv32e40p_v1.0.0 version), meaning that is has been fully verified as per its +`Verification Plan `_. +Final functional, code and test coverage reports can be found `here `_. + +The unofficial start date for the CV32E40P verification effort is 2020-02-27, +which is the date the core-v-verif environment "went live". Between then and +RTL Freeze, a total of 47 RTL issues and 38 User Manual issues were identified +and resolved [1]_. A breakdown of the RTL issues is as follows: + +.. table:: How RTL Issues Were Found + :name: How RTL Issues Were Found + :class: no-scrollbar-table + + +---------------------+-----------+----------------------------------------------------+ + | **"Found By"** | **Count** | **Note** | + +=====================+===========+====================================================+ + | Simulation | 18 | See classification below | + +---------------------+-----------+----------------------------------------------------+ + | Inspection | 13 | Human review of the RTL | + +---------------------+-----------+----------------------------------------------------+ + | Formal Verification | 13 | This includes both Designer and Verifier use of FV | + +---------------------+-----------+----------------------------------------------------+ + | Lint | 2 | | + +---------------------+-----------+----------------------------------------------------+ + | Unknown | 1 | | + +---------------------+-----------+----------------------------------------------------+ + +A classification of the simulation issues by method used to identify them is informative: + +.. table:: Breakdown of Issues found by Simulation + :name: Breakdown of Issues found by Simulation + :widths: 27 10 63 + :class: no-scrollbar-table + + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | **Simulation Method** | **Count** | **Note** | + +==============================+===========+========================================================================================+ + | Directed, self-checking test | 10 | Many test supplied by Design team and a couple from the Open Source Community at large | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Step & Compare | 6 | Issues directly attributed to S&C against ISS | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Constrained-Random | 2 | Test generated by corev-dv (extension of riscv-dv) | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + + + + + + +A classification of the issues themselves: + +.. table:: Issue Classification + :name: Issue Classification + :class: no-scrollbar-table + + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | **Issue Type** | **Count** | **Note** | + +==============================+===========+========================================================================================+ + | RTL Functional | 40 | A bug! | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | RTL coding style | 4 | Linter issues, removing TODOs, removing \`ifdefs, etc. | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Non-RTL functional | 1 | Issue related to behavioral tracer (not part of the core) | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Unreproducible | 1 | | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + | Invalid | 1 | | + +------------------------------+-----------+----------------------------------------------------------------------------------------+ + +Additional details are available as part of the `CV32E40P v1.0.0 Report `_. + +.. [1] + It is a testament on the quality of the work done by the PULP platform team + that it took a team of professonal verification engineers more than 9 months + to find all these issues. + + +v2.0.0 verification +------------------- + +Simulation verification +^^^^^^^^^^^^^^^^^^^^^^^ + +core-v-verif verification environment for v1.0.0 was using a *step&compare* methodology with an instruction set simulator (ISS) from Imperas Software as the reference model. +This strategy was successful, but inefficient because the *step&compare* logic in the testbench must compensate for the cycle-time effects of events that are asynchronous to the instruction stream such as interrupts, debug resets plus bus errors and random delays on instruction fetch and load/store memory buses. +For verification of v2.0.0 release of the CV32E40P core, the step-and-compare and the ISS have been replaced by a true reference model (RM) called ImperasDV. In addition, the Imperas Reference Model has been extended to support the v2 Xpulp instructions specification. + +Another innovation for v2.0.0 was the adoption of a standardized tracer interface to the DUT and RM, based on the open-source RISC-V Verification Interface (RVVI). The use of well documented, standardized interfaces greatly simplifies the integration of the DUT with the RM. + +WIP... + +.. ADD VERIFIED PARAMETERS VALUES TABLE + +.. ADD PLANS AND REPORTS LINKS + +.. `Verification Plan `_. + +.. TO DEVELOP ... + +Formal verification +^^^^^^^^^^^^^^^^^^^ + +To accelerate the verification of more than 300 Xpulp instructions, Formal Verification methodology has been used with Siemens EDA Onespin tools and their RISC-V ISA app. + +The Xpulp instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and Xpulp extensions. +This has been applied on 5 different core configurations (controlled via SystemVerilog parameters). + +WIP... + +.. ADD VERIFIED PARAMETERS VALUES TABLE + +.. ADD PLANS AND REPORTS LINKS + +.. `Verification Plan `_. +.. Final functional, code and test coverage reports can be found `here `_. + +.. TO DEVELOP ... + +Reports +^^^^^^^ + +WIP... + +.. ADD BUG LIST LINK AND TABLE LIKE ABOVE + +.. ADD MERGED RTL CODE COVERAGE GENERATED REPORTS LINK + + +Tracer +------ + +TODO: To re-work with ImperasDV tracer. + +.. ALL CHAPTER TO ADAPT WITH NEW IMPERASDV METHODOLOGY AND RVVI TRACER + +The module ``cv32e40p_tracer`` can be used to create a log of the executed instructions. +It is a behavioral, non-synthesizable, module instantiated in the example testbench that is provided for +the ``cv32e40p_top``. It can be enabled during simulation by defining **CV32E40P_TRACE_EXECUTION**. + +Output file +^^^^^^^^^^^ + +All traced instructions are written to a log file. +The log file is named ``trace_core_.log``, with ```` being the 32 digit hart ID of the core being traced. + +Trace output format +^^^^^^^^^^^^^^^^^^^ + +The trace output is in tab-separated columns. + +1. **Time**: The current simulation time. +2. **Cycle**: The number of cycles since the last reset. +3. **PC**: The program counter +4. **Instr**: The executed instruction (base 16). + 32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions. +5. **Decoded instruction**: The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like ``objdump -Mnumeric -Mno-aliases -D``. + - Unsigned numbers are given in hex (prefixed with ``0x``), signed numbers are given as decimal numbers. + - Numeric register names are used (e.g. ``x1``). + - Symbolic CSR names are used. + - Jump/branch targets are given as absolute address if possible (PC + immediate). +6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the address and the loaded and stored data are given. + +.. code-block:: text + + Time Cycle PC Instr Decoded instruction Register and memory contents + 130 61 00000150 4481 c.li x9,0 x9=0x00000000 + 132 62 00000152 00008437 lui x8,0x8 x8=0x00008000 + 134 63 00000156 fff40413 addi x8,x8,-1 x8:0x00008000 x8=0x00007fff + 136 64 0000015a 8c65 c.and x8,x9 x8:0x00007fff x9:0x00000000 x8=0x00000000 + 142 67 0000015c c622 c.swsp x8,12(x2) x2:0x00002000 x8:0x00000000 PA:0x0000200c