From b794f3af977ae1f63a78e6d9acb577d495e909fc Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Fri, 9 Feb 2024 17:19:35 +0100 Subject: [PATCH 01/20] Populate instruction chapter in CV32A65X Design Document --- docs/04_cv32a65x_design/source/instructions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04_cv32a65x_design/source/instructions.rst b/docs/04_cv32a65x_design/source/instructions.rst index 79c15be36d..3ee606b10f 100644 --- a/docs/04_cv32a65x_design/source/instructions.rst +++ b/docs/04_cv32a65x_design/source/instructions.rst @@ -13,7 +13,7 @@ Instructions The next first subchapter lists the extensions implemented in CVA6. By configuration, we can enable/disable the extensions. CV32A65X supports the extensions described in the next subchapters. -RVZicond, RV32A and RVZifencei extensions are not supported by CV32A65X. +Zicond and Atomic extensions are not supported by CV32A65X. .. toctree:: From 5b576f29e430869bfe933b0145c28fee5a04da3f Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Fri, 9 Feb 2024 17:19:35 +0100 Subject: [PATCH 02/20] Populate instruction chapter in CV32A65X Design Document --- docs/04_cv32a65x_design/source/instructions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04_cv32a65x_design/source/instructions.rst b/docs/04_cv32a65x_design/source/instructions.rst index 3ee606b10f..79c15be36d 100644 --- a/docs/04_cv32a65x_design/source/instructions.rst +++ b/docs/04_cv32a65x_design/source/instructions.rst @@ -13,7 +13,7 @@ Instructions The next first subchapter lists the extensions implemented in CVA6. By configuration, we can enable/disable the extensions. CV32A65X supports the extensions described in the next subchapters. -Zicond and Atomic extensions are not supported by CV32A65X. +RVZicond, RV32A and RVZifencei extensions are not supported by CV32A65X. .. toctree:: From a759213332ffb5732064b8d6f331d1eabdcd4ad6 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Mon, 12 Feb 2024 13:21:41 +0100 Subject: [PATCH 03/20] Improve documentation by adding submodule images --- .../images/ex_stage_modules.png | Bin 21008 -> 21705 bytes .../images/id_stage_modules.png | Bin 14334 -> 15475 bytes .../images/issue_stage_modules.png | Bin 16267 -> 16850 bytes .../source/cv32a6_execute.rst | 1565 ++++++++++++++++- .../source/cva6_id_stage.rst | 26 +- .../source/cva6_issue_stage.rst | 3 - 6 files changed, 1558 insertions(+), 36 deletions(-) diff --git a/docs/04_cv32a65x_design/images/ex_stage_modules.png b/docs/04_cv32a65x_design/images/ex_stage_modules.png index bd1f029b2c434d94f3c845de0978228d0ab766ee..97738c8b74ac8c8eb412e958e3d786a38a834867 100644 GIT binary patch literal 21705 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 literal 21008 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 z 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 KO!BGA9{&Y}q{lJ< diff --git a/docs/04_cv32a65x_design/images/id_stage_modules.png b/docs/04_cv32a65x_design/images/id_stage_modules.png index 8e0115f39e5aa01681401924fb3288b44bd1e05f..476a038e75dbdc1d68d8112dd9cf6b53165d735b 100644 GIT binary patch literal 15475 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%0DGjIWraN!yeX%PNgNPe)q# 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 literal 14334 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 V{+2q1QDlNpR#ZEfvj5bTe*rFeN&o-= diff --git a/docs/04_cv32a65x_design/images/issue_stage_modules.png b/docs/04_cv32a65x_design/images/issue_stage_modules.png index d0f14e46a4173d5ac47b063e62d586e3d81050a9..a1af1234c02617daebcf8da8d2374f1bc2bc6584 100644 GIT binary patch literal 16850 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 TwdC8x_2n_97RGIGfz#9ladfJ#i24!MP|E{ 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 Xt^O$!{Z#>EXr5G5`A5pHzuo?C3 Table 1: CVA6 MMU SV32 Input Output Signals

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection Type + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Sfence Committed + + * - ``enable_translation_i`` + - in + - CSR RegFile + - logic + - Indicate address translation request for instruction + + * - ``en_ld_st_translation_i`` + - in + - CSR RegFile + - logic + - Indicate address translation request for load or store + + * - ``icache_areq_i`` + - in + - Cache Subsystem + - icache_arsp_t + - Icache Response + + * - ``icache_areq_o`` + - out + - Cache Subsystem + - icache_areq_t + - Icache Request + + * - ``misaligned_ex_i`` + - in + - Load Store Unit + - exception_t + - Indicate misaligned exception + + * - ``lsu_req_i`` + - in + - Load Store Unit + - logic + - Request address translation + + * - ``lsu_vaddr_i`` + - in + - Load Store Unit + - logic [riscv::VLEN-1:0] + - Virtual Address In + + * - ``lsu_is_store_i`` + - in + - Store Unit + - logic + - Translation is requested by a store + + * - ``lsu_dtlb_hit_o`` + - out + - Store / Load Unit + - logic + - Indicate a DTLB hit + + * - ``lsu_dtlb_ppn_o`` + - out + - Load Unit + - logic [riscv::PPNW-1:0] + - Send PNN to LSU + + * - ``lsu_valid_o`` + - out + - Load Store Unit + - logic + - Indicate a valid translation + + * - ``lsu_paddr_o`` + - out + - Store / Load Unit + - logic [riscv::PLEN-1:0] + - Translated Address + + * - ``lsu_exception_o`` + - out + - Store / Load Unit + - exception_t + - Address Translation threw an exception + + * - ``priv_lvl_i`` + - in + - CSR RegFile + - riscv::priv_lvl_t + - Privilege level for instruction fetch interface + + * - ``ld_st_priv_lvl_i`` + - in + - CSR RegFile + - riscv::priv_lvl_t + - Privilege Level for Data Interface + + * - ``sum_i`` + - in + - CSR RegFile + - logic + - Supervisor User Memory Access bit in xSTATUS CSR register + + * - ``mxr_i`` + - in + - CSR RegFile + - logic + - Make Executable Readable bit in xSTATUS CSR register + + * - ``satp_ppn_I`` + - in + - CSR RegFile + - logic [riscv::PPNW-1:0] + - PPN of top level page table from SATP register + + * - ``asid_i`` + - in + - CSR RegFile + - logic [ASID_WIDTH-1:0] + - ASID to for the lookup + + * - ``asid_to_be_flushed`` + - in + - Execute Stage + - logic [ASID_WIDTH-1:0] + - ASID of the entry to be flushed. + + * - ``vaddr_to_be_flushed_i`` + - in + - Execute Stage + - logic [riscv::VLEN-1:0] + - Virtual address of the entry to be flushed. + + * - ``flush_tlb_i`` + - in + - Controller + - logic + - SFENCE.VMA committed + + * - ``itlb_miss_o`` + - out + - Performance Counter + - logic + - Indicate an ITLB miss + + * - ``dtlb_miss_o`` + - out + - Performance Counter + - logic + - Indicate a DTLB miss + + * - ``req_port_i`` + - in + - Cache Subsystem + - dcache_req_o_t + - D Cache Data Requests + + * - ``req_port_o`` + - out + - Cache Subsystem + - dcache_req_i_t + - D Cache Data Response + + * - ``pmpcfg_i`` + - in + - CSR RegFile + - riscv::pmpcfg_t [15:0] + - PMP configurations + + * - ``pmpaddr_i`` + - in + - CSR RegFile + - logic [15:0][riscv::PLEN-3:0] + - PMP Address + +.. raw:: html + + Struct Description + +.. raw:: html + +

Table 2: I Cache Request Struct (icache_areq_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``fetch_valid`` + - logic + - Address Translation Valid + + * - ``fetch_paddr`` + - logic [riscv::PLEN-1:0] + - Physical Address In + + * - ``fetch_exception`` + - exception_t + - Exception occurred during fetch + +.. raw:: html + +

Table 3: I Cache Response Struct (icache_arsq_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``fetch_req`` + - logic + - Address Translation Request + + * - ``fetch_vaddr`` + - logic [riscv::VLEN-1:0] + - Virtual Address out + +.. raw:: html + +

Table 4: Exception Struct (exception_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``cause`` + - riscv::xlen_t + - Cause of exception + + * - ``tval`` + - riscv::xlen_t + - Additional information of causing exception (e.g. instruction causing it), address of LD/ST fault + + * - ``valid`` + - logic + - Indicate that exception is valid + +.. raw:: html + +

Table 5: PMP Configuration Struct (pmpcfg_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``locked`` + - logic + - Lock this configuration + + * - ``reserved`` + - logic[1:0] + - Reserved bits in pmpcfg CSR + + * - ``addr_mode`` + - pmp_addr_mode_t + - Addressing Modes: OFF, TOR, NA4, NAPOT + + * - ``access_type`` + - pmpcfg_access_t + - None, read, write, execute + +.. raw:: html + + Control Flow in MMU SV32 Module + +.. figure:: ../images/mmu_control_flow.png + :name: **Figure 3:** Control Flow in CVA6 MMU SV32 + :align: center + :width: 95% + :alt: mmu_control_flow + + **Figure 3:** Control Flow in CVA6 MMU SV32 + +.. raw:: html + + Exception Sources with Address Translation Enabled + +Two potential exception sources exist: + +* Hardware Page Table Walker (HPTW) throwing an exception, signifying a page fault exception. +* Access error due to insufficient permissions of PMP, known as an access exception. + +.. raw:: html + + Instruction Fetch Interface + +The IF stage initiates a request to retrieve memory content at a specific virtual address. When the MMU is disabled, the instruction fetch request is directly passed to the I$ without modifications. + +.. raw:: html + + Address Translation in Instruction Interface + +If virtual memory translation is enabled for instruction fetches, the following operations are performed in the instruction interface: + +* Compatibility of requested virtual address with selected page based address translation scheme is checked. +* For 4K page translation, the module determines the fetch physical address by combining the physical page number (PPN) from ITLB content and the offset from the virtual address. +* In the case of Mega page translation, if the ITLB indicates a 4M page, the VPN0 from the fetch virtual address is written to the PPN0 of the fetch physical address to ensure alignment for superpage translation. +* If the Instruction TLB (ITLB) lookup hits, the fetch valid signal (which indicates a valid physical address) is activated in response to the input fetch request. Memory region accessibility is checked from the perspective of the fetch operation, potentially triggering a page fault exception in case of an access error or insufficient PMP permission. +* In case of an ITLB miss, if the page table walker (PTW) is active (only active if there is a shared TLB miss) and handling instruction fetches, the fetch valid signal is determined based on PTW errors or access exceptions. + +If the fetch physical address doesn't match any execute region, an Instruction Access Fault is raised. When not translating, PMPs are immediately checked against the physical address for access verification. + +.. raw:: html + + Data Interface + +.. raw:: html + + Address Translation in Data Interface + +If address translation is enabled for load or store, and no misaligned exception has occurred, the following operations are performed in the data interface: + +* Initially, translation is assumed to be invalid, signified by the MMU to LSU. +* The translated physical address is formed by combining the PPN from the Page Table Entry (PTE) and the offset from the virtual address requiring translation. This send one cycle later due to the additional bank of registers which delayed the MMU’s answer. The PPN from the PTE is also shared separately with LSU in the same cycle as the hit. +* In the case of superpage translation, as in SV32, known as the 4M page, PPN0 of the translated physical address and the separately shared PPN are updated with the VPN0 of the virtual address. + +If a Data TLB (DTLB) hit occurs, it indicates a valid translation, and various fault checks are performed depending on whether it's a load or store request. + +* For store requests, if the page is not writable, the dirty flag isn't set, or privileges are violated, it results in a page fault corresponding to the store access. If PMPs are also violated, it leads to an access fault corresponding to the store access. Page faults take precedence over access faults. +* For load requests, a page fault is triggered if there are insufficient access privileges. PMPs are checked again during load access, resulting in an access fault corresponding to load access if PMPs are violated. + +In case of a DTLB miss, potential exceptions are monitored during the page table walk. If the PTW indicates a page fault, the corresponding page fault related to the requested type is signaled. If the PTW indicates an access exception, the load access fault is indicated through address translation because the page table walker can only throw load access faults. + +.. raw:: html + + Address Translation is Disabled + +When address translation is not enabled, the physical address is immediately checked against Physical Memory Protections (PMPs). If there is a request from LSU, no misaligned exception, and PMPs are violated, it results in an access fault corresponding to the request being indicated. + +---------------------------- +Translation Lookaside Buffer +---------------------------- + +Page tables are accessed for translating virtual memory addresses to physical memory addresses. This translation needs to be carried out for every load and store instruction and also for every instruction fetch. Since page tables are resident in physical memory, accessing these tables in all these situations has a significant impact on performance. Page table accesses occur in patterns that are closely related in time. Furthermore, the spatial and temporal locality of data accesses or instruction fetches mean that the same page is referenced repeatedly. Taking advantage of these access patterns the processor keeps the information of recent address translations, to enable fast retrieval, in a small cache called the Translation Lookaside Buffer (TLB) or an address-translation cache. + +The CVA6 TLB is structured as a fully associative cache, where the virtual address that needs to be translated is compared against all the individual TLB entries. Given a virtual address, the processor examines the TLB (TLB lookup) to determine if the virtual page number (VPN) of the page being accessed is in the TLB. When a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is used to calculate the target physical address. If no TLB entry is found (TLB miss) the processor has to read individual page table entries from memory (Table walk). In CVA6 table walking is supported by dedicated hardware. Once the processor finishes the table walk it has the Physical Page Number (PPN) corresponding to the Virtual Page Number (VPN) That needs to be translated. The processor adds an entry for this address translation to the TLB so future translations of that virtual address will happen quickly through the TLB. During the table walk the processor may find out that the corresponding physical page is not resident in memory. At this stage a page table exception (Page Fault) is generated which gets handled by the operating system. The operating system places the appropriate page in memory, updates the appropriate page tables and returns execution to the instruction which generated the exception. + +The inputs and output signals of the TLB are shown in the following two figures. + +.. figure:: ../images/in_out_tlb.png + :name: **Figure 4:** Inputs and Outputs of CVA6 TLB + :align: center + :width: 65% + :alt: in_out_tlb + + **Figure 4:** Inputs and Outputs of CVA6 TLB + +.. raw:: html + + Signal Description of TLB + +.. raw:: html + +

Table 6: CVA6 TLB Input Output Signals

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - connection + - Type + - Description + + * - ``clk_i`` + - in + - SUBSYSTEM + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - SUBSYSTEM + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Asynchronous reset active low + + * - ``update_i`` + - in + - Shared TLB + - tlb_update_sv32_t + - Updated tag and content of TLB + + * - ``lu_access_i`` + - in + - Cache Subsystem + - logic + - Signal indicating a lookup access is being requested + + * - ``lu_asid_i`` + - in + - CSR RegFile + - logic[ASID_WIDTH-1:0] + - ASID (Address Space Identifier) for the lookup + + * - ``lu_vaddr_i`` + - in + - Cache Subsystem + - logic[riscv::VLEN-1:0] + - Virtual address for the lookup + + * - ``lu_content_o`` + - out + - MMU SV32 + - riscv::pte_sv32_t + - Output for the content of the TLB entry + + * - ``asid_to_be_flushed_i`` + - in + - Execute Stage + - logic[ASID_WIDTH-1:0] + - ASID of the entry to be flushed + + * - ``vaddr_to_be_flushed_i`` + - in + - Execute Stage + - logic[riscv::VLEN-1:0] + - Virtual address of the entry to be flushed + + * - ``lu_is_4M_o`` + - out + - MMU SV32 + - logic + - Output indicating whether the TLB entry corresponds to a 4MB page + + * - ``lu_hit_o`` + - out + - MMU SV32 + - logic + - Output indicating whether the lookup resulted in a hit or miss + +.. raw:: html + + Struct Description + +.. raw:: html + +

Table 7: SV32 TLB Update Struct (tlb_update_sv32_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``valid`` + - logic + - Indicates whether the TLB update entry is valid or not + + * - ``is_4M`` + - logic + - Indicates if the TLB entry corresponds to a 4MB page + + * - ``vpn`` + - logic[19:0] + - Virtual Page Number (VPN) used for updating the TLB, consisting of 20 bits + + * - ``asid`` + - logic[8:0] + - Address Space Identifier (ASID) used for updating the TLB, with a length of 9 bits for Sv32 MMU + + * - ``content`` + - riscv::pte_sv32_t + - Content of the TLB update entry, defined by the structure + +.. raw:: html + +

Table 8: SV32 PTE Struct (riscv::pte_sv32_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``ppn`` + - logic[21:0] + - 22 bit Physical Page Number (PPN) + + * - ``rsw`` + - logic[1:0] + - Reserved for use by supervisor software + + * - ``d`` + - logic + - | Dirty bit indicating whether the page has been modified (dirty) or not + | 0: Page is clean i.e., has not been written + | 1: Page is dirty i.e., has been written + + * - ``a`` + - logic + - | Accessed bit indicating whether the page has been accessed + | 0: Virtual page has not been accessed since the last time A bit was cleared + | 1: Virtual page has been read, written, or fetched from since the last time the A bit was cleared + + * - ``g`` + - logic + - | Global bit marking a page as part of a global address space valid for all ASIDs + | 0: Translation is valid for specific ASID + | 1: Translation is valid for all ASIDs + + * - ``u`` + - logic + - | User bit indicating privilege level of the page + | 0: Page is not accessible in user mode but in supervisor mode + | 1: Page is accessible in user mode but not in supervisor mode + + * - ``x`` + - logic + - | Execute bit which allows execution of code from the page + | 0: Code execution is not allowed + | 1: Code execution is permitted + + * - ``w`` + - logic + - | Write bit allows the page to be written + | 0: Write operations are not allowed + | 1: Write operations are permitted + + * - ``r`` + - logic + - | Read bit allows read access to the page + | 0: Read operations are not allowed + | 1: Read operations are permitted + + * - ``v`` + - logic + - | Valid bit indicating the page table entry is valid + | 0: Page is invalid i.e. page is not in DRAM, translation is not valid + | 1: Page is valid i.e. page resides in the DRAM, translation is valid + +.. raw:: html + + TLB Entry Fields + +The number of TLB entries can be changed via a design parameter. In 32-bit configurations of CVA6 only 2 TLB entries are instantiated. Each TLB entry is made up of two fields: Tag and Content. The Tag field holds the virtual page number (VPN1, VPN0), ASID, page size (is_4M) along with a valid bit (VALID) indicating that the entry is valid. The SV32 virtual page number, which is supported by CV32A6X, is further split into two separate virtual page numbers VPN1 and VPN0. The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. Note that the V bit in the Content field is the V bit which is present in the page table in memory. It is copied from the page table, as is, and the VALID bit in the Tag is set based on its value.The TLB entry fields are shown in **Figure 2**. + +.. figure:: ../images/cva6_tlb_entry.png + :name: **Figure 5:** Fields in CVA6 TLB entry + :align: center + :width: 80% + :alt: cva6_tlb_entry + + **Figure 5:** Fields in CVA6 TLB entry + +.. raw:: html + + CVA6 TLB Management / Implementation + +The CVA6 TLB implements the following three functions: + +* **Translation:** This function implements the address lookup and match logic. +* **Update and Flush:** This function implements the update and flush logic. +* **Pseudo Least Recently Used Replacement Policy:** This function implements the replacement policy for TLB entries. + +.. raw:: html + + Translation + +This function takes in the virtual address and certain other fields, examines the TLB to determine if the virtual page number of the page being accessed is in the TLB or not. If a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is then used to calculate the target physical address. The following checks are done as part of this lookup function to find a match in the TLB: + +* **Validity Check:** For a TLB hit, the associated TLB entry must be valid . +* **ASID and Global Flag Check:** The TLB entry's ASID must match the given ASID (ASID associated with the Virtual address). If the TLB entry’s Global bit (G) bit is set then this check is not done. This ensures that the translation is either specific to the provided ASID or it is globally applicable. +* **Level 1 VPN match:** SV32 implements a two-level page table. As such the virtual address is broken up into three parts which are the virtual page number 1, virtual page number 0 and displacement. So the condition that is checked next is that the virtual page number 1 of the virtual address matches the virtual page number 1(VPN1) of the TLB entry. +* **Level 0 VPN match or 4-Mega Page:** The last condition to be checked, for a TLB hit, is that the virtual page number 0 of the virtual address matches the virtual page number 0 of the TLB entry (VPN0). This match is ignored if the is_4M bit in the Tag is set which implies a super 4M page. + +All the conditions listed above are checked against every TLB entry. If there is a TLB hit then the corresponding bit in the hit array is set. **Figure 3** Illustrates the TLB hit/miss process listed above. + +.. figure:: ../images/cva6_tlb_hit.png + :name: **Figure 6:** Block diagram of CVA6 TLB hit or miss + :align: center + :width: 75% + :alt: cva6_tlb_hit + + **Figure 6:** Block diagram of CVA6 TLB hit or miss + +.. raw:: html + + Flushing TLB entries + +The SFENCE.VMA instruction can be used with certain specific source register specifiers (rs1 & rs2) to flush a specific TLB entry, some set of TLB entries or all TLB entries. Like all instructions this action only takes place when the SFENCE.VMA instruction is committed (shown via the commit_sfence signal in the following figures.) The behavior of the instruction is as follows: + +* **If rs1 is not equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries which contain leaf page table entries corresponding to the virtual address in rs1 (shown below as Virtual Address to be flushed) and that match the address space identifier as specified by integer register rs2 (shown below as asid_to_be_flushed_i), except for entries containing global mappings. This is referred to as the “SFENCE.VMA vaddr asid” case. + +.. figure:: ../images/sfence_vaddr_asid.png + :name: **Figure 7:** Invalidate TLB entry if ASID and virtual address match + :align: center + :width: 75% + :alt: sfence_vaddr_asid + + **Figure 7:** Invalidate TLB entry if ASID and virtual address match + +* **If rs1 is equal to x0 and rs2 is equal to x0:** Invalidate all TLB entries for all address spaces. This is referred to as the "SFENCE.VMA x0 x0" case. + +.. figure:: ../images/sfence_x0_x0.png + :name: **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 + :align: center + :width: 62% + :alt: sfence_x0_x0 + + **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 + +* **If rs1 is not equal to x0 and rs2 is equal to x0:** invalidate all TLB entries that contain leaf page table entries corresponding to the virtual address in rs1, for all address spaces. This is referred to as the “SFENCE.VMA vaddr x0” case. + +.. figure:: ../images/sfence_vaddr_x0.png + :name: **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces + :align: center + :width: 75% + :alt: sfence_vaddr_x0 + + **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces + +* **If rs1 is equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries matching the address space identified by integer register rs2, except for entries containing global mappings. This is referred to as the “SFENCE.VMA 0 asid” case. + +.. figure:: ../images/sfence_x0_asid.png + :name: **Figure 10:** Invalidate TLB entry for matching ASIDs + :align: center + :width: 75% + :alt: sfence_x0_asid + + **Figure 10:** Invalidate TLB entry for matching ASIDs + +.. raw:: html + + Updating TLB + +When a TLB valid update request is signaled by the shared TLB, and the replacement policy select the update of a specific TLB entry, the corresponding entry's tag is updated with the new tag, and its associated content is refreshed with the information from the update request. This ensures that the TLB entry accurately reflects the new translation information. + +.. raw:: html + + Pseudo Least Recently Used Replacement Policy + +Cache replacement algorithms are used to determine which TLB entry should be replaced, because it is not likely to be used in the near future. The Pseudo-Least-Recently-Used (PLRU) is a cache entry replacement algorithm, derived from Least-Recently-Used (LRU) cache entry replacement algorithm, used by the TLB. Instead of precisely tracking recent usage as the LRU algorithm does, PLRU employs an approximate measure to determine which entry in the cache has not been recently used and as such can be replaced. + +CVA6 implements the PLRU algorithm via the Tree-PLRU method which implements a binary tree. The TLB entries are the leaf nodes of the tree. Each internal node, of the tree, consists of a single bit, referred to as the state bit or plru bit, indicating which subtree contains the (pseudo) least recently used entry (the PLRU); 0 for the left hand tree and 1 for the right hand tree. Following this traversal, the leaf node reached, corresponds to the PLRU entry which can be replaced. Having accessed an entry (so as to replace it) we need to promote that entry to be the Most Recently Used (MRU) entry. This is done by updating the value of each node along the access path to point away from that entry. If the accessed entry is a right child i.e., its parent node value is 1, it is set to 0, and if the parent is the left child of its parent (the grandparent of the accessed node) then its node value is set to 1 and so on all the way up to the root node. + +The PLRU binary tree is implemented as an array of node values. Nodes are organized in the array based on levels, with those from lower levels appearing before higher ones. Furthermore those on the left side of a node appear before those on the right side of a node. The figure below shows a tree and the corresponding array. + +.. figure:: ../images/plru_tree_indexing.png + :name: **Figure 11:** PLRU Tree Indexing + :align: center + :width: 60% + :alt: plru_tree_indexing + + **Figure 11:** PLRU Tree Indexing + +For n-way associative, we require n - 1 internal nodes in the tree. With those nodes, two operations need to be performed efficiently. + +* Promote the accessed entry to be MRU +* Identify which entry to replace (i.e. the PLRU entry) + +.. raw:: html + + Updating the PLRU-Tree + +For a TLB entry which is accessed, the following steps are taken to make it the MRU: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. +4. Calculate the new value that the node should have in order to make the accessed entry the Most Recently Used (MRU). The new value of the root node is the opposite of the TLB entry index, MSB at the root node, MSB - 1 at node at next level and so on. +5. Assign this new value to the relevant node, ensuring that the hit entry becomes the MRU within the binary tree structure. + +At level 0, no bit of the TLB entry’s index determines the offset from the index base because it’s a root node. At level 1, MSB of entry’s index determines the amount of offset from index base at that level. At level 2, the first two bits of the entry's index from MSB side determine the offset from the index base because there are 4 nodes at the level 2 and so on. + +.. figure:: ../images/update_tree.png + :name: **Figure 12:** Promote Entry to be MRU + :align: center + :width: 82% + :alt: update_tree + + **Figure 12:** Promote Entry to be MRU + +In the above figure entry at index 5, is accessed. To make it MRU entry, every node along the access path should point away from it. Entry 5 is a right child, therefore, its parent plru bit set to 0, its parent is a left child, its grand parent’s plru bit set to 1, and great grandparent’s plru bit set to 0. + +.. raw:: html + + Entry Selection for Replacement + +Every TLB entry is checked for the replacement entry. The following steps are taken: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. +4. If the corresponding bit of the entry's index matches the value of the node being traversed at the current level, keep the replacement signal high for that entry; otherwise, set the replacement signal to low. + +.. figure:: ../images/replacement_entry.png + :name: **Figure 13:** Possible path traverse for entry selection for replacement + :align: center + :width: 65% + :alt: replacement_entry + + **Figure 13:** Possible path traverse for entry selection for replacement + +Figure shows every possible path that traverses to find out the PLRU entry. If the plru bit at each level matches with the corresponding bit of the entry's index, that’s the next entry to replace. Below Table shows the entry selection for replacement. + +.. raw:: html + +

Table 9: Entry Selection for Reaplacement

+ ++-------------------+---------------+----------------------+ +| **Path Traverse** | **PLRU Bits** | **Entry to replace** | ++-------------------+---------------+----------------------+ +| 0 -> 1 -> 3 | 000 | 0 | +| +---------------+----------------------+ +| | 001 | 1 | ++-------------------+---------------+----------------------+ +| 0 -> 1 -> 4 | 010 | 2 | +| +---------------+----------------------+ +| | 011 | 3 | ++-------------------+---------------+----------------------+ +| 0 -> 2 -> 5 | 100 | 4 | +| +---------------+----------------------+ +| | 101 | 5 | ++-------------------+---------------+----------------------+ +| 0 -> 2 -> 6 | 110 | 6 | +| +---------------+----------------------+ +| | 111 | 7 | ++-------------------+---------------+----------------------+ + +----------------------------------- +Shared Translation Lookaside Buffer +----------------------------------- + +The CVA6 shared TLB is structured as a 2-way associative cache, where the virtual address requiring translation is compared with the set indicated by the virtual page number. The shared TLB is looked up in case of an Instruction TLB (ITLB) or data TLB (DTLB) miss, signaled by these TLBs. If the entry is found in the shared TLB set, the respective TLB, whose translation is being requested, is updated. If the entry is not found in the shared TLB, then the processor has to perform a page table walk. Once the processor obtains a PPN corresponding to the VPN, the shared TLB is updated with this information. If the physical page is not found in the page table, it results in a page fault, which is handled by the operating system. The operating system will then place the corresponding physical page in memory. + +The inputs and output signals of the shared TLB are shown in the following two figures. + +.. figure:: ../images/shared_tlb_in_out.png + :name: **Figure 14:** Inputs and outputs of CVA6 shared TLB + :align: center + :width: 60% + :alt: shared_tlb_in_out + + **Figure 14:** Inputs and outputs of CVA6 shared TLB + +.. raw:: html + + Signal Description + +.. raw:: html + +

Table 10: Signal Description of CVA6 shared TLB

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - TLB flush request + + * - ``enable_translation_i`` + - in + - CSR Regfile + - logic + - CSRs indicate to enable Sv32 + + * - ``en_ld_st_translation_i`` + - in + - CSR Regfile + - logic + - Enable virtual memory translation for load/stores + + * - ``asid_i`` + - in + - CSR Regfile + - logic + - ASID for the lookup + + * - ``itlb_access_i`` + - in + - Cache Subsystem + - logic + - Signal indicating a lookup access in ITLB is being requested. + + * - ``itlb_hit_i`` + - in + - ITLB + - logic + - Signal indicating an ITLB hit + + * - ``itlb_vaddr_i`` + - in + - Cache Subsystem + - logic[31:0] + - Virtual address lookup in ITLB + + * - ``dtlb_access_i`` + - in + - Load/Store Unit + - logic + - Signal indicating a lookup access in DTLB is being requested. + + * - ``dtlb_hit_i`` + - in + - DTLB + - logic + - Signal indicating a DTLB hit + + * - ``dtlb_vaddr_i`` + - in + - Load/Store Unit + - logic[31:0] + - Virtual address lookup in DTLB + + * - ``itlb_update_o`` + - out + - ITLB + - tlb_update_sv32_t + - Tag and content to update ITLB + + * - ``dtlb_update_o`` + - out + - DTLB + - tlb_update_sv32_t + - Tag and content to update DTLB + + * - ``itlb_miss_o`` + - out + - Performance Counter + - logic + - Signal indicating an ITLB miss + + * - ``dtlb_miss_o`` + - out + - Performance Counter + - logic + - Signal indicating a DTLB miss + + * - ``shared_tlb_access_o`` + - out + - PTW + - logic + - Signal indicating a lookup access in shared TLB is being requested + + * - ``shared_tlb_hit_o`` + - out + - PTW + - logic + - Signal indicating a shared TLB hit + + * - ``shared_tlb_vadd_o`` + - out + - PTW + - logic[31:0] + - Virtual address lookup in shared TLB + + * - ``itlb_req_o`` + - out + - PTW + - logic + - ITLB Request Output + + * - ``shared_tlb_update_i`` + - in + - PTW + - tlb_update_sv32_t + - Updated tag and content of shared TLB + +.. raw:: html + + Struct Description + +.. raw:: html + +

Table 11: Shared TLB Update Struct (shared_tag_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``is_4M`` + - logic + - Indicates if the shared TLB entry corresponds to a 4MB page. + + * - ``vpn1`` + - logic[9:0] + - Virtual Page Number (VPN) represents the index of PTE in the page table level 1. + + * - ``vpn0`` + - logic[9:0] + - Virtual Page Number (VPN) represents the index of PTE in the page table level 0. + + * - ``asid`` + - logic + - Address Space Identifier (ASID) used to identify different address spaces + +.. raw:: html + + Shared TLB Entry Structure + +Shared TLB is 2-way associative, with a depth of 64. A single entry in the set contains the valid bit, tag and the content. The Tag segment stores details such as the virtual page number (VPN1, VPN0), ASID, and page size (is_4M). The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. + +.. figure:: ../images/shared_tlb.png + :name: **Figure 15:** CVA6 Shared TLB Structure + :align: center + :width: 60% + :alt: shared_tlb + + **Figure 15:** CVA6 Shared TLB Structure + +.. raw:: html + + Shared TLB Implementation in CVA6 + +The implementation of a shared TLB in CVA6 is described in the following sections: + +* **ITLB and DTLB Miss:** Prepare a shared TLB lookup if the entry is not found in ITLB or DTLB. +* **Tag Comparison:** Look up the provided virtual address in the shared TLB. +* **Update and Flush:** Flush the shared TLB or update it. +* **Replacement Policies:** First non-valid entry and random replacement policy. + +.. raw:: html + + ITLB and DTLB Miss + +Consider a scenario where an entry is found in the ITLB or DTLB. In this case, there is no need to perform a lookup in the shared TLB since the entry has already been found. Next, there are two scenarios: an ITLB miss or a DTLB miss. + +To identify an ITLB miss, the following conditions need to be fulfilled: + +* Address translation must be enabled. +* There must be an access request to the ITLB. +* The ITLB should indicate an ITLB miss. +* There should be no access request to the DTLB. + +During an ITLB miss, access is granted to read the tag and content of the shared TLB from their respective sram. The address for reading the tag and content of the shared TLB entry is calculated using the virtual address for which translation is not found in the ITLB. The ITLB miss is also explicitly indicated by the shared TLB. A request for shared TLB access is initiated. + +To identify the DTLB miss, the following conditions need to be fulfilled: + +* Address translation for load and stores must be enabled. +* There must be an access request to the DTLB. +* The DTLB should indicate a DTLB miss. + +In the case of a DTLB miss, the same logic is employed as described for an ITLB miss. + +.. raw:: html + + Tag Comparison + +Shared TLB lookup for a hit occurs under the same conditions as described for the TLB modules used as ITLB and DTLB. However, there are some distinctions. In both the ITLB and DTLB, the virtual address requiring translation is compared against all TLB entries. In contrast, the shared TLB only compares the tag and content of the set indicated by the provided virtual page number. The index of the set is extracted from VPN0 of the requested virtual address. Given that the shared TLB is 2-way associative, each set contains two entries. Consequently, both of these entries are compared. Below figure illustrates how the set is opted for the lookup. + +.. figure:: ../images/shared_tlb_set.png + :name: **Figure 16:** Set opted for lookup in shared TLB + :align: center + :width: 60% + :alt: shared_tlb_set + + **Figure 16:** Set opted for lookup in shared TLB + +.. raw:: html + + Update and Flush + +Differing from the ITLB and DTLB, a specific virtual address or addressing space cannot be flushed in the shared TLB. When SFENCE.VMA is committed, all entries in the shared TLB are invalidated. (Cases of SFENCE.VMA should also be added in shared TLB) + +.. raw:: html + + Updating Shared TLB + +When the Page Table Walker signals a valid update request, the shared TLB is updated by selecting an entry through the replacement policy and marking it as valid. This also triggers the writing of the new tag and content to the respective SRAM. + +.. raw:: html + + Replacement Policy Implemented in CVA6 Shared TLB + +In CVA6's shared TLB, two replacement policies are employed for replacements based on a specific condition. These replacement policies select the entry within the set indicated by the virtual page number. The two policies are: + +* First non-valid encounter replacement policy +* Random replacement policy + +First replacement policy failed if all ways are valid. Therefore, a random replacement policy is opted for. + +.. raw:: html + + First non-valid encounter replacement policy + +The module implemented in CVA6 to find the first non-valid entry in the shared TLB is the Leading Zero Counter (LZC). It takes three parameters as input: + +1. **WIDTH:** The width of the input vector. +2. **MODE:** Mode selection - 0 for trailing zero, 1 for leading zero. +3. **CNT WIDTH:** Width of the output signal containing the zero count. + +The input signal is the vector to be counted, and the output represents the count of trailing/leading zeros. If all bits in the input vector are zero, it will also be indicated. + +When initializing the module, the width of the input vector is set to the number of shared TLB ways. The trailing zero counter mode is selected. The vector of valid bits is set as the input vector, but with negation. This is because we want the index of the first non-valid entry, and LZC returns the count of trailing zeros, which actually corresponds to the index of the first occurrence of 1 from the least significant bit (LSB). if there is at least one non-valid entry, that entry is opted for the replacement, and If not then this is signaled by LZC. + +.. figure:: ../images/LZC.png + :name: **Figure 17:** Replacement of First invalid entry. + :align: center + :width: 60% + :alt: LZC + + **Figure 17:** Replacement of First invalid entry. + +.. raw:: html + + Random replacement policy + +If all ways are valid, a random replacement policy is employed for the replacement process. The Linear Feedback Shift Register (LFSR) is utilized to select the replacement entry randomly. LFSR is commonly used in generating sequences of pseudo-random numbers. When the enable signal is active, the current state of the LFSR undergoes a transformation. Specifically, the state is shifted right by one bit, and the result is combined with a predetermined masking pattern. This masking pattern is derived from the predefined “Masks” array, introducing a non-linear behavior to the sequence generation of the LFSR. The masking process involves XOR operations between the shifted state bits and specific pattern bits, contributing to the complexity and unpredictability of the generated sequence. + +.. figure:: ../images/RR.png + :name: **Figure 18:** Entry selection for replacement using LFSR + :align: center + :width: 95% + :alt: RR + + **Figure 18:** Entry selection for replacement using LFSR + +----------------- +Page Table Walker +----------------- + +The "CVA6 Page Table Walker (PTW) for MMU Sv32" is a hardware module developed for the CV32A6 processor architecture, designed to facilitate the translation of virtual addresses into physical addresses, a crucial task in memory access management. + +.. figure:: ../images/ptw_in_out.png + :name: **Figure 19:** Input and Outputs of Page Table Walker + :align: center + :width: 60% + :alt: ptw_in_out + + **Figure 19:** Input and Outputs of Page Table Walker + +.. raw:: html + + Operation of PTW Module + +The PTW module operates through various states, each with its specific function, such as handling memory access requests, validating page table entries, and responding to errors. + +.. raw:: html + + Key Features and Capabilities + +Key features of this PTW module include support for two levels of page tables (LVL1 and LVL2) in the Sv32 standard, accommodating instruction and data page table walks. It rigorously validates and verifies page table entries (PTEs) to ensure translation accuracy and adherence to access permissions. This module seamlessly integrates with the CV32A6 processor's memory management unit (MMU), which governs memory access control. It also takes into account global mapping, access flags, and privilege levels during the translation process, ensuring that memory access adheres to the processor's security and privilege settings. + +.. raw:: html + + Exception Handling + +In addition to its translation capabilities, the PTW module is equipped to detect and manage errors, including page-fault exceptions and access exceptions, contributing to the robustness of the memory access system. It works harmoniously with physical memory protection (PMP) configurations, a critical aspect of modern processors' memory security. Moreover, the module efficiently processes virtual addresses, generating corresponding physical addresses, all while maintaining speculative translation, a feature essential for preserving processor performance during memory access operations. + +.. raw:: html + + Signal Description + +.. raw:: html + +

Table 12: Signal Description of PTW

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - IO + - Connection + - Type + - Description + + * - ``clk_i`` + - in + - Subsystem + - logic + - Subsystem Clock + + * - ``rst_ni`` + - in + - Subsystem + - logic + - Asynchronous reset active low + + * - ``flush_i`` + - in + - Controller + - logic + - Sfence Committed + + * - ``ptw_active_o`` + - out + - MMU + - logic + - Output signal indicating whether the Page Table Walker (PTW) is currently active + + * - ``walking_instr_o`` + - out + - MMU + - logic + - Indicating it's an instruction page table walk or not + + * - ``ptw_error_o`` + - out + - MMU + - logic + - Output signal indicating that an error occurred during PTW operation + + * - ``ptw_access_exception_o`` + - out + - MMU + - logic + - Output signal indicating that a PMP (Physical Memory Protection) access exception occurred during PTW operation. + + * - ``lsu_is_store_i`` + - in + - Store Unit + - logic + - Input signal indicating whether the translation was triggered by a store operation. + + * - ``req_port_i`` + - in + - Cache Subsystem + - dcache_req_o_t + - D Cache Data Requests + + * - ``req_port_o`` + - out + - Cache Subsystem / Perf Counter + - dcache_req_u_t + - D Cache Data Response + + * - ``shared_tlb_update_o`` + - out + - Shared TLB + - tlb_update_sv32_t + - Updated tag and content of shared TLB + + * - ``update_vaddr_o`` + - out + - MMU + - logic[riscv::VLEN-1:0] + - Updated VADDR from shared TLB + + * - ``asid_i`` + - in + - CSR RegFile + - logic[ASID_WIDTH-1:0] + - ASID for the lookup + + * - ``shared_tlb_access_i`` + - in + - Shared TLB + - logic + - Access request of shared TLB + + * - ``shared_tlb_hit_i`` + - in + - Shared TLB + - logic + - Indicate shared TLB hit + + * - ``shared_tlb_vaddr_i`` + - in + - Shared TLB + - logic[riscv::VLEN-1:0] + - Virtual Address from shared TLB + + * - ``itlb_req_i`` + - in + - Shared TLB + - logic + - Indicate request to ITLB + + * - ``satp_ppn_i`` + - in + - CSR RegFile + - logic[riscv::PPNW-1:0] + - PPN of top level page table from SATP register + + * - ``mxr_i`` + - in + - CSR RegFile + - logic + - Make Executable Readable bit in xSTATUS CSR register + + * - ``shared_tlb_miss_o`` + - out + - OPEN + - logic + - Indicate a shared TLB miss + + * - ``pmpcfg_i`` + - in + - CSR RegFile + - riscv::pmpcfg_t[15:0] + - PMP configuration + + * - ``pmpaddr_i`` + - in + - CSR RegFile + - logic[15:0][riscv::PLEN-3:0] + - PMP Address + + * - ``bad_paddr_o`` + - out + - MMU + - logic[riscv::PLEN-1:0] + - Bad Physical Address in case of access exception + +.. raw:: html + + Struct Description + +.. raw:: html + +

Table 13: D Cache Response Struct (dcache_req_i_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``address_index`` + - logic [DCACHE_INDEX_WIDTH-1:0] + - Index of the Dcache Line + + * - ``address_tag`` + - logic [DCACHE_TAG_WIDTH-1:0] + - Tag of the Dcache Line + + * - ``data_wdata`` + - riscv::xlen_t + - Data to write in the Dcache + + * - ``data_wuser`` + - logic [DCACHE_USER_WIDTH-1:0] + - data_wuser + + * - ``data_req`` + - logic + - Data Request + + * - ``data_we`` + - logic + - Data Write enabled + + * - ``data_be`` + - logic [(riscv::XLEN/8)-1:0] + - Data Byte enable + + * - ``data_size`` + - logic [1:0] + - Size of data + + * - ``data_id`` + - logic [DCACHE_TID_WIDTH-1:0] + - Data ID + + * - ``kill_req`` + - logic + - Kill the D cache request + + * - ``tag_valid`` + - logic + - Indicate that teh tag is valid + +.. raw:: html + +

Table 14: D Cache Request Struct (dcache_req_o_t)

+ +.. list-table:: + :header-rows: 1 + + * - Signal + - Type + - Description + + * - ``data_gnt`` + - logic + - Grant of data is given in response to the data request + + * - ``data_rvalid`` + - logic + - Indicate that data is valid which is sent by D cache + + * - ``data_rid`` + - logic [DCACHE_TID_WIDTH-1:0] + - Requested data ID + + * - ``data_rdata`` + - riscv::xlen_t + - Data from D cache + + * - ``data_ruser`` + - logic [DCACHE_USER_WIDTH-1:0] + - Requested data user + +.. raw:: html + + PTW State Machine + +Page Table Walker is implemented as a finite state machine. It listens to shared TLB for incoming translation requests. If there is a shared TLB miss, it saves the virtual address and starts the page table walk. Page table walker transition between 7 states in CVA6. + +* **IDLE:** The initial state where the PTW is awaiting a trigger, often a Shared TLB miss, to initiate a memory access request. +* **WAIT_GRANT:** Request memory access and wait for data grant +* **PTE_LOOKUP:** Once granted access, the PTW examines the valid Page Table Entry (PTE), checking attributes to determine the appropriate course of action. +* **PROPOGATE_ERROR:** If the PTE is invalid, this state handles the propagation of an error, often leading to a page-fault exception due to non-compliance with access conditions +* **PROPOGATE_ACCESS_ERROR:** Propagate access fault if access is not allowed from a PMP perspective +* **WAIT_RVALID:** After processing a PTE, the PTW waits for a valid data signal, indicating that relevant data is ready for further processing. +* **LATENCY:** Introduces a delay to account for synchronization or timing requirements between states. + +.. figure:: ../images/ptw_state_diagram.png + :name: **Figure 20:** State Machine Diagram of CVA6 PTW + :align: center + :width: 95% + :alt: ptw_state_diagram + + **Figure 20:** State Machine Diagram of CVA6 PTW + +.. raw:: html + + IDLE state + +In the IDLE state of the Page Table Walker (PTW) finite state machine, the system awaits a trigger to initiate the page table walk process. This trigger is often prompted by a Shared Translation Lookaside Buffer (TLB) miss, indicating that the required translation is not present in the shared TLB cache. The PTW's behavior in this state is explained as follows: + +1. The top-most page table is selected for the page table walk. In the case of SV32, which implements a two-level page table, the level 1 page table is chosen. +2. In the IDLE state, translations are assumed to be invalid in all addressing spaces. +3. The signal indicating the instruction page table walk is set to 0. +4. A conditional check is performed: if there is a shared TLB access request and the entry is not found in the shared TLB (indicating a shared TLB miss), the following steps are executed: + + a. The address of the desired Page Table Entry within the level 1 page table is calculated by multiplying the Physical Page Number (PPN) of the level 1 page table from the SATP register by the page size (4kB). This result is then added to the product of the Virtual Page Number (VPN1), and the size of a page table entry(4 bytes). + +.. figure:: ../images/ptw_idle.png + :name: **Figure 21:** Address of Desired PTE at Level 1 + :align: center + :width: 68% + :alt: ptw_idle + + **Figure 21:** Address of Desired PTE at Level 1 + +.. _example: + + b. The signal indicating whether it's an instruction page table walk is updated based on the ITLB miss. + c. The ASID and virtual address are saved for the page table walk. + d. A shared TLB miss is indicated. + +.. raw:: html + + WAIT GRANT state + +In the **WAIT_GRANT** state of the Page Table Walker's finite state machine, a data request is sent to retrieve memory information. It waits for a data grant signal from the Dcache controller, remaining in this state until granted. Once granted, it activates a tag valid signal, marking data validity. The state then transitions to "PTE_LOOKUP" for page table entry lookup. + +.. raw:: html + + PTE LOOKUP state + +In the **PTE_LOOKUP** state of the Page Table Walker (PTW) finite state machine, the PTW performs the actual lookup and evaluation of the page table entry (PTE) based on the virtual address translation. The behavior and operations performed in this state are detailed as follows: + +1. The state waits for a valid signal indicating that the data from the memory subsystem, specifically the page table entry, is available for processing. +2. Upon receiving the valid signal, the PTW proceeds with examining the retrieved page table entry to determine its properties and validity. +3. The state checks if the global mapping bit in the PTE is set, and if so, sets the global mapping signal to indicate that the translation applies globally across all address spaces. +4. The state distinguishes between two cases: Invalid PTE and Valid PTE. + + a. If the valid bit of the PTE is not set, or if the PTE has reserved RWX field encodings, it signifies an Invalid PTE. In such cases, the state transitions to the "PROPAGATE_ERROR" state, indicating a page-fault exception due to an invalid translation. + +.. figure:: ../images/ptw_pte_1.png + :name: **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault + :align: center + :width: 70% + :alt: ptw_pte_1 + + **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault + +.. _example1: + + b. If the PTE is valid, the state advances to the "LATENCY" state, indicating a period of processing latency. Additionally, if the "read" flag (pte.r) or the "execute" flag (pte.x) is set, the PTE is considered valid. + +5. Within the Valid PTE scenario, the state performs further checks based on whether the translation is intended for instruction fetching or data access: + + a. For instruction page table walk, if the page is not executable (pte.x is not set) or not marked as accessible (pte.a is not set), the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_iptw.png + :name: **Figure 23:** For Instruction Page Table Walk + :align: center + :width: 70% + :alt: ptw_iptw + + **Figure 23:** For Instruction Page Table Walk + +.. _example2: + + b. For data page table walk, the state checks if the page is readable (pte.r is set) or if the page is executable only but made readable by setting the MXR bit in xSTATUS CSR register. If either condition is met, it indicates a valid translation. If not, the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_dptw.png + :name: **Figure 24:** Data Access Page Table Walk + :width: 70% + :alt: ptw_dptw + + **Figure 24:** Data Access Page Table Walk + +.. _example3: + + c. If the access is intended for storing data, additional checks are performed: If the page is not writable (pte.w is not set) or if it is not marked as dirty (pte.d is not set), the state transitions to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_dptw_s.png + :name: **Figure 25:** Data Access Page Table Walk, Store requested + :align: center + :width: 70% + :alt: ptw_dptw_s + + **Figure 25:** Data Access Page Table Walk, Store requested + +6. The state also checks for potential misalignment issues in the translation: If the current page table level is the first level (LVL1) and if the PPN0 of in PTE is not zero, it indicates a misaligned superpage, leading to a transition to the "PROPAGATE_ERROR" state. + +.. figure:: ../images/ptw_mis_sup.png + :name: **Figure 26:** Misaligned Superpage Check + :align: center + :width: 70% + :alt: ptw_mis_sup + + **Figure 26:** Misaligned Superpage Check + +7. If the PTE is valid but the page is neither readable nor executable, the PTW recognizes the PTE as a pointer to the next level of the page table, indicating that additional translation information can be found in the referenced page table at a lower level. +8. If the current page table level is the first level (LVL1), the PTW proceeds to switch to the second level (LVL2) page table, updating the next level pointer and calculating the address for the next page table entry using the Physical Page Number from the PTE and the index of the level 2 page table from virtual address. + +.. figure:: ../images/ptw_nlvl.png + :name: **Figure 27:** Address of desired PTE at next level of Page Table + :align: center + :width: 70% + :alt: ptw_nlvl + + **Figure 27:** Address of desired PTE at next level of Page Table + +9. The state then transitions to the "WAIT_GRANT" state, indicating that the PTW is awaiting the grant signal to proceed with requesting the next level page table entry. +10. If the current level is already the second level (LVL2), an error is flagged, and the state transitions to the "PROPAGATE_ERROR" state, signifying an unexpected situation where the PTW is already at the last level page table. +11. If the translation access is found to be restricted by the Physical Memory Protection (PMP) settings (allow_access is false), the state updates the shared TLB update signal to indicate that the TLB entry should not be updated. Additionally, the saved address for the page table walk is restored to its previous value, and the state transitions to the "PROPAGATE_ACCESS_ERROR" state. +12. Lastly, if the data request for the page table entry was granted, the state indicates to the cache subsystem that the tag associated with the data is now valid. + +.. figure:: ../images/ptw_pte_flowchart.png + :name: **Figure 28:** Flow Chart of PTE LOOKUP State + :align: center + :alt: ptw_pte_flowchart + + **Figure 28:** Flow Chart of PTE LOOKUP State + +.. raw:: html + + PROPAGATE ERROR state + +This state indicates a detected error in the page table walk process, and an error signal is asserted to indicate the Page Table Walker's error condition, triggering a transition to the "LATENCY" state for error signal propagation. + +.. raw:: html + + PROPAGATE ACCESS ERROR state + +This state indicates a detected access error in the page table walk process, and an access error signal is asserted to indicate the Page Table Walker's access error condition, triggering a transition to the "LATENCY" state for access error signal propagation. + +.. raw:: html + + WAIT RVALID state + +This state waits until it gets the "read valid" signal, and when it does, it's ready to start a new page table walk. + +.. raw:: html + + LATENCY state + +The LATENCY state introduces a latency period to allow for necessary system actions or signals to stabilize. After the latency period, the FSM transitions back to the IDLE state, indicating that the system is prepared for a new translation request. + +.. raw:: html + + Flush Scenario + +The first step when a flush is triggered is to check whether the Page Table Entry (PTE) lookup process is currently in progress. If the PTW (Page Table Walker) module is indeed in the middle of a PTE lookup operation, the code then proceeds to evaluate a specific aspect of this operation. + +* **Check for Data Validity (rvalid):** Within the PTE lookup operation, it's important to ensure that the data being used for the translation is valid. In other words, the code checks whether the "rvalid" signal (which likely indicates the validity of the data) is not active. If the data is not yet valid, it implies that the PTW module is waiting for the data to become valid before completing the lookup. In such a case, the code takes appropriate action to wait for the data to become valid before proceeding further. + +* **Check for Waiting on Grant:** The second condition the code checks for during a flush scenario is whether the PTW module is currently waiting for a "grant." This "grant" signal is typically used to indicate permission or authorization to proceed with an operation. If the PTW module is indeed in a state of waiting for this grant signal, it implies that it requires authorization before continuing its task. + + * **Waiting for Grant:** If the PTW module is in a state of waiting for the grant signal, the code ensures that it continues to wait for the grant signal to be asserted before proceeding further. + +* **Return to Idle State if Neither Condition is Met:** After evaluating the above two conditions, the code determines whether either of these conditions is true. If neither of these conditions applies, it suggests that the PTW module can return to its idle state, indicating that it can continue normal operations without any dependencies on the flush condition. + +PMA/PMP Checks +============== + + CVXIF_fu ======== diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index bb221cac24..b3445a1893 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -53,30 +53,14 @@ Submodules ID_STAGE submodules -Compressed_decoder -~~~~~~~~~~~~~~~~~~ - -The compressed_decoder module decompresses all the compressed -instructions taking a 16-bit compressed instruction and expanding it -to its 32-bit equivalent. -All compressed instructions have a 32-bit equivalent. - -.. include:: port_compressed_decoder.rst - Decoder ~~~~~~~ -The decoder module takes the output of compressed_decoder module and decodes -it. -It transforms the instruction to the most fundamental control structure -in pipeline, a scoreboard entry. +TO BE COMPLETED -The scoreboard entry contains an exception entry which is composed of a -valid field, a cause and a value called TVAL. -As TVALEn configuration parameter is zero, the TVAL field is not implemented. -A potential illegal instruction exception can be detected during decoding. -If no exception has happened previously in fetch stage, the decoder will -valid the exception and add the cause and tval value to the scoreboard entry. -.. include:: port_decoder.rst +Compressed_decoder +~~~~~~~~~~~~~~~~~~ + +TO BE COMPLETED diff --git a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst index 34846dc383..6186ce461d 100644 --- a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst @@ -56,11 +56,8 @@ Scoreboard TO BE COMPLETED -.. include:: port_scoreboard.rst Issue_read_operands ~~~~~~~~~~~~~~~~~~~ TO BE COMPLETED - -.. include:: port_issue_read_operands.rst From 228ec7c194fcfbd1cc579532dfbe922fb762cd4f Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Mon, 12 Feb 2024 13:28:45 +0100 Subject: [PATCH 04/20] Remove MMU description as it is not supported in CV32A65X --- .../source/cv32a6_execute.rst | 1575 ----------------- 1 file changed, 1575 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index c5a9b49636..18a0921a23 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -81,1581 +81,6 @@ TO BE COMPLETED load_store_unit submodules ----------------------- -Memory Management Unit ----------------------- - -.. figure:: ../images/load_store_unit_modules.png - :name: load_store_unit submodules - :align: center - :alt: - - load_store_unit submodules - ----------- -store_unit ----------- - -TO BE COMPLETED - - ---------- -load unit ---------- - -TO BE COMPLETED - - ----------- -lsu_bypass ----------- - -TO BE COMPLETED - - - -CVXIF_fu -======== - -.. raw:: html - -

Table 1: CVA6 MMU SV32 Input Output Signals

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection Type - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Sfence Committed - - * - ``enable_translation_i`` - - in - - CSR RegFile - - logic - - Indicate address translation request for instruction - - * - ``en_ld_st_translation_i`` - - in - - CSR RegFile - - logic - - Indicate address translation request for load or store - - * - ``icache_areq_i`` - - in - - Cache Subsystem - - icache_arsp_t - - Icache Response - - * - ``icache_areq_o`` - - out - - Cache Subsystem - - icache_areq_t - - Icache Request - - * - ``misaligned_ex_i`` - - in - - Load Store Unit - - exception_t - - Indicate misaligned exception - - * - ``lsu_req_i`` - - in - - Load Store Unit - - logic - - Request address translation - - * - ``lsu_vaddr_i`` - - in - - Load Store Unit - - logic [riscv::VLEN-1:0] - - Virtual Address In - - * - ``lsu_is_store_i`` - - in - - Store Unit - - logic - - Translation is requested by a store - - * - ``lsu_dtlb_hit_o`` - - out - - Store / Load Unit - - logic - - Indicate a DTLB hit - - * - ``lsu_dtlb_ppn_o`` - - out - - Load Unit - - logic [riscv::PPNW-1:0] - - Send PNN to LSU - - * - ``lsu_valid_o`` - - out - - Load Store Unit - - logic - - Indicate a valid translation - - * - ``lsu_paddr_o`` - - out - - Store / Load Unit - - logic [riscv::PLEN-1:0] - - Translated Address - - * - ``lsu_exception_o`` - - out - - Store / Load Unit - - exception_t - - Address Translation threw an exception - - * - ``priv_lvl_i`` - - in - - CSR RegFile - - riscv::priv_lvl_t - - Privilege level for instruction fetch interface - - * - ``ld_st_priv_lvl_i`` - - in - - CSR RegFile - - riscv::priv_lvl_t - - Privilege Level for Data Interface - - * - ``sum_i`` - - in - - CSR RegFile - - logic - - Supervisor User Memory Access bit in xSTATUS CSR register - - * - ``mxr_i`` - - in - - CSR RegFile - - logic - - Make Executable Readable bit in xSTATUS CSR register - - * - ``satp_ppn_I`` - - in - - CSR RegFile - - logic [riscv::PPNW-1:0] - - PPN of top level page table from SATP register - - * - ``asid_i`` - - in - - CSR RegFile - - logic [ASID_WIDTH-1:0] - - ASID to for the lookup - - * - ``asid_to_be_flushed`` - - in - - Execute Stage - - logic [ASID_WIDTH-1:0] - - ASID of the entry to be flushed. - - * - ``vaddr_to_be_flushed_i`` - - in - - Execute Stage - - logic [riscv::VLEN-1:0] - - Virtual address of the entry to be flushed. - - * - ``flush_tlb_i`` - - in - - Controller - - logic - - SFENCE.VMA committed - - * - ``itlb_miss_o`` - - out - - Performance Counter - - logic - - Indicate an ITLB miss - - * - ``dtlb_miss_o`` - - out - - Performance Counter - - logic - - Indicate a DTLB miss - - * - ``req_port_i`` - - in - - Cache Subsystem - - dcache_req_o_t - - D Cache Data Requests - - * - ``req_port_o`` - - out - - Cache Subsystem - - dcache_req_i_t - - D Cache Data Response - - * - ``pmpcfg_i`` - - in - - CSR RegFile - - riscv::pmpcfg_t [15:0] - - PMP configurations - - * - ``pmpaddr_i`` - - in - - CSR RegFile - - logic [15:0][riscv::PLEN-3:0] - - PMP Address - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 2: I Cache Request Struct (icache_areq_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``fetch_valid`` - - logic - - Address Translation Valid - - * - ``fetch_paddr`` - - logic [riscv::PLEN-1:0] - - Physical Address In - - * - ``fetch_exception`` - - exception_t - - Exception occurred during fetch - -.. raw:: html - -

Table 3: I Cache Response Struct (icache_arsq_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``fetch_req`` - - logic - - Address Translation Request - - * - ``fetch_vaddr`` - - logic [riscv::VLEN-1:0] - - Virtual Address out - -.. raw:: html - -

Table 4: Exception Struct (exception_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``cause`` - - riscv::xlen_t - - Cause of exception - - * - ``tval`` - - riscv::xlen_t - - Additional information of causing exception (e.g. instruction causing it), address of LD/ST fault - - * - ``valid`` - - logic - - Indicate that exception is valid - -.. raw:: html - -

Table 5: PMP Configuration Struct (pmpcfg_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``locked`` - - logic - - Lock this configuration - - * - ``reserved`` - - logic[1:0] - - Reserved bits in pmpcfg CSR - - * - ``addr_mode`` - - pmp_addr_mode_t - - Addressing Modes: OFF, TOR, NA4, NAPOT - - * - ``access_type`` - - pmpcfg_access_t - - None, read, write, execute - -.. raw:: html - - Control Flow in MMU SV32 Module - -.. figure:: ../images/mmu_control_flow.png - :name: **Figure 3:** Control Flow in CVA6 MMU SV32 - :align: center - :width: 95% - :alt: mmu_control_flow - - **Figure 3:** Control Flow in CVA6 MMU SV32 - -.. raw:: html - - Exception Sources with Address Translation Enabled - -Two potential exception sources exist: - -* Hardware Page Table Walker (HPTW) throwing an exception, signifying a page fault exception. -* Access error due to insufficient permissions of PMP, known as an access exception. - -.. raw:: html - - Instruction Fetch Interface - -The IF stage initiates a request to retrieve memory content at a specific virtual address. When the MMU is disabled, the instruction fetch request is directly passed to the I$ without modifications. - -.. raw:: html - - Address Translation in Instruction Interface - -If virtual memory translation is enabled for instruction fetches, the following operations are performed in the instruction interface: - -* Compatibility of requested virtual address with selected page based address translation scheme is checked. -* For 4K page translation, the module determines the fetch physical address by combining the physical page number (PPN) from ITLB content and the offset from the virtual address. -* In the case of Mega page translation, if the ITLB indicates a 4M page, the VPN0 from the fetch virtual address is written to the PPN0 of the fetch physical address to ensure alignment for superpage translation. -* If the Instruction TLB (ITLB) lookup hits, the fetch valid signal (which indicates a valid physical address) is activated in response to the input fetch request. Memory region accessibility is checked from the perspective of the fetch operation, potentially triggering a page fault exception in case of an access error or insufficient PMP permission. -* In case of an ITLB miss, if the page table walker (PTW) is active (only active if there is a shared TLB miss) and handling instruction fetches, the fetch valid signal is determined based on PTW errors or access exceptions. - -If the fetch physical address doesn't match any execute region, an Instruction Access Fault is raised. When not translating, PMPs are immediately checked against the physical address for access verification. - -.. raw:: html - - Data Interface - -.. raw:: html - - Address Translation in Data Interface - -If address translation is enabled for load or store, and no misaligned exception has occurred, the following operations are performed in the data interface: - -* Initially, translation is assumed to be invalid, signified by the MMU to LSU. -* The translated physical address is formed by combining the PPN from the Page Table Entry (PTE) and the offset from the virtual address requiring translation. This send one cycle later due to the additional bank of registers which delayed the MMU’s answer. The PPN from the PTE is also shared separately with LSU in the same cycle as the hit. -* In the case of superpage translation, as in SV32, known as the 4M page, PPN0 of the translated physical address and the separately shared PPN are updated with the VPN0 of the virtual address. - -If a Data TLB (DTLB) hit occurs, it indicates a valid translation, and various fault checks are performed depending on whether it's a load or store request. - -* For store requests, if the page is not writable, the dirty flag isn't set, or privileges are violated, it results in a page fault corresponding to the store access. If PMPs are also violated, it leads to an access fault corresponding to the store access. Page faults take precedence over access faults. -* For load requests, a page fault is triggered if there are insufficient access privileges. PMPs are checked again during load access, resulting in an access fault corresponding to load access if PMPs are violated. - -In case of a DTLB miss, potential exceptions are monitored during the page table walk. If the PTW indicates a page fault, the corresponding page fault related to the requested type is signaled. If the PTW indicates an access exception, the load access fault is indicated through address translation because the page table walker can only throw load access faults. - -.. raw:: html - - Address Translation is Disabled - -When address translation is not enabled, the physical address is immediately checked against Physical Memory Protections (PMPs). If there is a request from LSU, no misaligned exception, and PMPs are violated, it results in an access fault corresponding to the request being indicated. - ----------------------------- -Translation Lookaside Buffer ----------------------------- - -Page tables are accessed for translating virtual memory addresses to physical memory addresses. This translation needs to be carried out for every load and store instruction and also for every instruction fetch. Since page tables are resident in physical memory, accessing these tables in all these situations has a significant impact on performance. Page table accesses occur in patterns that are closely related in time. Furthermore, the spatial and temporal locality of data accesses or instruction fetches mean that the same page is referenced repeatedly. Taking advantage of these access patterns the processor keeps the information of recent address translations, to enable fast retrieval, in a small cache called the Translation Lookaside Buffer (TLB) or an address-translation cache. - -The CVA6 TLB is structured as a fully associative cache, where the virtual address that needs to be translated is compared against all the individual TLB entries. Given a virtual address, the processor examines the TLB (TLB lookup) to determine if the virtual page number (VPN) of the page being accessed is in the TLB. When a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is used to calculate the target physical address. If no TLB entry is found (TLB miss) the processor has to read individual page table entries from memory (Table walk). In CVA6 table walking is supported by dedicated hardware. Once the processor finishes the table walk it has the Physical Page Number (PPN) corresponding to the Virtual Page Number (VPN) That needs to be translated. The processor adds an entry for this address translation to the TLB so future translations of that virtual address will happen quickly through the TLB. During the table walk the processor may find out that the corresponding physical page is not resident in memory. At this stage a page table exception (Page Fault) is generated which gets handled by the operating system. The operating system places the appropriate page in memory, updates the appropriate page tables and returns execution to the instruction which generated the exception. - -The inputs and output signals of the TLB are shown in the following two figures. - -.. figure:: ../images/in_out_tlb.png - :name: **Figure 4:** Inputs and Outputs of CVA6 TLB - :align: center - :width: 65% - :alt: in_out_tlb - - **Figure 4:** Inputs and Outputs of CVA6 TLB - -.. raw:: html - - Signal Description of TLB - -.. raw:: html - -

Table 6: CVA6 TLB Input Output Signals

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - connection - - Type - - Description - - * - ``clk_i`` - - in - - SUBSYSTEM - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - SUBSYSTEM - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Asynchronous reset active low - - * - ``update_i`` - - in - - Shared TLB - - tlb_update_sv32_t - - Updated tag and content of TLB - - * - ``lu_access_i`` - - in - - Cache Subsystem - - logic - - Signal indicating a lookup access is being requested - - * - ``lu_asid_i`` - - in - - CSR RegFile - - logic[ASID_WIDTH-1:0] - - ASID (Address Space Identifier) for the lookup - - * - ``lu_vaddr_i`` - - in - - Cache Subsystem - - logic[riscv::VLEN-1:0] - - Virtual address for the lookup - - * - ``lu_content_o`` - - out - - MMU SV32 - - riscv::pte_sv32_t - - Output for the content of the TLB entry - - * - ``asid_to_be_flushed_i`` - - in - - Execute Stage - - logic[ASID_WIDTH-1:0] - - ASID of the entry to be flushed - - * - ``vaddr_to_be_flushed_i`` - - in - - Execute Stage - - logic[riscv::VLEN-1:0] - - Virtual address of the entry to be flushed - - * - ``lu_is_4M_o`` - - out - - MMU SV32 - - logic - - Output indicating whether the TLB entry corresponds to a 4MB page - - * - ``lu_hit_o`` - - out - - MMU SV32 - - logic - - Output indicating whether the lookup resulted in a hit or miss - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 7: SV32 TLB Update Struct (tlb_update_sv32_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``valid`` - - logic - - Indicates whether the TLB update entry is valid or not - - * - ``is_4M`` - - logic - - Indicates if the TLB entry corresponds to a 4MB page - - * - ``vpn`` - - logic[19:0] - - Virtual Page Number (VPN) used for updating the TLB, consisting of 20 bits - - * - ``asid`` - - logic[8:0] - - Address Space Identifier (ASID) used for updating the TLB, with a length of 9 bits for Sv32 MMU - - * - ``content`` - - riscv::pte_sv32_t - - Content of the TLB update entry, defined by the structure - -.. raw:: html - -

Table 8: SV32 PTE Struct (riscv::pte_sv32_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``ppn`` - - logic[21:0] - - 22 bit Physical Page Number (PPN) - - * - ``rsw`` - - logic[1:0] - - Reserved for use by supervisor software - - * - ``d`` - - logic - - | Dirty bit indicating whether the page has been modified (dirty) or not - | 0: Page is clean i.e., has not been written - | 1: Page is dirty i.e., has been written - - * - ``a`` - - logic - - | Accessed bit indicating whether the page has been accessed - | 0: Virtual page has not been accessed since the last time A bit was cleared - | 1: Virtual page has been read, written, or fetched from since the last time the A bit was cleared - - * - ``g`` - - logic - - | Global bit marking a page as part of a global address space valid for all ASIDs - | 0: Translation is valid for specific ASID - | 1: Translation is valid for all ASIDs - - * - ``u`` - - logic - - | User bit indicating privilege level of the page - | 0: Page is not accessible in user mode but in supervisor mode - | 1: Page is accessible in user mode but not in supervisor mode - - * - ``x`` - - logic - - | Execute bit which allows execution of code from the page - | 0: Code execution is not allowed - | 1: Code execution is permitted - - * - ``w`` - - logic - - | Write bit allows the page to be written - | 0: Write operations are not allowed - | 1: Write operations are permitted - - * - ``r`` - - logic - - | Read bit allows read access to the page - | 0: Read operations are not allowed - | 1: Read operations are permitted - - * - ``v`` - - logic - - | Valid bit indicating the page table entry is valid - | 0: Page is invalid i.e. page is not in DRAM, translation is not valid - | 1: Page is valid i.e. page resides in the DRAM, translation is valid - -.. raw:: html - - TLB Entry Fields - -The number of TLB entries can be changed via a design parameter. In 32-bit configurations of CVA6 only 2 TLB entries are instantiated. Each TLB entry is made up of two fields: Tag and Content. The Tag field holds the virtual page number (VPN1, VPN0), ASID, page size (is_4M) along with a valid bit (VALID) indicating that the entry is valid. The SV32 virtual page number, which is supported by CV32A6X, is further split into two separate virtual page numbers VPN1 and VPN0. The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. Note that the V bit in the Content field is the V bit which is present in the page table in memory. It is copied from the page table, as is, and the VALID bit in the Tag is set based on its value.The TLB entry fields are shown in **Figure 2**. - -.. figure:: ../images/cva6_tlb_entry.png - :name: **Figure 5:** Fields in CVA6 TLB entry - :align: center - :width: 80% - :alt: cva6_tlb_entry - - **Figure 5:** Fields in CVA6 TLB entry - -.. raw:: html - - CVA6 TLB Management / Implementation - -The CVA6 TLB implements the following three functions: - -* **Translation:** This function implements the address lookup and match logic. -* **Update and Flush:** This function implements the update and flush logic. -* **Pseudo Least Recently Used Replacement Policy:** This function implements the replacement policy for TLB entries. - -.. raw:: html - - Translation - -This function takes in the virtual address and certain other fields, examines the TLB to determine if the virtual page number of the page being accessed is in the TLB or not. If a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is then used to calculate the target physical address. The following checks are done as part of this lookup function to find a match in the TLB: - -* **Validity Check:** For a TLB hit, the associated TLB entry must be valid . -* **ASID and Global Flag Check:** The TLB entry's ASID must match the given ASID (ASID associated with the Virtual address). If the TLB entry’s Global bit (G) bit is set then this check is not done. This ensures that the translation is either specific to the provided ASID or it is globally applicable. -* **Level 1 VPN match:** SV32 implements a two-level page table. As such the virtual address is broken up into three parts which are the virtual page number 1, virtual page number 0 and displacement. So the condition that is checked next is that the virtual page number 1 of the virtual address matches the virtual page number 1(VPN1) of the TLB entry. -* **Level 0 VPN match or 4-Mega Page:** The last condition to be checked, for a TLB hit, is that the virtual page number 0 of the virtual address matches the virtual page number 0 of the TLB entry (VPN0). This match is ignored if the is_4M bit in the Tag is set which implies a super 4M page. - -All the conditions listed above are checked against every TLB entry. If there is a TLB hit then the corresponding bit in the hit array is set. **Figure 3** Illustrates the TLB hit/miss process listed above. - -.. figure:: ../images/cva6_tlb_hit.png - :name: **Figure 6:** Block diagram of CVA6 TLB hit or miss - :align: center - :width: 75% - :alt: cva6_tlb_hit - - **Figure 6:** Block diagram of CVA6 TLB hit or miss - -.. raw:: html - - Flushing TLB entries - -The SFENCE.VMA instruction can be used with certain specific source register specifiers (rs1 & rs2) to flush a specific TLB entry, some set of TLB entries or all TLB entries. Like all instructions this action only takes place when the SFENCE.VMA instruction is committed (shown via the commit_sfence signal in the following figures.) The behavior of the instruction is as follows: - -* **If rs1 is not equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries which contain leaf page table entries corresponding to the virtual address in rs1 (shown below as Virtual Address to be flushed) and that match the address space identifier as specified by integer register rs2 (shown below as asid_to_be_flushed_i), except for entries containing global mappings. This is referred to as the “SFENCE.VMA vaddr asid” case. - -.. figure:: ../images/sfence_vaddr_asid.png - :name: **Figure 7:** Invalidate TLB entry if ASID and virtual address match - :align: center - :width: 75% - :alt: sfence_vaddr_asid - - **Figure 7:** Invalidate TLB entry if ASID and virtual address match - -* **If rs1 is equal to x0 and rs2 is equal to x0:** Invalidate all TLB entries for all address spaces. This is referred to as the "SFENCE.VMA x0 x0" case. - -.. figure:: ../images/sfence_x0_x0.png - :name: **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 - :align: center - :width: 62% - :alt: sfence_x0_x0 - - **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 - -* **If rs1 is not equal to x0 and rs2 is equal to x0:** invalidate all TLB entries that contain leaf page table entries corresponding to the virtual address in rs1, for all address spaces. This is referred to as the “SFENCE.VMA vaddr x0” case. - -.. figure:: ../images/sfence_vaddr_x0.png - :name: **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces - :align: center - :width: 75% - :alt: sfence_vaddr_x0 - - **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces - -* **If rs1 is equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries matching the address space identified by integer register rs2, except for entries containing global mappings. This is referred to as the “SFENCE.VMA 0 asid” case. - -.. figure:: ../images/sfence_x0_asid.png - :name: **Figure 10:** Invalidate TLB entry for matching ASIDs - :align: center - :width: 75% - :alt: sfence_x0_asid - - **Figure 10:** Invalidate TLB entry for matching ASIDs - -.. raw:: html - - Updating TLB - -When a TLB valid update request is signaled by the shared TLB, and the replacement policy select the update of a specific TLB entry, the corresponding entry's tag is updated with the new tag, and its associated content is refreshed with the information from the update request. This ensures that the TLB entry accurately reflects the new translation information. - -.. raw:: html - - Pseudo Least Recently Used Replacement Policy - -Cache replacement algorithms are used to determine which TLB entry should be replaced, because it is not likely to be used in the near future. The Pseudo-Least-Recently-Used (PLRU) is a cache entry replacement algorithm, derived from Least-Recently-Used (LRU) cache entry replacement algorithm, used by the TLB. Instead of precisely tracking recent usage as the LRU algorithm does, PLRU employs an approximate measure to determine which entry in the cache has not been recently used and as such can be replaced. - -CVA6 implements the PLRU algorithm via the Tree-PLRU method which implements a binary tree. The TLB entries are the leaf nodes of the tree. Each internal node, of the tree, consists of a single bit, referred to as the state bit or plru bit, indicating which subtree contains the (pseudo) least recently used entry (the PLRU); 0 for the left hand tree and 1 for the right hand tree. Following this traversal, the leaf node reached, corresponds to the PLRU entry which can be replaced. Having accessed an entry (so as to replace it) we need to promote that entry to be the Most Recently Used (MRU) entry. This is done by updating the value of each node along the access path to point away from that entry. If the accessed entry is a right child i.e., its parent node value is 1, it is set to 0, and if the parent is the left child of its parent (the grandparent of the accessed node) then its node value is set to 1 and so on all the way up to the root node. - -The PLRU binary tree is implemented as an array of node values. Nodes are organized in the array based on levels, with those from lower levels appearing before higher ones. Furthermore those on the left side of a node appear before those on the right side of a node. The figure below shows a tree and the corresponding array. - -.. figure:: ../images/plru_tree_indexing.png - :name: **Figure 11:** PLRU Tree Indexing - :align: center - :width: 60% - :alt: plru_tree_indexing - - **Figure 11:** PLRU Tree Indexing - -For n-way associative, we require n - 1 internal nodes in the tree. With those nodes, two operations need to be performed efficiently. - -* Promote the accessed entry to be MRU -* Identify which entry to replace (i.e. the PLRU entry) - -.. raw:: html - - Updating the PLRU-Tree - -For a TLB entry which is accessed, the following steps are taken to make it the MRU: - -1. Iterate through each level of the binary tree. -2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. -3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. -4. Calculate the new value that the node should have in order to make the accessed entry the Most Recently Used (MRU). The new value of the root node is the opposite of the TLB entry index, MSB at the root node, MSB - 1 at node at next level and so on. -5. Assign this new value to the relevant node, ensuring that the hit entry becomes the MRU within the binary tree structure. - -At level 0, no bit of the TLB entry’s index determines the offset from the index base because it’s a root node. At level 1, MSB of entry’s index determines the amount of offset from index base at that level. At level 2, the first two bits of the entry's index from MSB side determine the offset from the index base because there are 4 nodes at the level 2 and so on. - -.. figure:: ../images/update_tree.png - :name: **Figure 12:** Promote Entry to be MRU - :align: center - :width: 82% - :alt: update_tree - - **Figure 12:** Promote Entry to be MRU - -In the above figure entry at index 5, is accessed. To make it MRU entry, every node along the access path should point away from it. Entry 5 is a right child, therefore, its parent plru bit set to 0, its parent is a left child, its grand parent’s plru bit set to 1, and great grandparent’s plru bit set to 0. - -.. raw:: html - - Entry Selection for Replacement - -Every TLB entry is checked for the replacement entry. The following steps are taken: - -1. Iterate through each level of the binary tree. -2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. -3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. -4. If the corresponding bit of the entry's index matches the value of the node being traversed at the current level, keep the replacement signal high for that entry; otherwise, set the replacement signal to low. - -.. figure:: ../images/replacement_entry.png - :name: **Figure 13:** Possible path traverse for entry selection for replacement - :align: center - :width: 65% - :alt: replacement_entry - - **Figure 13:** Possible path traverse for entry selection for replacement - -Figure shows every possible path that traverses to find out the PLRU entry. If the plru bit at each level matches with the corresponding bit of the entry's index, that’s the next entry to replace. Below Table shows the entry selection for replacement. - -.. raw:: html - -

Table 9: Entry Selection for Reaplacement

- -+-------------------+---------------+----------------------+ -| **Path Traverse** | **PLRU Bits** | **Entry to replace** | -+-------------------+---------------+----------------------+ -| 0 -> 1 -> 3 | 000 | 0 | -| +---------------+----------------------+ -| | 001 | 1 | -+-------------------+---------------+----------------------+ -| 0 -> 1 -> 4 | 010 | 2 | -| +---------------+----------------------+ -| | 011 | 3 | -+-------------------+---------------+----------------------+ -| 0 -> 2 -> 5 | 100 | 4 | -| +---------------+----------------------+ -| | 101 | 5 | -+-------------------+---------------+----------------------+ -| 0 -> 2 -> 6 | 110 | 6 | -| +---------------+----------------------+ -| | 111 | 7 | -+-------------------+---------------+----------------------+ - ------------------------------------ -Shared Translation Lookaside Buffer ------------------------------------ - -The CVA6 shared TLB is structured as a 2-way associative cache, where the virtual address requiring translation is compared with the set indicated by the virtual page number. The shared TLB is looked up in case of an Instruction TLB (ITLB) or data TLB (DTLB) miss, signaled by these TLBs. If the entry is found in the shared TLB set, the respective TLB, whose translation is being requested, is updated. If the entry is not found in the shared TLB, then the processor has to perform a page table walk. Once the processor obtains a PPN corresponding to the VPN, the shared TLB is updated with this information. If the physical page is not found in the page table, it results in a page fault, which is handled by the operating system. The operating system will then place the corresponding physical page in memory. - -The inputs and output signals of the shared TLB are shown in the following two figures. - -.. figure:: ../images/shared_tlb_in_out.png - :name: **Figure 14:** Inputs and outputs of CVA6 shared TLB - :align: center - :width: 60% - :alt: shared_tlb_in_out - - **Figure 14:** Inputs and outputs of CVA6 shared TLB - -.. raw:: html - - Signal Description - -.. raw:: html - -

Table 10: Signal Description of CVA6 shared TLB

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - TLB flush request - - * - ``enable_translation_i`` - - in - - CSR Regfile - - logic - - CSRs indicate to enable Sv32 - - * - ``en_ld_st_translation_i`` - - in - - CSR Regfile - - logic - - Enable virtual memory translation for load/stores - - * - ``asid_i`` - - in - - CSR Regfile - - logic - - ASID for the lookup - - * - ``itlb_access_i`` - - in - - Cache Subsystem - - logic - - Signal indicating a lookup access in ITLB is being requested. - - * - ``itlb_hit_i`` - - in - - ITLB - - logic - - Signal indicating an ITLB hit - - * - ``itlb_vaddr_i`` - - in - - Cache Subsystem - - logic[31:0] - - Virtual address lookup in ITLB - - * - ``dtlb_access_i`` - - in - - Load/Store Unit - - logic - - Signal indicating a lookup access in DTLB is being requested. - - * - ``dtlb_hit_i`` - - in - - DTLB - - logic - - Signal indicating a DTLB hit - - * - ``dtlb_vaddr_i`` - - in - - Load/Store Unit - - logic[31:0] - - Virtual address lookup in DTLB - - * - ``itlb_update_o`` - - out - - ITLB - - tlb_update_sv32_t - - Tag and content to update ITLB - - * - ``dtlb_update_o`` - - out - - DTLB - - tlb_update_sv32_t - - Tag and content to update DTLB - - * - ``itlb_miss_o`` - - out - - Performance Counter - - logic - - Signal indicating an ITLB miss - - * - ``dtlb_miss_o`` - - out - - Performance Counter - - logic - - Signal indicating a DTLB miss - - * - ``shared_tlb_access_o`` - - out - - PTW - - logic - - Signal indicating a lookup access in shared TLB is being requested - - * - ``shared_tlb_hit_o`` - - out - - PTW - - logic - - Signal indicating a shared TLB hit - - * - ``shared_tlb_vadd_o`` - - out - - PTW - - logic[31:0] - - Virtual address lookup in shared TLB - - * - ``itlb_req_o`` - - out - - PTW - - logic - - ITLB Request Output - - * - ``shared_tlb_update_i`` - - in - - PTW - - tlb_update_sv32_t - - Updated tag and content of shared TLB - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 11: Shared TLB Update Struct (shared_tag_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``is_4M`` - - logic - - Indicates if the shared TLB entry corresponds to a 4MB page. - - * - ``vpn1`` - - logic[9:0] - - Virtual Page Number (VPN) represents the index of PTE in the page table level 1. - - * - ``vpn0`` - - logic[9:0] - - Virtual Page Number (VPN) represents the index of PTE in the page table level 0. - - * - ``asid`` - - logic - - Address Space Identifier (ASID) used to identify different address spaces - -.. raw:: html - - Shared TLB Entry Structure - -Shared TLB is 2-way associative, with a depth of 64. A single entry in the set contains the valid bit, tag and the content. The Tag segment stores details such as the virtual page number (VPN1, VPN0), ASID, and page size (is_4M). The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. - -.. figure:: ../images/shared_tlb.png - :name: **Figure 15:** CVA6 Shared TLB Structure - :align: center - :width: 60% - :alt: shared_tlb - - **Figure 15:** CVA6 Shared TLB Structure - -.. raw:: html - - Shared TLB Implementation in CVA6 - -The implementation of a shared TLB in CVA6 is described in the following sections: - -* **ITLB and DTLB Miss:** Prepare a shared TLB lookup if the entry is not found in ITLB or DTLB. -* **Tag Comparison:** Look up the provided virtual address in the shared TLB. -* **Update and Flush:** Flush the shared TLB or update it. -* **Replacement Policies:** First non-valid entry and random replacement policy. - -.. raw:: html - - ITLB and DTLB Miss - -Consider a scenario where an entry is found in the ITLB or DTLB. In this case, there is no need to perform a lookup in the shared TLB since the entry has already been found. Next, there are two scenarios: an ITLB miss or a DTLB miss. - -To identify an ITLB miss, the following conditions need to be fulfilled: - -* Address translation must be enabled. -* There must be an access request to the ITLB. -* The ITLB should indicate an ITLB miss. -* There should be no access request to the DTLB. - -During an ITLB miss, access is granted to read the tag and content of the shared TLB from their respective sram. The address for reading the tag and content of the shared TLB entry is calculated using the virtual address for which translation is not found in the ITLB. The ITLB miss is also explicitly indicated by the shared TLB. A request for shared TLB access is initiated. - -To identify the DTLB miss, the following conditions need to be fulfilled: - -* Address translation for load and stores must be enabled. -* There must be an access request to the DTLB. -* The DTLB should indicate a DTLB miss. - -In the case of a DTLB miss, the same logic is employed as described for an ITLB miss. - -.. raw:: html - - Tag Comparison - -Shared TLB lookup for a hit occurs under the same conditions as described for the TLB modules used as ITLB and DTLB. However, there are some distinctions. In both the ITLB and DTLB, the virtual address requiring translation is compared against all TLB entries. In contrast, the shared TLB only compares the tag and content of the set indicated by the provided virtual page number. The index of the set is extracted from VPN0 of the requested virtual address. Given that the shared TLB is 2-way associative, each set contains two entries. Consequently, both of these entries are compared. Below figure illustrates how the set is opted for the lookup. - -.. figure:: ../images/shared_tlb_set.png - :name: **Figure 16:** Set opted for lookup in shared TLB - :align: center - :width: 60% - :alt: shared_tlb_set - - **Figure 16:** Set opted for lookup in shared TLB - -.. raw:: html - - Update and Flush - -Differing from the ITLB and DTLB, a specific virtual address or addressing space cannot be flushed in the shared TLB. When SFENCE.VMA is committed, all entries in the shared TLB are invalidated. (Cases of SFENCE.VMA should also be added in shared TLB) - -.. raw:: html - - Updating Shared TLB - -When the Page Table Walker signals a valid update request, the shared TLB is updated by selecting an entry through the replacement policy and marking it as valid. This also triggers the writing of the new tag and content to the respective SRAM. - -.. raw:: html - - Replacement Policy Implemented in CVA6 Shared TLB - -In CVA6's shared TLB, two replacement policies are employed for replacements based on a specific condition. These replacement policies select the entry within the set indicated by the virtual page number. The two policies are: - -* First non-valid encounter replacement policy -* Random replacement policy - -First replacement policy failed if all ways are valid. Therefore, a random replacement policy is opted for. - -.. raw:: html - - First non-valid encounter replacement policy - -The module implemented in CVA6 to find the first non-valid entry in the shared TLB is the Leading Zero Counter (LZC). It takes three parameters as input: - -1. **WIDTH:** The width of the input vector. -2. **MODE:** Mode selection - 0 for trailing zero, 1 for leading zero. -3. **CNT WIDTH:** Width of the output signal containing the zero count. - -The input signal is the vector to be counted, and the output represents the count of trailing/leading zeros. If all bits in the input vector are zero, it will also be indicated. - -When initializing the module, the width of the input vector is set to the number of shared TLB ways. The trailing zero counter mode is selected. The vector of valid bits is set as the input vector, but with negation. This is because we want the index of the first non-valid entry, and LZC returns the count of trailing zeros, which actually corresponds to the index of the first occurrence of 1 from the least significant bit (LSB). if there is at least one non-valid entry, that entry is opted for the replacement, and If not then this is signaled by LZC. - -.. figure:: ../images/LZC.png - :name: **Figure 17:** Replacement of First invalid entry. - :align: center - :width: 60% - :alt: LZC - - **Figure 17:** Replacement of First invalid entry. - -.. raw:: html - - Random replacement policy - -If all ways are valid, a random replacement policy is employed for the replacement process. The Linear Feedback Shift Register (LFSR) is utilized to select the replacement entry randomly. LFSR is commonly used in generating sequences of pseudo-random numbers. When the enable signal is active, the current state of the LFSR undergoes a transformation. Specifically, the state is shifted right by one bit, and the result is combined with a predetermined masking pattern. This masking pattern is derived from the predefined “Masks” array, introducing a non-linear behavior to the sequence generation of the LFSR. The masking process involves XOR operations between the shifted state bits and specific pattern bits, contributing to the complexity and unpredictability of the generated sequence. - -.. figure:: ../images/RR.png - :name: **Figure 18:** Entry selection for replacement using LFSR - :align: center - :width: 95% - :alt: RR - - **Figure 18:** Entry selection for replacement using LFSR - ------------------ -Page Table Walker ------------------ - -The "CVA6 Page Table Walker (PTW) for MMU Sv32" is a hardware module developed for the CV32A6 processor architecture, designed to facilitate the translation of virtual addresses into physical addresses, a crucial task in memory access management. - -.. figure:: ../images/ptw_in_out.png - :name: **Figure 19:** Input and Outputs of Page Table Walker - :align: center - :width: 60% - :alt: ptw_in_out - - **Figure 19:** Input and Outputs of Page Table Walker - -.. raw:: html - - Operation of PTW Module - -The PTW module operates through various states, each with its specific function, such as handling memory access requests, validating page table entries, and responding to errors. - -.. raw:: html - - Key Features and Capabilities - -Key features of this PTW module include support for two levels of page tables (LVL1 and LVL2) in the Sv32 standard, accommodating instruction and data page table walks. It rigorously validates and verifies page table entries (PTEs) to ensure translation accuracy and adherence to access permissions. This module seamlessly integrates with the CV32A6 processor's memory management unit (MMU), which governs memory access control. It also takes into account global mapping, access flags, and privilege levels during the translation process, ensuring that memory access adheres to the processor's security and privilege settings. - -.. raw:: html - - Exception Handling - -In addition to its translation capabilities, the PTW module is equipped to detect and manage errors, including page-fault exceptions and access exceptions, contributing to the robustness of the memory access system. It works harmoniously with physical memory protection (PMP) configurations, a critical aspect of modern processors' memory security. Moreover, the module efficiently processes virtual addresses, generating corresponding physical addresses, all while maintaining speculative translation, a feature essential for preserving processor performance during memory access operations. - -.. raw:: html - - Signal Description - -.. raw:: html - -

Table 12: Signal Description of PTW

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Sfence Committed - - * - ``ptw_active_o`` - - out - - MMU - - logic - - Output signal indicating whether the Page Table Walker (PTW) is currently active - - * - ``walking_instr_o`` - - out - - MMU - - logic - - Indicating it's an instruction page table walk or not - - * - ``ptw_error_o`` - - out - - MMU - - logic - - Output signal indicating that an error occurred during PTW operation - - * - ``ptw_access_exception_o`` - - out - - MMU - - logic - - Output signal indicating that a PMP (Physical Memory Protection) access exception occurred during PTW operation. - - * - ``lsu_is_store_i`` - - in - - Store Unit - - logic - - Input signal indicating whether the translation was triggered by a store operation. - - * - ``req_port_i`` - - in - - Cache Subsystem - - dcache_req_o_t - - D Cache Data Requests - - * - ``req_port_o`` - - out - - Cache Subsystem / Perf Counter - - dcache_req_u_t - - D Cache Data Response - - * - ``shared_tlb_update_o`` - - out - - Shared TLB - - tlb_update_sv32_t - - Updated tag and content of shared TLB - - * - ``update_vaddr_o`` - - out - - MMU - - logic[riscv::VLEN-1:0] - - Updated VADDR from shared TLB - - * - ``asid_i`` - - in - - CSR RegFile - - logic[ASID_WIDTH-1:0] - - ASID for the lookup - - * - ``shared_tlb_access_i`` - - in - - Shared TLB - - logic - - Access request of shared TLB - - * - ``shared_tlb_hit_i`` - - in - - Shared TLB - - logic - - Indicate shared TLB hit - - * - ``shared_tlb_vaddr_i`` - - in - - Shared TLB - - logic[riscv::VLEN-1:0] - - Virtual Address from shared TLB - - * - ``itlb_req_i`` - - in - - Shared TLB - - logic - - Indicate request to ITLB - - * - ``satp_ppn_i`` - - in - - CSR RegFile - - logic[riscv::PPNW-1:0] - - PPN of top level page table from SATP register - - * - ``mxr_i`` - - in - - CSR RegFile - - logic - - Make Executable Readable bit in xSTATUS CSR register - - * - ``shared_tlb_miss_o`` - - out - - OPEN - - logic - - Indicate a shared TLB miss - - * - ``pmpcfg_i`` - - in - - CSR RegFile - - riscv::pmpcfg_t[15:0] - - PMP configuration - - * - ``pmpaddr_i`` - - in - - CSR RegFile - - logic[15:0][riscv::PLEN-3:0] - - PMP Address - - * - ``bad_paddr_o`` - - out - - MMU - - logic[riscv::PLEN-1:0] - - Bad Physical Address in case of access exception - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 13: D Cache Response Struct (dcache_req_i_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``address_index`` - - logic [DCACHE_INDEX_WIDTH-1:0] - - Index of the Dcache Line - - * - ``address_tag`` - - logic [DCACHE_TAG_WIDTH-1:0] - - Tag of the Dcache Line - - * - ``data_wdata`` - - riscv::xlen_t - - Data to write in the Dcache - - * - ``data_wuser`` - - logic [DCACHE_USER_WIDTH-1:0] - - data_wuser - - * - ``data_req`` - - logic - - Data Request - - * - ``data_we`` - - logic - - Data Write enabled - - * - ``data_be`` - - logic [(riscv::XLEN/8)-1:0] - - Data Byte enable - - * - ``data_size`` - - logic [1:0] - - Size of data - - * - ``data_id`` - - logic [DCACHE_TID_WIDTH-1:0] - - Data ID - - * - ``kill_req`` - - logic - - Kill the D cache request - - * - ``tag_valid`` - - logic - - Indicate that teh tag is valid - -.. raw:: html - -

Table 14: D Cache Request Struct (dcache_req_o_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``data_gnt`` - - logic - - Grant of data is given in response to the data request - - * - ``data_rvalid`` - - logic - - Indicate that data is valid which is sent by D cache - - * - ``data_rid`` - - logic [DCACHE_TID_WIDTH-1:0] - - Requested data ID - - * - ``data_rdata`` - - riscv::xlen_t - - Data from D cache - - * - ``data_ruser`` - - logic [DCACHE_USER_WIDTH-1:0] - - Requested data user - -.. raw:: html - - PTW State Machine - -Page Table Walker is implemented as a finite state machine. It listens to shared TLB for incoming translation requests. If there is a shared TLB miss, it saves the virtual address and starts the page table walk. Page table walker transition between 7 states in CVA6. - -* **IDLE:** The initial state where the PTW is awaiting a trigger, often a Shared TLB miss, to initiate a memory access request. -* **WAIT_GRANT:** Request memory access and wait for data grant -* **PTE_LOOKUP:** Once granted access, the PTW examines the valid Page Table Entry (PTE), checking attributes to determine the appropriate course of action. -* **PROPOGATE_ERROR:** If the PTE is invalid, this state handles the propagation of an error, often leading to a page-fault exception due to non-compliance with access conditions -* **PROPOGATE_ACCESS_ERROR:** Propagate access fault if access is not allowed from a PMP perspective -* **WAIT_RVALID:** After processing a PTE, the PTW waits for a valid data signal, indicating that relevant data is ready for further processing. -* **LATENCY:** Introduces a delay to account for synchronization or timing requirements between states. - -.. figure:: ../images/ptw_state_diagram.png - :name: **Figure 20:** State Machine Diagram of CVA6 PTW - :align: center - :width: 95% - :alt: ptw_state_diagram - - **Figure 20:** State Machine Diagram of CVA6 PTW - -.. raw:: html - - IDLE state - -In the IDLE state of the Page Table Walker (PTW) finite state machine, the system awaits a trigger to initiate the page table walk process. This trigger is often prompted by a Shared Translation Lookaside Buffer (TLB) miss, indicating that the required translation is not present in the shared TLB cache. The PTW's behavior in this state is explained as follows: - -1. The top-most page table is selected for the page table walk. In the case of SV32, which implements a two-level page table, the level 1 page table is chosen. -2. In the IDLE state, translations are assumed to be invalid in all addressing spaces. -3. The signal indicating the instruction page table walk is set to 0. -4. A conditional check is performed: if there is a shared TLB access request and the entry is not found in the shared TLB (indicating a shared TLB miss), the following steps are executed: - - a. The address of the desired Page Table Entry within the level 1 page table is calculated by multiplying the Physical Page Number (PPN) of the level 1 page table from the SATP register by the page size (4kB). This result is then added to the product of the Virtual Page Number (VPN1), and the size of a page table entry(4 bytes). - -.. figure:: ../images/ptw_idle.png - :name: **Figure 21:** Address of Desired PTE at Level 1 - :align: center - :width: 68% - :alt: ptw_idle - - **Figure 21:** Address of Desired PTE at Level 1 - -.. _example: - - b. The signal indicating whether it's an instruction page table walk is updated based on the ITLB miss. - c. The ASID and virtual address are saved for the page table walk. - d. A shared TLB miss is indicated. - -.. raw:: html - - WAIT GRANT state - -In the **WAIT_GRANT** state of the Page Table Walker's finite state machine, a data request is sent to retrieve memory information. It waits for a data grant signal from the Dcache controller, remaining in this state until granted. Once granted, it activates a tag valid signal, marking data validity. The state then transitions to "PTE_LOOKUP" for page table entry lookup. - -.. raw:: html - - PTE LOOKUP state - -In the **PTE_LOOKUP** state of the Page Table Walker (PTW) finite state machine, the PTW performs the actual lookup and evaluation of the page table entry (PTE) based on the virtual address translation. The behavior and operations performed in this state are detailed as follows: - -1. The state waits for a valid signal indicating that the data from the memory subsystem, specifically the page table entry, is available for processing. -2. Upon receiving the valid signal, the PTW proceeds with examining the retrieved page table entry to determine its properties and validity. -3. The state checks if the global mapping bit in the PTE is set, and if so, sets the global mapping signal to indicate that the translation applies globally across all address spaces. -4. The state distinguishes between two cases: Invalid PTE and Valid PTE. - - a. If the valid bit of the PTE is not set, or if the PTE has reserved RWX field encodings, it signifies an Invalid PTE. In such cases, the state transitions to the "PROPAGATE_ERROR" state, indicating a page-fault exception due to an invalid translation. - -.. figure:: ../images/ptw_pte_1.png - :name: **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault - :align: center - :width: 70% - :alt: ptw_pte_1 - - **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault - -.. _example1: - - b. If the PTE is valid, the state advances to the "LATENCY" state, indicating a period of processing latency. Additionally, if the "read" flag (pte.r) or the "execute" flag (pte.x) is set, the PTE is considered valid. - -5. Within the Valid PTE scenario, the state performs further checks based on whether the translation is intended for instruction fetching or data access: - - a. For instruction page table walk, if the page is not executable (pte.x is not set) or not marked as accessible (pte.a is not set), the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_iptw.png - :name: **Figure 23:** For Instruction Page Table Walk - :align: center - :width: 70% - :alt: ptw_iptw - - **Figure 23:** For Instruction Page Table Walk - -.. _example2: - - b. For data page table walk, the state checks if the page is readable (pte.r is set) or if the page is executable only but made readable by setting the MXR bit in xSTATUS CSR register. If either condition is met, it indicates a valid translation. If not, the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_dptw.png - :name: **Figure 24:** Data Access Page Table Walk - :width: 70% - :alt: ptw_dptw - - **Figure 24:** Data Access Page Table Walk - -.. _example3: - - c. If the access is intended for storing data, additional checks are performed: If the page is not writable (pte.w is not set) or if it is not marked as dirty (pte.d is not set), the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_dptw_s.png - :name: **Figure 25:** Data Access Page Table Walk, Store requested - :align: center - :width: 70% - :alt: ptw_dptw_s - - **Figure 25:** Data Access Page Table Walk, Store requested - -6. The state also checks for potential misalignment issues in the translation: If the current page table level is the first level (LVL1) and if the PPN0 of in PTE is not zero, it indicates a misaligned superpage, leading to a transition to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_mis_sup.png - :name: **Figure 26:** Misaligned Superpage Check - :align: center - :width: 70% - :alt: ptw_mis_sup - - **Figure 26:** Misaligned Superpage Check - -7. If the PTE is valid but the page is neither readable nor executable, the PTW recognizes the PTE as a pointer to the next level of the page table, indicating that additional translation information can be found in the referenced page table at a lower level. -8. If the current page table level is the first level (LVL1), the PTW proceeds to switch to the second level (LVL2) page table, updating the next level pointer and calculating the address for the next page table entry using the Physical Page Number from the PTE and the index of the level 2 page table from virtual address. - -.. figure:: ../images/ptw_nlvl.png - :name: **Figure 27:** Address of desired PTE at next level of Page Table - :align: center - :width: 70% - :alt: ptw_nlvl - - **Figure 27:** Address of desired PTE at next level of Page Table - -9. The state then transitions to the "WAIT_GRANT" state, indicating that the PTW is awaiting the grant signal to proceed with requesting the next level page table entry. -10. If the current level is already the second level (LVL2), an error is flagged, and the state transitions to the "PROPAGATE_ERROR" state, signifying an unexpected situation where the PTW is already at the last level page table. -11. If the translation access is found to be restricted by the Physical Memory Protection (PMP) settings (allow_access is false), the state updates the shared TLB update signal to indicate that the TLB entry should not be updated. Additionally, the saved address for the page table walk is restored to its previous value, and the state transitions to the "PROPAGATE_ACCESS_ERROR" state. -12. Lastly, if the data request for the page table entry was granted, the state indicates to the cache subsystem that the tag associated with the data is now valid. - -.. figure:: ../images/ptw_pte_flowchart.png - :name: **Figure 28:** Flow Chart of PTE LOOKUP State - :align: center - :alt: ptw_pte_flowchart - - **Figure 28:** Flow Chart of PTE LOOKUP State - -.. raw:: html - - PROPAGATE ERROR state - -This state indicates a detected error in the page table walk process, and an error signal is asserted to indicate the Page Table Walker's error condition, triggering a transition to the "LATENCY" state for error signal propagation. - -.. raw:: html - - PROPAGATE ACCESS ERROR state - -This state indicates a detected access error in the page table walk process, and an access error signal is asserted to indicate the Page Table Walker's access error condition, triggering a transition to the "LATENCY" state for access error signal propagation. - -.. raw:: html - - WAIT RVALID state - -This state waits until it gets the "read valid" signal, and when it does, it's ready to start a new page table walk. - -.. raw:: html - - LATENCY state - -The LATENCY state introduces a latency period to allow for necessary system actions or signals to stabilize. After the latency period, the FSM transitions back to the IDLE state, indicating that the system is prepared for a new translation request. - -.. raw:: html - - Flush Scenario - -The first step when a flush is triggered is to check whether the Page Table Entry (PTE) lookup process is currently in progress. If the PTW (Page Table Walker) module is indeed in the middle of a PTE lookup operation, the code then proceeds to evaluate a specific aspect of this operation. - -* **Check for Data Validity (rvalid):** Within the PTE lookup operation, it's important to ensure that the data being used for the translation is valid. In other words, the code checks whether the "rvalid" signal (which likely indicates the validity of the data) is not active. If the data is not yet valid, it implies that the PTW module is waiting for the data to become valid before completing the lookup. In such a case, the code takes appropriate action to wait for the data to become valid before proceeding further. - -* **Check for Waiting on Grant:** The second condition the code checks for during a flush scenario is whether the PTW module is currently waiting for a "grant." This "grant" signal is typically used to indicate permission or authorization to proceed with an operation. If the PTW module is indeed in a state of waiting for this grant signal, it implies that it requires authorization before continuing its task. - - * **Waiting for Grant:** If the PTW module is in a state of waiting for the grant signal, the code ensures that it continues to wait for the grant signal to be asserted before proceeding further. - -* **Return to Idle State if Neither Condition is Met:** After evaluating the above two conditions, the code determines whether either of these conditions is true. If neither of these conditions applies, it suggests that the PTW module can return to its idle state, indicating that it can continue normal operations without any dependencies on the flush condition. - -PMA/PMP Checks -============== - - CVXIF_fu ======== From b20ee7997e35874d9dbb05eee3d1831f94aefd30 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Mon, 12 Feb 2024 13:38:13 +0100 Subject: [PATCH 05/20] Add Execute submodule chapters --- .../images/ex_stage_modules.png | Bin 21705 -> 21008 bytes .../images/id_stage_modules.png | Bin 15475 -> 14334 bytes .../images/issue_stage_modules.png | Bin 16850 -> 16267 bytes .../source/cv32a6_execute.rst | 34 ++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/docs/04_cv32a65x_design/images/ex_stage_modules.png b/docs/04_cv32a65x_design/images/ex_stage_modules.png index 97738c8b74ac8c8eb412e958e3d786a38a834867..bd1f029b2c434d94f3c845de0978228d0ab766ee 100644 GIT binary patch literal 21008 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 z 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 KO!BGA9{&Y}q{lJ< literal 21705 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 diff --git a/docs/04_cv32a65x_design/images/id_stage_modules.png b/docs/04_cv32a65x_design/images/id_stage_modules.png index 476a038e75dbdc1d68d8112dd9cf6b53165d735b..8e0115f39e5aa01681401924fb3288b44bd1e05f 100644 GIT binary patch literal 14334 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 V{+2q1QDlNpR#ZEfvj5bTe*rFeN&o-= literal 15475 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%0DGjIWraN!yeX%PNgNPe)q# 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 diff --git a/docs/04_cv32a65x_design/images/issue_stage_modules.png b/docs/04_cv32a65x_design/images/issue_stage_modules.png index a1af1234c02617daebcf8da8d2374f1bc2bc6584..d0f14e46a4173d5ac47b063e62d586e3d81050a9 100644 GIT binary patch literal 16267 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 Xt^O$!{Z#>EXr5G5`A5pHzuo?C3*el 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 TwdC8x_2 Date: Tue, 13 Feb 2024 22:21:41 +0100 Subject: [PATCH 06/20] inverse typedata and description colomn in port table --- docs/04_cv32a65x_design/source/port_bht.rst | 17 +- docs/04_cv32a65x_design/source/port_btb.rst | 17 +- .../source/port_commit_stage.rst | 40 ++- .../source/port_controller.rst | 45 +++- .../source/port_csr_regfile.rst | 133 ++++++++-- docs/04_cv32a65x_design/source/port_cva6.rst | 22 +- .../source/port_ex_stage.rst | 238 +++++++++++++++--- .../source/port_frontend.rst | 43 +++- .../source/port_id_stage.rst | 85 +++++-- .../source/port_instr_queue.rst | 21 +- .../source/port_instr_realign.rst | 17 +- .../source/port_instr_scan.rst | 18 +- .../source/port_issue_stage.rst | 114 +++++++-- docs/04_cv32a65x_design/source/port_ras.rst | 11 +- 14 files changed, 673 insertions(+), 148 deletions(-) diff --git a/docs/04_cv32a65x_design/source/port_bht.rst b/docs/04_cv32a65x_design/source/port_bht.rst index 91a5f4a449..9e0f2aa2dc 100644 --- a/docs/04_cv32a65x_design/source/port_bht.rst +++ b/docs/04_cv32a65x_design/source/port_bht.rst @@ -22,39 +22,46 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request + - logic + + * - ``debug_mode_i`` + - in + - CSR + - Debug mode state - logic * - ``vpc_i`` - in - Virtual PC - CACHE + - Virtual PC - logic[riscv::VLEN-1:0] * - ``bht_update_i`` - in - Update bht with resolved address - EXECUTE + - Update bht with resolved address - ariane_pkg::bht_update_t * - ``bht_prediction_o`` - out - Prediction from bht - FRONTEND + - Prediction from bht - ariane_pkg::bht_prediction_t[ariane_pkg::INSTR_PER_FETCH-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_mode_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_btb.rst b/docs/04_cv32a65x_design/source/port_btb.rst index 225d583514..a30424287b 100644 --- a/docs/04_cv32a65x_design/source/port_btb.rst +++ b/docs/04_cv32a65x_design/source/port_btb.rst @@ -22,39 +22,46 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request + - logic + + * - ``debug_mode_i`` + - in + - CSR + - Debug mode state - logic * - ``vpc_i`` - in - Virtual PC - CACHE + - Virtual PC - logic[riscv::VLEN-1:0] * - ``btb_update_i`` - in - Update BTB with resolved address - EXECUTE + - Update BTB with resolved address - ariane_pkg::btb_update_t * - ``btb_prediction_o`` - out - BTB Prediction - FRONTEND + - BTB Prediction - ariane_pkg::btb_prediction_t[ariane_pkg::INSTR_PER_FETCH-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_mode_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_commit_stage.rst b/docs/04_cv32a65x_design/source/port_commit_stage.rst index ea35aa4dc1..27f07934f3 100644 --- a/docs/04_cv32a65x_design/source/port_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/port_commit_stage.rst @@ -22,177 +22,207 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``halt_i`` - in - Request to halt the core - CONTROLLER + - Request to halt the core - logic * - ``flush_dcache_i`` - in - request to flush dcache, also flush the pipeline - CACHE + - request to flush dcache, also flush the pipeline - logic * - ``exception_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - exception_t * - ``dirty_fp_state_o`` - out - Mark the F state as dirty - CSR_REGFILE + - Mark the F state as dirty - logic * - ``single_step_i`` - in - TO_BE_COMPLETED - CSR_REGFILE + - TO_BE_COMPLETED - logic * - ``commit_instr_i`` - in - The instruction we want to commit - ISSUE_STAGE + - The instruction we want to commit - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_o`` - out - Acknowledge that we are indeed committing - ISSUE_STAGE + - Acknowledge that we are indeed committing - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``waddr_o`` - out - Register file write address - ID_STAGE + - Register file write address - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] * - ``wdata_o`` - out - Register file write data - ID_STAGE + - Register file write data - logic[CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] * - ``we_gpr_o`` - out - Register file write enable - ID_STAGE + - Register file write enable - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``we_fpr_o`` - out - Floating point register enable - ID_STAGE + - Floating point register enable - logic[CVA6Cfg.NrCommitPorts-1:0] + * - ``amo_resp_i`` + - in + - CACHE + - Result of AMO operation + - amo_resp_t + * - ``pc_o`` - out - TO_BE_COMPLETED - FRONTEND_CSR + - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``csr_op_o`` - out - Decoded CSR operation - CSR_REGFILE + - Decoded CSR operation - fu_op * - ``csr_wdata_o`` - out - Data to write to CSR - CSR_REGFILE + - Data to write to CSR - riscv::xlen_t * - ``csr_rdata_i`` - in - Data to read from CSR - CSR_REGFILE + - Data to read from CSR - riscv::xlen_t * - ``csr_exception_i`` - in - Exception or interrupt occurred in CSR stage (the same as commit) - CSR_REGFILE + - Exception or interrupt occurred in CSR stage (the same as commit) - exception_t * - ``csr_write_fflags_o`` - out - Write the fflags CSR - CSR_REGFILE + - Write the fflags CSR - logic * - ``commit_lsu_o`` - out - Commit the pending store - EX_STAGE + - Commit the pending store - logic * - ``commit_lsu_ready_i`` - in - Commit buffer of LSU is ready - EX_STAGE + - Commit buffer of LSU is ready - logic * - ``commit_tran_id_o`` - out - Transaction id of first commit port - ID_STAGE + - Transaction id of first commit port - logic[TRANS_ID_BITS-1:0] * - ``amo_valid_commit_o`` - out - Valid AMO in commit stage - EX_STAGE + - Valid AMO in commit stage - logic * - ``no_st_pending_i`` - in - no store is pending - EX_STAGE + - no store is pending - logic * - ``commit_csr_o`` - out - Commit the pending CSR instruction - EX_STAGE + - Commit the pending CSR instruction - logic * - ``fence_i_o`` - out - Flush I$ and pipeline - CONTROLLER + - Flush I$ and pipeline - logic * - ``fence_o`` - out - Flush D$ and pipeline - CONTROLLER + - Flush D$ and pipeline - logic * - ``flush_commit_o`` - out - Request a pipeline flush - CONTROLLER + - Request a pipeline flush - logic * - ``sfence_vma_o`` - out - Flush TLBs and pipeline - CONTROLLER + - Flush TLBs and pipeline - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVA = 0, -| ``amo_resp_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_controller.rst b/docs/04_cv32a65x_design/source/port_controller.rst index 75e285168e..d70c0444e5 100644 --- a/docs/04_cv32a65x_design/source/port_controller.rst +++ b/docs/04_cv32a65x_design/source/port_controller.rst @@ -22,138 +22,169 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``set_pc_commit_o`` - out - Set PC om PC Gen - FRONTEND + - Set PC om PC Gen - logic * - ``flush_if_o`` - out - Flush the IF stage - FRONTEND + - Flush the IF stage - logic * - ``flush_unissued_instr_o`` - out - Flush un-issued instructions of the scoreboard - FRONTEND + - Flush un-issued instructions of the scoreboard - logic * - ``flush_id_o`` - out - Flush ID stage - ID_STAGE + - Flush ID stage - logic * - ``flush_ex_o`` - out - Flush EX stage - EX_STAGE + - Flush EX stage - logic * - ``flush_bp_o`` - out - Flush branch predictors - FRONTEND + - Flush branch predictors - logic * - ``flush_icache_o`` - out - Flush ICache - CACHE + - Flush ICache - logic * - ``flush_dcache_o`` - out - Flush DCache - CACHE + - Flush DCache - logic * - ``flush_dcache_ack_i`` - in - Acknowledge the whole DCache Flush - CACHE + - Acknowledge the whole DCache Flush - logic * - ``flush_tlb_o`` - out - Flush TLBs - EX_STAGE + - Flush TLBs - logic * - ``halt_csr_i`` - in - Halt request from CSR (WFI instruction) - CSR_REGFILE + - Halt request from CSR (WFI instruction) + - logic + + * - ``halt_acc_i`` + - in + - ACC_DISPATCHER + - Halt request from accelerator dispatcher - logic * - ``halt_o`` - out - Halt signal to commit stage - COMMIT_STAGE + - Halt signal to commit stage - logic * - ``eret_i`` - in - Return from exception - CSR_REGFILE + - Return from exception - logic * - ``ex_valid_i`` - in + - FRONTEND - We got an exception, flush the pipeline + - logic + + * - ``set_debug_pc_i`` + - in - FRONTEND + - set the debug pc from CSR - logic * - ``resolved_branch_i`` - in - We got a resolved branch, check if we need to flush the front-end - EX_STAGE + - We got a resolved branch, check if we need to flush the front-end - bp_resolve_t * - ``flush_csr_i`` - in - We got an instruction which altered the CSR, flush the pipeline - CSR_REGFILE + - We got an instruction which altered the CSR, flush the pipeline - logic * - ``fence_i_i`` - in - fence.i in - ACC_DISPATCH + - fence.i in - logic * - ``fence_i`` - in - fence in - ACC_DISPATCH + - fence in - logic * - ``sfence_vma_i`` - in - We got an instruction to flush the TLBs and pipeline - COMMIT_STAGE + - We got an instruction to flush the TLBs and pipeline - logic * - ``flush_commit_i`` - in - Flush request from commit stage - COMMIT_STAGE + - Flush request from commit stage - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As EnableAccelerator = 0, -| ``halt_acc_i`` input is tied to 0 -| ``flush_acc_i`` input is tied to 0 -| As DebugEn = 0, -| ``set_debug_pc_i`` input is tied to 0 + * - ``flush_acc_i`` + - in + - ACC_DISPATCHER + - Flush request from accelerator + - logic diff --git a/docs/04_cv32a65x_design/source/port_csr_regfile.rst b/docs/04_cv32a65x_design/source/port_csr_regfile.rst index 5aaf3bafe1..c6b308034d 100644 --- a/docs/04_cv32a65x_design/source/port_csr_regfile.rst +++ b/docs/04_cv32a65x_design/source/port_csr_regfile.rst @@ -22,286 +22,385 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``time_irq_i`` - in - Timer threw a interrupt - SUBSYSTEM + - Timer threw a interrupt - logic * - ``flush_o`` - out - send a flush request out when a CSR with a side effect changes - CONTROLLER + - send a flush request out when a CSR with a side effect changes - logic * - ``halt_csr_o`` - out - halt requested - CONTROLLER + - halt requested - logic * - ``commit_instr_i`` - in - Instruction to be committed - ID_STAGE + - Instruction to be committed - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_i`` - in - Commit acknowledged a instruction -> increase instret CSR - COMMIT_STAGE + - Commit acknowledged a instruction -> increase instret CSR - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``boot_addr_i`` - in - Address from which to start booting, mtvec is set to the same address - SUBSYSTEM + - Address from which to start booting, mtvec is set to the same address - logic[riscv::VLEN-1:0] * - ``hart_id_i`` - in - Hart id in a multicore environment (reflected in a CSR) - SUBSYSTEM + - Hart id in a multicore environment (reflected in a CSR) - logic[riscv::XLEN-1:0] * - ``ex_i`` - in - We've got an exception from the commit stage, take it - COMMIT_STAGE + - We've got an exception from the commit stage, take it - exception_t * - ``csr_op_i`` - in - Operation to perform on the CSR file - COMMIT_STAGE + - Operation to perform on the CSR file - fu_op * - ``csr_addr_i`` - in - Address of the register to read/write - EX_STAGE + - Address of the register to read/write - logic[11:0] * - ``csr_wdata_i`` - in - Write data in - COMMIT_STAGE + - Write data in - logic[riscv::XLEN-1:0] * - ``csr_rdata_o`` - out - Read data out - COMMIT_STAGE + - Read data out - logic[riscv::XLEN-1:0] * - ``dirty_fp_state_i`` - in - Mark the FP sate as dirty - COMMIT_STAGE + - Mark the FP sate as dirty - logic * - ``csr_write_fflags_i`` - in - Write fflags register e.g.: we are retiring a floating point instruction - COMMIT_STAGE + - Write fflags register e.g.: we are retiring a floating point instruction + - logic + + * - ``dirty_v_state_i`` + - in + - ACC_DISPATCHER + - Mark the V state as dirty - logic * - ``pc_i`` - in - PC of instruction accessing the CSR - COMMIT_STAGE + - PC of instruction accessing the CSR - logic[riscv::VLEN-1:0] * - ``csr_exception_o`` - out - attempts to access a CSR without appropriate privilege - COMMIT_STAGE + - attempts to access a CSR without appropriate privilege - exception_t * - ``epc_o`` - out - Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - FRONTEND + - Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - logic[riscv::VLEN-1:0] * - ``eret_o`` - out - Return from exception, set the PC of epc_o - FRONTEND + - Return from exception, set the PC of epc_o - logic * - ``trap_vector_base_o`` - out - Output base of exception vector, correct CSR is output (mtvec, stvec) - FRONTEND + - Output base of exception vector, correct CSR is output (mtvec, stvec) - logic[riscv::VLEN-1:0] * - ``priv_lvl_o`` - out - Current privilege level the CPU is in - EX_STAGE + - Current privilege level the CPU is in - riscv::priv_lvl_t + * - ``acc_fflags_ex_i`` + - in + - ACC_DISPATCHER + - Imprecise FP exception from the accelerator (fcsr.fflags format) + - logic[4:0] + + * - ``acc_fflags_ex_valid_i`` + - in + - ACC_DISPATCHER + - An FP exception from the accelerator occurred + - logic + * - ``fs_o`` - out - Floating point extension status - ID_STAGE + - Floating point extension status - riscv::xs_t * - ``fflags_o`` - out - Floating-Point Accured Exceptions - COMMIT_STAGE + - Floating-Point Accured Exceptions - logic[4:0] * - ``frm_o`` - out - Floating-Point Dynamic Rounding Mode - EX_STAGE + - Floating-Point Dynamic Rounding Mode - logic[2:0] * - ``fprec_o`` - out - Floating-Point Precision Control - EX_STAGE + - Floating-Point Precision Control - logic[6:0] * - ``vs_o`` - out - Vector extension status - ID_STAGE + - Vector extension status - riscv::xs_t * - ``irq_ctrl_o`` - out - interrupt management to id stage - ID_STAGE + - interrupt management to id stage - irq_ctrl_t * - ``en_translation_o`` - out - enable VA translation - EX_STAGE + - enable VA translation - logic * - ``en_ld_st_translation_o`` - out - enable VA translation for load and stores - EX_STAGE + - enable VA translation for load and stores - logic * - ``ld_st_priv_lvl_o`` - out - Privilege level at which load and stores should happen - EX_STAGE + - Privilege level at which load and stores should happen - riscv::priv_lvl_t * - ``sum_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic * - ``mxr_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic * - ``satp_ppn_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[riscv::PPNW-1:0] * - ``asid_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[AsidWidth-1:0] * - ``irq_i`` - in - external interrupt in - SUBSYSTEM + - external interrupt in - logic[1:0] * - ``ipi_i`` - in - inter processor interrupt -> connected to machine mode sw - SUBSYSTEM + - inter processor interrupt -> connected to machine mode sw + - logic + + * - ``debug_req_i`` + - in + - ID_STAGE + - debug request in - logic * - ``set_debug_pc_o`` - out - TO_BE_COMPLETED - FRONTEND + - TO_BE_COMPLETED - logic * - ``tvm_o`` - out - trap virtual memory - ID_STAGE + - trap virtual memory - logic * - ``tw_o`` - out - timeout wait - ID_STAGE + - timeout wait - logic * - ``tsr_o`` - out - trap sret - ID_STAGE + - trap sret - logic * - ``debug_mode_o`` - out - we are in debug mode -> that will change some decoding - EX_STAGE + - we are in debug mode -> that will change some decoding - logic * - ``single_step_o`` - out - we are in single-step mode - COMMIT_STAGE + - we are in single-step mode - logic * - ``icache_en_o`` - out - L1 ICache Enable - CACHE + - L1 ICache Enable - logic * - ``dcache_en_o`` - out - L1 DCache Enable - CACHE + - L1 DCache Enable + - logic + + * - ``acc_cons_en_o`` + - out + - ACC_DISPATCHER + - Accelerator memory consistent mode + - logic + + * - ``perf_addr_o`` + - out + - PERF_COUNTERS + - read/write address to performance counter module + - logic[11:0] + + * - ``perf_data_o`` + - out + - PERF_COUNTERS + - write data to performance counter module + - logic[riscv::XLEN-1:0] + + * - ``perf_data_i`` + - in + - PERF_COUNTERS + - read data from performance counter module + - logic[riscv::XLEN-1:0] + + * - ``perf_we_o`` + - out + - PERF_COUNTERS + - TO_BE_COMPLETED - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As EnableAccelerator = 0, -| ``dirty_v_state_i`` input is tied to 0 -| ``acc_fflags_ex_i`` input is tied to 0 -| ``acc_fflags_ex_valid_i`` input is tied to 0 -| ``acc_cons_en_o`` output is tied to 0 -| ``pmpcfg_o`` output is tied to 0 -| ``pmpaddr_o`` output is tied to 0 -| As DebugEn = 0, -| ``debug_req_i`` input is tied to 0 -| As PerfCounterEn = 0, -| ``perf_addr_o`` output is tied to 0 -| ``perf_data_o`` output is tied to 0 -| ``perf_data_i`` input is tied to 0 -| ``perf_we_o`` output is tied to 0 -| ``mcountinhibit_o`` output is tied to 0 + * - ``pmpcfg_o`` + - out + - ACC_DISPATCHER + - PMP configuration containing pmpcfg for max 16 PMPs + - riscv::pmpcfg_t[15:0] + + * - ``pmpaddr_o`` + - out + - ACC_DISPATCHER + - PMP addresses + - logic[15:0][riscv::PLEN-3:0] + + * - ``mcountinhibit_o`` + - out + - PERF_COUNTERS + - TO_BE_COMPLETED + - logic[31:0] diff --git a/docs/04_cv32a65x_design/source/port_cva6.rst b/docs/04_cv32a65x_design/source/port_cva6.rst index a439bf3a8c..19dd408017 100644 --- a/docs/04_cv32a65x_design/source/port_cva6.rst +++ b/docs/04_cv32a65x_design/source/port_cva6.rst @@ -22,75 +22,87 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``boot_addr_i`` - in - Reset boot address - SUBSYSTEM + - Reset boot address - logic[riscv::VLEN-1:0] * - ``hart_id_i`` - in - Hard ID reflected as CSR - SUBSYSTEM + - Hard ID reflected as CSR - logic[riscv::XLEN-1:0] * - ``irq_i`` - in - Level sensitive (async) interrupts - SUBSYSTEM + - Level sensitive (async) interrupts - logic[1:0] * - ``ipi_i`` - in - Inter-processor (async) interrupt - SUBSYSTEM + - Inter-processor (async) interrupt - logic * - ``time_irq_i`` - in + - SUBSYSTEM - Timer (async) interrupt + - logic + + * - ``debug_req_i`` + - in - SUBSYSTEM + - Debug (async) request - logic * - ``rvfi_probes_o`` - out - Probes to build RVFI, can be left open when not used - SUBSYSTEM + - Probes to build RVFI, can be left open when not used - rvfi_probes_t * - ``cvxif_req_o`` - out - CVXIF request - SUBSYSTEM + - CVXIF request - cvxif_req_t * - ``cvxif_resp_i`` - in - CVXIF response - SUBSYSTEM + - CVXIF response - cvxif_resp_t * - ``noc_req_o`` - out - noc request, can be AXI or OpenPiton - SUBSYSTEM + - noc request, can be AXI or OpenPiton - noc_req_t * - ``noc_resp_i`` - in - noc response, can be AXI or OpenPiton - SUBSYSTEM + - noc response, can be AXI or OpenPiton - noc_resp_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_req_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_ex_stage.rst b/docs/04_cv32a65x_design/source/port_ex_stage.rst index 3fc330347e..5ebea04037 100644 --- a/docs/04_cv32a65x_design/source/port_ex_stage.rst +++ b/docs/04_cv32a65x_design/source/port_ex_stage.rst @@ -22,392 +22,552 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request + - logic + + * - ``debug_mode_i`` + - in + - CSR_REGFILE + - TO_BE_COMPLETED - logic * - ``rs1_forwarding_i`` - in - rs1 forwarding - ID_STAGE + - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``rs2_forwarding_i`` - in - rs2 forwarding - ID_STAGE + - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``fu_data_i`` - in - FU data useful to execute instruction - ID_STAGE + - TO_BE_COMPLETED - fu_data_t * - ``pc_i`` - in - PC of the current instruction - ID_STAGE + - PC of the current instruction - logic[riscv::VLEN-1:0] * - ``is_compressed_instr_i`` - in - Report whether isntruction is compressed - ID_STAGE + - Report whether isntruction is compressed - logic * - ``flu_result_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - riscv::xlen_t * - ``flu_trans_id_o`` - out - ID of the scoreboard entry at which a=to write back - ID_STAGE + - ID of the scoreboard entry at which a=to write back - logic[TRANS_ID_BITS-1:0] * - ``flu_exception_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - exception_t * - ``flu_ready_o`` - out - FLU is ready - ID_STAGE + - FLU is ready - logic * - ``flu_valid_o`` - out - FLU result is valid - ID_STAGE + - FLU result is valid - logic * - ``alu_valid_i`` - in - ALU result is valid - ID_STAGE + - ALU result is valid - logic * - ``branch_valid_i`` - in - Branch unit result is valid - ID_STAGE + - Branch unit result is valid - logic * - ``branch_predict_i`` - in - Information of branch prediction - ID_STAGE + - TO_BE_COMPLETED - branchpredict_sbe_t * - ``resolved_branch_o`` - out - - The branch engine uses the write back from the ALU - - several_modules + - none + - none - bp_resolve_t * - ``resolve_branch_o`` - out - ID signaling that we resolved the branch - ID_STAGE + - ID signaling that we resolved the branch - logic * - ``csr_valid_i`` - in - CSR result is valid - ID_STAGE + - TO_BE_COMPLETED - logic * - ``csr_addr_o`` - out - TO_BE_COMPLETED - CSR_REGISTERS + - TO_BE_COMPLETED - logic[11:0] * - ``csr_commit_i`` - in - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED - logic * - ``mult_valid_i`` - in - MULT result is valid - ID_STAGE + - MULT result is valid - logic * - ``lsu_ready_o`` - out - FU is ready - ID_STAGE + - FU is ready - logic * - ``lsu_valid_i`` - in - LSU result is valid - ID_STAGE + - LSU result is valid - logic * - ``load_valid_o`` - out - Load result is valid - ID_STAGE + - TO_BE_COMPLETED - logic * - ``load_result_o`` - out - Load result valid - ID_STAGE + - TO_BE_COMPLETED - riscv::xlen_t * - ``load_trans_id_o`` - out - Load instruction ID - ID_STAGE + - TO_BE_COMPLETED - logic[TRANS_ID_BITS-1:0] * - ``load_exception_o`` - out - Exception generated by load instruction - ID_STAGE + - TO_BE_COMPLETED - exception_t * - ``store_valid_o`` - out - Store result is valid - ID_STAGE + - TO_BE_COMPLETED - logic * - ``store_result_o`` - out - Store result - ID_STAGE + - TO_BE_COMPLETED - riscv::xlen_t * - ``store_trans_id_o`` - out - Store instruction ID - ID_STAGE + - TO_BE_COMPLETED - logic[TRANS_ID_BITS-1:0] * - ``store_exception_o`` - out - Exception generated by store instruction - ID_STAGE + - TO_BE_COMPLETED - exception_t * - ``lsu_commit_i`` - in - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED - logic * - ``lsu_commit_ready_o`` - out - Commit queue ready to accept another commit request - COMMIT_STAGE + - Commit queue is ready to accept another commit request - logic * - ``commit_tran_id_i`` - in - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED - logic[TRANS_ID_BITS-1:0] + * - ``stall_st_pending_i`` + - in + - ACC_DISPATCHER + - TO_BE_COMPLETED + - logic + * - ``no_st_pending_o`` - out - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED + - logic + + * - ``amo_valid_commit_i`` + - in + - COMMIT_STAGE + - TO_BE_COMPLETED + - logic + + * - ``fpu_ready_o`` + - out + - ID_STAGE + - FU is ready + - logic + + * - ``fpu_valid_i`` + - in + - ID_STAGE + - Output is ready + - logic + + * - ``fpu_fmt_i`` + - in + - ID_STAGE + - report FP format + - logic[1:0] + + * - ``fpu_rm_i`` + - in + - ID_STAGE + - FP rm + - logic[2:0] + + * - ``fpu_frm_i`` + - in + - ID_STAGE + - FP frm + - logic[2:0] + + * - ``fpu_prec_i`` + - in + - CSR_REGFILE + - FP precision control + - logic[6:0] + + * - ``fpu_trans_id_o`` + - out + - ID_STAGE + - TO_BE_COMPLETED + - logic[TRANS_ID_BITS-1:0] + + * - ``fpu_result_o`` + - out + - ID_STAGE + - TO_BE_COMPLETED + - riscv::xlen_t + + * - ``fpu_valid_o`` + - out + - ID_STAGE + - TO_BE_COMPLETED - logic + * - ``fpu_exception_o`` + - out + - ID_STAGE + - TO_BE_COMPLETED + - exception_t + * - ``x_valid_i`` - in - - CVXIF instruction is valid - - ISSUE_STAGE + - ID_STAGE + - TO_BE_COMPLETED - logic * - ``x_ready_o`` - out - - CVXIF is ready - - ISSUE_STAGE + - ID_STAGE + - TO_BE_COMPLETED - logic * - ``x_off_instr_i`` - in - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - logic[31:0] * - ``x_trans_id_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - logic[TRANS_ID_BITS-1:0] * - ``x_exception_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - exception_t * - ``x_result_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - riscv::xlen_t * - ``x_valid_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - logic * - ``x_we_o`` - out - TO_BE_COMPLETED - ID_STAGE + - TO_BE_COMPLETED - logic * - ``cvxif_req_o`` - out - TO_BE_COMPLETED - SUBSYSTEM + - TO_BE_COMPLETED - cvxif_pkg::cvxif_req_t * - ``cvxif_resp_i`` - in - TO_BE_COMPLETED - SUBSYSTEM + - TO_BE_COMPLETED - cvxif_pkg::cvxif_resp_t + * - ``acc_valid_i`` + - in + - ACC_DISPATCHER + - TO_BE_COMPLETED + - logic + * - ``enable_translation_i`` - in - TO_BE_COMPLETED - CSR_REGFILE + - TO_BE_COMPLETED - logic * - ``en_ld_st_translation_i`` - in - TO_BE_COMPLETED - CSR_REGFILE + - TO_BE_COMPLETED + - logic + + * - ``flush_tlb_i`` + - in + - CONTROLLER + - TO_BE_COMPLETED - logic + * - ``priv_lvl_i`` + - in + - CSR_REGFILE + - TO_BE_COMPLETED + - riscv::priv_lvl_t + + * - ``ld_st_priv_lvl_i`` + - in + - CSR_REGFILE + - TO_BE_COMPLETED + - riscv::priv_lvl_t + * - ``sum_i`` - in - Supervisor user memory - CSR_REGFILE + - TO_BE_COMPLETED - logic * - ``mxr_i`` - in - Make executable readable - CSR_REGFILE + - TO_BE_COMPLETED - logic * - ``satp_ppn_i`` - in - TO_BE_COMPLETED - CSR_REGFILE + - TO_BE_COMPLETED - logic[riscv::PPNW-1:0] * - ``asid_i`` - in - TO_BE_COMPLETED - CSR_REGFILE + - TO_BE_COMPLETED - logic[ASID_WIDTH-1:0] * - ``icache_areq_i`` - in - icache translation response - CACHE + - icache translation response - icache_arsp_t * - ``icache_areq_o`` - out - icache translation request - CACHE + - icache translation request - icache_areq_t * - ``dcache_req_ports_i`` - in - TO_BE_COMPLETED - CACHE + - TO_BE_COMPLETED - dcache_req_o_t[2:0] * - ``dcache_req_ports_o`` - out - TO_BE_COMPLETED - CACHE + - TO_BE_COMPLETED - dcache_req_i_t[2:0] * - ``dcache_wbuffer_empty_i`` - in - TO_BE_COMPLETED - CACHE + - TO_BE_COMPLETED - logic * - ``dcache_wbuffer_not_ni_i`` - in + - CACHE - TO_BE_COMPLETED + - logic + + * - ``amo_req_o`` + - out - CACHE + - AMO request + - amo_req_t + + * - ``amo_resp_i`` + - in + - CACHE + - AMO response from cache + - amo_resp_t + + * - ``itlb_miss_o`` + - out + - PERF_COUNTERS + - To count the instruction TLB misses + - logic + + * - ``dtlb_miss_o`` + - out + - PERF_COUNTERS + - To count the data TLB misses - logic * - ``pmpcfg_i`` - in - Report the PMP configuration - CSR_REGFILE + - Report the PMP configuration - riscv::pmpcfg_t[15:0] * - ``pmpaddr_i`` - in - Report the PMP addresses - CSR_REGFILE + - Report the PMP addresses - logic[15:0][riscv::PLEN-3:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_mode_i`` input is tied to 0 -| As EnableAccelerator = 0, -| ``stall_st_pending_i`` input is tied to 0 -| ``acc_valid_i`` input is tied to 0 -| As RVA = 0, -| ``amo_valid_commit_i`` input is tied to 0 -| ``amo_req_o`` output is tied to 0 -| ``amo_resp_i`` input is tied to 0 -| As RVF = 0, -| ``fpu_ready_o`` output is tied to 0 -| ``fpu_valid_i`` input is tied to 0 -| ``fpu_fmt_i`` input is tied to 0 -| ``fpu_rm_i`` input is tied to 0 -| ``fpu_frm_i`` input is tied to 0 -| ``fpu_prec_i`` input is tied to 0 -| ``fpu_trans_id_o`` output is tied to 0 -| ``fpu_result_o`` output is tied to 0 -| ``fpu_valid_o`` output is tied to 0 -| ``fpu_exception_o`` output is tied to 0 -| As MMUPresent = 0, -| ``flush_tlb_i`` input is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| ``ld_st_priv_lvl_i`` input is tied to MAchineMode -| As PerfCounterEn = 0, -| ``itlb_miss_o`` output is tied to 0 -| ``dtlb_miss_o`` output is tied to 0 -| As IsRVFI = 0, -| ``rvfi_lsu_ctrl_o`` output is tied to 0 -| ``rvfi_mem_paddr_o`` output is tied to 0 + * - ``rvfi_lsu_ctrl_o`` + - out + - SUBSYSTEM + - Information dedicated to RVFI + - lsu_ctrl_t + + * - ``rvfi_mem_paddr_o`` + - out + - SUBSYSTEM + - Information dedicated to RVFI + - [riscv::PLEN-1:0] diff --git a/docs/04_cv32a65x_design/source/port_frontend.rst b/docs/04_cv32a65x_design/source/port_frontend.rst index 49405e9d24..177a30f9e4 100644 --- a/docs/04_cv32a65x_design/source/port_frontend.rst +++ b/docs/04_cv32a65x_design/source/port_frontend.rst @@ -22,108 +22,135 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request + - logic + + * - ``flush_bp_i`` + - in + - zero + - flush branch prediction - logic * - ``halt_i`` - in - halt commit stage - CONTROLLER + - halt commit stage + - logic + + * - ``debug_mode_i`` + - in + - CSR + - Debug mode state - logic * - ``boot_addr_i`` - in - Next PC when reset - SUBSYSTEM + - Next PC when reset - logic[riscv::VLEN-1:0] * - ``resolved_branch_i`` - in - mispredict event and next PC - EXECUTE + - mispredict event and next PC - bp_resolve_t * - ``set_pc_commit_i`` - in - Set the PC coming from COMMIT as next PC - CONTROLLER + - Set the PC coming from COMMIT as next PC - logic * - ``pc_commit_i`` - in - Next PC when flushing pipeline - COMMIT + - Next PC when flushing pipeline - logic[riscv::VLEN-1:0] * - ``epc_i`` - in - Next PC when returning from exception - CSR + - Next PC when returning from exception - logic[riscv::VLEN-1:0] * - ``eret_i`` - in - Return from exception event - CSR + - Return from exception event - logic * - ``trap_vector_base_i`` - in - Next PC when jumping into exception - CSR + - Next PC when jumping into exception - logic[riscv::VLEN-1:0] * - ``ex_valid_i`` - in - Exception event - COMMIT + - Exception event + - logic + + * - ``set_debug_pc_i`` + - in + - CSR + - Debug event - logic * - ``icache_dreq_o`` - out - Handshake between CACHE and FRONTEND (fetch) - CACHES + - Handshake between CACHE and FRONTEND (fetch) - icache_dreq_t * - ``icache_dreq_i`` - in - Handshake between CACHE and FRONTEND (fetch) - CACHES + - Handshake between CACHE and FRONTEND (fetch) - icache_drsp_t * - ``fetch_entry_o`` - out - Handshake's data between fetch and decode - ID_STAGE + - Handshake's data between fetch and decode - fetch_entry_t * - ``fetch_entry_valid_o`` - out - Handshake's valid between fetch and decode - ID_STAGE + - Handshake's valid between fetch and decode - logic * - ``fetch_entry_ready_i`` - in - Handshake's ready between fetch and decode - ID_STAGE + - Handshake's ready between fetch and decode - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| For any HW configuration, -| ``flush_bp_i`` input is tied to zero -| As DebugEn = 0, -| ``debug_mode_i`` input is tied to 0 -| ``set_debug_pc_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_id_stage.rst b/docs/04_cv32a65x_design/source/port_id_stage.rst index aaaa305437..8d9ff2dcec 100644 --- a/docs/04_cv32a65x_design/source/port_id_stage.rst +++ b/docs/04_cv32a65x_design/source/port_id_stage.rst @@ -22,109 +22,148 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request + - logic + + * - ``debug_req_i`` + - in + - SUBSYSTEM + - Debug (async) request - logic * - ``fetch_entry_i`` - in - Handshake's data between fetch and decode - FRONTEND + - Handshake's data between fetch and decode - ariane_pkg::fetch_entry_t * - ``fetch_entry_valid_i`` - in - Handshake's valid between fetch and decode - FRONTEND + - Handshake's valid between fetch and decode - logic * - ``fetch_entry_ready_o`` - out - Handshake's ready between fetch and decode - FRONTEND + - Handshake's ready between fetch and decode - logic * - ``issue_entry_o`` - out - Handshake's data between decode and issue - ISSUE + - Handshake's data between decode and issue - ariane_pkg::scoreboard_entry_t * - ``orig_instr_o`` - out - Instruction value - ISSUE + - instruction value - logic[31:0] * - ``issue_entry_valid_o`` - out - Handshake's valid between decode and issue - ISSUE + - Handshake's valid between decode and issue - logic * - ``is_ctrl_flow_o`` - out - Report if instruction is a control flow instruction - ISSUE + - Report if instruction is a control flow instruction - logic * - ``issue_instr_ack_i`` - in - Handshake's acknowlege between decode and issue - ISSUE + - Handshake's acknowlege between decode and issue + - logic + + * - ``rvfi_is_compressed_o`` + - out + - none + - none - logic + * - ``priv_lvl_i`` + - in + - CSR + - Report current privilege level + - riscv::priv_lvl_t + + * - ``fs_i`` + - in + - CSR + - Report floating point extension status + - riscv::xs_t + + * - ``frm_i`` + - in + - CSR + - Report floating point dynamic rounding mode + - logic[2:0] + + * - ``vs_i`` + - in + - CSR + - Report vector extension status + - riscv::xs_t + * - ``irq_i`` - in - Level sensitive (async) interrupts - SUBSYSTEM + - Level sensitive (async) interrupts - logic[1:0] * - ``irq_ctrl_i`` - in - - Interrupt control status - - CSR_REGFILE + - CSR + - TBD - ariane_pkg::irq_ctrl_t + * - ``debug_mode_i`` + - in + - CSR + - Report if current mode is debug + - logic + * - ``tvm_i`` - in - - Trap virtual memory - - CSR_REGFILE + - CSR + - TBD - logic * - ``tw_i`` - in - - Timeout wait - - CSR_REGFILE + - CSR + - TBD - logic * - ``tsr_i`` - in - - Trap sret - - CSR_REGFILE + - none + - none - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_req_i`` input is tied to 0 -| ``debug_mode_i`` input is tied to 0 -| As IsRVFI = 0, -| ``rvfi_is_compressed_o`` output is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| As RVF = 0, -| ``fs_i`` input is tied to 0 -| ``frm_i`` input is tied to 0 -| As RVV = 0, -| ``vs_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_instr_queue.rst b/docs/04_cv32a65x_design/source/port_instr_queue.rst index 6041227c20..f2e0bad520 100644 --- a/docs/04_cv32a65x_design/source/port_instr_queue.rst +++ b/docs/04_cv32a65x_design/source/port_instr_queue.rst @@ -22,104 +22,117 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request - logic * - ``instr_i`` - in - Instruction - instr_realign + - Instruction - logic[ariane_pkg::INSTR_PER_FETCH-1:0][31:0] * - ``addr_i`` - in - Instruction address - instr_realign + - Instruction address - logic[ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] * - ``valid_i`` - in - Instruction is valid - instr_realign + - Instruction is valid - logic[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``ready_o`` - out - Handshake’s ready with CACHE - CACHE + - Handshake’s ready with CACHE - logic * - ``consumed_o`` - out - Indicates instructions consummed, or popped by ID_STAGE - FRONTEND + - Indicates instructions consummed, or popped by ID_STAGE - logic[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``exception_i`` - in - Exception (which is page-table fault) - CACHE + - Exception (which is page-table fault) - ariane_pkg::frontend_exception_t * - ``exception_addr_i`` - in - Exception address - CACHE + - Exception address - logic[riscv::VLEN-1:0] * - ``predict_address_i`` - in - Branch predict - FRONTEND + - Branch predict - logic[riscv::VLEN-1:0] * - ``cf_type_i`` - in - Instruction predict address - FRONTEND + - Instruction predict address - ariane_pkg::cf_t[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``replay_o`` - out - Replay instruction because one of the FIFO was full - FRONTEND + - Replay instruction because one of the FIFO was full - logic * - ``replay_addr_o`` - out - Address at which to replay the fetch - FRONTEND + - Address at which to replay the fetch - logic[riscv::VLEN-1:0] * - ``fetch_entry_o`` - out - Handshake’s data with ID_STAGE - ID_STAGE + - Handshake’s data with ID_STAGE - ariane_pkg::fetch_entry_t * - ``fetch_entry_valid_o`` - out - Handshake’s valid with ID_STAGE - ID_STAGE + - Handshake’s valid with ID_STAGE - logic * - ``fetch_entry_ready_i`` - in - Handshake’s ready with ID_STAGE - ID_STAGE + - Handshake’s ready with ID_STAGE - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -none diff --git a/docs/04_cv32a65x_design/source/port_instr_realign.rst b/docs/04_cv32a65x_design/source/port_instr_realign.rst index baf4e921bf..f11f69e527 100644 --- a/docs/04_cv32a65x_design/source/port_instr_realign.rst +++ b/docs/04_cv32a65x_design/source/port_instr_realign.rst @@ -22,62 +22,67 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request - logic * - ``valid_i`` - in - 32-bit block is valid - CACHE + - 32-bit block is valid - logic * - ``serving_unaligned_o`` - out - Instruction is unaligned - FRONTEND + - Instruction is unaligned - logic * - ``address_i`` - in - 32-bit block address - CACHE + - 32-bit block address - logic[riscv::VLEN-1:0] * - ``data_i`` - in - 32-bit block - CACHE + - 32-bit block - logic[FETCH_WIDTH-1:0] * - ``valid_o`` - out - instruction is valid - FRONTEND + - instruction is valid - logic[INSTR_PER_FETCH-1:0] * - ``addr_o`` - out - Instruction address - FRONTEND + - Instruction address - logic[INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] * - ``instr_o`` - out - - Instruction - - instr_scan&instr_queue + - none + - none - logic[INSTR_PER_FETCH-1:0][31:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -none diff --git a/docs/04_cv32a65x_design/source/port_instr_scan.rst b/docs/04_cv32a65x_design/source/port_instr_scan.rst index a11b0b0d50..4d46c5605f 100644 --- a/docs/04_cv32a65x_design/source/port_instr_scan.rst +++ b/docs/04_cv32a65x_design/source/port_instr_scan.rst @@ -22,86 +22,96 @@ - in - Instruction to be predecoded - instr_realign + - Instruction to be predecoded - logic[31:0] * - ``rvi_return_o`` - out - Return instruction - FRONTEND + - Return instruction - logic * - ``rvi_call_o`` - out - JAL instruction - FRONTEND + - JAL instruction - logic * - ``rvi_branch_o`` - out - Branch instruction - FRONTEND + - Branch instruction - logic * - ``rvi_jalr_o`` - out - JALR instruction - FRONTEND + - JALR instruction - logic * - ``rvi_jump_o`` - out - Unconditional jump instruction - FRONTEND + - Unconditional jump instruction - logic * - ``rvi_imm_o`` - out - Instruction immediat - FRONTEND + - Instruction immediat - logic[riscv::VLEN-1:0] * - ``rvc_branch_o`` - out - Branch compressed instruction - FRONTEND + - Branch compressed instruction - logic * - ``rvc_jump_o`` - out - Unconditional jump compressed instruction - FRONTEND + - Unconditional jump compressed instruction - logic * - ``rvc_jr_o`` - out - JR compressed instruction - FRONTEND + - JR compressed instruction - logic * - ``rvc_return_o`` - out - Return compressed instruction - FRONTEND + - Return compressed instruction - logic * - ``rvc_jalr_o`` - out - JALR compressed instruction - FRONTEND + - JALR compressed instruction - logic * - ``rvc_call_o`` - out - JAL compressed instruction - FRONTEND + - JAL compressed instruction - logic * - ``rvc_imm_o`` - out - Instruction compressed immediat - FRONTEND + - Instruction compressed immediat - logic[riscv::VLEN-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -none diff --git a/docs/04_cv32a65x_design/source/port_issue_stage.rst b/docs/04_cv32a65x_design/source/port_issue_stage.rst index 4e91674586..b7f18e74d8 100644 --- a/docs/04_cv32a65x_design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/port_issue_stage.rst @@ -22,249 +22,331 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low + - logic + + * - ``sb_full_o`` + - out + - PERF_COUNTERS + - TO_BE_COMPLETED - logic * - ``flush_unissued_instr_i`` - in - TO_BE_COMPLETED - CONTROLLER + - TO_BE_COMPLETED - logic * - ``flush_i`` - in - TO_BE_COMPLETED - CONTROLLER + - TO_BE_COMPLETED + - logic + + * - ``stall_i`` + - in + - ACC_DISPATCHER + - zero when accelerate port is disable - logic * - ``decoded_instr_i`` - in - Handshake's data with decode stage - ID_STAGE + - Handshake's data between decode and issue - scoreboard_entry_t * - ``orig_instr_i`` - in - instruction value - ID_STAGE + - instruction value - logic[31:0] * - ``decoded_instr_valid_i`` - in - Handshake's valid with decode stage - ID_STAGE + - Handshake's valid between decode and issue - logic * - ``is_ctrl_flow_i`` - in - Is instruction a control flow instruction - ID_STAGE + - Report if instruction is a control flow instruction - logic * - ``decoded_instr_ack_o`` - out - Handshake's acknowlege with decode stage - ID_STAGE + - Handshake's acknowlege between decode and issue - logic * - ``rs1_forwarding_o`` - out - rs1 forwarding - EX_STAGE + - TO_BE_COMPLETED - [riscv::VLEN-1:0] * - ``rs2_forwarding_o`` - out - rs2 forwarding - EX_STAGE + - TO_BE_COMPLETED - [riscv::VLEN-1:0] * - ``fu_data_o`` - out - FU data useful to execute instruction - EX_STAGE + - TO_BE_COMPLETED - fu_data_t * - ``pc_o`` - out - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``is_compressed_instr_o`` - out - Is compressed instruction - EX_STAGE + - TO_BE_COMPLETED - logic * - ``flu_ready_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic * - ``alu_valid_o`` - out - ALU FU is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``resolve_branch_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic * - ``lsu_ready_i`` - in - Load store unit FU is ready - EX_STAGE + - TO_BE_COMPLETED - logic * - ``lsu_valid_o`` - out - Load store unit FU is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``branch_valid_o`` - out - Branch unit is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``branch_predict_o`` - out - Information of branch prediction - EX_STAGE + - TO_BE_COMPLETED - branchpredict_sbe_t * - ``mult_valid_o`` - out - Mult FU is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``fpu_ready_i`` - in - FPU FU is ready - EX_STAGE + - TO_BE_COMPLETED - logic + * - ``fpu_valid_o`` + - out + - EX_STAGE + - TO_BE_COMPLETED + - logic + + * - ``fpu_fmt_o`` + - out + - EX_STAGE + - Report FP fmt field + - logic[1:0] + + * - ``fpu_rm_o`` + - out + - EX_STAGE + - report FP rm field + - logic[2:0] + * - ``csr_valid_o`` - out - CSR is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``x_issue_valid_o`` - out - CVXIF FU is valid - EX_STAGE + - TO_BE_COMPLETED - logic * - ``x_issue_ready_i`` - in - CVXIF is FU ready - EX_STAGE + - TO_BE_COMPLETED - logic * - ``x_off_instr_o`` - out - CVXIF offloader instruction value - EX_STAGE + - TO_BE_COMPLETED - logic[31:0] + * - ``issue_instr_o`` + - out + - ACC_DISPATCHER + - TO_BE_COMPLETED + - scoreboard_entry_t + + * - ``issue_instr_hs_o`` + - out + - ACC_DISPATCHER + - TO_BE_COMPLETED + - logic + * - ``trans_id_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0][TRANS_ID_BITS-1:0] * - ``resolved_branch_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - bp_resolve_t * - ``wbdata_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] * - ``ex_ex_i`` - in - exception from execute stage or CVXIF - EX_STAGE + - exception from execute stage or CVXIF offloaded instruction - exception_t[CVA6Cfg.NrWbPorts-1:0] * - ``wt_valid_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0] * - ``x_we_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic * - ``waddr_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] * - ``wdata_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] * - ``we_gpr_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``we_fpr_i`` - in - TO_BE_COMPLETED - EX_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_instr_o`` - out - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_i`` - in - TO_BE_COMPLETED - COMMIT_STAGE + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As PerfCounterEn = 0, -| ``sb_full_o`` output is tied to 0 -| ``stall_issue_o`` output is tied to 0 -| As EnableAccelerator = 0, -| ``stall_i`` input is tied to 0 -| ``issue_instr_o`` output is tied to 0 -| ``issue_instr_hs_o`` output is tied to 0 -| As RVF = 0, -| ``fpu_valid_o`` output is tied to 0 -| ``fpu_fmt_o`` output is tied to 0 -| ``fpu_rm_o`` output is tied to 0 -| As IsRVFI = 0, -| ``rvfi_issue_pointer_o`` output is tied to 0 -| ``rvfi_commit_pointer_o`` output is tied to 0 + * - ``stall_issue_o`` + - out + - PERF_COUNTERS + - Issue stall + - logic + + * - ``rvfi_issue_pointer_o`` + - out + - SUBSYSTEM + - Information dedicated to RVFI + - logic[TRANS_ID_BITS-1:0] + + * - ``rvfi_commit_pointer_o`` + - out + - SUBSYSTEM + - Information dedicated to RVFI + - logic[CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] diff --git a/docs/04_cv32a65x_design/source/port_ras.rst b/docs/04_cv32a65x_design/source/port_ras.rst index f91820b462..eece1c5f88 100644 --- a/docs/04_cv32a65x_design/source/port_ras.rst +++ b/docs/04_cv32a65x_design/source/port_ras.rst @@ -22,44 +22,47 @@ - in - Subsystem Clock - SUBSYSTEM + - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM + - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER + - Fetch flush request - logic * - ``push_i`` - in - Push address in RAS - FRONTEND + - Push address in RAS - logic * - ``pop_i`` - in - Pop address from RAS - FRONTEND + - Pop address from RAS - logic * - ``data_i`` - in - Data to be pushed - FRONTEND + - Data to be pushed - logic[riscv::VLEN-1:0] * - ``data_o`` - out - Popped data - FRONTEND + - Popped data - ariane_pkg::ras_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -none From 5b96ea8423890b538a577fef4c2a894bff9d7552 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Tue, 13 Feb 2024 23:36:24 +0100 Subject: [PATCH 07/20] First description of ID_STAGE --- .../source/cva6_id_stage.rst | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index b3445a1893..1e5d5e1ace 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -16,7 +16,7 @@ Description ----------- The ID_STAGE module implements the decode stage of the pipeline. -Its main purpose is to decode RISC-V instructions coming from FRONTEND module +Its main purpose is to decode instructions coming from FRONTEND module (fetch stage) and send them to the ISSUE_STAGE module (issue stage). The compressed_decoder module checks whether the incoming instruction is @@ -53,14 +53,26 @@ Submodules ID_STAGE submodules -Decoder -~~~~~~~ - -TO BE COMPLETED - - Compressed_decoder ~~~~~~~~~~~~~~~~~~ -TO BE COMPLETED +The compressed_decoder module decompresses all the compressed +instructions taking a 16-bit compressed instruction and expanding it +to its 32-bit equivalent. +All compressed instructions have a 32-bit equivalent. + +Decoder +~~~~~~~ + +The decoder module takes the output of compressed_decoder module and decodes +it. +It transforms the instruction to the most fundamental control structure +in pipeline, a scoreboard entry. + +The scoreboard entry contains an exception entry which is composed of a +valid field, a cause and a value called TVAL. +As TVALEn configuration parameter is zero, the TVAL field is not implemented. +A potential illegal instruction exception can be detected during decoding. +If no exception has happened previously in fetch stage, the decoder will +valid the exception and add the cause and tval value to the scoreboard entry. From c5a6463149d27806b431ddd23e9a4a5ed4f3b3b4 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Wed, 14 Feb 2024 09:40:50 +0100 Subject: [PATCH 08/20] Add compressed_decoder and decoder modules in DD --- core/compressed_decoder.sv | 8 +- core/decoder.sv | 28 ++--- .../source/cv32a6_frontend.rst | 8 +- .../source/cva6_id_stage.rst | 4 + .../source/port_compressed_decoder.rst | 22 ++-- .../source/port_decoder.rst | 101 +++++++++++------- 6 files changed, 95 insertions(+), 76 deletions(-) diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 2c0a527172..d3e40fcfb8 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -22,13 +22,13 @@ module compressed_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - // Input instruction coming from fetch stage - FRONTEND + // Input instruction which can be compressed - FRONTEND input logic [31:0] instr_i, - // Output instruction in uncompressed format - decoder + // Output instruction which is uncompressed - ID_STAGE output logic [31:0] instr_o, - // Input instruction is illegal - decoder + // Illegal instruction exception - TO_BE_COMPLETED output logic illegal_instr_o, - // Output instruction is compressed - decoder + // report if instruction is compressed - TO_BE_COMPLETED output logic is_compressed_o ); diff --git a/core/decoder.sv b/core/decoder.sv index 0ebf6b9819..17a02478b0 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -24,29 +24,29 @@ module decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - // Debug (async) request - SUBSYSTEM + // External debug request - TO_BE_COMPLETED input logic debug_req_i, - // PC from fetch stage - FRONTEND + // PC from IF - TO_BE_COMPLETED input logic [riscv::VLEN-1:0] pc_i, - // Is a compressed instruction - compressed_decoder + // Is a compressed instruction - TO_BE_COMPLETED input logic is_compressed_i, - // Compressed form of instruction - FRONTEND + // Compressed form of instruction - TO_BE_COMPLETED input logic [15:0] compressed_instr_i, - // Illegal compressed instruction - compressed_decoder + // Illegal compressed instruction - TO_BE_COMPLETED input logic is_illegal_i, - // Instruction from fetch stage - FRONTEND + // Instruction from IF - TO_BE_COMPLETED input logic [31:0] instruction_i, - // Is a branch predict instruction - FRONTEND + // TO_BE_COMPLETED - TO_BE_COMPLETED input branchpredict_sbe_t branch_predict_i, - // If an exception occured in fetch stage - FRONTEND + // If an exception occured in if - TO_BE_COMPLETED input exception_t ex_i, - // Level sensitive (async) interrupts - SUBSYSTEM + // External interrupt - TO_BE_COMPLETED input logic [1:0] irq_i, - // Interrupt control status - CSR_REGFILE + // Interrupt control and status information from CSRs - TO_BE_COMPLETED input irq_ctrl_t irq_ctrl_i, // Current privilege level - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, - // Is debug mode - CSR_REGFILE + // We are in debug mode - CSR_REGFILE input logic debug_mode_i, // Floating point extension status - CSR_REGFILE input riscv::xs_t fs_i, @@ -60,11 +60,11 @@ module decoder input logic tw_i, // Trap sret - CSR_REGFILE input logic tsr_i, - // Instruction to be added to scoreboard entry - ISSUE_STAGE + // Scoreboard entry to scoreboard - COMMIT_STAGE output scoreboard_entry_t instruction_o, - // Instruction - ISSUE_STAGE + // Instruction opcode to issue read operand for CVXIF - TO_BE_COMPLETED output logic [31:0] orig_instr_o, - // Is a control flow instruction - ISSUE_STAGE + // This instruction will change the control flow - TO_BE_COMPLETED output logic is_control_flow_instr_o ); logic illegal_instr; diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index c650dd305c..b3d1d14140 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -172,9 +172,7 @@ BTB (Branch Target Buffer) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a unconditional jumps to a register (JALR instruction) is mispredicted -by the EXECUTE, the relative information is stored into the BTB, that is -to say the JALR PC and the target address. +When a unconditional jumps to a register (JALR instruction) is mispredicted by the EXECUTE, the relative information is stored into the BTB, that is to say the JALR PC and the target address. The information is stored in a 8 entry table. @@ -194,9 +192,7 @@ RAS (Return Address Stack) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When an unconditional jumps to a known target address (JAL instruction) -is consummed by the instr_queue, the next pc after the JAL instruction -and the return address are stored into a FIFO. +When an unconditional jumps to a known target address (JAL instruction) is consummed by the instr_queue, the next pc after the JAL instruction and the return address are stored into a FIFO. The RAS FIFO depth is 2. diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index 1e5d5e1ace..ab975747df 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -61,6 +61,8 @@ instructions taking a 16-bit compressed instruction and expanding it to its 32-bit equivalent. All compressed instructions have a 32-bit equivalent. +.. include:: port_compressed_decoder.rst + Decoder ~~~~~~~ @@ -76,3 +78,5 @@ A potential illegal instruction exception can be detected during decoding. If no exception has happened previously in fetch stage, the decoder will valid the exception and add the cause and tval value to the scoreboard entry. +.. include:: port_decoder.rst + diff --git a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst index e42dd8e0fb..91d60c7aaa 100644 --- a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst @@ -14,34 +14,30 @@ * - Signal - IO - - Description - - connexion + - Connection - Type + - Description * - ``instr_i`` - in - - Input instruction coming from fetch stage - FRONTEND + - Input instruction which can be compressed - logic[31:0] * - ``instr_o`` - out - - Output instruction in uncompressed format - - decoder + - ID_STAGE + - Output instruction which is uncompressed - logic[31:0] * - ``illegal_instr_o`` - out - - Input instruction is illegal - - decoder + - TO_BE_COMPLETED + - Illegal instruction exception - logic * - ``is_compressed_o`` - out - - Output instruction is compressed - - decoder + - TO_BE_COMPLETED + - report if instruction is compressed - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -none diff --git a/docs/04_cv32a65x_design/source/port_decoder.rst b/docs/04_cv32a65x_design/source/port_decoder.rst index cf3f108d45..3ab480ddb7 100644 --- a/docs/04_cv32a65x_design/source/port_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_decoder.rst @@ -14,109 +14,132 @@ * - Signal - IO - - Description - - connexion + - Connection - Type + - Description + + * - ``debug_req_i`` + - in + - TO_BE_COMPLETED + - External debug request + - logic * - ``pc_i`` - in - - PC from fetch stage - - FRONTEND + - TO_BE_COMPLETED + - PC from IF - logic[riscv::VLEN-1:0] * - ``is_compressed_i`` - in + - TO_BE_COMPLETED - Is a compressed instruction - - compressed_decoder - logic * - ``compressed_instr_i`` - in + - TO_BE_COMPLETED - Compressed form of instruction - - FRONTEND - logic[15:0] * - ``is_illegal_i`` - in + - TO_BE_COMPLETED - Illegal compressed instruction - - compressed_decoder - logic * - ``instruction_i`` - in - - Instruction from fetch stage - - FRONTEND + - TO_BE_COMPLETED + - Instruction from IF - logic[31:0] * - ``branch_predict_i`` - in - - Is a branch predict instruction - - FRONTEND + - TO_BE_COMPLETED + - TO_BE_COMPLETED - branchpredict_sbe_t * - ``ex_i`` - in - - If an exception occured in fetch stage - - FRONTEND + - TO_BE_COMPLETED + - If an exception occured in if - exception_t * - ``irq_i`` - in - - Level sensitive (async) interrupts - - SUBSYSTEM + - TO_BE_COMPLETED + - External interrupt - logic[1:0] * - ``irq_ctrl_i`` - in - - Interrupt control status - - CSR_REGFILE + - TO_BE_COMPLETED + - Interrupt control and status information from CSRs - irq_ctrl_t + * - ``priv_lvl_i`` + - in + - CSR_REGFILE + - Current privilege level + - riscv::priv_lvl_t + + * - ``debug_mode_i`` + - in + - CSR_REGFILE + - We are in debug mode + - logic + + * - ``fs_i`` + - in + - CSR_REGFILE + - Floating point extension status + - riscv::xs_t + + * - ``frm_i`` + - in + - CSR_REGFILE + - Floating-point dynamic rounding mode + - logic[2:0] + + * - ``vs_i`` + - in + - CSR_REGFILE + - Vector extension status + - riscv::xs_t + * - ``tvm_i`` - in - - Trap virtual memory - CSR_REGFILE + - Trap virtual memory - logic * - ``tw_i`` - in - - Timeout wait - CSR_REGFILE + - Timeout wait - logic * - ``tsr_i`` - in - - Trap sret - CSR_REGFILE + - Trap sret - logic * - ``instruction_o`` - out - - Instruction to be added to scoreboard entry - - ISSUE_STAGE + - COMMIT_STAGE + - Scoreboard entry to scoreboard - scoreboard_entry_t * - ``orig_instr_o`` - out - - Instruction - - ISSUE_STAGE + - TO_BE_COMPLETED + - Instruction opcode to issue read operand for CVXIF - logic[31:0] * - ``is_control_flow_instr_o`` - out - - Is a control flow instruction - - ISSUE_STAGE + - TO_BE_COMPLETED + - This instruction will change the control flow - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = 0, -| ``debug_req_i`` input is tied to 0 -| ``debug_mode_i`` input is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| As RVF = 0, -| ``fs_i`` input is tied to 0 -| ``frm_i`` input is tied to 0 -| As RVV = 0, -| ``vs_i`` input is tied to 0 From 9eba442e7aa6bbe56c8a6a7b7223178938528041 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Wed, 14 Feb 2024 10:31:55 +0100 Subject: [PATCH 09/20] ID_STAGE decodes RISC-V isntruction --- docs/04_cv32a65x_design/source/cva6_id_stage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index ab975747df..bb221cac24 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -16,7 +16,7 @@ Description ----------- The ID_STAGE module implements the decode stage of the pipeline. -Its main purpose is to decode instructions coming from FRONTEND module +Its main purpose is to decode RISC-V instructions coming from FRONTEND module (fetch stage) and send them to the ISSUE_STAGE module (issue stage). The compressed_decoder module checks whether the incoming instruction is From 8c66292b3c9e7de8daff76834f15fcf302844b5e Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Wed, 14 Feb 2024 16:58:08 +0100 Subject: [PATCH 10/20] Complete ID_stage port description fix id_stage implement the black_list ports temporary Generate black list ports rename python script Black reformat --- core/alu.sv | 13 +- core/branch_unit.sv | 30 +- core/compressed_decoder.sv | 8 +- core/csr_buffer.sv | 26 +- core/csr_regfile.sv | 8 +- core/cva6.sv | 2 +- core/cvxif_fu.sv | 21 +- core/decoder.sv | 28 +- core/ex_stage.sv | 27 +- core/issue_read_operands.sv | 93 +++-- core/issue_stage.sv | 20 +- core/load_store_unit.sv | 92 ++-- core/load_unit.sv | 46 +- core/lsu_bypass.sv | 9 + core/mult.sv | 13 +- core/multiplier.sv | 17 +- core/scoreboard.sv | 61 ++- core/serdiv.sv | 18 +- core/store_unit.sv | 45 +- .../source/cv32a6_execute.rst | 96 ++++- .../source/cv32a6_frontend.rst | 8 +- .../source/cva6_commit_stage.rst | 14 +- .../source/cva6_issue_stage.rst | 8 +- docs/04_cv32a65x_design/source/port_alu.rst | 53 +++ docs/04_cv32a65x_design/source/port_bht.rst | 17 +- .../source/port_branch_unit.rst | 102 +++++ docs/04_cv32a65x_design/source/port_btb.rst | 17 +- .../source/port_commit_stage.rst | 99 +---- .../source/port_compressed_decoder.rst | 22 +- .../source/port_controller.rst | 76 +--- .../source/port_csr_buffer.rst | 77 ++++ .../source/port_csr_regfile.rst | 284 ++----------- docs/04_cv32a65x_design/source/port_cva6.rst | 30 +- .../source/port_cvxif_fu.rst | 102 +++++ .../source/port_decoder.rst | 116 ++--- .../source/port_ex_stage.rst | 395 +++++------------- .../source/port_frontend.rst | 43 +- .../source/port_id_stage.rst | 92 +--- .../source/port_instr_queue.rst | 21 +- .../source/port_instr_realign.rst | 17 +- .../source/port_instr_scan.rst | 18 +- .../source/port_issue_read_operands.rst | 245 +++++------ .../source/port_issue_stage.rst | 146 ++----- .../source/port_load_store_unit.rst | 208 +++++++++ .../source/port_load_unit.rst | 152 +++++++ .../source/port_lsu_bypass.rst | 77 ++++ docs/04_cv32a65x_design/source/port_mult.rst | 77 ++++ .../source/port_multiplier.rst | 89 ++++ docs/04_cv32a65x_design/source/port_ras.rst | 11 +- .../source/port_scoreboard.rst | 192 ++++----- .../04_cv32a65x_design/source/port_serdiv.rst | 101 +++++ .../source/port_store_unit.rst | 168 ++++++++ docs/scripts/define_blacklist.py | 63 ++- docs/scripts/spec_builder.py | 11 + 54 files changed, 2293 insertions(+), 1531 deletions(-) create mode 100644 docs/04_cv32a65x_design/source/port_alu.rst create mode 100644 docs/04_cv32a65x_design/source/port_branch_unit.rst create mode 100644 docs/04_cv32a65x_design/source/port_csr_buffer.rst create mode 100644 docs/04_cv32a65x_design/source/port_cvxif_fu.rst create mode 100644 docs/04_cv32a65x_design/source/port_load_store_unit.rst create mode 100644 docs/04_cv32a65x_design/source/port_load_unit.rst create mode 100644 docs/04_cv32a65x_design/source/port_lsu_bypass.rst create mode 100644 docs/04_cv32a65x_design/source/port_mult.rst create mode 100644 docs/04_cv32a65x_design/source/port_multiplier.rst create mode 100644 docs/04_cv32a65x_design/source/port_serdiv.rst create mode 100644 docs/04_cv32a65x_design/source/port_store_unit.rst diff --git a/core/alu.sv b/core/alu.sv index a928725ebc..fd65e585db 100644 --- a/core/alu.sv +++ b/core/alu.sv @@ -23,11 +23,16 @@ module alu #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - input fu_data_t fu_data_i, + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // FU data needed to execute instruction - ISSUE_STAGE + input fu_data_t fu_data_i, + // ALU result - ISSUE_STAGE output riscv::xlen_t result_o, - output logic alu_branch_res_o + // ALU branch compare result - branch_unit + output logic alu_branch_res_o ); riscv::xlen_t operand_a_rev; diff --git a/core/branch_unit.sv b/core/branch_unit.sv index d04adb7308..7bbd3d9c39 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -15,22 +15,34 @@ module branch_unit #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( + // Subsystem Clock - SUBSYSTEM input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Debug mode state - CSR_REGFILE input logic debug_mode_i, + // FU data needed to execute instruction - ISSUE_STAGE input ariane_pkg::fu_data_t fu_data_i, - input logic [riscv::VLEN-1:0] pc_i, // PC of instruction + // Instruction PC - ISSUE_STAGE + input logic [riscv::VLEN-1:0] pc_i, + // Instruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, - input logic fu_valid_i, // any functional unit is valid, check that there is no accidental mis-predict + // any functional unit is valid, check that there is no accidental mis-predict - TO_BE_COMPLETED + input logic fu_valid_i, + // Branch unit instruction is valid - ISSUE_STAGE input logic branch_valid_i, - input logic branch_comp_res_i, // branch comparison result from ALU + // ALU branch compare result - ALU + input logic branch_comp_res_i, + // Brach unit result - ISSUE_STAGE output logic [riscv::VLEN-1:0] branch_result_o, - - input ariane_pkg::branchpredict_sbe_t branch_predict_i, // this is the address we predicted - output ariane_pkg::bp_resolve_t resolved_branch_o, // this is the actual address we are targeting - output logic resolve_branch_o, // to ID to clear that we resolved the branch and we can - // accept new entries to the scoreboard - output ariane_pkg::exception_t branch_exception_o // branch exception out + // Information of branch prediction - ISSUE_STAGE + input ariane_pkg::branchpredict_sbe_t branch_predict_i, + // Signaling that we resolved the branch - ISSUE_STAGE + output ariane_pkg::bp_resolve_t resolved_branch_o, + // Branch is resolved, new entries can be accept by scoreboard - ID_STAGE + output logic resolve_branch_o, + // Branch exception out - TO_BE_COMPLETED + output ariane_pkg::exception_t branch_exception_o ); logic [riscv::VLEN-1:0] target_address; logic [riscv::VLEN-1:0] next_pc; diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index d3e40fcfb8..2c0a527172 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -22,13 +22,13 @@ module compressed_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - // Input instruction which can be compressed - FRONTEND + // Input instruction coming from fetch stage - FRONTEND input logic [31:0] instr_i, - // Output instruction which is uncompressed - ID_STAGE + // Output instruction in uncompressed format - decoder output logic [31:0] instr_o, - // Illegal instruction exception - TO_BE_COMPLETED + // Input instruction is illegal - decoder output logic illegal_instr_o, - // report if instruction is compressed - TO_BE_COMPLETED + // Output instruction is compressed - decoder output logic is_compressed_o ); diff --git a/core/csr_buffer.sv b/core/csr_buffer.sv index 57be04dda4..456fd63d3e 100644 --- a/core/csr_buffer.sv +++ b/core/csr_buffer.sv @@ -19,18 +19,24 @@ module csr_buffer #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // Flush CSR - CONTROLLER input logic flush_i, - + // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, - - output logic csr_ready_o, // FU is ready e.g. not busy - input logic csr_valid_i, // Input is valid - output riscv::xlen_t csr_result_o, - input logic csr_commit_i, // commit the pending CSR OP - // to CSR file - output logic [11:0] csr_addr_o // CSR address to commit stage + // CSR FU is ready - ISSUE_STAGE + output logic csr_ready_o, + // CSR instruction is valid - ISSUE_STAGE + input logic csr_valid_i, + // CSR buffer result - ISSUE_STAGE + output riscv::xlen_t csr_result_o, + // commit the pending CSR OP - TO_BE_COMPLETED + input logic csr_commit_i, + // CSR address to write - COMMIT_STAGE + output logic [11:0] csr_addr_o ); // this is a single entry store buffer for the address of the CSR // which we are going to need in the commit stage diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 8ddf8fd478..68be675cde 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -83,15 +83,15 @@ module csr_regfile output riscv::xs_t vs_o, // interrupt management to id stage - ID_STAGE output irq_ctrl_t irq_ctrl_o, - // enable VA translation - EX_STAGE + // enable virtual address translation - EX_STAGE output logic en_translation_o, - // enable VA translation for load and stores - EX_STAGE + // enable virtual address translation for load and stores - EX_STAGE output logic en_ld_st_translation_o, // Privilege level at which load and stores should happen - EX_STAGE output riscv::priv_lvl_t ld_st_priv_lvl_o, - // TO_BE_COMPLETED - EX_STAGE + // Supervisor User Memory - EX_STAGE output logic sum_o, - // TO_BE_COMPLETED - EX_STAGE + // Make Executable Readable - EX_STAGE output logic mxr_o, // TO_BE_COMPLETED - EX_STAGE output logic [ riscv::PPNW-1:0] satp_ppn_o, diff --git a/core/cva6.sv b/core/cva6.sv index 385a487908..9b40998ebf 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -131,7 +131,7 @@ module cva6 input logic time_irq_i, // Debug (async) request - SUBSYSTEM input logic debug_req_i, - // Probes to build RVFI, can be left open when not used - SUBSYSTEM + // Probes to build RVFI, can be left open when not used - RVFI output rvfi_probes_t rvfi_probes_o, // CVXIF request - SUBSYSTEM output cvxif_req_t cvxif_req_o, diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index ebe180621c..7543150e12 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -15,22 +15,33 @@ module cvxif_fu #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, - input logic rst_ni, + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, + // Current privilege mode - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, - //from issue + // CVXIF instruction is valid - ISSUE_STAGE input logic x_valid_i, + // CVXIF is ready - ISSUE_STAGE output logic x_ready_o, + // undecoded instruction - ISSUE_STAGE input logic [ 31:0] x_off_instr_i, - //to writeback + // CVXIF transaction ID - ISSUE_STAGE output logic [TRANS_ID_BITS-1:0] x_trans_id_o, + // CVXIF exception - ISSUE_STAGE output exception_t x_exception_o, + // CVXIF FU result - ISSUE_STAGE output riscv::xlen_t x_result_o, + // CVXIF result valid - ISSUE_STAGE output logic x_valid_o, + // CVXIF write enable - ISSUE_STAGE output logic x_we_o, - //to coprocessor + // CVXIF request - SUBSYSTEM output cvxif_pkg::cvxif_req_t cvxif_req_o, + // CVXIF response - SUBSYSTEM input cvxif_pkg::cvxif_resp_t cvxif_resp_i ); localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; diff --git a/core/decoder.sv b/core/decoder.sv index 17a02478b0..0ebf6b9819 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -24,29 +24,29 @@ module decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - // External debug request - TO_BE_COMPLETED + // Debug (async) request - SUBSYSTEM input logic debug_req_i, - // PC from IF - TO_BE_COMPLETED + // PC from fetch stage - FRONTEND input logic [riscv::VLEN-1:0] pc_i, - // Is a compressed instruction - TO_BE_COMPLETED + // Is a compressed instruction - compressed_decoder input logic is_compressed_i, - // Compressed form of instruction - TO_BE_COMPLETED + // Compressed form of instruction - FRONTEND input logic [15:0] compressed_instr_i, - // Illegal compressed instruction - TO_BE_COMPLETED + // Illegal compressed instruction - compressed_decoder input logic is_illegal_i, - // Instruction from IF - TO_BE_COMPLETED + // Instruction from fetch stage - FRONTEND input logic [31:0] instruction_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, - // If an exception occured in if - TO_BE_COMPLETED + // If an exception occured in fetch stage - FRONTEND input exception_t ex_i, - // External interrupt - TO_BE_COMPLETED + // Level sensitive (async) interrupts - SUBSYSTEM input logic [1:0] irq_i, - // Interrupt control and status information from CSRs - TO_BE_COMPLETED + // Interrupt control status - CSR_REGFILE input irq_ctrl_t irq_ctrl_i, // Current privilege level - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, - // We are in debug mode - CSR_REGFILE + // Is debug mode - CSR_REGFILE input logic debug_mode_i, // Floating point extension status - CSR_REGFILE input riscv::xs_t fs_i, @@ -60,11 +60,11 @@ module decoder input logic tw_i, // Trap sret - CSR_REGFILE input logic tsr_i, - // Scoreboard entry to scoreboard - COMMIT_STAGE + // Instruction to be added to scoreboard entry - ISSUE_STAGE output scoreboard_entry_t instruction_o, - // Instruction opcode to issue read operand for CVXIF - TO_BE_COMPLETED + // Instruction - ISSUE_STAGE output logic [31:0] orig_instr_o, - // This instruction will change the control flow - TO_BE_COMPLETED + // Is a control flow instruction - ISSUE_STAGE output logic is_control_flow_instr_o ); logic illegal_instr; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index e31f7b2670..646097c976 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -26,7 +26,7 @@ module ex_stage input logic rst_ni, // Fetch flush request - CONTROLLER input logic flush_i, - // TO_BE_COMPLETED - CSR_REGFILE + // Mode is debug - CSR_REGFILE input logic debug_mode_i, // rs1 forwarding - ISSUE_STAGE input logic [riscv::VLEN-1:0] rs1_forwarding_i, @@ -38,11 +38,11 @@ module ex_stage input logic [riscv::VLEN-1:0] pc_i, // Report whether isntruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, - // TO_BE_COMPLETED - ISSUE_STAGE + // Fixed Latency Unit result - ISSUE_STAGE output riscv::xlen_t flu_result_o, // ID of the scoreboard entry at which a=to write back - ISSUE_STAGE output logic [TRANS_ID_BITS-1:0] flu_trans_id_o, - // TO_BE_COMPLETED - ISSUE_STAGE + // Fixed Latency Unit exception - ISSUE_STAGE output exception_t flu_exception_o, // FLU is ready - ISSUE_STAGE output logic flu_ready_o, @@ -62,7 +62,7 @@ module ex_stage input logic csr_valid_i, // CSR address to write - COMMIT_STAGE output logic [11:0] csr_addr_o, - // TO_BE_COMPLETED - COMMIT_STAGE + // CSR commit - COMMIT_STAGE input logic csr_commit_i, // MULT instruction is valid - ISSUE_STAGE input logic mult_valid_i, @@ -86,11 +86,11 @@ module ex_stage output logic [TRANS_ID_BITS-1:0] store_trans_id_o, // Exception generated by store instruction - ISSUE_STAGE output exception_t store_exception_o, - // TO_BE_COMPLETED - COMMIT_STAGE + // LSU commit - COMMIT_STAGE input logic lsu_commit_i, // Commit queue ready to accept another commit request - COMMIT_STAGE output logic lsu_commit_ready_o, - // TO_BE_COMPLETED - COMMIT_STAGE + // Commit transaction ID - COMMIT_STAGE input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, // TO_BE_COMPLETED - ACC_DISPATCHER input logic stall_st_pending_i, @@ -140,11 +140,11 @@ module ex_stage input cvxif_pkg::cvxif_resp_t cvxif_resp_i, // accelerate port result is valid - ACC_DISPATCHER input logic acc_valid_i, - // TO_BE_COMPLETED - CSR_REGFILE + // Enable virtual memory translation - CSR_REGFILE input logic enable_translation_i, - // TO_BE_COMPLETED - CSR_REGFILE + // Enable virtual memory translation for load/stores - CSR_REGFILE input logic en_ld_st_translation_i, - // TO_BE_COMPLETED - CONTROLLER + // Flush TLB - CONTROLLER input logic flush_tlb_i, // Privilege mode - CSR_REGFILE input riscv::priv_lvl_t priv_lvl_i, @@ -162,18 +162,17 @@ module ex_stage input icache_arsp_t icache_areq_i, // icache translation request - CACHE output icache_areq_t icache_areq_o, - // TO_BE_COMPLETED - CACHE - // interface to dcache + // Data cache request ouput - CACHE input dcache_req_o_t [2:0] dcache_req_ports_i, - // TO_BE_COMPLETED - CACHE + // Data cache request input - CACHE output dcache_req_i_t [2:0] dcache_req_ports_o, - // TO_BE_COMPLETED - CACHE + // Write buffer is empty - CACHE input logic dcache_wbuffer_empty_i, // TO_BE_COMPLETED - CACHE input logic dcache_wbuffer_not_ni_i, // AMO request - CACHE output amo_req_t amo_req_o, - // AMO response from cache - CACHE + // AMO response - CACHE input amo_resp_t amo_resp_i, // To count the instruction TLB misses - PERF_COUNTERS output logic itlb_miss_o, diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index b62d016b88..2254a5b93a 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -20,69 +20,96 @@ module issue_read_operands parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rs3_len_t = logic ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - // flush + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // Flush - CONTROLLER input logic flush_i, - // stall + // Stall inserted by Acc dispatcher - ACC_DISPATCHER input logic stall_i, - // coming from decoder + // TO_BE_COMPLETED - TO_BE_COMPLETED input scoreboard_entry_t issue_instr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [31:0] orig_instr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic issue_instr_valid_i, + // Issue stage acknowledge - TO_BE_COMPLETED output logic issue_ack_o, - // lookup rd in scoreboard + // rs1 operand - scoreboard output logic [REG_ADDR_SIZE-1:0] rs1_o, + // rs1 operand - scoreboard input riscv::xlen_t rs1_i, + // rs1 operand is valid - scoreboard input logic rs1_valid_i, + // rs2 operand - scoreboard output logic [REG_ADDR_SIZE-1:0] rs2_o, + // rs2 operand - scoreboard input riscv::xlen_t rs2_i, + // rs2 operand is valid - scoreboard input logic rs2_valid_i, + // rs3 operand - scoreboard output logic [REG_ADDR_SIZE-1:0] rs3_o, + // rs3 operand - scoreboard input rs3_len_t rs3_i, + // rs3 operand is valid - scoreboard input logic rs3_valid_i, // get clobber input + // TO_BE_COMPLETED - TO_BE_COMPLETED input fu_t [2**REG_ADDR_SIZE-1:0] rd_clobber_gpr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input fu_t [2**REG_ADDR_SIZE-1:0] rd_clobber_fpr_i, - // To FU, just single issue for now + // TO_BE_COMPLETED - TO_BE_COMPLETED output fu_data_t fu_data_o, - output riscv::xlen_t rs1_forwarding_o, // unregistered version of fu_data_o.operanda - output riscv::xlen_t rs2_forwarding_o, // unregistered version of fu_data_o.operandb + // unregistered version of fu_data_o.operanda - TO_BE_COMPLETED + output riscv::xlen_t rs1_forwarding_o, + // unregistered version of fu_data_o.operandb - TO_BE_COMPLETED + output riscv::xlen_t rs2_forwarding_o, + // Instruction pc - TO_BE_COMPLETED output logic [riscv::VLEN-1:0] pc_o, + // Is compressed instruction - TO_BE_COMPLETED output logic is_compressed_instr_o, - // ALU 1 - input logic flu_ready_i, // Fixed latency unit ready to accept a new request - output logic alu_valid_o, // Output is valid - // Branches and Jumps - output logic branch_valid_o, // this is a valid branch instruction + // Fixed latency unit ready to accept new request - TO_BE_COMPLETED + input logic flu_ready_i, + // ALU output is valid - TO_BE_COMPLETED + output logic alu_valid_o, + // branch instruction is valid - TO_BE_COMPLETED + output logic branch_valid_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED output branchpredict_sbe_t branch_predict_o, - // LSU - input logic lsu_ready_i, // FU is ready - output logic lsu_valid_o, // Output is valid - // MULT - output logic mult_valid_o, // Output is valid - // FPU - input logic fpu_ready_i, // FU is ready - output logic fpu_valid_o, // Output is valid - output logic [1:0] fpu_fmt_o, // FP fmt field from instr. - output logic [2:0] fpu_rm_o, // FP rm field from instr. - // CSR - output logic csr_valid_o, // Output is valid - // CVXIF + // load store unit is ready - TO_BE_COMPLETED + input logic lsu_ready_i, + // load store unit result is valid - TO_BE_COMPLETED + output logic lsu_valid_o, + // mult result is valid - TO_BE_COMPLETED + output logic mult_valid_o, + // FPU is ready - TO_BE_COMPLETED + input logic fpu_ready_i, + // FPU result is valid - TO_BE_COMPLETED + output logic fpu_valid_o, + // FPU fmt field from instruction - TO_BE_COMPLETED + output logic [1:0] fpu_fmt_o, + // FPU rm field from isntruction - TO_BE_COMPLETED + output logic [2:0] fpu_rm_o, + // CSR result is valid - TO_BE_COMPLETED + output logic csr_valid_o, + // CVXIF result is valid - TO_BE_COMPLETED output logic cvxif_valid_o, + // CVXIF is ready - TO_BE_COMPLETED input logic cvxif_ready_i, + // CVXIF offloaded instruction - TO_BE_COMPLETED output logic [31:0] cvxif_off_instr_o, - // commit port + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i, - output logic stall_issue_o // stall signal, we do not want to fetch any more entries - // committing instruction instruction - // from scoreboard - // input scoreboard_entry commit_instr_i, - // output logic commit_ack_o + // Stall signal, we do not want to fetch any more entries - TO_BE_COMPLETED + output logic stall_issue_o ); logic stall; logic fu_busy; // functional unit is busy diff --git a/core/issue_stage.sv b/core/issue_stage.sv index d046b24f68..ac9c8518b7 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -47,15 +47,15 @@ module issue_stage output [riscv::VLEN-1:0] rs2_forwarding_o, // FU data useful to execute instruction - EX_STAGE output fu_data_t fu_data_o, - // TO_BE_COMPLETED - EX_STAGE + // Program Counter - EX_STAGE output logic [riscv::VLEN-1:0] pc_o, // Is compressed instruction - EX_STAGE output logic is_compressed_instr_o, - // TO_BE_COMPLETED - EX_STAGE + // Fixed Latency Unit is ready - EX_STAGE input logic flu_ready_i, // ALU FU is valid - EX_STAGE output logic alu_valid_o, - // TO_BE_COMPLETED - EX_STAGE + // Signaling that we resolved the branch - EX_STAGE input logic resolve_branch_i, // Load store unit FU is ready - EX_STAGE input logic lsu_ready_i, @@ -87,9 +87,9 @@ module issue_stage output scoreboard_entry_t issue_instr_o, // TO_BE_COMPLETED - ACC_DISPATCHER output logic issue_instr_hs_o, - // TO_BE_COMPLETED - EX_STAGE + // Transaction ID - EX_STAGE input logic [CVA6Cfg.NrWbPorts-1:0][TRANS_ID_BITS-1:0] trans_id_i, - // TO_BE_COMPLETED - EX_STAGE + // The branch engine uses the write back from the ALU - EX_STAGE input bp_resolve_t resolved_branch_i, // TO_BE_COMPLETED - EX_STAGE input logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, @@ -97,19 +97,19 @@ module issue_stage input exception_t [CVA6Cfg.NrWbPorts-1:0] ex_ex_i, // TO_BE_COMPLETED - EX_STAGE input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, - // TO_BE_COMPLETED - EX_STAGE + // CVXIF write enable - EX_STAGE input logic x_we_i, // TO_BE_COMPLETED - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i, // TO_BE_COMPLETED - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] wdata_i, - // TO_BE_COMPLETED - EX_STAGE + // GPR write enable - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr_i, - // TO_BE_COMPLETED - EX_STAGE + // FPR write enable - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i, - // TO_BE_COMPLETED - COMMIT_STAGE + // Commit instruction - COMMIT_STAGE output scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_o, - // TO_BE_COMPLETED - COMMIT_STAGE + // Commit acknowledge - COMMIT_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, // Issue stall - PERF_COUNTERS output logic stall_issue_o, diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 9a5c9245c6..1687cd2be3 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -19,65 +19,103 @@ module load_store_unit parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned ASID_WIDTH = 1 ) ( - input logic clk_i, - input logic rst_ni, + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic stall_st_pending_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic no_st_pending_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic amo_valid_commit_i, - + // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, - output logic lsu_ready_o, // FU is ready e.g. not busy - input logic lsu_valid_i, // Input is valid - - output logic [TRANS_ID_BITS-1:0] load_trans_id_o, // ID of scoreboard entry at which to write back + // Load and store unit is ready - ISSUE_STAGE + output logic lsu_ready_o, + // Load and Store unit is valid - ISSUE_STAGE + input logic lsu_valid_i, + + // Load transaction ID - ISSUE_STAGE + output logic [TRANS_ID_BITS-1:0] load_trans_id_o, + // Load result - ISSUE_STAGE output riscv::xlen_t load_result_o, + // Load result is valid - ISSUE_STAGE output logic load_valid_o, - output exception_t load_exception_o, // to WB, signal exception status LD exception + // Load exception - ISSUE_STAGE + output exception_t load_exception_o, - output logic [TRANS_ID_BITS-1:0] store_trans_id_o, // ID of scoreboard entry at which to write back + // Store transaction ID - ISSUE_STAGE + output logic [TRANS_ID_BITS-1:0] store_trans_id_o, + // Store result - ISSUE_STAGE output riscv::xlen_t store_result_o, + // Store result is valid - ISSUE_STAGE output logic store_valid_o, - output exception_t store_exception_o, // to WB, signal exception status ST exception - - input logic commit_i, // commit the pending store - output logic commit_ready_o, // commit queue is ready to accept another commit request + // Store exception - ISSUE_STAGE + output exception_t store_exception_o, + + // Commit the pending store - TO_BE_COMPLETED + input logic commit_i, + // commit queue is ready to accept another commit request - TO_BE_COMPLETED + output logic commit_ready_o, + // Commit transaction ID - TO_BE_COMPLETED input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, - input logic enable_translation_i, // enable virtual memory translation - input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores + // Enable virtual memory translation - TO_BE_COMPLETED + input logic enable_translation_i, + // Enable virtual memory translation for load/stores - TO_BE_COMPLETED + input logic en_ld_st_translation_i, - // icache translation requests + // Instruction cache input request - CACHES input icache_arsp_t icache_areq_i, + // Instruction cache output request - CACHES output icache_areq_t icache_areq_o, - input riscv::priv_lvl_t priv_lvl_i, // From CSR register file - input riscv::priv_lvl_t ld_st_priv_lvl_i, // From CSR register file - input logic sum_i, // From CSR register file - input logic mxr_i, // From CSR register file - input logic [riscv::PPNW-1:0] satp_ppn_i, // From CSR register file - input logic [ ASID_WIDTH-1:0] asid_i, // From CSR register file + // Current privilege mode - CSR_REGFILE + input riscv::priv_lvl_t priv_lvl_i, + // Privilege level at which load and stores should happen - CSR_REGFILE + input riscv::priv_lvl_t ld_st_priv_lvl_i, + // Supervisor User Memory - CSR_REGFILE + input logic sum_i, + // Make Executable Readable - CSR_REGFILE + input logic mxr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED + input logic [riscv::PPNW-1:0] satp_ppn_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED + input logic [ ASID_WIDTH-1:0] asid_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [ ASID_WIDTH-1:0] asid_to_be_flushed_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i, + // TLB flush - CONTROLLER input logic flush_tlb_i, - // Performance counters + // instruction TLB miss - PERF_COUNTERS output logic itlb_miss_o, + // data TLB miss - PERF_COUNTERS output logic dtlb_miss_o, - // interface to dcache + // Data cache request output - CACHES input dcache_req_o_t [ 2:0] dcache_req_ports_i, + // Data cache request input - CACHES output dcache_req_i_t [ 2:0] dcache_req_ports_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic dcache_wbuffer_empty_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic dcache_wbuffer_not_ni_i, - // AMO interface + // AMO request - CACHE output amo_req_t amo_req_o, + // AMO response - CACHE input amo_resp_t amo_resp_i, - // PMP + // PMP configuration - CSR_REGFILE input riscv::pmpcfg_t [15:0] pmpcfg_i, + // PMP address - CSR_REGFILE input logic [15:0][riscv::PLEN-3:0] pmpaddr_i, - //RVFI + // RVFI inforamtion - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, + // RVFI information - RVFI output [riscv::PLEN-1:0] rvfi_mem_paddr_o ); // data is misaligned diff --git a/core/load_unit.sv b/core/load_unit.sv index 512b498cf3..d6be99d8f5 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -23,33 +23,51 @@ module load_unit #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, - // load unit input port + // load unit input port - TO_BE_COMPLETED input logic valid_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input lsu_ctrl_t lsu_ctrl_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic pop_ld_o, - // load unit output port + // load unit result is valid - TO_BE_COMPLETED output logic valid_o, + // Load transaction ID - TO_BE_COMPLETED output logic [TRANS_ID_BITS-1:0] trans_id_o, + // Load result - TO_BE_COMPLETED output riscv::xlen_t result_o, + // Load exception - TO_BE_COMPLETED output exception_t ex_o, - // MMU -> Address Translation - output logic translation_req_o, // request address translation - output logic [riscv::VLEN-1:0] vaddr_o, // virtual address out - input logic [riscv::PLEN-1:0] paddr_i, // physical address in - input exception_t ex_i, // exception which may has happened earlier. for example: mis-aligned exception - input logic dtlb_hit_i, // hit on the dtlb, send in the same cycle as the request - input logic [riscv::PPNW-1:0] dtlb_ppn_i, // ppn on the dtlb, send in the same cycle as the request - // address checker + // Request address translation - TO_BE_COMPLETED + output logic translation_req_o, + // Vistual address - TO_BE_COMPLETED + output logic [riscv::VLEN-1:0] vaddr_o, + // Physical address - TO_BE_COMPLETED + input logic [riscv::PLEN-1:0] paddr_i, + // Excepted which appears before load - TO_BE_COMPLETED + input exception_t ex_i, + // Data TLB hit - lsu + input logic dtlb_hit_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED + input logic [riscv::PPNW-1:0] dtlb_ppn_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic [11:0] page_offset_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic page_offset_matches_i, - input logic store_buffer_empty_i, // the entire store-buffer is empty + // Stoer buffer is empty - TO_BE_COMPLETED + input logic store_buffer_empty_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, - // D$ interface + // Data cache request out - CACHES input dcache_req_o_t req_port_i, + // Data cache request in - CACHES output dcache_req_i_t req_port_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic dcache_wbuffer_not_ni_i ); enum logic [3:0] { diff --git a/core/lsu_bypass.sv b/core/lsu_bypass.sv index 96f6d50252..5790c73a95 100644 --- a/core/lsu_bypass.sv +++ b/core/lsu_bypass.sv @@ -28,16 +28,25 @@ module lsu_bypass #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( + // Subsystem Clock - SUBSYSTEM input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input lsu_ctrl_t lsu_req_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic lsu_req_valid_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic pop_ld_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic pop_st_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output lsu_ctrl_t lsu_ctrl_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic ready_o ); diff --git a/core/mult.sv b/core/mult.sv index 7270389569..4f1e2bb0ea 100644 --- a/core/mult.sv +++ b/core/mult.sv @@ -5,14 +5,23 @@ module mult #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, - input logic rst_ni, + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // Flush - CONTROLLER input logic flush_i, + // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, + // Mult instruction is valid - ISSUE_STAGE input logic mult_valid_i, + // Mult result - ISSUE_STAGE output riscv::xlen_t result_o, + // Mult result is valid - ISSUE_STAGE output logic mult_valid_o, + // Mutl is ready - ISSUE_STAGE output logic mult_ready_o, + // Mult transaction ID - ISSUE_STAGE output logic [TRANS_ID_BITS-1:0] mult_trans_id_o ); logic mul_valid; diff --git a/core/multiplier.sv b/core/multiplier.sv index e13d614749..44f44ca93d 100644 --- a/core/multiplier.sv +++ b/core/multiplier.sv @@ -20,17 +20,28 @@ module multiplier #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, - input logic rst_ni, + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // Multiplier transaction ID - Mult input logic [TRANS_ID_BITS-1:0] trans_id_i, + // Multiplier instruction is valid - Mult input logic mult_valid_i, + // Multiplier operation - Mult input fu_op operation_i, + // A operand - Mult input riscv::xlen_t operand_a_i, + // B operand - Mult input riscv::xlen_t operand_b_i, + // Multiplier result - Mult output riscv::xlen_t result_o, + // Mutliplier result is valid - Mult output logic mult_valid_o, + // Multiplier FU is ready - Mult output logic mult_ready_o, - output logic [TRANS_ID_BITS-1:0] mult_trans_id_o + // Multiplier transaction ID - Mult + output logic [TRANS_ID_BITS-1:0] mult_trans_id_o ); // Carry-less multiplication logic [riscv::XLEN-1:0] diff --git a/core/scoreboard.sv b/core/scoreboard.sv index d5c06848e7..d274427059 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -16,56 +16,87 @@ module scoreboard #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rs3_len_t = logic ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic sb_full_o, - input logic flush_unissued_instr_i, // flush only un-issued instructions - input logic flush_i, // flush whole scoreboard - input logic unresolved_branch_i, // we have an unresolved branch - // list of clobbered registers to issue stage + // Flush only un-issued instructions - TO_BE_COMPLETED + input logic flush_unissued_instr_i, + // Flush whole scoreboard - TO_BE_COMPLETED + input logic flush_i, + // We have an unresolved branch - TO_BE_COMPLETED + input logic unresolved_branch_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_gpr_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_fpr_o, - // regfile like interface to operand read stage + // rs1 operand - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i, + // rs1 operand - issue_read_operands output riscv::xlen_t rs1_o, + // rs1 operand is valid - issue_read_operands output logic rs1_valid_o, + // rs2 operand - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs2_i, + // rs2 operand - issue_read_operands output riscv::xlen_t rs2_o, + // rs2 operand is valid - issue_read_operands output logic rs2_valid_o, + // rs3 operand - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs3_i, + // rs3 operand - issue_read_operands output rs3_len_t rs3_o, + // rs3 operand is valid - issue_read_operands output logic rs3_valid_o, // advertise instruction to commit stage, if commit_ack_i is asserted advance the commit pointer + // TO_BE_COMPLETED - TO_BE_COMPLETED output ariane_pkg::scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, // instruction to put on top of scoreboard e.g.: top pointer // we can always put this instruction to the top unless we signal with asserted full_o + // TO_BE_COMPLETED - TO_BE_COMPLETED input ariane_pkg::scoreboard_entry_t decoded_instr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [31:0] orig_instr_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic decoded_instr_valid_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic decoded_instr_ack_o, // instruction to issue logic, if issue_instr_valid and issue_ready is asserted, advance the issue pointer + // Issue scoreboard entry - ACC_DISPATCHER output ariane_pkg::scoreboard_entry_t issue_instr_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic [31:0] orig_instr_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic issue_instr_valid_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic issue_ack_i, - // write-back port + // TO_BE_COMPLETED - TO_BE_COMPLETED input ariane_pkg::bp_resolve_t resolved_branch_i, - input logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] trans_id_i, // transaction ID at which to write the result back - input logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, // write data in - input ariane_pkg::exception_t [CVA6Cfg.NrWbPorts-1:0] ex_i, // exception from a functional unit (e.g.: ld/st exception) - input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, // data in is valid - input logic x_we_i, // cvxif we for writeback - - // RVFI + // Transaction ID at which to write the result back - TO_BE_COMPLETED + input logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] trans_id_i, + // Write data in - TO_BE_COMPLETED + input logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, + // Exception from a functional unit (e.g.: ld/st exception) - TO_BE_COMPLETED + input ariane_pkg::exception_t [CVA6Cfg.NrWbPorts-1:0] ex_i, + // Data in is valid - TO_BE_COMPLETED + input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, + // Cvxif we for writeback - TO_BE_COMPLETED + input logic x_we_i, + + // TO_BE_COMPLETED - RVFI output logic [ariane_pkg::TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, + // TO_BE_COMPLETED - RVFI output logic [CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] rvfi_commit_pointer_o ); diff --git a/core/serdiv.sv b/core/serdiv.sv index 244ee975dc..c8ee6f8394 100644 --- a/core/serdiv.sv +++ b/core/serdiv.sv @@ -22,21 +22,31 @@ module serdiv parameter WIDTH = 64, parameter STABLE_HANDSHAKE = 0 // Guarantee a stable in_rdy_o during the input handshake. Keep it at 0 in CVA6 ) ( + // Subsystem Clock - SUBSYSTEM input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, - // input IF + // Serdiv translation ID - Mult input logic [TRANS_ID_BITS-1:0] id_i, + // A operand - Mult input logic [WIDTH-1:0] op_a_i, + // B operand - Mult input logic [WIDTH-1:0] op_b_i, + // Serdiv operation - Mult input logic [1:0] opcode_i, // 0: udiv, 2: urem, 1: div, 3: rem - // handshake - input logic in_vld_i, // there is a cycle delay from in_rdy_o->in_vld_i, see issue_read_operands.sv stage + // Serdiv instruction is valid - Mult + input logic in_vld_i, + // Serdiv FU is ready - Mult output logic in_rdy_o, + // Flush - CONTROLLER input logic flush_i, - // output IF + // Serdiv result is valid - Mult output logic out_vld_o, + // Serdiv is ready - Mult input logic out_rdy_i, + // Serdiv transaction ID - Mult output logic [TRANS_ID_BITS-1:0] id_o, + // Serdiv result - Mult output logic [WIDTH-1:0] res_o ); diff --git a/core/store_unit.sv b/core/store_unit.sv index fb93818c24..f855756547 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -18,38 +18,61 @@ module store_unit #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // Flush - CONTROLLER input logic flush_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic stall_st_pending_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic no_st_pending_o, + // Store buffer is empty - TO_BE_COMPLETED output logic store_buffer_empty_o, - // store unit input port + // Store instruction is valid - ISSUE_STAGE input logic valid_i, + // data input - ISSUE_STAGE input lsu_ctrl_t lsu_ctrl_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic pop_st_o, + // Instruction commit - TO_BE_COMPLETED input logic commit_i, + // TO_BE_COMPLETED - TO_BE_COMPLETED output logic commit_ready_o, + // TO_BE_COMPLETED - TO_BE_COMPLETED input logic amo_valid_commit_i, - // store unit output port + // Store result is valid - ISSUE_STAGE output logic valid_o, + // Transaction ID - ISSUE_STAGE output logic [TRANS_ID_BITS-1:0] trans_id_o, + // Store result - ISSUE_STAGE output riscv::xlen_t result_o, + // Store exception output - TO_BE_COMPLETED output exception_t ex_o, - // MMU -> Address Translation - output logic translation_req_o, // request address translation - output logic [riscv::VLEN-1:0] vaddr_o, // virtual address out + // Address translation request - TO_BE_COMPLETED + output logic translation_req_o, + // Virtual address - TO_BE_COMPLETED + output logic [riscv::VLEN-1:0] vaddr_o, + // RVFI information - RVFI output [riscv::PLEN-1:0] rvfi_mem_paddr_o, - input logic [riscv::PLEN-1:0] paddr_i, // physical address in + // Physical address - TO_BE_COMPLETED + input logic [riscv::PLEN-1:0] paddr_i, + // Exception raised before store - TO_BE_COMPLETED input exception_t ex_i, - input logic dtlb_hit_i, // will be one in the same cycle translation_req was asserted if it hits - // address checker + // Data TLB hit - lsu + input logic dtlb_hit_i, + // Address to be checked - load_unit input logic [11:0] page_offset_i, + // Address check result - load_unit output logic page_offset_matches_o, - // D$ interface + // AMO request - CACHES output amo_req_t amo_req_o, + // AMO response - CACHES input amo_resp_t amo_resp_i, + // Data cache request - CACHES input dcache_req_o_t req_port_i, + // Data cache response - CACHES output dcache_req_i_t req_port_o ); // it doesn't matter what we are writing back as stores don't return anything diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index f1c163a7c9..96aaf1bd08 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -8,9 +8,9 @@ EX_STAGE Module Description *********** -The EX_STAGE module is a logical stage which implements the execute stage. -It encapsulates the following functional units: -ALU, Branch Unit, CSR buffer, Mult, load and store and CVXIF. +The EX_STAGE module is a logical stage which implements the execute +stage. It encapsulates the following functional units: ALU, Branch Unit, +CSR buffer, Mult, load and store and CVXIF. The module is connected to: @@ -40,25 +40,42 @@ Submodules ALU === -TO BE COMPLETED +The arithmetic logic unit (ALU) is a small piece of hardware which +performs 32 and 64-bit arithmetical operations: subtraction, addition, +shifts, comparisons... +It always completes its operation in a single cycle. + +.. include:: port_alu.rst Branch Unit =========== -TO BE COMPLETED +The branch unit module manages all kind of control flow changes +i.e.: conditional and unconditional jumps. It calculates the target +address and decides whether to take the branch or not. +It also decides if a branch was mis-predicted or not and reports +corrective actions to the pipeline stages. + +.. include:: port_branch_unit.rst CSR Buffer ========== -TO BE COMPLETED +The CSR buffer module stores the CSR address at which the +instruction is going to read/write. As the CSR instruction alters the +processor architectural state, this instruction has to be buffered until +the commit stage decides to execute the instruction. + +.. include:: port_csr_buffer.rst Mult ==== -TO BE COMPLETED +The multiplier module supports the division and multiplication +operations. .. figure:: ../images/mult_modules.png :name: mult submodules @@ -67,24 +84,39 @@ TO BE COMPLETED mult submodules +.. include:: port_mult.rst + + ---------- multiplier ---------- -TO BE COMPLETED +Multiplication is performed in two cycles and is fully pipelined. + +.. include:: port_multiplier.rst ------ serdiv ------ -TO BE COMPLETED +The division is a simple serial divider which needs 64 cycles in the +worst case. + +.. include:: port_serdiv.rst -Load Store Unit (LSU) +Load_Store_Unit (LSU) ===================== -TO BE COMPLETED +The load store module interfaces with the data memory (D$) to manage the +load and store operations. + +The LSU does not handle misaligned accesses: access which are not +aligned to a 64 bit boundary for double word accesses, access which are +not aligned to a 32-bit boundary for word access and the accesses which +are not aligned on 16-bit boundary for half word access. If encounters +such a load or store it will throw a misaligned exception. .. figure:: ../images/load_store_unit_modules.png :name: load_store_unit submodules @@ -93,18 +125,50 @@ TO BE COMPLETED load_store_unit submodules +.. include:: port_load_store_unit.rst + + ---------- store_unit ---------- -TO BE COMPLETED +The store_unit module manages the data store operations. + +As stores can be speculative, the store instructions need to be +committed by ISSUE_STAGE module before possibily altering the processor +state. +Store buffer keeps track of store requests. XXXXXXXXXXX for outstanding store +instructions (which are still speculative) and one buffer for committed +store instructions. +When ISSUE_STAGE module commits a store instruction, outstanding store +becomes committed. + +When commit buffer is not empty, the buffer automatically +tries to write the oldest store to the data cache. + +Furthermore, the store_unit module provides information to the load_unit +to know if any outstanding store matches load. + +.. include:: port_store_unit.rst --------- -load unit +load_unit --------- -TO BE COMPLETED +The load_unit module manages the data load operations. + +Before issuing a load, the load unit needs to check the store buffer for +potential aliasing. It wwill insert stalls until it can't satisfy the +current request. This means: +* Two loads to the same address are allowed. +* Two stores to the same address are allowed. +* A store followed by a load to the same address can only be satisfied +if the store has already been committed (marked as committed in the +store buffer). + + +.. include:: port_load_unit.rst ---------- @@ -113,9 +177,13 @@ lsu_bypass TO BE COMPLETED +.. include:: port_lsu_bypass.rst CVXIF_fu ======== TO BE COMPLETED + +.. include:: port_cvxif_fu.rst + diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index b3d1d14140..c650dd305c 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -172,7 +172,9 @@ BTB (Branch Target Buffer) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a unconditional jumps to a register (JALR instruction) is mispredicted by the EXECUTE, the relative information is stored into the BTB, that is to say the JALR PC and the target address. +When a unconditional jumps to a register (JALR instruction) is mispredicted +by the EXECUTE, the relative information is stored into the BTB, that is +to say the JALR PC and the target address. The information is stored in a 8 entry table. @@ -192,7 +194,9 @@ RAS (Return Address Stack) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When an unconditional jumps to a known target address (JAL instruction) is consummed by the instr_queue, the next pc after the JAL instruction and the return address are stored into a FIFO. +When an unconditional jumps to a known target address (JAL instruction) +is consummed by the instr_queue, the next pc after the JAL instruction +and the return address are stored into a FIFO. The RAS FIFO depth is 2. diff --git a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst index c401f7e2e8..557489ae01 100644 --- a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst @@ -15,7 +15,19 @@ COMMIT_STAGE Module Description ----------- -The COMMIT_STAGE module implements ... TO BE COMPLETED +The COMMIT_STAGE module implements the commit stage, which is the +last stage in the processor’s +pipeline. It takes incoming instruction and update the architectural +state: writing CSR registers, committing stores and writing back data to +the register file. The commit stage controls the stalling and the +flushing of the processor. + +The commit stage also manages the exceptions. An exception can occur +during the first four pipeline stages (PCgen cannot generate an +exception) or happen during commit stage coming from the CSR_REGFILE or +from an interrupt. To allow precise interrupts to happen they are +considered during the commit only and associated with teh related +instruction. The module is connected to: diff --git a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst index 6186ce461d..ea681439f3 100644 --- a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst @@ -54,10 +54,16 @@ Submodules Scoreboard ~~~~~~~~~~ -TO BE COMPLETED +The scoreboard is contains a FIFO to store the decoded instructions. +Instruction is pushed to the FIFO whether the scoreboard is not full. +It indicates which registers are going to be clobbered by a previously +scheduled instruction. +.. include:: port_scoreboard.rst Issue_read_operands ~~~~~~~~~~~~~~~~~~~ TO BE COMPLETED + +.. include:: port_issue_read_operands.rst diff --git a/docs/04_cv32a65x_design/source/port_alu.rst b/docs/04_cv32a65x_design/source/port_alu.rst new file mode 100644 index 0000000000..aa33f9a209 --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_alu.rst @@ -0,0 +1,53 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_alu_ports: + +.. list-table:: alu module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - fu_data_t + + * - ``result_o`` + - out + - ALU result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``alu_branch_res_o`` + - out + - ALU branch compare result + - branch_unit + - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_bht.rst b/docs/04_cv32a65x_design/source/port_bht.rst index 9e0f2aa2dc..91a5f4a449 100644 --- a/docs/04_cv32a65x_design/source/port_bht.rst +++ b/docs/04_cv32a65x_design/source/port_bht.rst @@ -22,46 +22,39 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - - logic - - * - ``debug_mode_i`` - - in - - CSR - - Debug mode state - logic * - ``vpc_i`` - in - Virtual PC - CACHE - - Virtual PC - logic[riscv::VLEN-1:0] * - ``bht_update_i`` - in - Update bht with resolved address - EXECUTE - - Update bht with resolved address - ariane_pkg::bht_update_t * - ``bht_prediction_o`` - out - Prediction from bht - FRONTEND - - Prediction from bht - ariane_pkg::bht_prediction_t[ariane_pkg::INSTR_PER_FETCH-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_mode_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_branch_unit.rst b/docs/04_cv32a65x_design/source/port_branch_unit.rst new file mode 100644 index 0000000000..ce5fe9affd --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_branch_unit.rst @@ -0,0 +1,102 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_branch_unit_ports: + +.. list-table:: branch_unit module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - ariane_pkg::fu_data_t + + * - ``pc_i`` + - in + - Instruction PC + - ISSUE_STAGE + - logic[riscv::VLEN-1:0] + + * - ``is_compressed_instr_i`` + - in + - Instruction is compressed + - ISSUE_STAGE + - logic + + * - ``fu_valid_i`` + - in + - any functional unit is valid, check that there is no accidental mis-predict + - TO_BE_COMPLETED + - logic + + * - ``branch_valid_i`` + - in + - Branch unit instruction is valid + - ISSUE_STAGE + - logic + + * - ``branch_comp_res_i`` + - in + - ALU branch compare result + - ALU + - logic + + * - ``branch_result_o`` + - out + - Brach unit result + - ISSUE_STAGE + - logic[riscv::VLEN-1:0] + + * - ``branch_predict_i`` + - in + - Information of branch prediction + - ISSUE_STAGE + - ariane_pkg::branchpredict_sbe_t + + * - ``resolved_branch_o`` + - out + - Signaling that we resolved the branch + - ISSUE_STAGE + - ariane_pkg::bp_resolve_t + + * - ``resolve_branch_o`` + - out + - Branch is resolved, new entries can be accept by scoreboard + - ID_STAGE + - logic + + * - ``branch_exception_o`` + - out + - Branch exception out + - TO_BE_COMPLETED + - ariane_pkg::exception_t + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_mode_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_btb.rst b/docs/04_cv32a65x_design/source/port_btb.rst index a30424287b..225d583514 100644 --- a/docs/04_cv32a65x_design/source/port_btb.rst +++ b/docs/04_cv32a65x_design/source/port_btb.rst @@ -22,46 +22,39 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - - logic - - * - ``debug_mode_i`` - - in - - CSR - - Debug mode state - logic * - ``vpc_i`` - in - Virtual PC - CACHE - - Virtual PC - logic[riscv::VLEN-1:0] * - ``btb_update_i`` - in - Update BTB with resolved address - EXECUTE - - Update BTB with resolved address - ariane_pkg::btb_update_t * - ``btb_prediction_o`` - out - BTB Prediction - FRONTEND - - BTB Prediction - ariane_pkg::btb_prediction_t[ariane_pkg::INSTR_PER_FETCH-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_mode_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_commit_stage.rst b/docs/04_cv32a65x_design/source/port_commit_stage.rst index 27f07934f3..c47c7bf1e8 100644 --- a/docs/04_cv32a65x_design/source/port_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/port_commit_stage.rst @@ -22,207 +22,146 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``halt_i`` - in - Request to halt the core - CONTROLLER - - Request to halt the core - logic * - ``flush_dcache_i`` - in - request to flush dcache, also flush the pipeline - CACHE - - request to flush dcache, also flush the pipeline - logic * - ``exception_o`` - out - TO_BE_COMPLETED - EX_STAGE - - TO_BE_COMPLETED - exception_t - * - ``dirty_fp_state_o`` - - out - - Mark the F state as dirty - - CSR_REGFILE - - Mark the F state as dirty - - logic - - * - ``single_step_i`` - - in - - TO_BE_COMPLETED - - CSR_REGFILE - - TO_BE_COMPLETED - - logic - * - ``commit_instr_i`` - in - The instruction we want to commit - ISSUE_STAGE - - The instruction we want to commit - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_o`` - out - Acknowledge that we are indeed committing - ISSUE_STAGE - - Acknowledge that we are indeed committing - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``waddr_o`` - out - Register file write address - - ID_STAGE - - Register file write address + - ISSUE_STAGE - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] * - ``wdata_o`` - out - Register file write data - - ID_STAGE - - Register file write data + - ISSUE_STAGE - logic[CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] * - ``we_gpr_o`` - out - Register file write enable - - ID_STAGE - - Register file write enable + - ISSUE_STAGE - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``we_fpr_o`` - out - Floating point register enable - - ID_STAGE - - Floating point register enable + - ISSUE_STAGE - logic[CVA6Cfg.NrCommitPorts-1:0] - * - ``amo_resp_i`` - - in - - CACHE - - Result of AMO operation - - amo_resp_t - * - ``pc_o`` - out - TO_BE_COMPLETED - FRONTEND_CSR - - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``csr_op_o`` - out - Decoded CSR operation - CSR_REGFILE - - Decoded CSR operation - fu_op * - ``csr_wdata_o`` - out - Data to write to CSR - CSR_REGFILE - - Data to write to CSR - riscv::xlen_t * - ``csr_rdata_i`` - in - Data to read from CSR - CSR_REGFILE - - Data to read from CSR - riscv::xlen_t * - ``csr_exception_i`` - in - Exception or interrupt occurred in CSR stage (the same as commit) - CSR_REGFILE - - Exception or interrupt occurred in CSR stage (the same as commit) - exception_t - * - ``csr_write_fflags_o`` - - out - - Write the fflags CSR - - CSR_REGFILE - - Write the fflags CSR - - logic - * - ``commit_lsu_o`` - out - Commit the pending store - EX_STAGE - - Commit the pending store - logic * - ``commit_lsu_ready_i`` - in - Commit buffer of LSU is ready - EX_STAGE - - Commit buffer of LSU is ready - logic * - ``commit_tran_id_o`` - out - Transaction id of first commit port - ID_STAGE - - Transaction id of first commit port - logic[TRANS_ID_BITS-1:0] - * - ``amo_valid_commit_o`` - - out - - Valid AMO in commit stage - - EX_STAGE - - Valid AMO in commit stage - - logic - * - ``no_st_pending_i`` - in - no store is pending - EX_STAGE - - no store is pending - logic * - ``commit_csr_o`` - out - Commit the pending CSR instruction - EX_STAGE - - Commit the pending CSR instruction - - logic - - * - ``fence_i_o`` - - out - - Flush I$ and pipeline - - CONTROLLER - - Flush I$ and pipeline - - logic - - * - ``fence_o`` - - out - - Flush D$ and pipeline - - CONTROLLER - - Flush D$ and pipeline - logic * - ``flush_commit_o`` - out - Request a pipeline flush - CONTROLLER - - Request a pipeline flush - logic - * - ``sfence_vma_o`` - - out - - Flush TLBs and pipeline - - CONTROLLER - - Flush TLBs and pipeline - - logic +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As RVF = 0, +| ``dirty_fp_state_o`` output is tied to 0 +| ``csr_write_fflags_o`` output is tied to 0 +| As DebugEn = 0, +| ``single_step_i`` input is tied to 0 +| As RVA = 0, +| ``amo_resp_i`` input is tied to 0 +| ``amo_valid_commit_o`` output is tied to 0 +| As FenceEn = 0, +| ``fence_i_o`` output is tied to 0 +| ``fence_o`` output is tied to 0 +| As RVS = 0, +| ``sfence_vma_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst index 91d60c7aaa..e42dd8e0fb 100644 --- a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst @@ -14,30 +14,34 @@ * - Signal - IO - - Connection - - Type - Description + - connexion + - Type * - ``instr_i`` - in + - Input instruction coming from fetch stage - FRONTEND - - Input instruction which can be compressed - logic[31:0] * - ``instr_o`` - out - - ID_STAGE - - Output instruction which is uncompressed + - Output instruction in uncompressed format + - decoder - logic[31:0] * - ``illegal_instr_o`` - out - - TO_BE_COMPLETED - - Illegal instruction exception + - Input instruction is illegal + - decoder - logic * - ``is_compressed_o`` - out - - TO_BE_COMPLETED - - report if instruction is compressed + - Output instruction is compressed + - decoder - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_controller.rst b/docs/04_cv32a65x_design/source/port_controller.rst index d70c0444e5..44e4a96c3f 100644 --- a/docs/04_cv32a65x_design/source/port_controller.rst +++ b/docs/04_cv32a65x_design/source/port_controller.rst @@ -22,169 +22,121 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``set_pc_commit_o`` - out - Set PC om PC Gen - FRONTEND - - Set PC om PC Gen - logic * - ``flush_if_o`` - out - Flush the IF stage - FRONTEND - - Flush the IF stage - logic * - ``flush_unissued_instr_o`` - out - Flush un-issued instructions of the scoreboard - FRONTEND - - Flush un-issued instructions of the scoreboard - logic * - ``flush_id_o`` - out - Flush ID stage - ID_STAGE - - Flush ID stage - logic * - ``flush_ex_o`` - out - Flush EX stage - EX_STAGE - - Flush EX stage - logic * - ``flush_bp_o`` - out - Flush branch predictors - FRONTEND - - Flush branch predictors - logic * - ``flush_icache_o`` - out - Flush ICache - CACHE - - Flush ICache - logic * - ``flush_dcache_o`` - out - Flush DCache - CACHE - - Flush DCache - logic * - ``flush_dcache_ack_i`` - in - Acknowledge the whole DCache Flush - CACHE - - Acknowledge the whole DCache Flush - - logic - - * - ``flush_tlb_o`` - - out - - Flush TLBs - - EX_STAGE - - Flush TLBs - logic * - ``halt_csr_i`` - in - Halt request from CSR (WFI instruction) - CSR_REGFILE - - Halt request from CSR (WFI instruction) - - logic - - * - ``halt_acc_i`` - - in - - ACC_DISPATCHER - - Halt request from accelerator dispatcher - logic * - ``halt_o`` - out - Halt signal to commit stage - COMMIT_STAGE - - Halt signal to commit stage - logic * - ``eret_i`` - in - Return from exception - CSR_REGFILE - - Return from exception - logic * - ``ex_valid_i`` - in - - FRONTEND - We got an exception, flush the pipeline - - logic - - * - ``set_debug_pc_i`` - - in - FRONTEND - - set the debug pc from CSR - logic * - ``resolved_branch_i`` - in - We got a resolved branch, check if we need to flush the front-end - EX_STAGE - - We got a resolved branch, check if we need to flush the front-end - bp_resolve_t * - ``flush_csr_i`` - in - We got an instruction which altered the CSR, flush the pipeline - CSR_REGFILE - - We got an instruction which altered the CSR, flush the pipeline - - logic - - * - ``fence_i_i`` - - in - - fence.i in - - ACC_DISPATCH - - fence.i in - - logic - - * - ``fence_i`` - - in - - fence in - - ACC_DISPATCH - - fence in - - logic - - * - ``sfence_vma_i`` - - in - - We got an instruction to flush the TLBs and pipeline - - COMMIT_STAGE - - We got an instruction to flush the TLBs and pipeline - logic * - ``flush_commit_i`` - in - Flush request from commit stage - COMMIT_STAGE - - Flush request from commit stage - logic - * - ``flush_acc_i`` - - in - - ACC_DISPATCHER - - Flush request from accelerator - - logic +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As MMUPresent = 0, +| ``flush_tlb_o`` output is tied to 0 +| As EnableAccelerator = 0, +| ``halt_acc_i`` input is tied to 0 +| ``flush_acc_i`` input is tied to 0 +| As DebugEn = 0, +| ``set_debug_pc_i`` input is tied to 0 +| As FenceEn = 0, +| ``fence_i_i`` input is tied to 0 +| ``fence_i`` input is tied to 0 +| As RVS = 0, +| ``sfence_vma_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_csr_buffer.rst b/docs/04_cv32a65x_design/source/port_csr_buffer.rst new file mode 100644 index 0000000000..f0f7e87f42 --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_csr_buffer.rst @@ -0,0 +1,77 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_csr_buffer_ports: + +.. list-table:: csr_buffer module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - Flush CSR + - CONTROLLER + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - fu_data_t + + * - ``csr_ready_o`` + - out + - CSR FU is ready + - ISSUE_STAGE + - logic + + * - ``csr_valid_i`` + - in + - CSR instruction is valid + - ISSUE_STAGE + - logic + + * - ``csr_result_o`` + - out + - CSR buffer result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``csr_commit_i`` + - in + - commit the pending CSR OP + - TO_BE_COMPLETED + - logic + + * - ``csr_addr_o`` + - out + - CSR address to write + - COMMIT_STAGE + - logic[11:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_csr_regfile.rst b/docs/04_cv32a65x_design/source/port_csr_regfile.rst index c6b308034d..bba8bf7686 100644 --- a/docs/04_cv32a65x_design/source/port_csr_regfile.rst +++ b/docs/04_cv32a65x_design/source/port_csr_regfile.rst @@ -22,385 +22,185 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``time_irq_i`` - in - Timer threw a interrupt - SUBSYSTEM - - Timer threw a interrupt - logic * - ``flush_o`` - out - send a flush request out when a CSR with a side effect changes - CONTROLLER - - send a flush request out when a CSR with a side effect changes - logic * - ``halt_csr_o`` - out - halt requested - CONTROLLER - - halt requested - logic * - ``commit_instr_i`` - in - Instruction to be committed - ID_STAGE - - Instruction to be committed - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_i`` - in - Commit acknowledged a instruction -> increase instret CSR - COMMIT_STAGE - - Commit acknowledged a instruction -> increase instret CSR - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``boot_addr_i`` - in - Address from which to start booting, mtvec is set to the same address - SUBSYSTEM - - Address from which to start booting, mtvec is set to the same address - logic[riscv::VLEN-1:0] * - ``hart_id_i`` - in - Hart id in a multicore environment (reflected in a CSR) - SUBSYSTEM - - Hart id in a multicore environment (reflected in a CSR) - logic[riscv::XLEN-1:0] * - ``ex_i`` - in - We've got an exception from the commit stage, take it - COMMIT_STAGE - - We've got an exception from the commit stage, take it - exception_t * - ``csr_op_i`` - in - Operation to perform on the CSR file - COMMIT_STAGE - - Operation to perform on the CSR file - fu_op * - ``csr_addr_i`` - in - Address of the register to read/write - EX_STAGE - - Address of the register to read/write - logic[11:0] * - ``csr_wdata_i`` - in - Write data in - COMMIT_STAGE - - Write data in - logic[riscv::XLEN-1:0] * - ``csr_rdata_o`` - out - Read data out - COMMIT_STAGE - - Read data out - logic[riscv::XLEN-1:0] - * - ``dirty_fp_state_i`` - - in - - Mark the FP sate as dirty - - COMMIT_STAGE - - Mark the FP sate as dirty - - logic - - * - ``csr_write_fflags_i`` - - in - - Write fflags register e.g.: we are retiring a floating point instruction - - COMMIT_STAGE - - Write fflags register e.g.: we are retiring a floating point instruction - - logic - - * - ``dirty_v_state_i`` - - in - - ACC_DISPATCHER - - Mark the V state as dirty - - logic - * - ``pc_i`` - in - PC of instruction accessing the CSR - COMMIT_STAGE - - PC of instruction accessing the CSR - logic[riscv::VLEN-1:0] * - ``csr_exception_o`` - out - attempts to access a CSR without appropriate privilege - COMMIT_STAGE - - attempts to access a CSR without appropriate privilege - exception_t * - ``epc_o`` - out - Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - FRONTEND - - Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - logic[riscv::VLEN-1:0] * - ``eret_o`` - out - Return from exception, set the PC of epc_o - FRONTEND - - Return from exception, set the PC of epc_o - logic * - ``trap_vector_base_o`` - out - Output base of exception vector, correct CSR is output (mtvec, stvec) - FRONTEND - - Output base of exception vector, correct CSR is output (mtvec, stvec) - logic[riscv::VLEN-1:0] - * - ``priv_lvl_o`` - - out - - Current privilege level the CPU is in - - EX_STAGE - - Current privilege level the CPU is in - - riscv::priv_lvl_t - - * - ``acc_fflags_ex_i`` - - in - - ACC_DISPATCHER - - Imprecise FP exception from the accelerator (fcsr.fflags format) - - logic[4:0] - - * - ``acc_fflags_ex_valid_i`` - - in - - ACC_DISPATCHER - - An FP exception from the accelerator occurred - - logic - - * - ``fs_o`` - - out - - Floating point extension status - - ID_STAGE - - Floating point extension status - - riscv::xs_t - - * - ``fflags_o`` - - out - - Floating-Point Accured Exceptions - - COMMIT_STAGE - - Floating-Point Accured Exceptions - - logic[4:0] - - * - ``frm_o`` - - out - - Floating-Point Dynamic Rounding Mode - - EX_STAGE - - Floating-Point Dynamic Rounding Mode - - logic[2:0] - - * - ``fprec_o`` - - out - - Floating-Point Precision Control - - EX_STAGE - - Floating-Point Precision Control - - logic[6:0] - - * - ``vs_o`` - - out - - Vector extension status - - ID_STAGE - - Vector extension status - - riscv::xs_t - * - ``irq_ctrl_o`` - out - interrupt management to id stage - ID_STAGE - - interrupt management to id stage - irq_ctrl_t - * - ``en_translation_o`` - - out - - enable VA translation - - EX_STAGE - - enable VA translation - - logic - - * - ``en_ld_st_translation_o`` - - out - - enable VA translation for load and stores - - EX_STAGE - - enable VA translation for load and stores - - logic - - * - ``ld_st_priv_lvl_o`` - - out - - Privilege level at which load and stores should happen - - EX_STAGE - - Privilege level at which load and stores should happen - - riscv::priv_lvl_t - - * - ``sum_o`` - - out - - TO_BE_COMPLETED - - EX_STAGE - - TO_BE_COMPLETED - - logic - - * - ``mxr_o`` - - out - - TO_BE_COMPLETED - - EX_STAGE - - TO_BE_COMPLETED - - logic - - * - ``satp_ppn_o`` - - out - - TO_BE_COMPLETED - - EX_STAGE - - TO_BE_COMPLETED - - logic[riscv::PPNW-1:0] - - * - ``asid_o`` - - out - - TO_BE_COMPLETED - - EX_STAGE - - TO_BE_COMPLETED - - logic[AsidWidth-1:0] - * - ``irq_i`` - in - external interrupt in - SUBSYSTEM - - external interrupt in - logic[1:0] * - ``ipi_i`` - in - inter processor interrupt -> connected to machine mode sw - SUBSYSTEM - - inter processor interrupt -> connected to machine mode sw - - logic - - * - ``debug_req_i`` - - in - - ID_STAGE - - debug request in - - logic - - * - ``set_debug_pc_o`` - - out - - TO_BE_COMPLETED - - FRONTEND - - TO_BE_COMPLETED - - logic - - * - ``tvm_o`` - - out - - trap virtual memory - - ID_STAGE - - trap virtual memory - - logic - - * - ``tw_o`` - - out - - timeout wait - - ID_STAGE - - timeout wait - - logic - - * - ``tsr_o`` - - out - - trap sret - - ID_STAGE - - trap sret - - logic - - * - ``debug_mode_o`` - - out - - we are in debug mode -> that will change some decoding - - EX_STAGE - - we are in debug mode -> that will change some decoding - - logic - - * - ``single_step_o`` - - out - - we are in single-step mode - - COMMIT_STAGE - - we are in single-step mode - logic * - ``icache_en_o`` - out - L1 ICache Enable - CACHE - - L1 ICache Enable - logic * - ``dcache_en_o`` - out - L1 DCache Enable - CACHE - - L1 DCache Enable - - logic - - * - ``acc_cons_en_o`` - - out - - ACC_DISPATCHER - - Accelerator memory consistent mode - - logic - - * - ``perf_addr_o`` - - out - - PERF_COUNTERS - - read/write address to performance counter module - - logic[11:0] - - * - ``perf_data_o`` - - out - - PERF_COUNTERS - - write data to performance counter module - - logic[riscv::XLEN-1:0] - - * - ``perf_data_i`` - - in - - PERF_COUNTERS - - read data from performance counter module - - logic[riscv::XLEN-1:0] - - * - ``perf_we_o`` - - out - - PERF_COUNTERS - - TO_BE_COMPLETED - logic - * - ``pmpcfg_o`` - - out - - ACC_DISPATCHER - - PMP configuration containing pmpcfg for max 16 PMPs - - riscv::pmpcfg_t[15:0] - - * - ``pmpaddr_o`` - - out - - ACC_DISPATCHER - - PMP addresses - - logic[15:0][riscv::PLEN-3:0] - - * - ``mcountinhibit_o`` - - out - - PERF_COUNTERS - - TO_BE_COMPLETED - - logic[31:0] +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As RVF = 0, +| ``dirty_fp_state_i`` input is tied to 0 +| ``csr_write_fflags_i`` input is tied to 0 +| ``fs_o`` output is tied to 0 +| ``fflags_o`` output is tied to 0 +| ``frm_o`` output is tied to 0 +| ``fprec_o`` output is tied to 0 +| As EnableAccelerator = 0, +| ``dirty_v_state_i`` input is tied to 0 +| ``acc_fflags_ex_i`` input is tied to 0 +| ``acc_fflags_ex_valid_i`` input is tied to 0 +| ``acc_cons_en_o`` output is tied to 0 +| ``pmpcfg_o`` output is tied to 0 +| ``pmpaddr_o`` output is tied to 0 +| As PRIV = MachineOnly, +| ``priv_lvl_o`` output is tied to MachineMode +| ``ld_st_priv_lvl_o`` output is tied to MAchineMode +| ``tvm_o`` output is tied to 0 +| ``tw_o`` output is tied to 0 +| ``tsr_o`` output is tied to 0 +| As RVV = 0, +| ``vs_o`` output is tied to 0 +| As RVS = 0, +| ``en_translation_o`` output is tied to 0 +| ``en_ld_st_translation_o`` output is tied to 0 +| ``sum_o`` output is tied to 0 +| ``mxr_o`` output is tied to 0 +| ``satp_ppn_o`` output is tied to 0 +| ``asid_o`` output is tied to 0 +| As DebugEn = 0, +| ``debug_req_i`` input is tied to 0 +| ``set_debug_pc_o`` output is tied to 0 +| ``debug_mode_o`` output is tied to 0 +| ``single_step_o`` output is tied to 0 +| As PerfCounterEn = 0, +| ``perf_addr_o`` output is tied to 0 +| ``perf_data_o`` output is tied to 0 +| ``perf_data_i`` input is tied to 0 +| ``perf_we_o`` output is tied to 0 +| ``mcountinhibit_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_cva6.rst b/docs/04_cv32a65x_design/source/port_cva6.rst index 19dd408017..4566a88299 100644 --- a/docs/04_cv32a65x_design/source/port_cva6.rst +++ b/docs/04_cv32a65x_design/source/port_cva6.rst @@ -22,87 +22,71 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``boot_addr_i`` - in - Reset boot address - SUBSYSTEM - - Reset boot address - logic[riscv::VLEN-1:0] * - ``hart_id_i`` - in - Hard ID reflected as CSR - SUBSYSTEM - - Hard ID reflected as CSR - logic[riscv::XLEN-1:0] * - ``irq_i`` - in - Level sensitive (async) interrupts - SUBSYSTEM - - Level sensitive (async) interrupts - logic[1:0] * - ``ipi_i`` - in - Inter-processor (async) interrupt - SUBSYSTEM - - Inter-processor (async) interrupt - logic * - ``time_irq_i`` - in - - SUBSYSTEM - Timer (async) interrupt - - logic - - * - ``debug_req_i`` - - in - SUBSYSTEM - - Debug (async) request - logic - * - ``rvfi_probes_o`` - - out - - Probes to build RVFI, can be left open when not used - - SUBSYSTEM - - Probes to build RVFI, can be left open when not used - - rvfi_probes_t - * - ``cvxif_req_o`` - out - CVXIF request - SUBSYSTEM - - CVXIF request - cvxif_req_t * - ``cvxif_resp_i`` - in - CVXIF response - SUBSYSTEM - - CVXIF response - cvxif_resp_t * - ``noc_req_o`` - out - noc request, can be AXI or OpenPiton - SUBSYSTEM - - noc request, can be AXI or OpenPiton - noc_req_t * - ``noc_resp_i`` - in - noc response, can be AXI or OpenPiton - SUBSYSTEM - - noc response, can be AXI or OpenPiton - noc_resp_t + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_req_i`` input is tied to 0 +| As IsRVFI = 0, +| ``rvfi_probes_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst new file mode 100644 index 0000000000..3aae8fa56c --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst @@ -0,0 +1,102 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_cvxif_fu_ports: + +.. list-table:: cvxif_fu module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - fu_data_t + + * - ``x_valid_i`` + - in + - CVXIF instruction is valid + - ISSUE_STAGE + - logic + + * - ``x_ready_o`` + - out + - CVXIF is ready + - ISSUE_STAGE + - logic + + * - ``x_off_instr_i`` + - in + - undecoded instruction + - ISSUE_STAGE + - logic[31:0] + + * - ``x_trans_id_o`` + - out + - CVXIF transaction ID + - ISSUE_STAGE + - logic[TRANS_ID_BITS-1:0] + + * - ``x_exception_o`` + - out + - CVXIF exception + - ISSUE_STAGE + - exception_t + + * - ``x_result_o`` + - out + - CVXIF FU result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``x_valid_o`` + - out + - CVXIF result valid + - ISSUE_STAGE + - logic + + * - ``x_we_o`` + - out + - CVXIF write enable + - ISSUE_STAGE + - logic + + * - ``cvxif_req_o`` + - out + - CVXIF request + - SUBSYSTEM + - cvxif_pkg::cvxif_req_t + + * - ``cvxif_resp_i`` + - in + - CVXIF response + - SUBSYSTEM + - cvxif_pkg::cvxif_resp_t + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As PRIV = MachineOnly, +| ``priv_lvl_i`` input is tied to MachineMode diff --git a/docs/04_cv32a65x_design/source/port_decoder.rst b/docs/04_cv32a65x_design/source/port_decoder.rst index 3ab480ddb7..4a49b8e2af 100644 --- a/docs/04_cv32a65x_design/source/port_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_decoder.rst @@ -14,132 +14,94 @@ * - Signal - IO - - Connection - - Type - Description - - * - ``debug_req_i`` - - in - - TO_BE_COMPLETED - - External debug request - - logic + - connexion + - Type * - ``pc_i`` - in - - TO_BE_COMPLETED - - PC from IF + - PC from fetch stage + - FRONTEND - logic[riscv::VLEN-1:0] * - ``is_compressed_i`` - in - - TO_BE_COMPLETED - Is a compressed instruction + - compressed_decoder - logic * - ``compressed_instr_i`` - in - - TO_BE_COMPLETED - Compressed form of instruction + - FRONTEND - logic[15:0] * - ``is_illegal_i`` - in - - TO_BE_COMPLETED - Illegal compressed instruction + - compressed_decoder - logic * - ``instruction_i`` - in - - TO_BE_COMPLETED - - Instruction from IF + - Instruction from fetch stage + - FRONTEND - logic[31:0] * - ``branch_predict_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Is a branch predict instruction + - FRONTEND - branchpredict_sbe_t * - ``ex_i`` - in - - TO_BE_COMPLETED - - If an exception occured in if + - If an exception occured in fetch stage + - FRONTEND - exception_t * - ``irq_i`` - in - - TO_BE_COMPLETED - - External interrupt + - Level sensitive (async) interrupts + - SUBSYSTEM - logic[1:0] * - ``irq_ctrl_i`` - in - - TO_BE_COMPLETED - - Interrupt control and status information from CSRs - - irq_ctrl_t - - * - ``priv_lvl_i`` - - in - - CSR_REGFILE - - Current privilege level - - riscv::priv_lvl_t - - * - ``debug_mode_i`` - - in - - CSR_REGFILE - - We are in debug mode - - logic - - * - ``fs_i`` - - in - - CSR_REGFILE - - Floating point extension status - - riscv::xs_t - - * - ``frm_i`` - - in + - Interrupt control status - CSR_REGFILE - - Floating-point dynamic rounding mode - - logic[2:0] - - * - ``vs_i`` - - in - - CSR_REGFILE - - Vector extension status - - riscv::xs_t - - * - ``tvm_i`` - - in - - CSR_REGFILE - - Trap virtual memory - - logic - - * - ``tw_i`` - - in - - CSR_REGFILE - - Timeout wait - - logic - - * - ``tsr_i`` - - in - - CSR_REGFILE - - Trap sret - - logic + - irq_ctrl_t * - ``instruction_o`` - out - - COMMIT_STAGE - - Scoreboard entry to scoreboard + - Instruction to be added to scoreboard entry + - ISSUE_STAGE - scoreboard_entry_t * - ``orig_instr_o`` - out - - TO_BE_COMPLETED - - Instruction opcode to issue read operand for CVXIF + - Instruction + - ISSUE_STAGE - logic[31:0] * - ``is_control_flow_instr_o`` - out - - TO_BE_COMPLETED - - This instruction will change the control flow + - Is a control flow instruction + - ISSUE_STAGE - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_req_i`` input is tied to 0 +| ``debug_mode_i`` input is tied to 0 +| As PRIV = MachineOnly, +| ``priv_lvl_i`` input is tied to MachineMode +| ``tvm_i`` input is tied to 0 +| ``tw_i`` input is tied to 0 +| ``tsr_i`` input is tied to 0 +| As RVF = 0, +| ``fs_i`` input is tied to 0 +| ``frm_i`` input is tied to 0 +| As RVV = 0, +| ``vs_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_ex_stage.rst b/docs/04_cv32a65x_design/source/port_ex_stage.rst index 5ebea04037..dfa2539ab2 100644 --- a/docs/04_cv32a65x_design/source/port_ex_stage.rst +++ b/docs/04_cv32a65x_design/source/port_ex_stage.rst @@ -22,552 +22,363 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - - logic - - * - ``debug_mode_i`` - - in - - CSR_REGFILE - - TO_BE_COMPLETED - logic * - ``rs1_forwarding_i`` - in - rs1 forwarding - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[riscv::VLEN-1:0] * - ``rs2_forwarding_i`` - in - rs2 forwarding - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[riscv::VLEN-1:0] * - ``fu_data_i`` - in - FU data useful to execute instruction - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - fu_data_t * - ``pc_i`` - in - PC of the current instruction - - ID_STAGE - - PC of the current instruction + - ISSUE_STAGE - logic[riscv::VLEN-1:0] * - ``is_compressed_instr_i`` - in - Report whether isntruction is compressed - - ID_STAGE - - Report whether isntruction is compressed + - ISSUE_STAGE - logic * - ``flu_result_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - Fixed Latency Unit result + - ISSUE_STAGE - riscv::xlen_t * - ``flu_trans_id_o`` - out - ID of the scoreboard entry at which a=to write back - - ID_STAGE - - ID of the scoreboard entry at which a=to write back + - ISSUE_STAGE - logic[TRANS_ID_BITS-1:0] * - ``flu_exception_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - Fixed Latency Unit exception + - ISSUE_STAGE - exception_t * - ``flu_ready_o`` - out - FLU is ready - - ID_STAGE - - FLU is ready + - ISSUE_STAGE - logic * - ``flu_valid_o`` - out - FLU result is valid - - ID_STAGE - - FLU result is valid + - ISSUE_STAGE - logic * - ``alu_valid_i`` - in - - ALU result is valid - - ID_STAGE - - ALU result is valid + - ALU instruction is valid + - ISSUE_STAGE - logic * - ``branch_valid_i`` - in - - Branch unit result is valid - - ID_STAGE - - Branch unit result is valid + - Branch unit instruction is valid + - ISSUE_STAGE - logic * - ``branch_predict_i`` - in - Information of branch prediction - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - branchpredict_sbe_t * - ``resolved_branch_o`` - out - - none - - none + - The branch engine uses the write back from the ALU + - several_modules - bp_resolve_t * - ``resolve_branch_o`` - out - - ID signaling that we resolved the branch - - ID_STAGE - - ID signaling that we resolved the branch + - Signaling that we resolved the branch + - ISSUE_STAGE - logic * - ``csr_valid_i`` - in - - CSR result is valid - - ID_STAGE - - TO_BE_COMPLETED + - CSR instruction is valid + - ISSUE_STAGE - logic * - ``csr_addr_o`` - out - - TO_BE_COMPLETED - - CSR_REGISTERS - - TO_BE_COMPLETED + - CSR address to write + - COMMIT_STAGE - logic[11:0] * - ``csr_commit_i`` - in - - TO_BE_COMPLETED + - CSR commit - COMMIT_STAGE - - TO_BE_COMPLETED - logic * - ``mult_valid_i`` - in - - MULT result is valid - - ID_STAGE - - MULT result is valid + - MULT instruction is valid + - ISSUE_STAGE - logic * - ``lsu_ready_o`` - out - - FU is ready - - ID_STAGE - - FU is ready + - LSU is ready + - ISSUE_STAGE - logic * - ``lsu_valid_i`` - in - - LSU result is valid - - ID_STAGE - - LSU result is valid + - LSU instruction is valid + - ISSUE_STAGE - logic * - ``load_valid_o`` - out - Load result is valid - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - logic * - ``load_result_o`` - out - Load result valid - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - riscv::xlen_t * - ``load_trans_id_o`` - out - Load instruction ID - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[TRANS_ID_BITS-1:0] * - ``load_exception_o`` - out - Exception generated by load instruction - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - exception_t * - ``store_valid_o`` - out - Store result is valid - - ID_STAGE - - TO_BE_COMPLETED + - ISSUe_STAGE - logic * - ``store_result_o`` - out - Store result - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - riscv::xlen_t * - ``store_trans_id_o`` - out - Store instruction ID - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[TRANS_ID_BITS-1:0] * - ``store_exception_o`` - out - Exception generated by store instruction - - ID_STAGE - - TO_BE_COMPLETED + - ISSUE_STAGE - exception_t * - ``lsu_commit_i`` - in - - TO_BE_COMPLETED + - LSU commit - COMMIT_STAGE - - TO_BE_COMPLETED - logic * - ``lsu_commit_ready_o`` - out - Commit queue ready to accept another commit request - COMMIT_STAGE - - Commit queue is ready to accept another commit request - logic * - ``commit_tran_id_i`` - in - - TO_BE_COMPLETED + - Commit transaction ID - COMMIT_STAGE - - TO_BE_COMPLETED - logic[TRANS_ID_BITS-1:0] - * - ``stall_st_pending_i`` - - in - - ACC_DISPATCHER - - TO_BE_COMPLETED - - logic - * - ``no_st_pending_o`` - out - TO_BE_COMPLETED - COMMIT_STAGE - - TO_BE_COMPLETED - logic - * - ``amo_valid_commit_i`` - - in - - COMMIT_STAGE - - TO_BE_COMPLETED - - logic - - * - ``fpu_ready_o`` - - out - - ID_STAGE - - FU is ready - - logic - - * - ``fpu_valid_i`` - - in - - ID_STAGE - - Output is ready - - logic - - * - ``fpu_fmt_i`` - - in - - ID_STAGE - - report FP format - - logic[1:0] - - * - ``fpu_rm_i`` - - in - - ID_STAGE - - FP rm - - logic[2:0] - - * - ``fpu_frm_i`` - - in - - ID_STAGE - - FP frm - - logic[2:0] - - * - ``fpu_prec_i`` - - in - - CSR_REGFILE - - FP precision control - - logic[6:0] - - * - ``fpu_trans_id_o`` - - out - - ID_STAGE - - TO_BE_COMPLETED - - logic[TRANS_ID_BITS-1:0] - - * - ``fpu_result_o`` - - out - - ID_STAGE - - TO_BE_COMPLETED - - riscv::xlen_t - - * - ``fpu_valid_o`` - - out - - ID_STAGE - - TO_BE_COMPLETED - - logic - - * - ``fpu_exception_o`` - - out - - ID_STAGE - - TO_BE_COMPLETED - - exception_t - * - ``x_valid_i`` - in - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF instruction is valid + - ISSUE_STAGE - logic * - ``x_ready_o`` - out - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF is ready + - ISSUE_STAGE - logic * - ``x_off_instr_i`` - in - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - undecoded instruction + - ISSUE_STAGE - logic[31:0] * - ``x_trans_id_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF transaction ID + - ISSUE_STAGE - logic[TRANS_ID_BITS-1:0] * - ``x_exception_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF exception + - ISSUE_STAGE - exception_t * - ``x_result_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF result + - ISSUE_STAGE - riscv::xlen_t * - ``x_valid_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF result valid + - ISSUE_STAGE - logic * - ``x_we_o`` - out - - TO_BE_COMPLETED - - ID_STAGE - - TO_BE_COMPLETED + - CVXIF write enable + - ISSUE_STAGE - logic * - ``cvxif_req_o`` - out - - TO_BE_COMPLETED + - CVXIF request - SUBSYSTEM - - TO_BE_COMPLETED - cvxif_pkg::cvxif_req_t * - ``cvxif_resp_i`` - in - - TO_BE_COMPLETED + - CVXIF response - SUBSYSTEM - - TO_BE_COMPLETED - cvxif_pkg::cvxif_resp_t - * - ``acc_valid_i`` - - in - - ACC_DISPATCHER - - TO_BE_COMPLETED - - logic - - * - ``enable_translation_i`` - - in - - TO_BE_COMPLETED - - CSR_REGFILE - - TO_BE_COMPLETED - - logic - - * - ``en_ld_st_translation_i`` - - in - - TO_BE_COMPLETED - - CSR_REGFILE - - TO_BE_COMPLETED - - logic - - * - ``flush_tlb_i`` - - in - - CONTROLLER - - TO_BE_COMPLETED - - logic - - * - ``priv_lvl_i`` - - in - - CSR_REGFILE - - TO_BE_COMPLETED - - riscv::priv_lvl_t - - * - ``ld_st_priv_lvl_i`` - - in - - CSR_REGFILE - - TO_BE_COMPLETED - - riscv::priv_lvl_t - - * - ``sum_i`` - - in - - Supervisor user memory - - CSR_REGFILE - - TO_BE_COMPLETED - - logic - - * - ``mxr_i`` - - in - - Make executable readable - - CSR_REGFILE - - TO_BE_COMPLETED - - logic - - * - ``satp_ppn_i`` - - in - - TO_BE_COMPLETED - - CSR_REGFILE - - TO_BE_COMPLETED - - logic[riscv::PPNW-1:0] - - * - ``asid_i`` - - in - - TO_BE_COMPLETED - - CSR_REGFILE - - TO_BE_COMPLETED - - logic[ASID_WIDTH-1:0] - * - ``icache_areq_i`` - in - icache translation response - CACHE - - icache translation response - icache_arsp_t * - ``icache_areq_o`` - out - icache translation request - CACHE - - icache translation request - icache_areq_t * - ``dcache_req_ports_i`` - in - - TO_BE_COMPLETED + - Data cache request ouput - CACHE - - TO_BE_COMPLETED - dcache_req_o_t[2:0] * - ``dcache_req_ports_o`` - out - - TO_BE_COMPLETED + - Data cache request input - CACHE - - TO_BE_COMPLETED - dcache_req_i_t[2:0] * - ``dcache_wbuffer_empty_i`` - in - - TO_BE_COMPLETED + - Write buffer is empty - CACHE - - TO_BE_COMPLETED - logic * - ``dcache_wbuffer_not_ni_i`` - in - - CACHE - TO_BE_COMPLETED - - logic - - * - ``amo_req_o`` - - out - CACHE - - AMO request - - amo_req_t - - * - ``amo_resp_i`` - - in - - CACHE - - AMO response from cache - - amo_resp_t - - * - ``itlb_miss_o`` - - out - - PERF_COUNTERS - - To count the instruction TLB misses - - logic - - * - ``dtlb_miss_o`` - - out - - PERF_COUNTERS - - To count the data TLB misses - logic * - ``pmpcfg_i`` - in - Report the PMP configuration - CSR_REGFILE - - Report the PMP configuration - riscv::pmpcfg_t[15:0] * - ``pmpaddr_i`` - in - Report the PMP addresses - CSR_REGFILE - - Report the PMP addresses - logic[15:0][riscv::PLEN-3:0] - * - ``rvfi_lsu_ctrl_o`` - - out - - SUBSYSTEM - - Information dedicated to RVFI - - lsu_ctrl_t - - * - ``rvfi_mem_paddr_o`` - - out - - SUBSYSTEM - - Information dedicated to RVFI - - [riscv::PLEN-1:0] +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_mode_i`` input is tied to 0 +| As EnableAccelerator = 0, +| ``stall_st_pending_i`` input is tied to 0 +| ``acc_valid_i`` input is tied to 0 +| As RVA = 0, +| ``amo_valid_commit_i`` input is tied to 0 +| ``amo_req_o`` output is tied to 0 +| ``amo_resp_i`` input is tied to 0 +| As RVF = 0, +| ``fpu_ready_o`` output is tied to 0 +| ``fpu_valid_i`` input is tied to 0 +| ``fpu_fmt_i`` input is tied to 0 +| ``fpu_rm_i`` input is tied to 0 +| ``fpu_frm_i`` input is tied to 0 +| ``fpu_prec_i`` input is tied to 0 +| ``fpu_trans_id_o`` output is tied to 0 +| ``fpu_result_o`` output is tied to 0 +| ``fpu_valid_o`` output is tied to 0 +| ``fpu_exception_o`` output is tied to 0 +| As RVS = 0, +| ``enable_translation_i`` input is tied to 0 +| ``en_ld_st_translation_i`` input is tied to 0 +| ``sum_i`` input is tied to 0 +| ``mxr_i`` input is tied to 0 +| ``satp_ppn_i`` input is tied to 0 +| ``asid_i`` input is tied to 0 +| As MMUPresent = 0, +| ``flush_tlb_i`` input is tied to 0 +| As PRIV = MachineOnly, +| ``priv_lvl_i`` input is tied to MachineMode +| ``ld_st_priv_lvl_i`` input is tied to MAchineMode +| As PerfCounterEn = 0, +| ``itlb_miss_o`` output is tied to 0 +| ``dtlb_miss_o`` output is tied to 0 +| As IsRVFI = 0, +| ``rvfi_lsu_ctrl_o`` output is tied to 0 +| ``rvfi_mem_paddr_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_frontend.rst b/docs/04_cv32a65x_design/source/port_frontend.rst index 177a30f9e4..aeea8aadda 100644 --- a/docs/04_cv32a65x_design/source/port_frontend.rst +++ b/docs/04_cv32a65x_design/source/port_frontend.rst @@ -22,135 +22,108 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - - logic - - * - ``flush_bp_i`` - - in - - zero - - flush branch prediction - logic * - ``halt_i`` - in - halt commit stage - CONTROLLER - - halt commit stage - - logic - - * - ``debug_mode_i`` - - in - - CSR - - Debug mode state - logic * - ``boot_addr_i`` - in - Next PC when reset - SUBSYSTEM - - Next PC when reset - logic[riscv::VLEN-1:0] * - ``resolved_branch_i`` - in - mispredict event and next PC - EXECUTE - - mispredict event and next PC - bp_resolve_t * - ``set_pc_commit_i`` - in - Set the PC coming from COMMIT as next PC - CONTROLLER - - Set the PC coming from COMMIT as next PC - logic * - ``pc_commit_i`` - in - Next PC when flushing pipeline - COMMIT - - Next PC when flushing pipeline - logic[riscv::VLEN-1:0] * - ``epc_i`` - in - Next PC when returning from exception - CSR - - Next PC when returning from exception - logic[riscv::VLEN-1:0] * - ``eret_i`` - in - Return from exception event - CSR - - Return from exception event - logic * - ``trap_vector_base_i`` - in - Next PC when jumping into exception - CSR - - Next PC when jumping into exception - logic[riscv::VLEN-1:0] * - ``ex_valid_i`` - in - Exception event - COMMIT - - Exception event - - logic - - * - ``set_debug_pc_i`` - - in - - CSR - - Debug event - logic * - ``icache_dreq_o`` - out - Handshake between CACHE and FRONTEND (fetch) - CACHES - - Handshake between CACHE and FRONTEND (fetch) - icache_dreq_t * - ``icache_dreq_i`` - in - Handshake between CACHE and FRONTEND (fetch) - CACHES - - Handshake between CACHE and FRONTEND (fetch) - icache_drsp_t * - ``fetch_entry_o`` - out - Handshake's data between fetch and decode - ID_STAGE - - Handshake's data between fetch and decode - fetch_entry_t * - ``fetch_entry_valid_o`` - out - Handshake's valid between fetch and decode - ID_STAGE - - Handshake's valid between fetch and decode - logic * - ``fetch_entry_ready_i`` - in - Handshake's ready between fetch and decode - ID_STAGE - - Handshake's ready between fetch and decode - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| For any HW configuration, +| ``flush_bp_i`` input is tied to 0 +| As DebugEn = 0, +| ``debug_mode_i`` input is tied to 0 +| ``set_debug_pc_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_id_stage.rst b/docs/04_cv32a65x_design/source/port_id_stage.rst index 8d9ff2dcec..c7c4e8d62e 100644 --- a/docs/04_cv32a65x_design/source/port_id_stage.rst +++ b/docs/04_cv32a65x_design/source/port_id_stage.rst @@ -22,148 +22,94 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - - logic - - * - ``debug_req_i`` - - in - - SUBSYSTEM - - Debug (async) request - logic * - ``fetch_entry_i`` - in - Handshake's data between fetch and decode - FRONTEND - - Handshake's data between fetch and decode - ariane_pkg::fetch_entry_t * - ``fetch_entry_valid_i`` - in - Handshake's valid between fetch and decode - FRONTEND - - Handshake's valid between fetch and decode - logic * - ``fetch_entry_ready_o`` - out - Handshake's ready between fetch and decode - FRONTEND - - Handshake's ready between fetch and decode - logic * - ``issue_entry_o`` - out - Handshake's data between decode and issue - ISSUE - - Handshake's data between decode and issue - ariane_pkg::scoreboard_entry_t * - ``orig_instr_o`` - out - Instruction value - ISSUE - - instruction value - logic[31:0] * - ``issue_entry_valid_o`` - out - Handshake's valid between decode and issue - ISSUE - - Handshake's valid between decode and issue - logic * - ``is_ctrl_flow_o`` - out - Report if instruction is a control flow instruction - ISSUE - - Report if instruction is a control flow instruction - logic * - ``issue_instr_ack_i`` - in - Handshake's acknowlege between decode and issue - ISSUE - - Handshake's acknowlege between decode and issue - logic - * - ``rvfi_is_compressed_o`` - - out - - none - - none - - logic - - * - ``priv_lvl_i`` - - in - - CSR - - Report current privilege level - - riscv::priv_lvl_t - - * - ``fs_i`` - - in - - CSR - - Report floating point extension status - - riscv::xs_t - - * - ``frm_i`` - - in - - CSR - - Report floating point dynamic rounding mode - - logic[2:0] - - * - ``vs_i`` - - in - - CSR - - Report vector extension status - - riscv::xs_t - * - ``irq_i`` - in - Level sensitive (async) interrupts - SUBSYSTEM - - Level sensitive (async) interrupts - logic[1:0] * - ``irq_ctrl_i`` - in - - CSR - - TBD + - Interrupt control status + - CSR_REGFILE - ariane_pkg::irq_ctrl_t - * - ``debug_mode_i`` - - in - - CSR - - Report if current mode is debug - - logic - - * - ``tvm_i`` - - in - - CSR - - TBD - - logic - - * - ``tw_i`` - - in - - CSR - - TBD - - logic - - * - ``tsr_i`` - - in - - none - - none - - logic +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As DebugEn = 0, +| ``debug_req_i`` input is tied to 0 +| ``debug_mode_i`` input is tied to 0 +| As IsRVFI = 0, +| ``rvfi_is_compressed_o`` output is tied to 0 +| As PRIV = MachineOnly, +| ``priv_lvl_i`` input is tied to MachineMode +| ``tvm_i`` input is tied to 0 +| ``tw_i`` input is tied to 0 +| ``tsr_i`` input is tied to 0 +| As RVF = 0, +| ``fs_i`` input is tied to 0 +| ``frm_i`` input is tied to 0 +| As RVV = 0, +| ``vs_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_instr_queue.rst b/docs/04_cv32a65x_design/source/port_instr_queue.rst index f2e0bad520..6041227c20 100644 --- a/docs/04_cv32a65x_design/source/port_instr_queue.rst +++ b/docs/04_cv32a65x_design/source/port_instr_queue.rst @@ -22,117 +22,104 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - logic * - ``instr_i`` - in - Instruction - instr_realign - - Instruction - logic[ariane_pkg::INSTR_PER_FETCH-1:0][31:0] * - ``addr_i`` - in - Instruction address - instr_realign - - Instruction address - logic[ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] * - ``valid_i`` - in - Instruction is valid - instr_realign - - Instruction is valid - logic[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``ready_o`` - out - Handshake’s ready with CACHE - CACHE - - Handshake’s ready with CACHE - logic * - ``consumed_o`` - out - Indicates instructions consummed, or popped by ID_STAGE - FRONTEND - - Indicates instructions consummed, or popped by ID_STAGE - logic[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``exception_i`` - in - Exception (which is page-table fault) - CACHE - - Exception (which is page-table fault) - ariane_pkg::frontend_exception_t * - ``exception_addr_i`` - in - Exception address - CACHE - - Exception address - logic[riscv::VLEN-1:0] * - ``predict_address_i`` - in - Branch predict - FRONTEND - - Branch predict - logic[riscv::VLEN-1:0] * - ``cf_type_i`` - in - Instruction predict address - FRONTEND - - Instruction predict address - ariane_pkg::cf_t[ariane_pkg::INSTR_PER_FETCH-1:0] * - ``replay_o`` - out - Replay instruction because one of the FIFO was full - FRONTEND - - Replay instruction because one of the FIFO was full - logic * - ``replay_addr_o`` - out - Address at which to replay the fetch - FRONTEND - - Address at which to replay the fetch - logic[riscv::VLEN-1:0] * - ``fetch_entry_o`` - out - Handshake’s data with ID_STAGE - ID_STAGE - - Handshake’s data with ID_STAGE - ariane_pkg::fetch_entry_t * - ``fetch_entry_valid_o`` - out - Handshake’s valid with ID_STAGE - ID_STAGE - - Handshake’s valid with ID_STAGE - logic * - ``fetch_entry_ready_i`` - in - Handshake’s ready with ID_STAGE - ID_STAGE - - Handshake’s ready with ID_STAGE - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_instr_realign.rst b/docs/04_cv32a65x_design/source/port_instr_realign.rst index f11f69e527..baf4e921bf 100644 --- a/docs/04_cv32a65x_design/source/port_instr_realign.rst +++ b/docs/04_cv32a65x_design/source/port_instr_realign.rst @@ -22,67 +22,62 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - logic * - ``valid_i`` - in - 32-bit block is valid - CACHE - - 32-bit block is valid - logic * - ``serving_unaligned_o`` - out - Instruction is unaligned - FRONTEND - - Instruction is unaligned - logic * - ``address_i`` - in - 32-bit block address - CACHE - - 32-bit block address - logic[riscv::VLEN-1:0] * - ``data_i`` - in - 32-bit block - CACHE - - 32-bit block - logic[FETCH_WIDTH-1:0] * - ``valid_o`` - out - instruction is valid - FRONTEND - - instruction is valid - logic[INSTR_PER_FETCH-1:0] * - ``addr_o`` - out - Instruction address - FRONTEND - - Instruction address - logic[INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] * - ``instr_o`` - out - - none - - none + - Instruction + - instr_scan&instr_queue - logic[INSTR_PER_FETCH-1:0][31:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_instr_scan.rst b/docs/04_cv32a65x_design/source/port_instr_scan.rst index 4d46c5605f..a11b0b0d50 100644 --- a/docs/04_cv32a65x_design/source/port_instr_scan.rst +++ b/docs/04_cv32a65x_design/source/port_instr_scan.rst @@ -22,96 +22,86 @@ - in - Instruction to be predecoded - instr_realign - - Instruction to be predecoded - logic[31:0] * - ``rvi_return_o`` - out - Return instruction - FRONTEND - - Return instruction - logic * - ``rvi_call_o`` - out - JAL instruction - FRONTEND - - JAL instruction - logic * - ``rvi_branch_o`` - out - Branch instruction - FRONTEND - - Branch instruction - logic * - ``rvi_jalr_o`` - out - JALR instruction - FRONTEND - - JALR instruction - logic * - ``rvi_jump_o`` - out - Unconditional jump instruction - FRONTEND - - Unconditional jump instruction - logic * - ``rvi_imm_o`` - out - Instruction immediat - FRONTEND - - Instruction immediat - logic[riscv::VLEN-1:0] * - ``rvc_branch_o`` - out - Branch compressed instruction - FRONTEND - - Branch compressed instruction - logic * - ``rvc_jump_o`` - out - Unconditional jump compressed instruction - FRONTEND - - Unconditional jump compressed instruction - logic * - ``rvc_jr_o`` - out - JR compressed instruction - FRONTEND - - JR compressed instruction - logic * - ``rvc_return_o`` - out - Return compressed instruction - FRONTEND - - Return compressed instruction - logic * - ``rvc_jalr_o`` - out - JALR compressed instruction - FRONTEND - - JALR compressed instruction - logic * - ``rvc_call_o`` - out - JAL compressed instruction - FRONTEND - - JAL compressed instruction - logic * - ``rvc_imm_o`` - out - Instruction compressed immediat - FRONTEND - - Instruction compressed immediat - logic[riscv::VLEN-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst index e68a5d41f8..92c8e853ed 100644 --- a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst +++ b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst @@ -18,270 +18,241 @@ - connexion - Type - * - ``Clock`` + * - ``clk_i`` - in - - none - - none - - logicclk_i,// - - * - ``low`` - - in - - none - - none - - logicrst_ni,//Asynchronousresetactive + - Subsystem Clock + - SUBSYSTEM + - logic - * - ``flush_i`` + * - ``rst_ni`` - in - - none - - none + - Asynchronous reset active low + - SUBSYSTEM - logic - * - ``stall_i`` + * - ``flush_i`` - in - - none - - none + - Flush + - CONTROLLER - logic * - ``issue_instr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - scoreboard_entry_t * - ``orig_instr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[31:0] * - ``issue_instr_valid_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic * - ``issue_ack_o`` - out - - none - - none + - Issue stage acknowledge + - TO_BE_COMPLETED - logic * - ``rs1_o`` - out - - none - - none + - rs1 operand + - scoreboard - logic[REG_ADDR_SIZE-1:0] * - ``rs1_i`` - in - - none - - none + - rs1 operand + - scoreboard - riscv::xlen_t * - ``rs1_valid_i`` - in - - none - - none + - rs1 operand is valid + - scoreboard - logic * - ``rs2_o`` - out - - none - - none + - rs2 operand + - scoreboard - logic[REG_ADDR_SIZE-1:0] * - ``rs2_i`` - in - - none - - none + - rs2 operand + - scoreboard - riscv::xlen_t * - ``rs2_valid_i`` - in - - none - - none + - rs2 operand is valid + - scoreboard - logic * - ``rs3_o`` - out - - none - - none + - rs3 operand + - scoreboard - logic[REG_ADDR_SIZE-1:0] * - ``rs3_i`` - in - - none - - none + - rs3 operand + - scoreboard - rs3_len_t * - ``rs3_valid_i`` - in - - none - - none + - rs3 operand is valid + - scoreboard - logic * - ``rd_clobber_gpr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - fu_t[2**REG_ADDR_SIZE-1:0] * - ``rd_clobber_fpr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - fu_t[2**REG_ADDR_SIZE-1:0] * - ``fu_data_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - fu_data_t - * - ``fu_data_o.operanda`` + * - ``rs1_forwarding_o`` - out - - none - - none - - riscv::xlen_trs1_forwarding_o,//unregisteredversionof + - unregistered version of fu_data_o.operanda + - TO_BE_COMPLETED + - riscv::xlen_t - * - ``fu_data_o.operandb`` + * - ``rs2_forwarding_o`` - out - - none - - none - - riscv::xlen_trs2_forwarding_o,//unregisteredversionof + - unregistered version of fu_data_o.operandb + - TO_BE_COMPLETED + - riscv::xlen_t * - ``pc_o`` - out - - none - - none + - Instruction pc + - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``is_compressed_instr_o`` - out - - none - - none + - Is compressed instruction + - TO_BE_COMPLETED - logic - * - ``request`` + * - ``flu_ready_i`` - in - - none - - none - - logicflu_ready_i,//Fixedlatencyunitreadytoacceptanew + - Fixed latency unit ready to accept new request + - TO_BE_COMPLETED + - logic - * - ``valid`` + * - ``alu_valid_o`` - out - - none - - none - - logicalu_valid_o,//Outputis + - ALU output is valid + - TO_BE_COMPLETED + - logic - * - ``instruction`` + * - ``branch_valid_o`` - out - - none - - none - - logicbranch_valid_o,//thisisavalidbranch + - branch instruction is valid + - TO_BE_COMPLETED + - logic * - ``branch_predict_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - branchpredict_sbe_t - * - ``ready`` - - in - - none - - none - - logiclsu_ready_i,//FUis - - * - ``valid`` - - out - - none - - none - - logiclsu_valid_o,//Outputis - - * - ``valid`` - - out - - none - - none - - logicmult_valid_o,//Outputis - - * - ``ready`` + * - ``lsu_ready_i`` - in - - none - - none - - logicfpu_ready_i,//FUis - - * - ``valid`` - - out - - none - - none - - logicfpu_valid_o,//Outputis + - load store unit is ready + - TO_BE_COMPLETED + - logic - * - ``instr.`` + * - ``lsu_valid_o`` - out - - none - - none - - logic[1:0]fpu_fmt_o,//FPfmtfieldfrom + - load store unit result is valid + - TO_BE_COMPLETED + - logic - * - ``instr.`` + * - ``mult_valid_o`` - out - - none - - none - - logic[2:0]fpu_rm_o,//FPrmfieldfrom + - mult result is valid + - TO_BE_COMPLETED + - logic - * - ``valid`` + * - ``csr_valid_o`` - out - - none - - none - - logiccsr_valid_o,//Outputis + - CSR result is valid + - TO_BE_COMPLETED + - logic * - ``cvxif_valid_o`` - out - - none - - none + - CVXIF result is valid + - TO_BE_COMPLETED - logic * - ``cvxif_ready_i`` - in - - none - - none + - CVXIF is ready + - TO_BE_COMPLETED - logic * - ``cvxif_off_instr_o`` - out - - none - - none + - CVXIF offloaded instruction + - TO_BE_COMPLETED - logic[31:0] * - ``waddr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] * - ``wdata_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] * - ``we_gpr_i`` - in - - none - - none - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``we_fpr_i`` - - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] - * - ``entries`` + * - ``stall_issue_o`` - out - - none - - none - - logicstall_issue_o//stallsignal,wedonotwanttofetchanymore + - Stall signal, we do not want to fetch any more entries + - TO_BE_COMPLETED + - logic Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none +| As EnableAccelerator = 0, +| ``stall_i`` input is tied to 0 +| As RVF = 0, +| ``fpu_ready_i`` input is tied to 0 +| ``fpu_valid_o`` output is tied to 0 +| ``fpu_fmt_o`` output is tied to 0 +| ``fpu_rm_o`` output is tied to 0 +| ``we_fpr_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_issue_stage.rst b/docs/04_cv32a65x_design/source/port_issue_stage.rst index b7f18e74d8..7a653d81fc 100644 --- a/docs/04_cv32a65x_design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/port_issue_stage.rst @@ -22,331 +22,239 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - - logic - - * - ``sb_full_o`` - - out - - PERF_COUNTERS - - TO_BE_COMPLETED - logic * - ``flush_unissued_instr_i`` - in - TO_BE_COMPLETED - CONTROLLER - - TO_BE_COMPLETED - logic * - ``flush_i`` - in - TO_BE_COMPLETED - CONTROLLER - - TO_BE_COMPLETED - - logic - - * - ``stall_i`` - - in - - ACC_DISPATCHER - - zero when accelerate port is disable - logic * - ``decoded_instr_i`` - in - Handshake's data with decode stage - ID_STAGE - - Handshake's data between decode and issue - scoreboard_entry_t * - ``orig_instr_i`` - in - instruction value - ID_STAGE - - instruction value - logic[31:0] * - ``decoded_instr_valid_i`` - in - Handshake's valid with decode stage - ID_STAGE - - Handshake's valid between decode and issue - logic * - ``is_ctrl_flow_i`` - in - Is instruction a control flow instruction - ID_STAGE - - Report if instruction is a control flow instruction - logic * - ``decoded_instr_ack_o`` - out - Handshake's acknowlege with decode stage - ID_STAGE - - Handshake's acknowlege between decode and issue - logic * - ``rs1_forwarding_o`` - out - rs1 forwarding - EX_STAGE - - TO_BE_COMPLETED - [riscv::VLEN-1:0] * - ``rs2_forwarding_o`` - out - rs2 forwarding - EX_STAGE - - TO_BE_COMPLETED - [riscv::VLEN-1:0] * - ``fu_data_o`` - out - FU data useful to execute instruction - EX_STAGE - - TO_BE_COMPLETED - fu_data_t * - ``pc_o`` - out - - TO_BE_COMPLETED + - Program Counter - EX_STAGE - - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] * - ``is_compressed_instr_o`` - out - Is compressed instruction - EX_STAGE - - TO_BE_COMPLETED - logic * - ``flu_ready_i`` - in - - TO_BE_COMPLETED + - Fixed Latency Unit is ready - EX_STAGE - - TO_BE_COMPLETED - logic * - ``alu_valid_o`` - out - ALU FU is valid - EX_STAGE - - TO_BE_COMPLETED - logic * - ``resolve_branch_i`` - in - - TO_BE_COMPLETED + - Signaling that we resolved the branch - EX_STAGE - - TO_BE_COMPLETED - logic * - ``lsu_ready_i`` - in - Load store unit FU is ready - EX_STAGE - - TO_BE_COMPLETED - logic * - ``lsu_valid_o`` - out - Load store unit FU is valid - EX_STAGE - - TO_BE_COMPLETED - logic * - ``branch_valid_o`` - out - Branch unit is valid - EX_STAGE - - TO_BE_COMPLETED - logic * - ``branch_predict_o`` - out - Information of branch prediction - EX_STAGE - - TO_BE_COMPLETED - branchpredict_sbe_t * - ``mult_valid_o`` - out - Mult FU is valid - EX_STAGE - - TO_BE_COMPLETED - - logic - - * - ``fpu_ready_i`` - - in - - FPU FU is ready - - EX_STAGE - - TO_BE_COMPLETED - logic - * - ``fpu_valid_o`` - - out - - EX_STAGE - - TO_BE_COMPLETED - - logic - - * - ``fpu_fmt_o`` - - out - - EX_STAGE - - Report FP fmt field - - logic[1:0] - - * - ``fpu_rm_o`` - - out - - EX_STAGE - - report FP rm field - - logic[2:0] - * - ``csr_valid_o`` - out - CSR is valid - EX_STAGE - - TO_BE_COMPLETED - logic * - ``x_issue_valid_o`` - out - CVXIF FU is valid - EX_STAGE - - TO_BE_COMPLETED - logic * - ``x_issue_ready_i`` - in - CVXIF is FU ready - EX_STAGE - - TO_BE_COMPLETED - logic * - ``x_off_instr_o`` - out - CVXIF offloader instruction value - EX_STAGE - - TO_BE_COMPLETED - logic[31:0] - * - ``issue_instr_o`` - - out - - ACC_DISPATCHER - - TO_BE_COMPLETED - - scoreboard_entry_t - - * - ``issue_instr_hs_o`` - - out - - ACC_DISPATCHER - - TO_BE_COMPLETED - - logic - * - ``trans_id_i`` - in - - TO_BE_COMPLETED + - Transaction ID - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0][TRANS_ID_BITS-1:0] * - ``resolved_branch_i`` - in - - TO_BE_COMPLETED + - The branch engine uses the write back from the ALU - EX_STAGE - - TO_BE_COMPLETED - bp_resolve_t * - ``wbdata_i`` - in - TO_BE_COMPLETED - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] * - ``ex_ex_i`` - in - exception from execute stage or CVXIF - EX_STAGE - - exception from execute stage or CVXIF offloaded instruction - exception_t[CVA6Cfg.NrWbPorts-1:0] * - ``wt_valid_i`` - in - TO_BE_COMPLETED - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0] * - ``x_we_i`` - in - - TO_BE_COMPLETED + - CVXIF write enable - EX_STAGE - - TO_BE_COMPLETED - logic * - ``waddr_i`` - in - TO_BE_COMPLETED - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] * - ``wdata_i`` - in - TO_BE_COMPLETED - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0][riscv::XLEN-1:0] * - ``we_gpr_i`` - in - - TO_BE_COMPLETED + - GPR write enable - EX_STAGE - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``we_fpr_i`` - - in - - TO_BE_COMPLETED - - EX_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_instr_o`` - out - - TO_BE_COMPLETED + - Commit instruction - COMMIT_STAGE - - TO_BE_COMPLETED - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_i`` - in - - TO_BE_COMPLETED + - Commit acknowledge - COMMIT_STAGE - - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] - * - ``stall_issue_o`` - - out - - PERF_COUNTERS - - Issue stall - - logic - - * - ``rvfi_issue_pointer_o`` - - out - - SUBSYSTEM - - Information dedicated to RVFI - - logic[TRANS_ID_BITS-1:0] - - * - ``rvfi_commit_pointer_o`` - - out - - SUBSYSTEM - - Information dedicated to RVFI - - logic[CVA6Cfg.NrCommitPorts-1:0][TRANS_ID_BITS-1:0] +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As PerfCounterEn = 0, +| ``sb_full_o`` output is tied to 0 +| ``stall_issue_o`` output is tied to 0 +| As EnableAccelerator = 0, +| ``stall_i`` input is tied to 0 +| ``issue_instr_o`` output is tied to 0 +| ``issue_instr_hs_o`` output is tied to 0 +| As RVF = 0, +| ``fpu_ready_i`` input is tied to 0 +| ``fpu_valid_o`` output is tied to 0 +| ``fpu_fmt_o`` output is tied to 0 +| ``fpu_rm_o`` output is tied to 0 +| ``we_fpr_i`` input is tied to 0 +| As IsRVFI = 0, +| ``rvfi_issue_pointer_o`` output is tied to 0 +| ``rvfi_commit_pointer_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_load_store_unit.rst b/docs/04_cv32a65x_design/source/port_load_store_unit.rst new file mode 100644 index 0000000000..fa0ddae9c7 --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_load_store_unit.rst @@ -0,0 +1,208 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_load_store_unit_ports: + +.. list-table:: load_store_unit module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``stall_st_pending_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``no_st_pending_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - fu_data_t + + * - ``lsu_ready_o`` + - out + - Load and store unit is ready + - ISSUE_STAGE + - logic + + * - ``lsu_valid_i`` + - in + - Load and Store unit is valid + - ISSUE_STAGE + - logic + + * - ``load_trans_id_o`` + - out + - Load transaction ID + - ISSUE_STAGE + - logic[TRANS_ID_BITS-1:0] + + * - ``load_result_o`` + - out + - Load result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``load_valid_o`` + - out + - Load result is valid + - ISSUE_STAGE + - logic + + * - ``load_exception_o`` + - out + - Load exception + - ISSUE_STAGE + - exception_t + + * - ``store_trans_id_o`` + - out + - Store transaction ID + - ISSUE_STAGE + - logic[TRANS_ID_BITS-1:0] + + * - ``store_result_o`` + - out + - Store result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``store_valid_o`` + - out + - Store result is valid + - ISSUE_STAGE + - logic + + * - ``store_exception_o`` + - out + - Store exception + - ISSUE_STAGE + - exception_t + + * - ``commit_i`` + - in + - Commit the pending store + - TO_BE_COMPLETED + - logic + + * - ``commit_ready_o`` + - out + - commit queue is ready to accept another commit request + - TO_BE_COMPLETED + - logic + + * - ``commit_tran_id_i`` + - in + - Commit transaction ID + - TO_BE_COMPLETED + - logic[TRANS_ID_BITS-1:0] + + * - ``icache_areq_i`` + - in + - Instruction cache input request + - CACHES + - icache_arsp_t + + * - ``icache_areq_o`` + - out + - Instruction cache output request + - CACHES + - icache_areq_t + + * - ``dcache_req_ports_i`` + - in + - Data cache request output + - CACHES + - dcache_req_o_t[2:0] + + * - ``dcache_req_ports_o`` + - out + - Data cache request input + - CACHES + - dcache_req_i_t[2:0] + + * - ``dcache_wbuffer_empty_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``dcache_wbuffer_not_ni_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``pmpcfg_i`` + - in + - PMP configuration + - CSR_REGFILE + - riscv::pmpcfg_t[15:0] + + * - ``pmpaddr_i`` + - in + - PMP address + - CSR_REGFILE + - logic[15:0][riscv::PLEN-3:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As RVA = 0, +| ``amo_valid_commit_i`` input is tied to 0 +| ``amo_req_o`` output is tied to 0 +| ``amo_resp_i`` input is tied to 0 +| As RVS = 0, +| ``enable_translation_i`` input is tied to 0 +| ``en_ld_st_translation_i`` input is tied to 0 +| ``sum_i`` input is tied to 0 +| ``mxr_i`` input is tied to 0 +| ``satp_ppn_i`` input is tied to 0 +| ``asid_i`` input is tied to 0 +| ``asid_to_be_flushed_i`` input is tied to 0 +| ``vaddr_to_be_flushed_i`` input is tied to 0 +| As PRIV = MachineOnly, +| ``priv_lvl_i`` input is tied to MachineMode +| ``ld_st_priv_lvl_i`` input is tied to MAchineMode +| As MMUPresent = 0, +| ``flush_tlb_i`` input is tied to 0 +| As PerfCounterEn = 0, +| ``itlb_miss_o`` output is tied to 0 +| ``dtlb_miss_o`` output is tied to 0 +| As IsRVFI = 0, +| ``rvfi_lsu_ctrl_o`` output is tied to 0 +| ``rvfi_mem_paddr_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_load_unit.rst b/docs/04_cv32a65x_design/source/port_load_unit.rst new file mode 100644 index 0000000000..3e30d95802 --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_load_unit.rst @@ -0,0 +1,152 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_load_unit_ports: + +.. list-table:: load_unit module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``valid_i`` + - in + - load unit input port + - TO_BE_COMPLETED + - logic + + * - ``lsu_ctrl_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - lsu_ctrl_t + + * - ``pop_ld_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``valid_o`` + - out + - load unit result is valid + - TO_BE_COMPLETED + - logic + + * - ``trans_id_o`` + - out + - Load transaction ID + - TO_BE_COMPLETED + - logic[TRANS_ID_BITS-1:0] + + * - ``result_o`` + - out + - Load result + - TO_BE_COMPLETED + - riscv::xlen_t + + * - ``ex_o`` + - out + - Load exception + - TO_BE_COMPLETED + - exception_t + + * - ``translation_req_o`` + - out + - Request address translation + - TO_BE_COMPLETED + - logic + + * - ``vaddr_o`` + - out + - Vistual address + - TO_BE_COMPLETED + - logic[riscv::VLEN-1:0] + + * - ``paddr_i`` + - in + - Physical address + - TO_BE_COMPLETED + - logic[riscv::PLEN-1:0] + + * - ``ex_i`` + - in + - Excepted which appears before load + - TO_BE_COMPLETED + - exception_t + + * - ``page_offset_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic[11:0] + + * - ``page_offset_matches_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``store_buffer_empty_i`` + - in + - Stoer buffer is empty + - TO_BE_COMPLETED + - logic + + * - ``commit_tran_id_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic[TRANS_ID_BITS-1:0] + + * - ``req_port_i`` + - in + - Data cache request out + - CACHES + - dcache_req_o_t + + * - ``req_port_o`` + - out + - Data cache request in + - CACHES + - dcache_req_i_t + + * - ``dcache_wbuffer_not_ni_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| For any HW configuration, +| ``dtlb_hit_i`` input is tied to 1 +| As MMUPresent = 0, +| ``dtlb_ppn_i`` input is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_lsu_bypass.rst b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst new file mode 100644 index 0000000000..2ae2f91beb --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst @@ -0,0 +1,77 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_lsu_bypass_ports: + +.. list-table:: lsu_bypass module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``lsu_req_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - lsu_ctrl_t + + * - ``lsu_req_valid_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``pop_ld_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``pop_st_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``lsu_ctrl_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - lsu_ctrl_t + + * - ``ready_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_mult.rst b/docs/04_cv32a65x_design/source/port_mult.rst new file mode 100644 index 0000000000..921b6b100b --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_mult.rst @@ -0,0 +1,77 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_mult_ports: + +.. list-table:: mult module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - Flush + - CONTROLLER + - logic + + * - ``fu_data_i`` + - in + - FU data needed to execute instruction + - ISSUE_STAGE + - fu_data_t + + * - ``mult_valid_i`` + - in + - Mult instruction is valid + - ISSUE_STAGE + - logic + + * - ``result_o`` + - out + - Mult result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``mult_valid_o`` + - out + - Mult result is valid + - ISSUE_STAGE + - logic + + * - ``mult_ready_o`` + - out + - Mutl is ready + - ISSUE_STAGE + - logic + + * - ``mult_trans_id_o`` + - out + - Mult transaction ID + - ISSUE_STAGE + - logic[TRANS_ID_BITS-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_multiplier.rst b/docs/04_cv32a65x_design/source/port_multiplier.rst new file mode 100644 index 0000000000..b6131a789f --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_multiplier.rst @@ -0,0 +1,89 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_multiplier_ports: + +.. list-table:: multiplier module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``trans_id_i`` + - in + - Multiplier transaction ID + - Mult + - logic[TRANS_ID_BITS-1:0] + + * - ``mult_valid_i`` + - in + - Multiplier instruction is valid + - Mult + - logic + + * - ``operation_i`` + - in + - Multiplier operation + - Mult + - fu_op + + * - ``operand_a_i`` + - in + - A operand + - Mult + - riscv::xlen_t + + * - ``operand_b_i`` + - in + - B operand + - Mult + - riscv::xlen_t + + * - ``result_o`` + - out + - Multiplier result + - Mult + - riscv::xlen_t + + * - ``mult_valid_o`` + - out + - Mutliplier result is valid + - Mult + - logic + + * - ``mult_ready_o`` + - out + - Multiplier FU is ready + - Mult + - logic + + * - ``mult_trans_id_o`` + - out + - Multiplier transaction ID + - Mult + - logic[TRANS_ID_BITS-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_ras.rst b/docs/04_cv32a65x_design/source/port_ras.rst index eece1c5f88..f91820b462 100644 --- a/docs/04_cv32a65x_design/source/port_ras.rst +++ b/docs/04_cv32a65x_design/source/port_ras.rst @@ -22,47 +22,44 @@ - in - Subsystem Clock - SUBSYSTEM - - Subsystem Clock - logic * - ``rst_ni`` - in - Asynchronous reset active low - SUBSYSTEM - - Asynchronous reset active low - logic * - ``flush_i`` - in - Fetch flush request - CONTROLLER - - Fetch flush request - logic * - ``push_i`` - in - Push address in RAS - FRONTEND - - Push address in RAS - logic * - ``pop_i`` - in - Pop address from RAS - FRONTEND - - Pop address from RAS - logic * - ``data_i`` - in - Data to be pushed - FRONTEND - - Data to be pushed - logic[riscv::VLEN-1:0] * - ``data_o`` - out - Popped data - FRONTEND - - Popped data - ariane_pkg::ras_t + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_scoreboard.rst b/docs/04_cv32a65x_design/source/port_scoreboard.rst index 25f96423de..25f65b3e28 100644 --- a/docs/04_cv32a65x_design/source/port_scoreboard.rst +++ b/docs/04_cv32a65x_design/source/port_scoreboard.rst @@ -18,216 +18,202 @@ - connexion - Type - * - ``Clock`` + * - ``clk_i`` - in - - none - - none - - logicclk_i,// + - Subsystem Clock + - SUBSYSTEM + - logic - * - ``low`` + * - ``rst_ni`` - in - - none - - none - - logicrst_ni,//Asynchronousresetactive + - Asynchronous reset active low + - SUBSYSTEM + - logic * - ``sb_full_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic - * - ``instructions`` + * - ``flush_unissued_instr_i`` - in - - none - - none - - logicflush_unissued_instr_i,//flushonlyun-issued + - Flush only un-issued instructions + - TO_BE_COMPLETED + - logic - * - ``scoreboard`` + * - ``flush_i`` - in - - none - - none - - logicflush_i,//flushwhole + - Flush whole scoreboard + - TO_BE_COMPLETED + - logic - * - ``branch`` + * - ``unresolved_branch_i`` - in - - none - - none - - logicunresolved_branch_i,//wehaveanunresolved + - We have an unresolved branch + - TO_BE_COMPLETED + - logic * - ``rd_clobber_gpr_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rd_clobber_fpr_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs1_i`` - in - - none - - none + - rs1 operand + - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs1_o`` - out - - none - - none + - rs1 operand + - issue_read_operands - riscv::xlen_t * - ``rs1_valid_o`` - out - - none - - none + - rs1 operand is valid + - issue_read_operands - logic * - ``rs2_i`` - in - - none - - none + - rs2 operand + - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs2_o`` - out - - none - - none + - rs2 operand + - issue_read_operands - riscv::xlen_t * - ``rs2_valid_o`` - out - - none - - none + - rs2 operand is valid + - issue_read_operands - logic * - ``rs3_i`` - in - - none - - none + - rs3 operand + - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs3_o`` - out - - none - - none + - rs3 operand + - issue_read_operands - rs3_len_t * - ``rs3_valid_o`` - out - - none - - none + - rs3 operand is valid + - issue_read_operands - logic * - ``commit_instr_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - ariane_pkg::scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] * - ``commit_ack_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[CVA6Cfg.NrCommitPorts-1:0] * - ``decoded_instr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - ariane_pkg::scoreboard_entry_t * - ``orig_instr_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[31:0] * - ``decoded_instr_valid_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic * - ``decoded_instr_ack_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic - * - ``issue_instr_o`` - - out - - none - - none - - ariane_pkg::scoreboard_entry_t - * - ``orig_instr_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic[31:0] * - ``issue_instr_valid_o`` - out - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic * - ``issue_ack_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - logic * - ``resolved_branch_i`` - in - - none - - none + - TO_BE_COMPLETED + - TO_BE_COMPLETED - ariane_pkg::bp_resolve_t - * - ``back`` + * - ``trans_id_i`` - in - - none - - none - - logic[CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0]trans_id_i,//transactionIDatwhichtowritetheresult + - Transaction ID at which to write the result back + - TO_BE_COMPLETED + - logic[CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] - * - ``in`` + * - ``wbdata_i`` - in - - none - - none - - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0]wbdata_i,//writedata + - Write data in + - TO_BE_COMPLETED + - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] - * - ``exception)`` + * - ``ex_i`` - in - - none - - none - - ariane_pkg::exception_t[CVA6Cfg.NrWbPorts-1:0]ex_i,//exceptionfromafunctionalunit(e.g.:ld/st + - Exception from a functional unit (e.g.: ld/st exception) + - TO_BE_COMPLETED + - ariane_pkg::exception_t[CVA6Cfg.NrWbPorts-1:0] - * - ``valid`` + * - ``wt_valid_i`` - in - - none - - none - - logic[CVA6Cfg.NrWbPorts-1:0]wt_valid_i,//datainis + - Data in is valid + - TO_BE_COMPLETED + - logic[CVA6Cfg.NrWbPorts-1:0] - * - ``writeback`` + * - ``x_we_i`` - in - - none - - none - - logicx_we_i,//cvxifwefor - - * - ``rvfi_issue_pointer_o`` - - out - - none - - none - - logic[ariane_pkg::TRANS_ID_BITS-1:0] - - * - ``rvfi_commit_pointer_o`` - - out - - none - - none - - logic[CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] + - Cvxif we for writeback + - TO_BE_COMPLETED + - logic Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none +| As EnableAccelerator = 0, +| ``issue_instr_o`` output is tied to 0 +| As IsRVFI = 0, +| ``rvfi_issue_pointer_o`` output is tied to 0 +| ``rvfi_commit_pointer_o`` output is tied to 0 diff --git a/docs/04_cv32a65x_design/source/port_serdiv.rst b/docs/04_cv32a65x_design/source/port_serdiv.rst new file mode 100644 index 0000000000..994e02ef83 --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_serdiv.rst @@ -0,0 +1,101 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_serdiv_ports: + +.. list-table:: serdiv module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``id_i`` + - in + - Serdiv translation ID + - Mult + - logic[TRANS_ID_BITS-1:0] + + * - ``op_a_i`` + - in + - A operand + - Mult + - logic[WIDTH-1:0] + + * - ``op_b_i`` + - in + - B operand + - Mult + - logic[WIDTH-1:0] + + * - ``rem`` + - in + - Serdiv operation + - Mult + - logic[1:0]opcode_i,//0:udiv,2:urem,1:div,3: + + * - ``in_vld_i`` + - in + - Serdiv instruction is valid + - Mult + - logic + + * - ``in_rdy_o`` + - out + - Serdiv FU is ready + - Mult + - logic + + * - ``flush_i`` + - in + - Flush + - CONTROLLER + - logic + + * - ``out_vld_o`` + - out + - Serdiv result is valid + - Mult + - logic + + * - ``out_rdy_i`` + - in + - Serdiv is ready + - Mult + - logic + + * - ``id_o`` + - out + - Serdiv transaction ID + - Mult + - logic[TRANS_ID_BITS-1:0] + + * - ``res_o`` + - out + - Serdiv result + - Mult + - logic[WIDTH-1:0] + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +none diff --git a/docs/04_cv32a65x_design/source/port_store_unit.rst b/docs/04_cv32a65x_design/source/port_store_unit.rst new file mode 100644 index 0000000000..15c4dc774a --- /dev/null +++ b/docs/04_cv32a65x_design/source/port_store_unit.rst @@ -0,0 +1,168 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _CVA6_store_unit_ports: + +.. list-table:: store_unit module IO ports + :header-rows: 1 + + * - Signal + - IO + - Description + - connexion + - Type + + * - ``clk_i`` + - in + - Subsystem Clock + - SUBSYSTEM + - logic + + * - ``rst_ni`` + - in + - Asynchronous reset active low + - SUBSYSTEM + - logic + + * - ``flush_i`` + - in + - Flush + - CONTROLLER + - logic + + * - ``stall_st_pending_i`` + - in + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``no_st_pending_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``store_buffer_empty_o`` + - out + - Store buffer is empty + - TO_BE_COMPLETED + - logic + + * - ``valid_i`` + - in + - Store instruction is valid + - ISSUE_STAGE + - logic + + * - ``lsu_ctrl_i`` + - in + - data input + - ISSUE_STAGE + - lsu_ctrl_t + + * - ``pop_st_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``commit_i`` + - in + - Instruction commit + - TO_BE_COMPLETED + - logic + + * - ``commit_ready_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic + + * - ``valid_o`` + - out + - Store result is valid + - ISSUE_STAGE + - logic + + * - ``trans_id_o`` + - out + - Transaction ID + - ISSUE_STAGE + - logic[TRANS_ID_BITS-1:0] + + * - ``result_o`` + - out + - Store result + - ISSUE_STAGE + - riscv::xlen_t + + * - ``ex_o`` + - out + - Store exception output + - TO_BE_COMPLETED + - exception_t + + * - ``translation_req_o`` + - out + - Address translation request + - TO_BE_COMPLETED + - logic + + * - ``vaddr_o`` + - out + - Virtual address + - TO_BE_COMPLETED + - logic[riscv::VLEN-1:0] + + * - ``paddr_i`` + - in + - Physical address + - TO_BE_COMPLETED + - logic[riscv::PLEN-1:0] + + * - ``ex_i`` + - in + - Exception raised before store + - TO_BE_COMPLETED + - exception_t + + * - ``page_offset_i`` + - in + - Address to be checked + - load_unit + - logic[11:0] + + * - ``page_offset_matches_o`` + - out + - Address check result + - load_unit + - logic + + * - ``req_port_i`` + - in + - Data cache request + - CACHES + - dcache_req_o_t + + * - ``req_port_o`` + - out + - Data cache response + - CACHES + - dcache_req_i_t + +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +| As RVA = 0, +| ``amo_valid_commit_i`` input is tied to 0 +| ``amo_req_o`` output is tied to 0 +| ``amo_resp_i`` input is tied to 0 +| As IsRVFI = 0, +| ``rvfi_mem_paddr_o`` output is tied to 0 +| For any HW configuration, +| ``dtlb_hit_i`` input is tied to 1 diff --git a/docs/scripts/define_blacklist.py b/docs/scripts/define_blacklist.py index af08fd488c..dcbcc24646 100644 --- a/docs/scripts/define_blacklist.py +++ b/docs/scripts/define_blacklist.py @@ -13,7 +13,8 @@ def define_blacklist(parameters): black_list = {} - black_list["flush_bp_i"] = ["For any HW configuration", "zero"] + black_list["flush_bp_i"] = ["For any HW configuration", "0"] + black_list["dtlb_hit_i"] = ["For any HW configuration", "1"] param = "IsRVFI" paramvalue = "0" @@ -23,14 +24,42 @@ def define_blacklist(parameters): param = "DebugEn" paramvalue = parameters[param].value if paramvalue == "0": + black_list["set_debug_pc_o"] = [f"As {param} = {paramvalue}", "0"] black_list["set_debug_pc_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["debug_mode_o"] = [f"As {param} = {paramvalue}", "0"] black_list["debug_mode_i"] = [f"As {param} = {paramvalue}", "0"] black_list["debug_req_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["single_step_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["single_step_i"] = [f"As {param} = {paramvalue}", "0"] param = "RVV" paramvalue = parameters[param].value if paramvalue == "0": black_list["vs_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["vs_o"] = [f"As {param} = {paramvalue}", "0"] + + param = "RVS" + paramvalue = parameters[param].value + if paramvalue == "0": + black_list["en_translation_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["enable_translation_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["enable_translation_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["en_ld_st_translation_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["en_ld_st_translation_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["sum_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["sum_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["satp_ppn_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["satp_ppn_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["vaddr_to_be_flushed_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["vaddr_to_be_flushed_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["asid_to_be_flushed_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["asid_to_be_flushed_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["mxr_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["mxr_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["asid_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["asid_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["sfence_vma_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["sfence_vma_i"] = [f"As {param} = {paramvalue}", "0"] param = "EnableAccelerator" paramvalue = parameters[param].value @@ -40,10 +69,13 @@ def define_blacklist(parameters): param = "RVF" paramvalue = parameters[param].value if paramvalue == "0": + black_list["fs_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fs_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["frm_o"] = [f"As {param} = {paramvalue}", "0"] black_list["frm_i"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_valid_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_ready_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["fpu_ready_i"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_fmt_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_rm_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_valid_i"] = [f"As {param} = {paramvalue}", "0"] @@ -54,31 +86,54 @@ def define_blacklist(parameters): black_list["fpu_trans_id_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_result_o"] = [f"As {param} = {paramvalue}", "0"] black_list["fpu_exception_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["csr_write_fflags_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["fflags_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["csr_write_fflags_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["fprec_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["dirty_fp_state_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["dirty_fp_state_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["we_fpr_i"] = [f"As {param} = {paramvalue}", "0"] param = "RVA" paramvalue = parameters[param].value if paramvalue == "0": black_list["amo_req_o"] = [f"As {param} = {paramvalue}", "0"] black_list["amo_resp_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["amo_valid_commit_o"] = [f"As {param} = {paramvalue}", "0"] black_list["amo_valid_commit_i"] = [f"As {param} = {paramvalue}", "0"] param = "PRIV" paramvalue = "MachineOnly" if paramvalue == "MachineOnly": # TODO PRIV to be added to RTL parameters + black_list["ld_st_priv_lvl_o"] = [f"As {param} = {paramvalue}", "MAchineMode"] black_list["ld_st_priv_lvl_i"] = [f"As {param} = {paramvalue}", "MAchineMode"] + black_list["priv_lvl_o"] = [f"As {param} = {paramvalue}", "MachineMode"] black_list["priv_lvl_i"] = [f"As {param} = {paramvalue}", "MachineMode"] - # black_list["tvm_i"] = [f"As {param} = {paramvalue}", "0"] - # black_list["tw_i"] = [f"As {param} = {paramvalue}", "0"] - # black_list["tsr_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["tvm_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["tvm_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["tw_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["tw_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["tsr_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["tsr_i"] = [f"As {param} = {paramvalue}", "0"] param = "PerfCounterEn" paramvalue = "0" if paramvalue == "0": # TODO PerfCounterEn to be added to RTL parameters black_list["PERF_COUNTERS"] = [f"As {param} = {paramvalue}", "0"] + param = "FenceEn" + paramvalue = "0" + if paramvalue == "0": # TODO FenceEn to be added to RTL parameters + black_list["fence_i_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["fence_i_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["fence_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["fence_i"] = [f"As {param} = {paramvalue}", "0"] + param = "MMUPresent" paramvalue = "0" if paramvalue == "0": # TODO the MMUPresent to be added to RTL parameters black_list["flush_tlb_i"] = [f"As {param} = {paramvalue}", "0"] + black_list["flush_tlb_o"] = [f"As {param} = {paramvalue}", "0"] + black_list["dtlb_ppn_i"] = [f"As {param} = {paramvalue}", "0"] return black_list diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index 3d34df1dce..67e49d4ed3 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -48,6 +48,17 @@ file.append("../core/compressed_decoder.sv") file.append("../core/scoreboard.sv") file.append("../core/issue_read_operands.sv") + file.append("../core/alu.sv") + file.append("../core/branch_unit.sv") + file.append("../core/csr_buffer.sv") + file.append("../core/mult.sv") + file.append("../core/multiplier.sv") + file.append("../core/serdiv.sv") + file.append("../core/load_store_unit.sv") + file.append("../core/load_unit.sv") + file.append("../core/store_unit.sv") + file.append("../core/lsu_bypass.sv") + file.append("../core/cvxif_fu.sv") black_list = define_blacklist(parameters) From a21d22c541aa508bae1f014ec3769485bc484465 Mon Sep 17 00:00:00 2001 From: ALLART Come Date: Wed, 21 Feb 2024 14:50:05 +0100 Subject: [PATCH 11/20] Apply 25 suggestion(s) to 10 file(s) --- core/branch_unit.sv | 2 +- core/csr_regfile.sv | 4 ++-- core/cvxif_fu.sv | 2 +- core/ex_stage.sv | 2 +- core/issue_read_operands.sv | 14 +++++++------- core/issue_stage.sv | 2 +- core/load_store_unit.sv | 10 +++++----- core/load_unit.sv | 8 ++++---- core/scoreboard.sv | 4 ++-- core/store_unit.sv | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 7bbd3d9c39..3ae437483f 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -39,7 +39,7 @@ module branch_unit #( input ariane_pkg::branchpredict_sbe_t branch_predict_i, // Signaling that we resolved the branch - ISSUE_STAGE output ariane_pkg::bp_resolve_t resolved_branch_o, - // Branch is resolved, new entries can be accept by scoreboard - ID_STAGE + // Branch is resolved, new entries can be accepted by scoreboard - ID_STAGE output logic resolve_branch_o, // Branch exception out - TO_BE_COMPLETED output ariane_pkg::exception_t branch_exception_o diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 68be675cde..fbb2caf0ac 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -83,9 +83,9 @@ module csr_regfile output riscv::xs_t vs_o, // interrupt management to id stage - ID_STAGE output irq_ctrl_t irq_ctrl_o, - // enable virtual address translation - EX_STAGE + // Enable virtual address translation - EX_STAGE output logic en_translation_o, - // enable virtual address translation for load and stores - EX_STAGE + // Enable virtual address translation for load and stores - EX_STAGE output logic en_ld_st_translation_o, // Privilege level at which load and stores should happen - EX_STAGE output riscv::priv_lvl_t ld_st_priv_lvl_o, diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index 7543150e12..34783f5416 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -27,7 +27,7 @@ module cvxif_fu input logic x_valid_i, // CVXIF is ready - ISSUE_STAGE output logic x_ready_o, - // undecoded instruction - ISSUE_STAGE + // Offloaded instruction - ISSUE_STAGE input logic [ 31:0] x_off_instr_i, // CVXIF transaction ID - ISSUE_STAGE output logic [TRANS_ID_BITS-1:0] x_trans_id_o, diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 646097c976..d6237dcc24 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -26,7 +26,7 @@ module ex_stage input logic rst_ni, // Fetch flush request - CONTROLLER input logic flush_i, - // Mode is debug - CSR_REGFILE + // Debug mode is enabled - CSR_REGFILE input logic debug_mode_i, // rs1 forwarding - ISSUE_STAGE input logic [riscv::VLEN-1:0] rs1_forwarding_i, diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 2254a5b93a..c5b290b60f 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -61,27 +61,27 @@ module issue_read_operands input fu_t [2**REG_ADDR_SIZE-1:0] rd_clobber_fpr_i, // TO_BE_COMPLETED - TO_BE_COMPLETED output fu_data_t fu_data_o, - // unregistered version of fu_data_o.operanda - TO_BE_COMPLETED + // Unregistered version of fu_data_o.operanda - TO_BE_COMPLETED output riscv::xlen_t rs1_forwarding_o, - // unregistered version of fu_data_o.operandb - TO_BE_COMPLETED + // Unregistered version of fu_data_o.operandb - TO_BE_COMPLETED output riscv::xlen_t rs2_forwarding_o, // Instruction pc - TO_BE_COMPLETED output logic [riscv::VLEN-1:0] pc_o, // Is compressed instruction - TO_BE_COMPLETED output logic is_compressed_instr_o, - // Fixed latency unit ready to accept new request - TO_BE_COMPLETED + // Fixed Latency Unit ready to accept new request - TO_BE_COMPLETED input logic flu_ready_i, // ALU output is valid - TO_BE_COMPLETED output logic alu_valid_o, - // branch instruction is valid - TO_BE_COMPLETED + // Branch instruction is valid - TO_BE_COMPLETED output logic branch_valid_o, // TO_BE_COMPLETED - TO_BE_COMPLETED output branchpredict_sbe_t branch_predict_o, - // load store unit is ready - TO_BE_COMPLETED + // Load Store Unit is ready - TO_BE_COMPLETED input logic lsu_ready_i, - // load store unit result is valid - TO_BE_COMPLETED + // Load Store Unit result is valid - TO_BE_COMPLETED output logic lsu_valid_o, - // mult result is valid - TO_BE_COMPLETED + // Mult result is valid - TO_BE_COMPLETED output logic mult_valid_o, // FPU is ready - TO_BE_COMPLETED input logic fpu_ready_i, diff --git a/core/issue_stage.sv b/core/issue_stage.sv index ac9c8518b7..e5dfa3b51b 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -107,7 +107,7 @@ module issue_stage input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr_i, // FPR write enable - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i, - // Commit instruction - COMMIT_STAGE + // Instructions to commit - COMMIT_STAGE output scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_o, // Commit acknowledge - COMMIT_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 1687cd2be3..79fc09bccb 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -33,7 +33,7 @@ module load_store_unit input logic amo_valid_commit_i, // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, - // Load and store unit is ready - ISSUE_STAGE + // Load Store Unit is ready - ISSUE_STAGE output logic lsu_ready_o, // Load and Store unit is valid - ISSUE_STAGE input logic lsu_valid_i, @@ -56,9 +56,9 @@ module load_store_unit // Store exception - ISSUE_STAGE output exception_t store_exception_o, - // Commit the pending store - TO_BE_COMPLETED + // Commit the first pending store - TO_BE_COMPLETED input logic commit_i, - // commit queue is ready to accept another commit request - TO_BE_COMPLETED + // Commit queue is ready to accept another commit request - TO_BE_COMPLETED output logic commit_ready_o, // Commit transaction ID - TO_BE_COMPLETED input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, @@ -91,9 +91,9 @@ module load_store_unit input logic [riscv::VLEN-1:0] vaddr_to_be_flushed_i, // TLB flush - CONTROLLER input logic flush_tlb_i, - // instruction TLB miss - PERF_COUNTERS + // Instruction TLB miss - PERF_COUNTERS output logic itlb_miss_o, - // data TLB miss - PERF_COUNTERS + // Data TLB miss - PERF_COUNTERS output logic dtlb_miss_o, // Data cache request output - CACHES diff --git a/core/load_unit.sv b/core/load_unit.sv index d6be99d8f5..5bc001cfe6 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -29,13 +29,13 @@ module load_unit input logic rst_ni, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, - // load unit input port - TO_BE_COMPLETED + // Load unit input port - TO_BE_COMPLETED input logic valid_i, // TO_BE_COMPLETED - TO_BE_COMPLETED input lsu_ctrl_t lsu_ctrl_i, // TO_BE_COMPLETED - TO_BE_COMPLETED output logic pop_ld_o, - // load unit result is valid - TO_BE_COMPLETED + // Load unit result is valid - TO_BE_COMPLETED output logic valid_o, // Load transaction ID - TO_BE_COMPLETED output logic [TRANS_ID_BITS-1:0] trans_id_o, @@ -45,7 +45,7 @@ module load_unit output exception_t ex_o, // Request address translation - TO_BE_COMPLETED output logic translation_req_o, - // Vistual address - TO_BE_COMPLETED + // Virtual address - TO_BE_COMPLETED output logic [riscv::VLEN-1:0] vaddr_o, // Physical address - TO_BE_COMPLETED input logic [riscv::PLEN-1:0] paddr_i, @@ -59,7 +59,7 @@ module load_unit output logic [11:0] page_offset_o, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic page_offset_matches_i, - // Stoer buffer is empty - TO_BE_COMPLETED + // Store buffer is empty - TO_BE_COMPLETED input logic store_buffer_empty_i, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, diff --git a/core/scoreboard.sv b/core/scoreboard.sv index d274427059..17f0546afa 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -85,11 +85,11 @@ module scoreboard #( input ariane_pkg::bp_resolve_t resolved_branch_i, // Transaction ID at which to write the result back - TO_BE_COMPLETED input logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] trans_id_i, - // Write data in - TO_BE_COMPLETED + // Results to write back - TO_BE_COMPLETED input logic [CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] wbdata_i, // Exception from a functional unit (e.g.: ld/st exception) - TO_BE_COMPLETED input ariane_pkg::exception_t [CVA6Cfg.NrWbPorts-1:0] ex_i, - // Data in is valid - TO_BE_COMPLETED + // Indicates valid results - TO_BE_COMPLETED input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, // Cvxif we for writeback - TO_BE_COMPLETED input logic x_we_i, diff --git a/core/store_unit.sv b/core/store_unit.sv index f855756547..699f613ec8 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -32,7 +32,7 @@ module store_unit output logic store_buffer_empty_o, // Store instruction is valid - ISSUE_STAGE input logic valid_i, - // data input - ISSUE_STAGE + // Data input - ISSUE_STAGE input lsu_ctrl_t lsu_ctrl_i, // TO_BE_COMPLETED - TO_BE_COMPLETED output logic pop_st_o, From 4dd9adf6432c3be1c2c4608f27193db3bc428029 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Wed, 21 Feb 2024 18:24:44 +0100 Subject: [PATCH 12/20] Avoid carriage return inside sentences --- .../source/cv32a6_execute.rst | 58 ++++++---------- .../source/cv32a6_frontend.rst | 66 +++++++++---------- .../source/cva6_commit_stage.rst | 19 ++---- .../source/cva6_id_stage.rst | 12 ++-- .../source/cva6_issue_stage.rst | 13 ++-- docs/04_cv32a65x_design/source/mmu.rst | 15 +++-- 6 files changed, 75 insertions(+), 108 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index 96aaf1bd08..4f925c570a 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -8,9 +8,8 @@ EX_STAGE Module Description *********** -The EX_STAGE module is a logical stage which implements the execute -stage. It encapsulates the following functional units: ALU, Branch Unit, -CSR buffer, Mult, load and store and CVXIF. +The EX_STAGE module is a logical stage which implements the execute stage. +It encapsulates the following functional units: ALU, Branch Unit, CSR buffer, Mult, load and store and CVXIF. The module is connected to: @@ -40,9 +39,7 @@ Submodules ALU === -The arithmetic logic unit (ALU) is a small piece of hardware which -performs 32 and 64-bit arithmetical operations: subtraction, addition, -shifts, comparisons... +The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetical operations: subtraction, addition, shifts, comparisons... It always completes its operation in a single cycle. .. include:: port_alu.rst @@ -51,11 +48,9 @@ It always completes its operation in a single cycle. Branch Unit =========== -The branch unit module manages all kind of control flow changes -i.e.: conditional and unconditional jumps. It calculates the target -address and decides whether to take the branch or not. -It also decides if a branch was mis-predicted or not and reports -corrective actions to the pipeline stages. +The branch unit module manages all kind of control flow changes i.e.: conditional and unconditional jumps. +It calculates the target address and decides whether to take the branch or not. +It also decides if a branch was mis-predicted or not and reports corrective actions to the pipeline stages. .. include:: port_branch_unit.rst @@ -63,10 +58,8 @@ corrective actions to the pipeline stages. CSR Buffer ========== -The CSR buffer module stores the CSR address at which the -instruction is going to read/write. As the CSR instruction alters the -processor architectural state, this instruction has to be buffered until -the commit stage decides to execute the instruction. +The CSR buffer module stores the CSR address at which the instruction is going to read/write. +As the CSR instruction alters the processor architectural state, this instruction has to be buffered until the commit stage decides to execute the instruction. .. include:: port_csr_buffer.rst @@ -74,8 +67,7 @@ the commit stage decides to execute the instruction. Mult ==== -The multiplier module supports the division and multiplication -operations. +The multiplier module supports the division and multiplication operations. .. figure:: ../images/mult_modules.png :name: mult submodules @@ -100,8 +92,7 @@ Multiplication is performed in two cycles and is fully pipelined. serdiv ------ -The division is a simple serial divider which needs 64 cycles in the -worst case. +The division is a simple serial divider which needs 64 cycles in the worst case. .. include:: port_serdiv.rst @@ -109,14 +100,10 @@ worst case. Load_Store_Unit (LSU) ===================== -The load store module interfaces with the data memory (D$) to manage the -load and store operations. +The load store module interfaces with the data memory (D$) to manage the load and store operations. -The LSU does not handle misaligned accesses: access which are not -aligned to a 64 bit boundary for double word accesses, access which are -not aligned to a 32-bit boundary for word access and the accesses which -are not aligned on 16-bit boundary for half word access. If encounters -such a load or store it will throw a misaligned exception. +The LSU does not handle misaligned accesses: access which are not aligned to a 64 bit boundary for double word accesses, access which are not aligned to a 32-bit boundary for word access and the accesses which are not aligned on 16-bit boundary for half word access. +If encounters such a load or store it will throw a misaligned exception. .. figure:: ../images/load_store_unit_modules.png :name: load_store_unit submodules @@ -134,20 +121,16 @@ store_unit The store_unit module manages the data store operations. -As stores can be speculative, the store instructions need to be -committed by ISSUE_STAGE module before possibily altering the processor -state. +As stores can be speculative, the store instructions need to be committed by ISSUE_STAGE module before possibily altering the processor state. Store buffer keeps track of store requests. XXXXXXXXXXX for outstanding store instructions (which are still speculative) and one buffer for committed store instructions. When ISSUE_STAGE module commits a store instruction, outstanding store becomes committed. -When commit buffer is not empty, the buffer automatically -tries to write the oldest store to the data cache. +When commit buffer is not empty, the buffer automatically tries to write the oldest store to the data cache. -Furthermore, the store_unit module provides information to the load_unit -to know if any outstanding store matches load. +Furthermore, the store_unit module provides information to the load_unit to know if any outstanding store matches load. .. include:: port_store_unit.rst @@ -158,14 +141,11 @@ load_unit The load_unit module manages the data load operations. -Before issuing a load, the load unit needs to check the store buffer for -potential aliasing. It wwill insert stalls until it can't satisfy the -current request. This means: +Before issuing a load, the load unit needs to check the store buffer for potential aliasing. +It will insert stalls until it can't satisfy the current request. This means: * Two loads to the same address are allowed. * Two stores to the same address are allowed. -* A store followed by a load to the same address can only be satisfied -if the store has already been committed (marked as committed in the -store buffer). +* A store followed by a load to the same address can only be satisfied if the store has already been committed (marked as committed in the store buffer). .. include:: port_load_unit.rst diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index c650dd305c..0529b4a1e8 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -18,16 +18,10 @@ Description The FRONTEND module implements two first stages of the cva6 pipeline, PC gen and Fetch stages. -PC gen stage is responsible for generating the next program counter -hosting a Branch Target Buffer (BTB) a Branch History Table (BHT) and -a Return Address Stack (RAS) to speculate on the branch target address. +PC gen stage is responsible for generating the next program counter hosting a Branch Target Buffer (BTB) a Branch History Table (BHT) and a Return Address Stack (RAS) to speculate on the branch target address. -Fetch stage requests data to the CACHE module, realigns the data to -store them in instruction queue and transmits the instructions to the -DECODE module. -FRONTEND can fetch up to 2 instructions per cycles when -C extension instructions is used, but as instruction queue limits the -data rate, up to one instruction per cycle can be sent to DECODE. +Fetch stage requests data to the CACHE module, realigns the data to store them in instruction queue and transmits the instructions to the DECODE module. +FRONTEND can fetch up to 2 instructions per cycles when C extension instructions is used, but as instruction queue limits the data rate, up to one instruction per cycle can be sent to DECODE. The module is connected to: @@ -73,18 +67,23 @@ PC gen generates the next program counter. The next PC can originate from the fo * **Debug:** Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. The debug jump is requested by CSR. The address to be jumped into is HW coded. This debug feature is not supported by CV32A6 v0.1.0. -All program counters are logical addressed. If the logical to physical mapping changes a fence.vm instruction should used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. +All program counters are logical addressed. +If the logical to physical mapping changes a fence.vm instruction should used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. Fetch Stage ~~~~~~~~~~~ -Fetch stage controls by handshake protocol the CACHE module. Fetched data are 32-bit block with word aligned address. A granted fetch is realigned into instr_realign submodule to produce instructions. Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). This submodule stores the instructions and related information which allow to identify the outstanding transactions. In the case CONTROLLER decides to flush the instruction queue, the outstanding transactions are discarded. +Fetch stage controls by handshake protocol the CACHE module. Fetched data are 32-bit block with word aligned address. +A granted fetch is realigned into instr_realign submodule to produce instructions. Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). +This submodule stores the instructions and related information which allow to identify the outstanding transactions. +In the case CONTROLLER decides to flush the instruction queue, the outstanding transactions are discarded. *The Fetch stage asks the MMU (MMU is not enabled in CV32A6 v0.1.0) to translate the requested address.* -Memory *and MMU (MMU is not enabled in CV32A6 v0.1.0)* can feedback potential exceptions generated by the memory fetch request. They can be bus errors, invalid accesses or instruction page faults. +Memory *and MMU (MMU is not enabled in CV32A6 v0.1.0)* can feedback potential exceptions generated by the memory fetch request. +They can be bus errors, invalid accesses or instruction page faults. @@ -102,7 +101,11 @@ Submodules Instr_realign submodule ~~~~~~~~~~~~~~~~~~~~~~~ -The 32-bit aligned block coming from the CACHE module enters the instr_realign submodule. This submodule extracts the instructions from the 32-bit blocks, up to two instructions because it is possible to fetch two instructions when C extension is used. If the instructions are not compressed, it is possible that the instruction is not aligned on the block size but rather interleaved with two cache blocks. In that case, two cache accesses are needed. The instr_realign submodule provides at maximum one instruction per cycle. Not complete instruction is stored in instr_realign submodule before being provided in the next cycles. +The 32-bit aligned block coming from the CACHE module enters the instr_realign submodule. +This submodule extracts the instructions from the 32-bit blocks, up to two instructions because it is possible to fetch two instructions when C extension is used. +If the instructions are not compressed, it is possible that the instruction is not aligned on the block size but rather interleaved with two cache blocks. In that case, two cache accesses are needed. +The instr_realign submodule provides at maximum one instruction per cycle. +Not complete instruction is stored in instr_realign submodule before being provided in the next cycles. In case of mispredict, flush, replay or branch predict, the instr_realign is re-initialized, the internal register storing the instruction alignment state is reset. @@ -112,7 +115,9 @@ In case of mispredict, flush, replay or branch predict, the instr_realign is re- Instr_queue submodule ~~~~~~~~~~~~~~~~~~~~~ -The instr_queue receives 32bit block from CACHES to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). FRONTEND pushes in FIFO to store the instructions and related information needed in case of mispredict or exception: instructions, instruction control flow type, exception, exception address and predicted address. DECODE pops them when decode stage is ready and indicates to the FRONTEND the instruction has been consummed. +The instr_queue receives 32bit block from CACHES to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). +FRONTEND pushes in FIFO to store the instructions and related information needed in case of mispredict or exception: instructions, instruction control flow type, exception, exception address and predicted address. +DECODE pops them when decode stage is ready and indicates to the FRONTEND the instruction has been consummed. The instruction queue contains max 4 instructions. @@ -128,7 +133,9 @@ The instruction queue can be flushed by CONTROLLER. Instr_scan submodule ~~~~~~~~~~~~~~~~~~~~ -The instr_scan submodule pre-decodes the fetched instructions, instructions could be compressed or not. The outputs are used by the branch prediction feature. The instr_scan submodule tells if the instruction is compressed and provides the intruction type: branch, jump, return, jalr, imm, call or others. +The instr_scan submodule pre-decodes the fetched instructions, instructions could be compressed or not. +The outputs are used by the branch prediction feature. +The instr_scan submodule tells if the instruction is compressed and provides the intruction type: branch, jump, return, jalr, imm, call or others. .. include:: port_instr_scan.rst @@ -143,11 +150,9 @@ information is stored in the Branch History Table. The information is stored in a 1024 entry table. -The Branch History table is a two-bit saturation counter that takes the -virtual address of the current fetched instruction by the CACHE. +The Branch History table is a two-bit saturation counter that takes the virtual address of the current fetched instruction by the CACHE. It states whether the current branch request should be taken or not. -The two bit counter is updated by the successive execution of the current -instructions as shown in the following figure. +The two bit counter is updated by the successive execution of the current instructions as shown in the following figure. .. figure:: ../images/bht.png :name: BHT saturation @@ -158,10 +163,8 @@ instructions as shown in the following figure. The BHT is not updated if processor is in debug mode. -When a branch instruction is pre-decoded by instr_scan submodule, the BHT -informs whether the PC address is in the BHT. In this case, the BHT -predicts whether the branch is taken and provides the corresponding target -address. +When a branch instruction is pre-decoded by instr_scan submodule, the BHT informs whether the PC address is in the BHT. +In this case, the BHT predicts whether the branch is taken and provides the corresponding target address. The BHT is never flushed. @@ -172,17 +175,14 @@ BTB (Branch Target Buffer) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a unconditional jumps to a register (JALR instruction) is mispredicted -by the EXECUTE, the relative information is stored into the BTB, that is -to say the JALR PC and the target address. +When a unconditional jumps to a register (JALR instruction) is mispredicted by the EXECUTE, the relative information is stored into the BTB, that is to say the JALR PC and the target address. The information is stored in a 8 entry table. The BTB is not updated if processor is in debug mode. -When a branch instruction is pre-decoded by instr_scan submodule, the BTB -informs whether the input PC address is in BTB. In this case, the BTB -provides the corresponding target address. +When a branch instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in BTB. +In this case, the BTB provides the corresponding target address. The BTB is never flushed. @@ -194,15 +194,11 @@ RAS (Return Address Stack) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When an unconditional jumps to a known target address (JAL instruction) -is consummed by the instr_queue, the next pc after the JAL instruction -and the return address are stored into a FIFO. +When an unconditional jumps to a known target address (JAL instruction) is consummed by the instr_queue, the next pc after the JAL instruction and the return address are stored into a FIFO. The RAS FIFO depth is 2. -When a branch instruction is pre-decoded by instr_scan submodule, the -RAS informs whether the input PC address is in RAS. In this case, the -RAS provides the corresponding target address. +When a branch instruction is pre-decoded by instr_scan submodule, the RAS informs whether the input PC address is in RAS. In this case, the RAS provides the corresponding target address. The RAS is never flushed. diff --git a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst index 557489ae01..85e4abf1f2 100644 --- a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst @@ -15,19 +15,12 @@ COMMIT_STAGE Module Description ----------- -The COMMIT_STAGE module implements the commit stage, which is the -last stage in the processor’s -pipeline. It takes incoming instruction and update the architectural -state: writing CSR registers, committing stores and writing back data to -the register file. The commit stage controls the stalling and the -flushing of the processor. - -The commit stage also manages the exceptions. An exception can occur -during the first four pipeline stages (PCgen cannot generate an -exception) or happen during commit stage coming from the CSR_REGFILE or -from an interrupt. To allow precise interrupts to happen they are -considered during the commit only and associated with teh related -instruction. +The COMMIT_STAGE module implements the commit stage, which is the last stage in the processor’s pipeline. +It takes incoming instruction and update the architectural state: writing CSR registers, committing stores and writing back data to the register file. +The commit stage controls the stalling and the flushing of the processor. + +The commit stage also manages the exceptions. An exception can occur during the first four pipeline stages (PCgen cannot generate an exception) or happen during commit stage coming from the CSR_REGFILE or from an interrupt. +To allow precise interrupts to happen they are considered during the commit only and associated with teh related instruction. The module is connected to: diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index bb221cac24..5e7d81ce37 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -66,17 +66,13 @@ All compressed instructions have a 32-bit equivalent. Decoder ~~~~~~~ -The decoder module takes the output of compressed_decoder module and decodes -it. -It transforms the instruction to the most fundamental control structure -in pipeline, a scoreboard entry. +The decoder module takes the output of compressed_decoder module and decodes it. +It transforms the instruction to the most fundamental control structure in pipeline, a scoreboard entry. -The scoreboard entry contains an exception entry which is composed of a -valid field, a cause and a value called TVAL. +The scoreboard entry contains an exception entry which is composed of a valid field, a cause and a value called TVAL. As TVALEn configuration parameter is zero, the TVAL field is not implemented. A potential illegal instruction exception can be detected during decoding. -If no exception has happened previously in fetch stage, the decoder will -valid the exception and add the cause and tval value to the scoreboard entry. +If no exception has happened previously in fetch stage, the decoder will valid the exception and add the cause and tval value to the scoreboard entry. .. include:: port_decoder.rst diff --git a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst index ea681439f3..7a0ec6d74e 100644 --- a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst @@ -15,15 +15,11 @@ ISSUE_STAGE Module Description ----------- -The execution can be roughly divided into four parts: issue(1), -read operands(2), execute(3) and write-back(4). +The execution can be roughly divided into four parts: issue(1), read operands(2), execute(3) and write-back(4). The ISSUE_STAGE module handles step one, two and four. -The ISSUE_STAGE module receives the decoded instructions and issues them -to the various functional units. +The ISSUE_STAGE module receives the decoded instructions and issues them to the various functional units. -A data-structure called scoreboard is used to keep track of data related -to the issue instruction: which functional unit it is in and which -register it will write-back to. +A data-structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit it is in and which register it will write-back to. The scoreboard handle the write-back data received from the COMMIT_STAGE module. Furthermore it contains the CPU’s register file. @@ -56,8 +52,7 @@ Scoreboard The scoreboard is contains a FIFO to store the decoded instructions. Instruction is pushed to the FIFO whether the scoreboard is not full. -It indicates which registers are going to be clobbered by a previously -scheduled instruction. +It indicates which registers are going to be clobbered by a previously scheduled instruction. .. include:: port_scoreboard.rst diff --git a/docs/04_cv32a65x_design/source/mmu.rst b/docs/04_cv32a65x_design/source/mmu.rst index 137c3e8ae1..1f5493f0e9 100644 --- a/docs/04_cv32a65x_design/source/mmu.rst +++ b/docs/04_cv32a65x_design/source/mmu.rst @@ -15,7 +15,10 @@ The Memory Management Unit (MMU) SV32 module is a crucial component in the RISC- **Figure 1:** Inputs and Outputs of CVA6 MMU SV32 -At its core, the MMU SV32 plays a pivotal role in translating virtual addresses into their corresponding physical counterparts. This translation process is paramount for providing memory protection, isolation, and efficient memory management in modern computer systems. Importantly, it handles both instruction and data accesses, ensuring a seamless interaction between the processor and virtual memory. Within the MMU, several major blocks play pivotal roles in this address translation process. These includes: +At its core, the MMU SV32 plays a pivotal role in translating virtual addresses into their corresponding physical counterparts. +This translation process is paramount for providing memory protection, isolation, and efficient memory management in modern computer systems. +Importantly, it handles both instruction and data accesses, ensuring a seamless interaction between the processor and virtual memory. +Within the MMU, several major blocks play pivotal roles in this address translation process. These includes: * Instruction TLB (ITLB) * Data TLB (DTLB) @@ -30,15 +33,19 @@ At its core, the MMU SV32 plays a pivotal role in translating virtual addresses **Figure 2:** Major Blocks in CVA6 MMU SV32 -The MMU SV32 manages privilege levels and access control, enforcing permissions for user and supervisor modes while handling access exceptions. It employs Translation Lookaside Buffers (TLBs) for efficient address translation, reducing the need for page table access. TLB hits yield quick translations, but on misses, the shared TLB is consulted, and if necessary, the Page Table Walker (PTW) performs page table walks, updating TLBs and managing exceptions during the process. +The MMU SV32 manages privilege levels and access control, enforcing permissions for user and supervisor modes while handling access exceptions. +It employs Translation Lookaside Buffers (TLBs) for efficient address translation, reducing the need for page table access. +TLB hits yield quick translations, but on misses, the shared TLB is consulted, and if necessary, the Page Table Walker (PTW) performs page table walks, updating TLBs and managing exceptions during the process. -In addition to these functionalities, the MMU SV32 seamlessly integrates support for Physical Memory Protection (PMP), enabling it to enforce access permissions and memory protection configurations as specified by the PMP settings. This additional layer of security and control enhances the management of memory accesses +In addition to these functionalities, the MMU SV32 seamlessly integrates support for Physical Memory Protection (PMP), enabling it to enforce access permissions and memory protection configurations as specified by the PMP settings. +This additional layer of security and control enhances the management of memory accesses .. raw:: html Instruction and Data Interfaces -The MMU SV32 maintains interfaces with the instruction cache (ICache) and the load-store unit (LSU). It receives virtual addresses from these components and proceeds to translate them into physical addresses, a fundamental task for ensuring proper program execution and memory access. +The MMU SV32 maintains interfaces with the instruction cache (ICache) and the load-store unit (LSU). +It receives virtual addresses from these components and proceeds to translate them into physical addresses, a fundamental task for ensuring proper program execution and memory access. .. raw:: html From 4906435da8fe1b9988978364cbabc76aeed9ef29 Mon Sep 17 00:00:00 2001 From: ALLART Come Date: Thu, 22 Feb 2024 16:10:09 +0100 Subject: [PATCH 13/20] Apply 25 suggestion(s) to 4 file(s) --- .../source/cv32a6_execute.rst | 16 ++++++----- .../source/cv32a6_frontend.rst | 27 +++++++++++-------- .../source/cva6_commit_stage.rst | 7 ++--- .../source/cva6_issue_stage.rst | 8 +++--- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index 4f925c570a..3eda4701db 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -39,7 +39,7 @@ Submodules ALU === -The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetical operations: subtraction, addition, shifts, comparisons... +The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetic and bitwise operations: subtraction, addition, shifts, comparisons... It always completes its operation in a single cycle. .. include:: port_alu.rst @@ -48,7 +48,7 @@ It always completes its operation in a single cycle. Branch Unit =========== -The branch unit module manages all kind of control flow changes i.e.: conditional and unconditional jumps. +The branch unit module manages all kinds of control flow changes i.e.: conditional and unconditional jumps. It calculates the target address and decides whether to take the branch or not. It also decides if a branch was mis-predicted or not and reports corrective actions to the pipeline stages. @@ -100,10 +100,11 @@ The division is a simple serial divider which needs 64 cycles in the worst case. Load_Store_Unit (LSU) ===================== -The load store module interfaces with the data memory (D$) to manage the load and store operations. +The load store module interfaces with the data cache (D$) to manage the load and store operations. -The LSU does not handle misaligned accesses: access which are not aligned to a 64 bit boundary for double word accesses, access which are not aligned to a 32-bit boundary for word access and the accesses which are not aligned on 16-bit boundary for half word access. -If encounters such a load or store it will throw a misaligned exception. +The LSU does not handle misaligned accesses. +Misaligned accesses are double word accesses which are not aligned to a 64-bit boundary, word accesses which are not aligned to a 32-bit boundary and half word accesses which are not aligned on 16-bit boundary. +If the LSU encounters a misaligned load or store, it throws a misaligned exception. .. figure:: ../images/load_store_unit_modules.png :name: load_store_unit submodules @@ -130,7 +131,7 @@ becomes committed. When commit buffer is not empty, the buffer automatically tries to write the oldest store to the data cache. -Furthermore, the store_unit module provides information to the load_unit to know if any outstanding store matches load. +Furthermore, the store_unit module provides information to the load_unit to know if an outstanding store matches addresses with a load. .. include:: port_store_unit.rst @@ -142,7 +143,8 @@ load_unit The load_unit module manages the data load operations. Before issuing a load, the load unit needs to check the store buffer for potential aliasing. -It will insert stalls until it can't satisfy the current request. This means: +It inserts stalls until it can satisfy the current request. This means: + * Two loads to the same address are allowed. * Two stores to the same address are allowed. * A store followed by a load to the same address can only be satisfied if the store has already been committed (marked as committed in the store buffer). diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index 0529b4a1e8..f85b25f8a0 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -18,7 +18,8 @@ Description The FRONTEND module implements two first stages of the cva6 pipeline, PC gen and Fetch stages. -PC gen stage is responsible for generating the next program counter hosting a Branch Target Buffer (BTB) a Branch History Table (BHT) and a Return Address Stack (RAS) to speculate on the branch target address. +PC gen stage is responsible for generating the next program counter. +It hosts a Branch Target Buffer (BTB), a Branch History Table (BHT) and a Return Address Stack (RAS) to speculate on control flow instructions. Fetch stage requests data to the CACHE module, realigns the data to store them in instruction queue and transmits the instructions to the DECODE module. FRONTEND can fetch up to 2 instructions per cycles when C extension instructions is used, but as instruction queue limits the data rate, up to one instruction per cycle can be sent to DECODE. @@ -68,15 +69,17 @@ PC gen generates the next program counter. The next PC can originate from the fo * **Debug:** Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. The debug jump is requested by CSR. The address to be jumped into is HW coded. This debug feature is not supported by CV32A6 v0.1.0. All program counters are logical addressed. -If the logical to physical mapping changes a fence.vm instruction should used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. +If the logical to physical mapping changes, a ``fence.vm`` instruction should be used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. Fetch Stage ~~~~~~~~~~~ -Fetch stage controls by handshake protocol the CACHE module. Fetched data are 32-bit block with word aligned address. -A granted fetch is realigned into instr_realign submodule to produce instructions. Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). +Fetch stage controls the CACHE module by a handshaking protocol. +Fetched data is a 32-bit block with a word-aligned address. +A granted fetch is realigned into instr_realign submodule to produce instructions. +Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). This submodule stores the instructions and related information which allow to identify the outstanding transactions. In the case CONTROLLER decides to flush the instruction queue, the outstanding transactions are discarded. @@ -102,10 +105,12 @@ Instr_realign submodule ~~~~~~~~~~~~~~~~~~~~~~~ The 32-bit aligned block coming from the CACHE module enters the instr_realign submodule. -This submodule extracts the instructions from the 32-bit blocks, up to two instructions because it is possible to fetch two instructions when C extension is used. -If the instructions are not compressed, it is possible that the instruction is not aligned on the block size but rather interleaved with two cache blocks. In that case, two cache accesses are needed. +This submodule extracts the instructions from the 32-bit blocks. +It is possible to fetch up to two instructions per cycle when C extension is used. +An not-compressed instruction can be misaligned on the block size, interleaved with two cache blocks. +In that case, two cache accesses are needed to get the whole instruction. The instr_realign submodule provides at maximum one instruction per cycle. -Not complete instruction is stored in instr_realign submodule before being provided in the next cycles. +Incomplete instruction is stored in instr_realign submodule until its second half is fetched. In case of mispredict, flush, replay or branch predict, the instr_realign is re-initialized, the internal register storing the instruction alignment state is reset. @@ -150,7 +155,7 @@ information is stored in the Branch History Table. The information is stored in a 1024 entry table. -The Branch History table is a two-bit saturation counter that takes the virtual address of the current fetched instruction by the CACHE. +The Branch History Table is a two-bit saturating counter that takes the virtual address of the current fetched instruction by the CACHE. It states whether the current branch request should be taken or not. The two bit counter is updated by the successive execution of the current instructions as shown in the following figure. @@ -175,14 +180,14 @@ BTB (Branch Target Buffer) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a unconditional jumps to a register (JALR instruction) is mispredicted by the EXECUTE, the relative information is stored into the BTB, that is to say the JALR PC and the target address. +When an unconditional jump to a register (JALR instruction) is mispredicted by the EXECUTE, the JALR PC and the target address are stored into the BTB. The information is stored in a 8 entry table. The BTB is not updated if processor is in debug mode. -When a branch instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in BTB. -In this case, the BTB provides the corresponding target address. +When a branch instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in the BTB. +In this case, the BTB provides the predicted target address. The BTB is never flushed. diff --git a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst index 85e4abf1f2..cb5ed81753 100644 --- a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst @@ -16,11 +16,12 @@ Description ----------- The COMMIT_STAGE module implements the commit stage, which is the last stage in the processor’s pipeline. -It takes incoming instruction and update the architectural state: writing CSR registers, committing stores and writing back data to the register file. +It takes incoming instruction and updates the architectural state: writing CSR registers, committing stores and writing back data to the register file. The commit stage controls the stalling and the flushing of the processor. -The commit stage also manages the exceptions. An exception can occur during the first four pipeline stages (PCgen cannot generate an exception) or happen during commit stage coming from the CSR_REGFILE or from an interrupt. -To allow precise interrupts to happen they are considered during the commit only and associated with teh related instruction. +The commit stage also manages the exceptions. +An exception can occur during the first four pipeline stages (PCgen cannot generate an exception) or happen in commit stage, coming from the CSR_REGFILE or from an interrupt. +Exceptions are precise: they are considered during the commit only and associated with the related instruction. The module is connected to: diff --git a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst index 7a0ec6d74e..4370cd867e 100644 --- a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst @@ -19,7 +19,7 @@ The execution can be roughly divided into four parts: issue(1), read operands(2) The ISSUE_STAGE module handles step one, two and four. The ISSUE_STAGE module receives the decoded instructions and issues them to the various functional units. -A data-structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit it is in and which register it will write-back to. +A data structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit it is in and which register it will write-back to. The scoreboard handle the write-back data received from the COMMIT_STAGE module. Furthermore it contains the CPU’s register file. @@ -50,9 +50,9 @@ Submodules Scoreboard ~~~~~~~~~~ -The scoreboard is contains a FIFO to store the decoded instructions. -Instruction is pushed to the FIFO whether the scoreboard is not full. -It indicates which registers are going to be clobbered by a previously scheduled instruction. +The scoreboard contains a FIFO to store the decoded instructions. +Issued instruction is pushed to the FIFO if it is not full. +It indicates which registers are going to be clobbered by a previously issued instruction. .. include:: port_scoreboard.rst From a5588c0035448eb5c7e1142c7d01337952e541fa Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Thu, 22 Feb 2024 18:22:59 +0100 Subject: [PATCH 14/20] =?UTF-8?q?Fix=20C=C3=B4me's=20feedbacks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/issue_read_operands.sv | 6 +++--- core/load_store_unit.sv | 2 +- core/scoreboard.sv | 6 +++--- docs/04_cv32a65x_design/source/cv32a6_execute.rst | 9 ++++----- docs/04_cv32a65x_design/source/cv32a6_frontend.rst | 12 ++++++------ 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index c5b290b60f..a46bc81fe5 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -36,19 +36,19 @@ module issue_read_operands input logic issue_instr_valid_i, // Issue stage acknowledge - TO_BE_COMPLETED output logic issue_ack_o, - // rs1 operand - scoreboard + // rs1 operand address - scoreboard output logic [REG_ADDR_SIZE-1:0] rs1_o, // rs1 operand - scoreboard input riscv::xlen_t rs1_i, // rs1 operand is valid - scoreboard input logic rs1_valid_i, - // rs2 operand - scoreboard + // rs2 operand address - scoreboard output logic [REG_ADDR_SIZE-1:0] rs2_o, // rs2 operand - scoreboard input riscv::xlen_t rs2_i, // rs2 operand is valid - scoreboard input logic rs2_valid_i, - // rs3 operand - scoreboard + // rs3 operand address - scoreboard output logic [REG_ADDR_SIZE-1:0] rs3_o, // rs3 operand - scoreboard input rs3_len_t rs3_i, diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 79fc09bccb..95894906bb 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -35,7 +35,7 @@ module load_store_unit input fu_data_t fu_data_i, // Load Store Unit is ready - ISSUE_STAGE output logic lsu_ready_o, - // Load and Store unit is valid - ISSUE_STAGE + // Load Store Unit instruction is valid - ISSUE_STAGE input logic lsu_valid_i, // Load transaction ID - ISSUE_STAGE diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 17f0546afa..34131c1406 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -33,21 +33,21 @@ module scoreboard #( // TO_BE_COMPLETED - TO_BE_COMPLETED output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_fpr_o, - // rs1 operand - issue_read_operands + // rs1 operand address - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i, // rs1 operand - issue_read_operands output riscv::xlen_t rs1_o, // rs1 operand is valid - issue_read_operands output logic rs1_valid_o, - // rs2 operand - issue_read_operands + // rs2 operand address - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs2_i, // rs2 operand - issue_read_operands output riscv::xlen_t rs2_o, // rs2 operand is valid - issue_read_operands output logic rs2_valid_o, - // rs3 operand - issue_read_operands + // rs3 operand address - issue_read_operands input logic [ariane_pkg::REG_ADDR_SIZE-1:0] rs3_i, // rs3 operand - issue_read_operands output rs3_len_t rs3_o, diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index 3eda4701db..c9732a704c 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -123,11 +123,10 @@ store_unit The store_unit module manages the data store operations. As stores can be speculative, the store instructions need to be committed by ISSUE_STAGE module before possibily altering the processor state. -Store buffer keeps track of store requests. XXXXXXXXXXX for outstanding store -instructions (which are still speculative) and one buffer for committed -store instructions. -When ISSUE_STAGE module commits a store instruction, outstanding store -becomes committed. +Store buffer keeps track of store requests. +Outstanding store instructions (which are speculative) are differentiated from committed stores. +When ISSUE_STAGE module commits a store instruction, outstanding stores +become committed. When commit buffer is not empty, the buffer automatically tries to write the oldest store to the data cache. diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index f85b25f8a0..4e5d680c62 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -78,7 +78,7 @@ Fetch Stage Fetch stage controls the CACHE module by a handshaking protocol. Fetched data is a 32-bit block with a word-aligned address. -A granted fetch is realigned into instr_realign submodule to produce instructions. +A granted fetch is processed by the instr_realign submodule to produce instructions. Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). This submodule stores the instructions and related information which allow to identify the outstanding transactions. In the case CONTROLLER decides to flush the instruction queue, the outstanding transactions are discarded. @@ -138,9 +138,9 @@ The instruction queue can be flushed by CONTROLLER. Instr_scan submodule ~~~~~~~~~~~~~~~~~~~~ -The instr_scan submodule pre-decodes the fetched instructions, instructions could be compressed or not. -The outputs are used by the branch prediction feature. +The instr_scan submodule pre-decodes the fetched instructions coming from the instr_realign module, instructions could be compressed or not. The instr_scan submodule tells if the instruction is compressed and provides the intruction type: branch, jump, return, jalr, imm, call or others. +These outputs are used by the branch prediction feature. .. include:: port_instr_scan.rst @@ -155,9 +155,9 @@ information is stored in the Branch History Table. The information is stored in a 1024 entry table. -The Branch History Table is a two-bit saturating counter that takes the virtual address of the current fetched instruction by the CACHE. +The Branch History Table is a table of two-bit saturating counters that takes the virtual address of the current fetched instruction by the CACHE. It states whether the current branch request should be taken or not. -The two bit counter is updated by the successive execution of the current instructions as shown in the following figure. +The two bit counter is updated by the successive execution of the instructions as shown in the following figure. .. figure:: ../images/bht.png :name: BHT saturation @@ -180,7 +180,7 @@ BTB (Branch Target Buffer) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When an unconditional jump to a register (JALR instruction) is mispredicted by the EXECUTE, the JALR PC and the target address are stored into the BTB. +When an unconditional jump to a register (JALR instruction) is mispredicted by the EXECUTE module, the JALR PC and the target address are stored into the BTB. The information is stored in a 8 entry table. From 26a7bab6648dd2507208da5142049466ae01a831 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Thu, 22 Feb 2024 22:06:06 +0100 Subject: [PATCH 15/20] =?UTF-8?q?Fix=20C=C3=B4me's=20feedbacks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/include/config_pkg.sv | 32 +++++++++---------- .../source/port_branch_unit.rst | 2 +- .../source/port_cvxif_fu.rst | 2 +- .../source/port_issue_read_operands.rst | 20 ++++++------ .../source/port_issue_stage.rst | 2 +- .../source/port_load_store_unit.rst | 8 ++--- .../source/port_load_unit.rst | 8 ++--- .../source/port_scoreboard.rst | 10 +++--- .../source/port_store_unit.rst | 2 +- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index bb06c35aaf..f202411bb0 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -46,15 +46,15 @@ package config_pkg; int unsigned AxiIdWidth; // AXI User width int unsigned AxiUserWidth; - // TO_BE_COMPLETED + // Load buffer entry buffer int unsigned NrLoadBufEntries; - // FPU is enabled + // Floating Point bit FpuEn; - // TO_BE_COMPLETED + // Non standard 16bits Floating Point bit XF16; - // TO_BE_COMPLETED + // Non standard 16bits Floating Point Alt bit XF16ALT; - // TO_BE_COMPLETED + // Non standard 8bits Floating Point bit XF8; // Atomic RISC-V extension bit RVA; @@ -66,33 +66,33 @@ package config_pkg; bit RVC; // Zcb RISC-V extension bit RVZCB; - // TO_BE_COMPLETED + // Non standard Vector Floating Point bit XFVec; // CV-X-IF coprocessor interface is supported bit CvxifEn; - // Zicond RISC-V extension is enabled + // Zicond RISC-V extension bit ZiCondExtEn; // Single precision FP RISC-V extension bit RVF; // Double precision FP RISC-V extension bit RVD; - // Floating point is present + // Floating Point is present bit FpPresent; - // TO_BE_COMPLETED + // Non standard Floating is Point present bit NSX; - // TO_BE_COMPLETED + // Floating Point lenght int unsigned FLen; - // Vector floating point extension + // Vector Floating Point extension bit RVFVec; - // 16 bits vector floating point extension + // 16 bits vector Floating Point extension bit XF16Vec; - // TO_BE_COMPLETED + // 16 bits vector Floating Point Alt extension bit XF16ALTVec; - // 8 bits vector floating point extension + // 8 bits vector Floating Point extension bit XF8Vec; // TO_BE_COMPLETED int unsigned NrRgprPorts; - // TO_BE_COMPLETED + // Function Unit write back port number int unsigned NrWbPorts; // Accelerate Port coprocessor interface bit EnableAccelerator; @@ -144,7 +144,7 @@ package config_pkg; logic [NrMaxRules-1:0][63:0] CachedRegionLength; // Maximum number of outstanding stores int unsigned MaxOutstandingStores; - // Debug mode + // Debug support bit DebugEn; // Non idem potency bit NonIdemPotenceEn; diff --git a/docs/04_cv32a65x_design/source/port_branch_unit.rst b/docs/04_cv32a65x_design/source/port_branch_unit.rst index ce5fe9affd..16f2ab3036 100644 --- a/docs/04_cv32a65x_design/source/port_branch_unit.rst +++ b/docs/04_cv32a65x_design/source/port_branch_unit.rst @@ -86,7 +86,7 @@ * - ``resolve_branch_o`` - out - - Branch is resolved, new entries can be accept by scoreboard + - Branch is resolved, new entries can be accepted by scoreboard - ID_STAGE - logic diff --git a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst index 3aae8fa56c..cbe572903e 100644 --- a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst +++ b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst @@ -50,7 +50,7 @@ * - ``x_off_instr_i`` - in - - undecoded instruction + - Offloaded instruction - ISSUE_STAGE - logic[31:0] diff --git a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst index 92c8e853ed..5d3f66f380 100644 --- a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst +++ b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst @@ -62,7 +62,7 @@ * - ``rs1_o`` - out - - rs1 operand + - rs1 operand address - scoreboard - logic[REG_ADDR_SIZE-1:0] @@ -80,7 +80,7 @@ * - ``rs2_o`` - out - - rs2 operand + - rs2 operand address - scoreboard - logic[REG_ADDR_SIZE-1:0] @@ -98,7 +98,7 @@ * - ``rs3_o`` - out - - rs3 operand + - rs3 operand address - scoreboard - logic[REG_ADDR_SIZE-1:0] @@ -134,13 +134,13 @@ * - ``rs1_forwarding_o`` - out - - unregistered version of fu_data_o.operanda + - Unregistered version of fu_data_o.operanda - TO_BE_COMPLETED - riscv::xlen_t * - ``rs2_forwarding_o`` - out - - unregistered version of fu_data_o.operandb + - Unregistered version of fu_data_o.operandb - TO_BE_COMPLETED - riscv::xlen_t @@ -158,7 +158,7 @@ * - ``flu_ready_i`` - in - - Fixed latency unit ready to accept new request + - Fixed Latency Unit ready to accept new request - TO_BE_COMPLETED - logic @@ -170,7 +170,7 @@ * - ``branch_valid_o`` - out - - branch instruction is valid + - Branch instruction is valid - TO_BE_COMPLETED - logic @@ -182,19 +182,19 @@ * - ``lsu_ready_i`` - in - - load store unit is ready + - Load Store Unit is ready - TO_BE_COMPLETED - logic * - ``lsu_valid_o`` - out - - load store unit result is valid + - Load Store Unit result is valid - TO_BE_COMPLETED - logic * - ``mult_valid_o`` - out - - mult result is valid + - Mult result is valid - TO_BE_COMPLETED - logic diff --git a/docs/04_cv32a65x_design/source/port_issue_stage.rst b/docs/04_cv32a65x_design/source/port_issue_stage.rst index 7a653d81fc..93a904b232 100644 --- a/docs/04_cv32a65x_design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/port_issue_stage.rst @@ -230,7 +230,7 @@ * - ``commit_instr_o`` - out - - Commit instruction + - Instructions to commit - COMMIT_STAGE - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] diff --git a/docs/04_cv32a65x_design/source/port_load_store_unit.rst b/docs/04_cv32a65x_design/source/port_load_store_unit.rst index fa0ddae9c7..34cba9c003 100644 --- a/docs/04_cv32a65x_design/source/port_load_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_store_unit.rst @@ -56,13 +56,13 @@ * - ``lsu_ready_o`` - out - - Load and store unit is ready + - Load Store Unit is ready - ISSUE_STAGE - logic * - ``lsu_valid_i`` - in - - Load and Store unit is valid + - Load Store Unit instruction is valid - ISSUE_STAGE - logic @@ -116,13 +116,13 @@ * - ``commit_i`` - in - - Commit the pending store + - Commit the first pending store - TO_BE_COMPLETED - logic * - ``commit_ready_o`` - out - - commit queue is ready to accept another commit request + - Commit queue is ready to accept another commit request - TO_BE_COMPLETED - logic diff --git a/docs/04_cv32a65x_design/source/port_load_unit.rst b/docs/04_cv32a65x_design/source/port_load_unit.rst index 3e30d95802..f9a5e4d446 100644 --- a/docs/04_cv32a65x_design/source/port_load_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_unit.rst @@ -38,7 +38,7 @@ * - ``valid_i`` - in - - load unit input port + - Load unit input port - TO_BE_COMPLETED - logic @@ -56,7 +56,7 @@ * - ``valid_o`` - out - - load unit result is valid + - Load unit result is valid - TO_BE_COMPLETED - logic @@ -86,7 +86,7 @@ * - ``vaddr_o`` - out - - Vistual address + - Virtual address - TO_BE_COMPLETED - logic[riscv::VLEN-1:0] @@ -116,7 +116,7 @@ * - ``store_buffer_empty_i`` - in - - Stoer buffer is empty + - Store buffer is empty - TO_BE_COMPLETED - logic diff --git a/docs/04_cv32a65x_design/source/port_scoreboard.rst b/docs/04_cv32a65x_design/source/port_scoreboard.rst index 25f65b3e28..5271ab447a 100644 --- a/docs/04_cv32a65x_design/source/port_scoreboard.rst +++ b/docs/04_cv32a65x_design/source/port_scoreboard.rst @@ -68,7 +68,7 @@ * - ``rs1_i`` - in - - rs1 operand + - rs1 operand address - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] @@ -86,7 +86,7 @@ * - ``rs2_i`` - in - - rs2 operand + - rs2 operand address - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] @@ -104,7 +104,7 @@ * - ``rs3_i`` - in - - rs3 operand + - rs3 operand address - issue_read_operands - logic[ariane_pkg::REG_ADDR_SIZE-1:0] @@ -188,7 +188,7 @@ * - ``wbdata_i`` - in - - Write data in + - Results to write back - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] @@ -200,7 +200,7 @@ * - ``wt_valid_i`` - in - - Data in is valid + - Indicates valid results - TO_BE_COMPLETED - logic[CVA6Cfg.NrWbPorts-1:0] diff --git a/docs/04_cv32a65x_design/source/port_store_unit.rst b/docs/04_cv32a65x_design/source/port_store_unit.rst index 15c4dc774a..35347699fc 100644 --- a/docs/04_cv32a65x_design/source/port_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_store_unit.rst @@ -62,7 +62,7 @@ * - ``lsu_ctrl_i`` - in - - data input + - Data input - ISSUE_STAGE - lsu_ctrl_t From 1117670d6521de840101686c9098bd9b5309adb9 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Thu, 22 Feb 2024 22:50:42 +0100 Subject: [PATCH 16/20] Change IO port table title --- .../source/cv32a6_execute.rst | 10 +++--- .../source/parameters_cv32a65x.rst | 32 +++++++++---------- docs/04_cv32a65x_design/source/port_alu.rst | 2 +- docs/04_cv32a65x_design/source/port_bht.rst | 2 +- .../source/port_branch_unit.rst | 2 +- docs/04_cv32a65x_design/source/port_btb.rst | 2 +- .../source/port_commit_stage.rst | 2 +- .../source/port_compressed_decoder.rst | 2 +- .../source/port_controller.rst | 2 +- .../source/port_csr_buffer.rst | 2 +- .../source/port_csr_regfile.rst | 2 +- docs/04_cv32a65x_design/source/port_cva6.rst | 2 +- .../source/port_cvxif_fu.rst | 2 +- .../source/port_decoder.rst | 2 +- .../source/port_ex_stage.rst | 2 +- .../source/port_frontend.rst | 2 +- .../source/port_id_stage.rst | 2 +- .../source/port_instr_queue.rst | 2 +- .../source/port_instr_realign.rst | 2 +- .../source/port_instr_scan.rst | 2 +- .../source/port_issue_read_operands.rst | 2 +- .../source/port_issue_stage.rst | 2 +- .../source/port_load_store_unit.rst | 2 +- .../source/port_load_unit.rst | 2 +- .../source/port_lsu_bypass.rst | 2 +- docs/04_cv32a65x_design/source/port_mult.rst | 2 +- .../source/port_multiplier.rst | 2 +- docs/04_cv32a65x_design/source/port_ras.rst | 2 +- .../source/port_scoreboard.rst | 2 +- .../04_cv32a65x_design/source/port_serdiv.rst | 2 +- .../source/port_store_unit.rst | 2 +- docs/scripts/spec_builder.py | 2 +- 32 files changed, 51 insertions(+), 51 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index c9732a704c..9d482796b6 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -36,7 +36,7 @@ Submodules EX_STAGE submodules -ALU +alu === The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetic and bitwise operations: subtraction, addition, shifts, comparisons... @@ -45,7 +45,7 @@ It always completes its operation in a single cycle. .. include:: port_alu.rst -Branch Unit +branch_unit =========== The branch unit module manages all kinds of control flow changes i.e.: conditional and unconditional jumps. @@ -55,7 +55,7 @@ It also decides if a branch was mis-predicted or not and reports corrective acti .. include:: port_branch_unit.rst -CSR Buffer +CSR_buffer ========== The CSR buffer module stores the CSR address at which the instruction is going to read/write. @@ -64,7 +64,7 @@ As the CSR instruction alters the processor architectural state, this instructio .. include:: port_csr_buffer.rst -Mult +mult ==== The multiplier module supports the division and multiplication operations. @@ -97,7 +97,7 @@ The division is a simple serial divider which needs 64 cycles in the worst case. .. include:: port_serdiv.rst -Load_Store_Unit (LSU) +load_store_unit (LSU) ===================== The load store module interfaces with the data cache (D$) to manage the load and store operations. diff --git a/docs/04_cv32a65x_design/source/parameters_cv32a65x.rst b/docs/04_cv32a65x_design/source/parameters_cv32a65x.rst index fe20c4fdb8..9f8a2563cf 100644 --- a/docs/04_cv32a65x_design/source/parameters_cv32a65x.rst +++ b/docs/04_cv32a65x_design/source/parameters_cv32a65x.rst @@ -37,23 +37,23 @@ - 32 * - NrLoadBufEntries - - TO_BE_COMPLETED + - Load buffer entry buffer - 1 * - FpuEn - - FPU is enabled + - Floating Point - 0 * - XF16 - - TO_BE_COMPLETED + - Non standard 16bits Floating Point - 0 * - XF16ALT - - TO_BE_COMPLETED + - Non standard 16bits Floating Point Alt - 0 * - XF8 - - TO_BE_COMPLETED + - Non standard 8bits Floating Point - 0 * - RVA @@ -77,7 +77,7 @@ - 1 * - XFVec - - TO_BE_COMPLETED + - Non standard Vector Floating Point - 0 * - CvxifEn @@ -85,7 +85,7 @@ - 1 * - ZiCondExtEn - - Zicond RISC-V extension is enabled + - Zicond RISC-V extension - 0 * - RVF @@ -97,31 +97,31 @@ - 0 * - FpPresent - - Floating point is present + - Floating Point is present - 0 * - NSX - - TO_BE_COMPLETED + - Non standard Floating is Point present - 0 * - FLen - - TO_BE_COMPLETED + - Floating Point lenght - 0 * - RVFVec - - Vector floating point extension + - Vector Floating Point extension - 0 * - XF16Vec - - 16 bits vector floating point extension + - 16 bits vector Floating Point extension - 0 * - XF16ALTVec - - TO_BE_COMPLETED + - 16 bits vector Floating Point Alt extension - 0 * - XF8Vec - - 8 bits vector floating point extension + - 8 bits vector Floating Point extension - 0 * - NrRgprPorts @@ -129,7 +129,7 @@ - 0 * - NrWbPorts - - TO_BE_COMPLETED + - Function Unit write back port number - 0 * - EnableAccelerator @@ -233,7 +233,7 @@ - 7 * - DebugEn - - Debug mode + - Debug support - 0 * - NonIdemPotenceEn diff --git a/docs/04_cv32a65x_design/source/port_alu.rst b/docs/04_cv32a65x_design/source/port_alu.rst index aa33f9a209..f6f94ea34e 100644 --- a/docs/04_cv32a65x_design/source/port_alu.rst +++ b/docs/04_cv32a65x_design/source/port_alu.rst @@ -9,7 +9,7 @@ .. _CVA6_alu_ports: -.. list-table:: alu module IO ports +.. list-table:: **alu module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_bht.rst b/docs/04_cv32a65x_design/source/port_bht.rst index 91a5f4a449..6618ed78a9 100644 --- a/docs/04_cv32a65x_design/source/port_bht.rst +++ b/docs/04_cv32a65x_design/source/port_bht.rst @@ -9,7 +9,7 @@ .. _CVA6_bht_ports: -.. list-table:: bht module IO ports +.. list-table:: **bht module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_branch_unit.rst b/docs/04_cv32a65x_design/source/port_branch_unit.rst index 16f2ab3036..96a340fdb6 100644 --- a/docs/04_cv32a65x_design/source/port_branch_unit.rst +++ b/docs/04_cv32a65x_design/source/port_branch_unit.rst @@ -9,7 +9,7 @@ .. _CVA6_branch_unit_ports: -.. list-table:: branch_unit module IO ports +.. list-table:: **branch_unit module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_btb.rst b/docs/04_cv32a65x_design/source/port_btb.rst index 225d583514..9a80b27782 100644 --- a/docs/04_cv32a65x_design/source/port_btb.rst +++ b/docs/04_cv32a65x_design/source/port_btb.rst @@ -9,7 +9,7 @@ .. _CVA6_btb_ports: -.. list-table:: btb module IO ports +.. list-table:: **btb module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_commit_stage.rst b/docs/04_cv32a65x_design/source/port_commit_stage.rst index c47c7bf1e8..1298e8b5af 100644 --- a/docs/04_cv32a65x_design/source/port_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/port_commit_stage.rst @@ -9,7 +9,7 @@ .. _CVA6_commit_stage_ports: -.. list-table:: commit_stage module IO ports +.. list-table:: **commit_stage module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst index e42dd8e0fb..3cdaed2f60 100644 --- a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst @@ -9,7 +9,7 @@ .. _CVA6_compressed_decoder_ports: -.. list-table:: compressed_decoder module IO ports +.. list-table:: **compressed_decoder module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_controller.rst b/docs/04_cv32a65x_design/source/port_controller.rst index 44e4a96c3f..5916f3219d 100644 --- a/docs/04_cv32a65x_design/source/port_controller.rst +++ b/docs/04_cv32a65x_design/source/port_controller.rst @@ -9,7 +9,7 @@ .. _CVA6_controller_ports: -.. list-table:: controller module IO ports +.. list-table:: **controller module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_csr_buffer.rst b/docs/04_cv32a65x_design/source/port_csr_buffer.rst index f0f7e87f42..96f42db689 100644 --- a/docs/04_cv32a65x_design/source/port_csr_buffer.rst +++ b/docs/04_cv32a65x_design/source/port_csr_buffer.rst @@ -9,7 +9,7 @@ .. _CVA6_csr_buffer_ports: -.. list-table:: csr_buffer module IO ports +.. list-table:: **csr_buffer module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_csr_regfile.rst b/docs/04_cv32a65x_design/source/port_csr_regfile.rst index bba8bf7686..d03f99d955 100644 --- a/docs/04_cv32a65x_design/source/port_csr_regfile.rst +++ b/docs/04_cv32a65x_design/source/port_csr_regfile.rst @@ -9,7 +9,7 @@ .. _CVA6_csr_regfile_ports: -.. list-table:: csr_regfile module IO ports +.. list-table:: **csr_regfile module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_cva6.rst b/docs/04_cv32a65x_design/source/port_cva6.rst index 4566a88299..7a9aae4798 100644 --- a/docs/04_cv32a65x_design/source/port_cva6.rst +++ b/docs/04_cv32a65x_design/source/port_cva6.rst @@ -9,7 +9,7 @@ .. _CVA6_cva6_ports: -.. list-table:: cva6 module IO ports +.. list-table:: **cva6 module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst index cbe572903e..1a4df90210 100644 --- a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst +++ b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst @@ -9,7 +9,7 @@ .. _CVA6_cvxif_fu_ports: -.. list-table:: cvxif_fu module IO ports +.. list-table:: **cvxif_fu module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_decoder.rst b/docs/04_cv32a65x_design/source/port_decoder.rst index 4a49b8e2af..614f8b47ca 100644 --- a/docs/04_cv32a65x_design/source/port_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_decoder.rst @@ -9,7 +9,7 @@ .. _CVA6_decoder_ports: -.. list-table:: decoder module IO ports +.. list-table:: **decoder module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_ex_stage.rst b/docs/04_cv32a65x_design/source/port_ex_stage.rst index dfa2539ab2..7c002f82cc 100644 --- a/docs/04_cv32a65x_design/source/port_ex_stage.rst +++ b/docs/04_cv32a65x_design/source/port_ex_stage.rst @@ -9,7 +9,7 @@ .. _CVA6_ex_stage_ports: -.. list-table:: ex_stage module IO ports +.. list-table:: **ex_stage module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_frontend.rst b/docs/04_cv32a65x_design/source/port_frontend.rst index aeea8aadda..3bc358b9d2 100644 --- a/docs/04_cv32a65x_design/source/port_frontend.rst +++ b/docs/04_cv32a65x_design/source/port_frontend.rst @@ -9,7 +9,7 @@ .. _CVA6_frontend_ports: -.. list-table:: frontend module IO ports +.. list-table:: **frontend module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_id_stage.rst b/docs/04_cv32a65x_design/source/port_id_stage.rst index c7c4e8d62e..93e917acb9 100644 --- a/docs/04_cv32a65x_design/source/port_id_stage.rst +++ b/docs/04_cv32a65x_design/source/port_id_stage.rst @@ -9,7 +9,7 @@ .. _CVA6_id_stage_ports: -.. list-table:: id_stage module IO ports +.. list-table:: **id_stage module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_instr_queue.rst b/docs/04_cv32a65x_design/source/port_instr_queue.rst index 6041227c20..bac8a0f4d7 100644 --- a/docs/04_cv32a65x_design/source/port_instr_queue.rst +++ b/docs/04_cv32a65x_design/source/port_instr_queue.rst @@ -9,7 +9,7 @@ .. _CVA6_instr_queue_ports: -.. list-table:: instr_queue module IO ports +.. list-table:: **instr_queue module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_instr_realign.rst b/docs/04_cv32a65x_design/source/port_instr_realign.rst index baf4e921bf..11f5d8ffb9 100644 --- a/docs/04_cv32a65x_design/source/port_instr_realign.rst +++ b/docs/04_cv32a65x_design/source/port_instr_realign.rst @@ -9,7 +9,7 @@ .. _CVA6_instr_realign_ports: -.. list-table:: instr_realign module IO ports +.. list-table:: **instr_realign module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_instr_scan.rst b/docs/04_cv32a65x_design/source/port_instr_scan.rst index a11b0b0d50..9923c68c0a 100644 --- a/docs/04_cv32a65x_design/source/port_instr_scan.rst +++ b/docs/04_cv32a65x_design/source/port_instr_scan.rst @@ -9,7 +9,7 @@ .. _CVA6_instr_scan_ports: -.. list-table:: instr_scan module IO ports +.. list-table:: **instr_scan module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst index 5d3f66f380..bd81a0760a 100644 --- a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst +++ b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst @@ -9,7 +9,7 @@ .. _CVA6_issue_read_operands_ports: -.. list-table:: issue_read_operands module IO ports +.. list-table:: **issue_read_operands module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_issue_stage.rst b/docs/04_cv32a65x_design/source/port_issue_stage.rst index 93a904b232..4bbae3b90c 100644 --- a/docs/04_cv32a65x_design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/port_issue_stage.rst @@ -9,7 +9,7 @@ .. _CVA6_issue_stage_ports: -.. list-table:: issue_stage module IO ports +.. list-table:: **issue_stage module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_load_store_unit.rst b/docs/04_cv32a65x_design/source/port_load_store_unit.rst index 34cba9c003..57bdcd221e 100644 --- a/docs/04_cv32a65x_design/source/port_load_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_store_unit.rst @@ -9,7 +9,7 @@ .. _CVA6_load_store_unit_ports: -.. list-table:: load_store_unit module IO ports +.. list-table:: **load_store_unit module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_load_unit.rst b/docs/04_cv32a65x_design/source/port_load_unit.rst index f9a5e4d446..ea9e3174ee 100644 --- a/docs/04_cv32a65x_design/source/port_load_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_unit.rst @@ -9,7 +9,7 @@ .. _CVA6_load_unit_ports: -.. list-table:: load_unit module IO ports +.. list-table:: **load_unit module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_lsu_bypass.rst b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst index 2ae2f91beb..5cafbac963 100644 --- a/docs/04_cv32a65x_design/source/port_lsu_bypass.rst +++ b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst @@ -9,7 +9,7 @@ .. _CVA6_lsu_bypass_ports: -.. list-table:: lsu_bypass module IO ports +.. list-table:: **lsu_bypass module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_mult.rst b/docs/04_cv32a65x_design/source/port_mult.rst index 921b6b100b..aee6a76e91 100644 --- a/docs/04_cv32a65x_design/source/port_mult.rst +++ b/docs/04_cv32a65x_design/source/port_mult.rst @@ -9,7 +9,7 @@ .. _CVA6_mult_ports: -.. list-table:: mult module IO ports +.. list-table:: **mult module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_multiplier.rst b/docs/04_cv32a65x_design/source/port_multiplier.rst index b6131a789f..bfe086abd3 100644 --- a/docs/04_cv32a65x_design/source/port_multiplier.rst +++ b/docs/04_cv32a65x_design/source/port_multiplier.rst @@ -9,7 +9,7 @@ .. _CVA6_multiplier_ports: -.. list-table:: multiplier module IO ports +.. list-table:: **multiplier module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_ras.rst b/docs/04_cv32a65x_design/source/port_ras.rst index f91820b462..12e0ea84a7 100644 --- a/docs/04_cv32a65x_design/source/port_ras.rst +++ b/docs/04_cv32a65x_design/source/port_ras.rst @@ -9,7 +9,7 @@ .. _CVA6_ras_ports: -.. list-table:: ras module IO ports +.. list-table:: **ras module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_scoreboard.rst b/docs/04_cv32a65x_design/source/port_scoreboard.rst index 5271ab447a..d3d2ba99f1 100644 --- a/docs/04_cv32a65x_design/source/port_scoreboard.rst +++ b/docs/04_cv32a65x_design/source/port_scoreboard.rst @@ -9,7 +9,7 @@ .. _CVA6_scoreboard_ports: -.. list-table:: scoreboard module IO ports +.. list-table:: **scoreboard module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_serdiv.rst b/docs/04_cv32a65x_design/source/port_serdiv.rst index 994e02ef83..23a0139207 100644 --- a/docs/04_cv32a65x_design/source/port_serdiv.rst +++ b/docs/04_cv32a65x_design/source/port_serdiv.rst @@ -9,7 +9,7 @@ .. _CVA6_serdiv_ports: -.. list-table:: serdiv module IO ports +.. list-table:: **serdiv module** IO ports :header-rows: 1 * - Signal diff --git a/docs/04_cv32a65x_design/source/port_store_unit.rst b/docs/04_cv32a65x_design/source/port_store_unit.rst index 35347699fc..c9ff481401 100644 --- a/docs/04_cv32a65x_design/source/port_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_store_unit.rst @@ -9,7 +9,7 @@ .. _CVA6_store_unit_ports: -.. list-table:: store_unit module IO ports +.. list-table:: **store_unit module** IO ports :header-rows: 1 * - Signal diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index 67e49d4ed3..dfdff8d5e5 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -139,7 +139,7 @@ ) fout.write(" Original Author: Jean-Roch COULON - Thales\n\n") fout.write(f".. _CVA6_{module}_ports:\n\n") - fout.write(f".. list-table:: {module} module IO ports\n") + fout.write(f".. list-table:: **{module} module** IO ports\n") fout.write(" :header-rows: 1\n") fout.write("\n") fout.write(" * - Signal\n") From fdf9b8017ff800cad13937dd04d5f74b9a620065 Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Thu, 22 Feb 2024 22:58:33 +0100 Subject: [PATCH 17/20] Remove "none" if no discarded ports --- docs/04_cv32a65x_design/source/port_alu.rst | 2 -- docs/04_cv32a65x_design/source/port_bht.rst | 1 + .../04_cv32a65x_design/source/port_branch_unit.rst | 1 + docs/04_cv32a65x_design/source/port_btb.rst | 1 + .../source/port_commit_stage.rst | 1 + .../source/port_compressed_decoder.rst | 2 -- docs/04_cv32a65x_design/source/port_controller.rst | 1 + docs/04_cv32a65x_design/source/port_csr_buffer.rst | 2 -- .../04_cv32a65x_design/source/port_csr_regfile.rst | 1 + docs/04_cv32a65x_design/source/port_cva6.rst | 1 + docs/04_cv32a65x_design/source/port_cvxif_fu.rst | 1 + docs/04_cv32a65x_design/source/port_decoder.rst | 1 + docs/04_cv32a65x_design/source/port_ex_stage.rst | 1 + docs/04_cv32a65x_design/source/port_frontend.rst | 1 + docs/04_cv32a65x_design/source/port_id_stage.rst | 1 + .../04_cv32a65x_design/source/port_instr_queue.rst | 2 -- .../source/port_instr_realign.rst | 2 -- docs/04_cv32a65x_design/source/port_instr_scan.rst | 2 -- .../source/port_issue_read_operands.rst | 1 + .../04_cv32a65x_design/source/port_issue_stage.rst | 1 + .../source/port_load_store_unit.rst | 1 + docs/04_cv32a65x_design/source/port_load_unit.rst | 1 + docs/04_cv32a65x_design/source/port_lsu_bypass.rst | 2 -- docs/04_cv32a65x_design/source/port_mult.rst | 2 -- docs/04_cv32a65x_design/source/port_multiplier.rst | 2 -- docs/04_cv32a65x_design/source/port_ras.rst | 2 -- docs/04_cv32a65x_design/source/port_scoreboard.rst | 1 + docs/04_cv32a65x_design/source/port_serdiv.rst | 2 -- docs/04_cv32a65x_design/source/port_store_unit.rst | 1 + docs/scripts/spec_builder.py | 14 +++++++------- 30 files changed, 25 insertions(+), 29 deletions(-) diff --git a/docs/04_cv32a65x_design/source/port_alu.rst b/docs/04_cv32a65x_design/source/port_alu.rst index f6f94ea34e..c6cea25699 100644 --- a/docs/04_cv32a65x_design/source/port_alu.rst +++ b/docs/04_cv32a65x_design/source/port_alu.rst @@ -48,6 +48,4 @@ - branch_unit - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_bht.rst b/docs/04_cv32a65x_design/source/port_bht.rst index 6618ed78a9..239ca590ae 100644 --- a/docs/04_cv32a65x_design/source/port_bht.rst +++ b/docs/04_cv32a65x_design/source/port_bht.rst @@ -58,3 +58,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As DebugEn = 0, | ``debug_mode_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_branch_unit.rst b/docs/04_cv32a65x_design/source/port_branch_unit.rst index 96a340fdb6..2231f52e5c 100644 --- a/docs/04_cv32a65x_design/source/port_branch_unit.rst +++ b/docs/04_cv32a65x_design/source/port_branch_unit.rst @@ -100,3 +100,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As DebugEn = 0, | ``debug_mode_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_btb.rst b/docs/04_cv32a65x_design/source/port_btb.rst index 9a80b27782..87bf24bbdc 100644 --- a/docs/04_cv32a65x_design/source/port_btb.rst +++ b/docs/04_cv32a65x_design/source/port_btb.rst @@ -58,3 +58,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As DebugEn = 0, | ``debug_mode_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_commit_stage.rst b/docs/04_cv32a65x_design/source/port_commit_stage.rst index 1298e8b5af..8acb95c4aa 100644 --- a/docs/04_cv32a65x_design/source/port_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/port_commit_stage.rst @@ -165,3 +165,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``fence_o`` output is tied to 0 | As RVS = 0, | ``sfence_vma_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst index 3cdaed2f60..99d55c4ecd 100644 --- a/docs/04_cv32a65x_design/source/port_compressed_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_compressed_decoder.rst @@ -42,6 +42,4 @@ - decoder - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_controller.rst b/docs/04_cv32a65x_design/source/port_controller.rst index 5916f3219d..74f520340d 100644 --- a/docs/04_cv32a65x_design/source/port_controller.rst +++ b/docs/04_cv32a65x_design/source/port_controller.rst @@ -140,3 +140,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``fence_i`` input is tied to 0 | As RVS = 0, | ``sfence_vma_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_csr_buffer.rst b/docs/04_cv32a65x_design/source/port_csr_buffer.rst index 96f42db689..c50d72cb1b 100644 --- a/docs/04_cv32a65x_design/source/port_csr_buffer.rst +++ b/docs/04_cv32a65x_design/source/port_csr_buffer.rst @@ -72,6 +72,4 @@ - COMMIT_STAGE - logic[11:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_csr_regfile.rst b/docs/04_cv32a65x_design/source/port_csr_regfile.rst index d03f99d955..7be41edad9 100644 --- a/docs/04_cv32a65x_design/source/port_csr_regfile.rst +++ b/docs/04_cv32a65x_design/source/port_csr_regfile.rst @@ -204,3 +204,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``perf_data_i`` input is tied to 0 | ``perf_we_o`` output is tied to 0 | ``mcountinhibit_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_cva6.rst b/docs/04_cv32a65x_design/source/port_cva6.rst index 7a9aae4798..7ea51ae6a9 100644 --- a/docs/04_cv32a65x_design/source/port_cva6.rst +++ b/docs/04_cv32a65x_design/source/port_cva6.rst @@ -90,3 +90,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``debug_req_i`` input is tied to 0 | As IsRVFI = 0, | ``rvfi_probes_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst index 1a4df90210..7d71c3e1c3 100644 --- a/docs/04_cv32a65x_design/source/port_cvxif_fu.rst +++ b/docs/04_cv32a65x_design/source/port_cvxif_fu.rst @@ -100,3 +100,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As PRIV = MachineOnly, | ``priv_lvl_i`` input is tied to MachineMode + diff --git a/docs/04_cv32a65x_design/source/port_decoder.rst b/docs/04_cv32a65x_design/source/port_decoder.rst index 614f8b47ca..30772b20af 100644 --- a/docs/04_cv32a65x_design/source/port_decoder.rst +++ b/docs/04_cv32a65x_design/source/port_decoder.rst @@ -105,3 +105,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``frm_i`` input is tied to 0 | As RVV = 0, | ``vs_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_ex_stage.rst b/docs/04_cv32a65x_design/source/port_ex_stage.rst index 7c002f82cc..8799172d55 100644 --- a/docs/04_cv32a65x_design/source/port_ex_stage.rst +++ b/docs/04_cv32a65x_design/source/port_ex_stage.rst @@ -382,3 +382,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As IsRVFI = 0, | ``rvfi_lsu_ctrl_o`` output is tied to 0 | ``rvfi_mem_paddr_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_frontend.rst b/docs/04_cv32a65x_design/source/port_frontend.rst index 3bc358b9d2..2ed9bb5d3a 100644 --- a/docs/04_cv32a65x_design/source/port_frontend.rst +++ b/docs/04_cv32a65x_design/source/port_frontend.rst @@ -127,3 +127,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As DebugEn = 0, | ``debug_mode_i`` input is tied to 0 | ``set_debug_pc_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_id_stage.rst b/docs/04_cv32a65x_design/source/port_id_stage.rst index 93e917acb9..8283c51d6b 100644 --- a/docs/04_cv32a65x_design/source/port_id_stage.rst +++ b/docs/04_cv32a65x_design/source/port_id_stage.rst @@ -113,3 +113,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``frm_i`` input is tied to 0 | As RVV = 0, | ``vs_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_instr_queue.rst b/docs/04_cv32a65x_design/source/port_instr_queue.rst index bac8a0f4d7..ddb759f577 100644 --- a/docs/04_cv32a65x_design/source/port_instr_queue.rst +++ b/docs/04_cv32a65x_design/source/port_instr_queue.rst @@ -120,6 +120,4 @@ - ID_STAGE - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_instr_realign.rst b/docs/04_cv32a65x_design/source/port_instr_realign.rst index 11f5d8ffb9..98f6014881 100644 --- a/docs/04_cv32a65x_design/source/port_instr_realign.rst +++ b/docs/04_cv32a65x_design/source/port_instr_realign.rst @@ -78,6 +78,4 @@ - instr_scan&instr_queue - logic[INSTR_PER_FETCH-1:0][31:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_instr_scan.rst b/docs/04_cv32a65x_design/source/port_instr_scan.rst index 9923c68c0a..f95e363e55 100644 --- a/docs/04_cv32a65x_design/source/port_instr_scan.rst +++ b/docs/04_cv32a65x_design/source/port_instr_scan.rst @@ -102,6 +102,4 @@ - FRONTEND - logic[riscv::VLEN-1:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst index bd81a0760a..6c43aa94e0 100644 --- a/docs/04_cv32a65x_design/source/port_issue_read_operands.rst +++ b/docs/04_cv32a65x_design/source/port_issue_read_operands.rst @@ -256,3 +256,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``fpu_fmt_o`` output is tied to 0 | ``fpu_rm_o`` output is tied to 0 | ``we_fpr_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_issue_stage.rst b/docs/04_cv32a65x_design/source/port_issue_stage.rst index 4bbae3b90c..9de390d84b 100644 --- a/docs/04_cv32a65x_design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/port_issue_stage.rst @@ -258,3 +258,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As IsRVFI = 0, | ``rvfi_issue_pointer_o`` output is tied to 0 | ``rvfi_commit_pointer_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_load_store_unit.rst b/docs/04_cv32a65x_design/source/port_load_store_unit.rst index 57bdcd221e..fa85194602 100644 --- a/docs/04_cv32a65x_design/source/port_load_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_store_unit.rst @@ -206,3 +206,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As IsRVFI = 0, | ``rvfi_lsu_ctrl_o`` output is tied to 0 | ``rvfi_mem_paddr_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_load_unit.rst b/docs/04_cv32a65x_design/source/port_load_unit.rst index ea9e3174ee..1ba1466f22 100644 --- a/docs/04_cv32a65x_design/source/port_load_unit.rst +++ b/docs/04_cv32a65x_design/source/port_load_unit.rst @@ -150,3 +150,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``dtlb_hit_i`` input is tied to 1 | As MMUPresent = 0, | ``dtlb_ppn_i`` input is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_lsu_bypass.rst b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst index 5cafbac963..8eac0f7ab4 100644 --- a/docs/04_cv32a65x_design/source/port_lsu_bypass.rst +++ b/docs/04_cv32a65x_design/source/port_lsu_bypass.rst @@ -72,6 +72,4 @@ - TO_BE_COMPLETED - logic -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_mult.rst b/docs/04_cv32a65x_design/source/port_mult.rst index aee6a76e91..358e77dd7e 100644 --- a/docs/04_cv32a65x_design/source/port_mult.rst +++ b/docs/04_cv32a65x_design/source/port_mult.rst @@ -72,6 +72,4 @@ - ISSUE_STAGE - logic[TRANS_ID_BITS-1:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_multiplier.rst b/docs/04_cv32a65x_design/source/port_multiplier.rst index bfe086abd3..77da9c48be 100644 --- a/docs/04_cv32a65x_design/source/port_multiplier.rst +++ b/docs/04_cv32a65x_design/source/port_multiplier.rst @@ -84,6 +84,4 @@ - Mult - logic[TRANS_ID_BITS-1:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_ras.rst b/docs/04_cv32a65x_design/source/port_ras.rst index 12e0ea84a7..f42e125dcc 100644 --- a/docs/04_cv32a65x_design/source/port_ras.rst +++ b/docs/04_cv32a65x_design/source/port_ras.rst @@ -60,6 +60,4 @@ - FRONTEND - ariane_pkg::ras_t -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_scoreboard.rst b/docs/04_cv32a65x_design/source/port_scoreboard.rst index d3d2ba99f1..9a8ad0c3db 100644 --- a/docs/04_cv32a65x_design/source/port_scoreboard.rst +++ b/docs/04_cv32a65x_design/source/port_scoreboard.rst @@ -217,3 +217,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | As IsRVFI = 0, | ``rvfi_issue_pointer_o`` output is tied to 0 | ``rvfi_commit_pointer_o`` output is tied to 0 + diff --git a/docs/04_cv32a65x_design/source/port_serdiv.rst b/docs/04_cv32a65x_design/source/port_serdiv.rst index 23a0139207..392f049392 100644 --- a/docs/04_cv32a65x_design/source/port_serdiv.rst +++ b/docs/04_cv32a65x_design/source/port_serdiv.rst @@ -96,6 +96,4 @@ - Mult - logic[WIDTH-1:0] -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below -none diff --git a/docs/04_cv32a65x_design/source/port_store_unit.rst b/docs/04_cv32a65x_design/source/port_store_unit.rst index c9ff481401..6bcbc5918c 100644 --- a/docs/04_cv32a65x_design/source/port_store_unit.rst +++ b/docs/04_cv32a65x_design/source/port_store_unit.rst @@ -166,3 +166,4 @@ Due to cv32a65x configuration, some ports are tied to a static value. These port | ``rvfi_mem_paddr_o`` output is tied to 0 | For any HW configuration, | ``dtlb_hit_i`` input is tied to 1 + diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index dfdff8d5e5..41f6a43508 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -155,11 +155,11 @@ fout.write(f" - {port.connexion}\n") fout.write(f" - {port.data_type}\n") fout.write("\n") - fout.write( - f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n" - ) + if len(comments) != 0: + fout.write( + f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n" + ) + fout.write("\n") + for comment in comments: + fout.write(f"| {comment[0]},\n| {comment[1]}\n") fout.write("\n") - for comment in comments: - fout.write(f"| {comment[0]},\n| {comment[1]}\n") - if len(comments) == 0: - fout.write("none\n") From d9bd953283677dcd8aaa8ef62cb02e89086036af Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Fri, 23 Feb 2024 07:00:16 +0100 Subject: [PATCH 18/20] Fix come's comment (it is finished!) --- .../source/cv32a6_execute.rst | 1 + .../source/cv32a6_frontend.rst | 94 ++++++++++++------- .../source/cva6_commit_stage.rst | 2 +- .../source/cva6_id_stage.rst | 1 + .../source/cva6_issue_stage.rst | 2 +- 5 files changed, 64 insertions(+), 36 deletions(-) diff --git a/docs/04_cv32a65x_design/source/cv32a6_execute.rst b/docs/04_cv32a65x_design/source/cv32a6_execute.rst index 9d482796b6..c411d44eda 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_execute.rst @@ -148,6 +148,7 @@ It inserts stalls until it can satisfy the current request. This means: * Two stores to the same address are allowed. * A store followed by a load to the same address can only be satisfied if the store has already been committed (marked as committed in the store buffer). +.. TO_BE_COMPLETED, But once the store is committed, do we do forwarding without waiting for the store to actually be finished? Or do we authorize the outcome of the load, which will be carried out in memory/cache? .. include:: port_load_unit.rst diff --git a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst index 4e5d680c62..c5a4694f25 100644 --- a/docs/04_cv32a65x_design/source/cv32a6_frontend.rst +++ b/docs/04_cv32a65x_design/source/cv32a6_frontend.rst @@ -22,7 +22,7 @@ PC gen stage is responsible for generating the next program counter. It hosts a Branch Target Buffer (BTB), a Branch History Table (BHT) and a Return Address Stack (RAS) to speculate on control flow instructions. Fetch stage requests data to the CACHE module, realigns the data to store them in instruction queue and transmits the instructions to the DECODE module. -FRONTEND can fetch up to 2 instructions per cycles when C extension instructions is used, but as instruction queue limits the data rate, up to one instruction per cycle can be sent to DECODE. +FRONTEND can fetch up to 2 instructions per cycles when C extension instructions is enabled, but DECODE module decodes up to one instruction per cycles. The module is connected to: @@ -46,27 +46,39 @@ PC gen generates the next program counter. The next PC can originate from the fo * **Branch Predict:** Fetched instruction is predecoded thanks to instr_scan submodule. When instruction is a control flow, three cases need to be considered: - + 1) If instruction is a JALR and BTB (Branch Target Buffer) returns a valid address, next PC is predicted by BTB. Else JALR is not considered as a control flow instruction, which will generate a mispredict. + + 1) If instruction is a JALR and BTB (Branch Target Buffer) returns a valid address, next PC is predicted by BTB. + Else JALR is not considered as a control flow instruction, which will generate a mispredict. + 2) If instruction is a branch and BTH (Branch History table) returns a valid address, next PC is predicted by BHT. Else branch is not considered as an control flow instruction, which will generate a mispredict when branch is taken. - + 3) If instruction is a RET and RAS (Return Address Stack) returns a valid address and RET has already been consummed by instruction queue. Else RET is considered as a control flow instruction but next PC is not predicted. A mispredict wil be generated. + + 3) If instruction is a RET and RAS (Return Address Stack) returns a valid address and RET has already been consummed by instruction queue. + Else RET is considered as a control flow instruction but next PC is not predicted. + A mispredict wil be generated. - Then the PC gen informs the Fetch stage that it performed a prediction on the PC. *In CV32A6 v0.1.0, Branch Prediction is simplified: no information is stored in BTB, BHT and RAS. JALR, branch and RET instructions are not considered as control flow instruction and will generates mispredict.* + Then the PC gen informs the Fetch stage that it performed a prediction on the PC. *In CV32A6 v0.1.0, Branch Prediction is simplified: no information is stored in BTB, BHT and RAS. + JALR, branch and RET instructions are not considered as control flow instruction and will generates mispredict.* * **Default:** PC + 4 is fetched. PC Gen always fetches on a word boundary (32-bit). Compressed instructions are handled by fetch stage. -* **Mispredict:** When a branch prediction is mispredicted, the EXECUTE feedbacks a misprediction. This can either be a 'real' mis-prediction or a branch which was not recognized as one. In any case we need to correct our action and start fetching from the correct address. +* **Mispredict:** When a branch prediction is mispredicted, the EXECUTE feedbacks a misprediction. This can either be a 'real' mis-prediction or a branch which was not recognized as one. +In any case we need to correct our action and start fetching from the correct address. * **Replay instruction fetch:** When the instruction queue is full, the instr_queue submodule asks the fetch replay and provides the address to be replayed. * **Return from environment call:** When CSR asks a return from an environment call, the PC is assigned to the successive PC to the one stored in the CSR [m-s]epc register. -* **Exception/Interrupt:** If an exception (or interrupt, which is in the context of RISC-V subsystems quite similar) is triggered by the COMMIT, the next PC Gen is assigned to the CSR trap vector base address. The trap vector base address can be different depending on whether the exception traps to S-Mode or M-Mode (user mode exceptions are currently not supported). It is the purpose of the CSR Unit to figure out where to trap to and present the correct address to PC Gen. +* **Exception/Interrupt:** If an exception (or interrupt, which is in the context of RISC-V subsystems quite similar) is triggered by the COMMIT, the next PC Gen is assigned to the CSR trap vector base address. +The trap vector base address can be different depending on whether the exception traps to S-Mode or M-Mode (user mode exceptions are currently not supported). +It is the purpose of the CSR Unit to figure out where to trap to and present the correct address to PC Gen. -* **Pipeline Flush:** When a CSR with side-effects gets written the whole pipeline is flushed by CONTROLLER and FRONTEND starts fetching from the next instruction again in order to take the up-dated information into account (for example virtual memory base pointer changes). The PC related to the flush action is provided by the COMMIT. Moreover flush is also transmitted to the CACHES through the next fetch CACHES access and instruction queue is reset. +* **Pipeline Flush:** When a CSR with side-effects gets written the whole pipeline is flushed by CONTROLLER and FRONTEND starts fetching from the next instruction again in order to take the up-dated information into account (for example virtual memory base pointer changes). +The PC related to the flush action is provided by the COMMIT. +Moreover flush is also transmitted to the CACHES through the next fetch CACHES access and instruction queue is reset. -* **Debug:** Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. The debug jump is requested by CSR. The address to be jumped into is HW coded. This debug feature is not supported by CV32A6 v0.1.0. +* **Debug:** Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. +The debug jump is requested by CSR. +The address to be jumped into is HW coded. +This debug feature is not supported by CV32A6 v0.1.0. All program counters are logical addressed. If the logical to physical mapping changes, a ``fence.vm`` instruction should be used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. @@ -80,12 +92,11 @@ Fetch stage controls the CACHE module by a handshaking protocol. Fetched data is a 32-bit block with a word-aligned address. A granted fetch is processed by the instr_realign submodule to produce instructions. Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). -This submodule stores the instructions and related information which allow to identify the outstanding transactions. -In the case CONTROLLER decides to flush the instruction queue, the outstanding transactions are discarded. +This submodule stores the instructions and sends them to the DECODE module. -*The Fetch stage asks the MMU (MMU is not enabled in CV32A6 v0.1.0) to translate the requested address.* +.. TO_BE_COMPLETED MMU also feedback an exception, but not present in 65X -Memory *and MMU (MMU is not enabled in CV32A6 v0.1.0)* can feedback potential exceptions generated by the memory fetch request. +Memory can feedback potential exceptions generated by the memory fetch request. They can be bus errors, invalid accesses or instruction page faults. @@ -109,7 +120,7 @@ This submodule extracts the instructions from the 32-bit blocks. It is possible to fetch up to two instructions per cycle when C extension is used. An not-compressed instruction can be misaligned on the block size, interleaved with two cache blocks. In that case, two cache accesses are needed to get the whole instruction. -The instr_realign submodule provides at maximum one instruction per cycle. +The instr_realign submodule provides at maximum two instructions per cycle when compressed extensionis enabled, else one instruction per cycle. Incomplete instruction is stored in instr_realign submodule until its second half is fetched. In case of mispredict, flush, replay or branch predict, the instr_realign is re-initialized, the internal register storing the instruction alignment state is reset. @@ -120,7 +131,7 @@ In case of mispredict, flush, replay or branch predict, the instr_realign is re- Instr_queue submodule ~~~~~~~~~~~~~~~~~~~~~ -The instr_queue receives 32bit block from CACHES to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). +The instr_queue receives mutliple instructions from instr_realign submodule to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). FRONTEND pushes in FIFO to store the instructions and related information needed in case of mispredict or exception: instructions, instruction control flow type, exception, exception address and predicted address. DECODE pops them when decode stage is ready and indicates to the FRONTEND the instruction has been consummed. @@ -135,11 +146,13 @@ The instruction queue can be flushed by CONTROLLER. .. include:: port_instr_queue.rst -Instr_scan submodule +instr_scan submodule ~~~~~~~~~~~~~~~~~~~~ -The instr_scan submodule pre-decodes the fetched instructions coming from the instr_realign module, instructions could be compressed or not. -The instr_scan submodule tells if the instruction is compressed and provides the intruction type: branch, jump, return, jalr, imm, call or others. +When compressed extnsino is enabled, two instr_scan are instantiated to handle up to two instructions per cycle. + +Each instr_scan submodule pre-decodes the fetched instructions coming from the instr_realign module, instructions could be compressed or not. +The instr_scan submodule is a flox controler which provides the intruction type: branch, jump, return, jalr, imm, call or others. These outputs are used by the branch prediction feature. .. include:: port_instr_scan.rst @@ -153,7 +166,9 @@ BHT (Branch History Table) submodule When a branch instruction is resolved by the EXECUTE, the relative information is stored in the Branch History Table. -The information is stored in a 1024 entry table. +The information is stored in a *BHTDepth configuration parameter* entry table. + +.. TO_BE_COMPLETED: Specify the behaviour when BHT is saturated The Branch History Table is a table of two-bit saturating counters that takes the virtual address of the current fetched instruction by the CACHE. It states whether the current branch request should be taken or not. @@ -166,46 +181,57 @@ The two bit counter is updated by the successive execution of the instructions a BHT saturation -The BHT is not updated if processor is in debug mode. +.. TO_BE_COMPLETED if debug enable, The BHT is not updated if processor is in debug mode. -When a branch instruction is pre-decoded by instr_scan submodule, the BHT informs whether the PC address is in the BHT. -In this case, the BHT predicts whether the branch is taken and provides the corresponding target address. +When a branch instruction is pre-decoded by instr_scan submodule, the BHT valids whether the PC address is in the BHT and provides the taken or not prediction. The BHT is never flushed. + .. include:: port_bht.rst +.. As BTB is unsed in cv32a65x, comment the chapter + BTB (Branch Target Buffer) submodule + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -BTB (Branch Target Buffer) submodule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + When an JALR instruction jump to a register is mispredicted by the EXECUTE module, the JALR PC and the target address are stored into the BTB. -When an unconditional jump to a register (JALR instruction) is mispredicted by the EXECUTE module, the JALR PC and the target address are stored into the BTB. + The information is stored in a *BTBDepth configuration parameter* entry table. -The information is stored in a 8 entry table. + .. TO_BE_COMPLETED: Specify the behaviour when BTB is saturated -The BTB is not updated if processor is in debug mode. + .. TO_BE_COMPLETED when debug enabled, The BTB is not updated if processor is in debug mode. -When a branch instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in the BTB. -In this case, the BTB provides the predicted target address. + When a JALR instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in the BTB. + In this case, the BTB provides the predicted target address. -The BTB is never flushed. + The BTB is never flushed. -.. include:: port_btb.rst + .. include:: port_btb.rst RAS (Return Address Stack) submodule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +RAS is implemented as a FIFO which is composed of *RASDepth configuration parameter* entries. -When an unconditional jumps to a known target address (JAL instruction) is consummed by the instr_queue, the next pc after the JAL instruction and the return address are stored into a FIFO. +A JAL instruction pushes the return address onto the RAS only when rd=x1 or rd=x5. -The RAS FIFO depth is 2. - -When a branch instruction is pre-decoded by instr_scan submodule, the RAS informs whether the input PC address is in RAS. In this case, the RAS provides the corresponding target address. +JALR instruction pushes/pops a RAS as follows. +In the below, *link* is true when the register is either x1 or x5. +* when rd=!link and rs1=!link, none +* when rd=!link and rs1=link, pop +* when rd=link and rs1=!link, push +* when rd=link and rs1=link and rd!=rs1, pop then push +* when rd=link and rs1=link and rd=rs1, push The RAS is never flushed. +Mispredicted JAL or JALR instructions must not alter the RAS content. + +.. TO_BE_COMPLETED: Specify the behaviour when RAS is saturated + .. include:: port_ras.rst diff --git a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst index cb5ed81753..b4dde9e917 100644 --- a/docs/04_cv32a65x_design/source/cva6_commit_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_commit_stage.rst @@ -16,7 +16,7 @@ Description ----------- The COMMIT_STAGE module implements the commit stage, which is the last stage in the processor’s pipeline. -It takes incoming instruction and updates the architectural state: writing CSR registers, committing stores and writing back data to the register file. +For the instructions for which the execution is completed, it updates the architectural state: writing CSR registers, committing stores and writing back data to the register file. The commit stage controls the stalling and the flushing of the processor. The commit stage also manages the exceptions. diff --git a/docs/04_cv32a65x_design/source/cva6_id_stage.rst b/docs/04_cv32a65x_design/source/cva6_id_stage.rst index 5e7d81ce37..faa3c579ea 100644 --- a/docs/04_cv32a65x_design/source/cva6_id_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_id_stage.rst @@ -71,6 +71,7 @@ It transforms the instruction to the most fundamental control structure in pipel The scoreboard entry contains an exception entry which is composed of a valid field, a cause and a value called TVAL. As TVALEn configuration parameter is zero, the TVAL field is not implemented. + A potential illegal instruction exception can be detected during decoding. If no exception has happened previously in fetch stage, the decoder will valid the exception and add the cause and tval value to the scoreboard entry. diff --git a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst index 4370cd867e..a0d542d763 100644 --- a/docs/04_cv32a65x_design/source/cva6_issue_stage.rst +++ b/docs/04_cv32a65x_design/source/cva6_issue_stage.rst @@ -19,7 +19,7 @@ The execution can be roughly divided into four parts: issue(1), read operands(2) The ISSUE_STAGE module handles step one, two and four. The ISSUE_STAGE module receives the decoded instructions and issues them to the various functional units. -A data structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit it is in and which register it will write-back to. +A data structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit and which destination register they are. The scoreboard handle the write-back data received from the COMMIT_STAGE module. Furthermore it contains the CPU’s register file. From 748400d74a5b553747b1280a62d16bf60b23f17e Mon Sep 17 00:00:00 2001 From: Jean-Roch Coulon Date: Fri, 23 Feb 2024 07:14:00 +0100 Subject: [PATCH 19/20] Remove BTB module in image Fix BHT image --- docs/04_cv32a65x_design/images/bht.png | Bin 113873 -> 76434 bytes .../images/frontend_modules.png | Bin 29540 -> 10504 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/04_cv32a65x_design/images/bht.png b/docs/04_cv32a65x_design/images/bht.png index 5983816a4e2e9a582a28e7b432099400f2155928..33d3a7533a28cbfe5f53d7fcd77ae514e26a6376 100644 GIT binary patch literal 76434 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%0D|?49 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 literal 113873 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