diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml
new file mode 100644
index 0000000000..6fb9c0b865
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.yaml
@@ -0,0 +1,18 @@
+name: CVA6 bug
+description: Create a CVA6 bug
+title: "[BUG]
"
+labels: ["Type:Bug"]
+body:
+- type: checkboxes
+ attributes:
+ label: Is there an existing CVA6 bug for this?
+ description: Please search to see if an issue already exist for the bug you need to create
+ options:
+ - label: I have searched the existing bug issues
+ required: true
+- type: textarea
+ attributes:
+ label: Bug Description
+ description: A concise description of the bug
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/task.yaml b/.github/ISSUE_TEMPLATE/task.yaml
index 2add406692..cf4df0ac26 100644
--- a/.github/ISSUE_TEMPLATE/task.yaml
+++ b/.github/ISSUE_TEMPLATE/task.yaml
@@ -1,11 +1,11 @@
name: CVA6 Task
-description: Create a CVA6-SDK Project Task
+description: Create a CVA6 Project Task
title: "[TASK] "
labels: ["task"]
body:
- type: checkboxes
attributes:
- label: Is there an existing CVA6-SDK task for this?
+ label: Is there an existing CVA6 task for this?
description: Please search to see if a task issue already exists for the task you need to create
options:
- label: I have searched the existing task issues
@@ -22,6 +22,10 @@ body:
description: What are the criteria for completion of this task?
validations:
required: true
+- type: textarea
+ attributes:
+ label: Associated PRs
+ description: Use this area to provide a link to PRs used to complete this task.
- type: markdown
attributes:
value: |
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index aee1feccec..f76bc8b83d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -40,17 +40,18 @@ include:
workflow:
rules:
- - if: '$CI_COMMIT_REF_NAME =~ /^master.*/ || $CI_COMMIT_REF_NAME =~ /^hotfix.*/ || $CI_COMMIT_REF_NAME =~ /^rc.*/'
+ - if: '$CI_WEIGHT == "forced"' #bypass workflow
+ - if: '$CI_COMMIT_REF_NAME =~ /^master.*|^hotfix.*|^rc.*|^github-pr.*/'
variables:
CI_WEIGHT: "full"
- - if: '$CI_COMMIT_REF_NAME =~ /^dev.*/ || $CI_COMMIT_REF_NAME =~ /^feature.*/'
+ - if: '$CI_COMMIT_REF_NAME =~ /^dev.*|^feature.*/'
variables:
- CI_WEIGHT: "lite"
- - if: '$CI_COMMIT_REF_NAME =~ /^cvvdev\/master.*/ || $CI_COMMIT_REF_NAME =~ /^cvvdev\/hotfix.*/ || $CI_COMMIT_REF_NAME =~ /^cvvdev\/rc.*/'
+ CI_WEIGHT: "short"
+ - if: '$CI_COMMIT_REF_NAME =~ /^cvvdev\/master.*|^cvvdev\/hotfix.*|^cvvdev\/rc.*/'
variables:
CI_WEIGHT: "full"
CORE_V_VERIF_BRANCH: $CI_COMMIT_REF_NAME
- - if: '$CI_COMMIT_REF_NAME =~ /^cvvdev\/dev.*/ || $CI_COMMIT_REF_NAME =~ /^cvvdev\/feature.*/'
+ - if: '$CI_COMMIT_REF_NAME =~ /^cvvdev\/dev.*|^cvvdev\/feature.*/'
variables:
CI_WEIGHT: "lite"
CORE_V_VERIF_BRANCH: $CI_COMMIT_REF_NAME
diff --git a/Flist.ariane b/Flist.ariane
index 7ca8b5de72..e28ed5de6d 100644
--- a/Flist.ariane
+++ b/Flist.ariane
@@ -15,139 +15,150 @@
// Author: Michael Schaffner , ETH Zurich
// Date: 15.08.2018
// Description: File list for OpenPiton flow
-+incdir+src/common_cells/include/
-+incdir+src/util/
-include/riscv_pkg.sv
-src/riscv-dbg/src/dm_pkg.sv
-include/ariane_pkg.sv
-src/common_cells/src/deprecated/rrarbiter.sv
-src/common_cells/src/deprecated/fifo_v1.sv
-src/common_cells/src/deprecated/fifo_v2.sv
-src/common_cells/src/fifo_v3.sv
-src/common_cells/src/lfsr_8bit.sv
-src/common_cells/src/lzc.sv
-src/common_cells/src/rr_arb_tree.sv
-src/common_cells/src/rstgen_bypass.sv
-src/common_cells/src/cdc_2phase.sv
-src/common_cells/src/shift_reg.sv
-src/common_cells/src/unread.sv
-src/common_cells/src/popcount.sv
-src/common_cells/src/exp_backoff.sv
-src/register_interface/src/apb_to_reg.sv
-src/register_interface/src/reg_intf_pkg.sv
-src/register_interface/src/reg_intf.sv
-src/fpu/src/fpnew_pkg.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
-src/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
-src/fpu/src/fpnew_cast_multi.sv
-src/fpu/src/fpnew_classifier.sv
-src/fpu/src/fpnew_divsqrt_multi.sv
-src/fpu/src/fpnew_fma_multi.sv
-src/fpu/src/fpnew_fma.sv
-src/fpu/src/fpnew_noncomp.sv
-src/fpu/src/fpnew_opgroup_block.sv
-src/fpu/src/fpnew_opgroup_fmt_slice.sv
-src/fpu/src/fpnew_opgroup_multifmt_slice.sv
-src/fpu/src/fpnew_rounding.sv
-src/fpu/src/fpnew_top.sv
-src/axi/src/axi_pkg.sv
-tb/ariane_soc_pkg.sv
-tb/ariane_axi_soc_pkg.sv
-include/ariane_axi_pkg.sv
-include/wt_cache_pkg.sv
-include/std_cache_pkg.sv
-include/axi_intf.sv
-include/instr_tracer_pkg.sv
-src/util/instr_tracer_if.sv
-src/util/instr_tracer.sv
-src/util/sram.sv
-src/fpga-support/rtl/SyncSpRamBeNx64.sv
-src/dromajo_ram.sv
-src/axi_mem_if/src/axi2mem.sv
-src/tech_cells_generic/src/pulp_clock_gating.sv
-src/tech_cells_generic/src/cluster_clock_inverter.sv
-src/tech_cells_generic/src/pulp_clock_mux2.sv
-src/pmp/src/pmp.sv
-src/pmp/src/pmp_entry.sv
-src/axi_adapter.sv
-src/alu.sv
-src/fpu_wrap.sv
-src/ariane.sv
-src/branch_unit.sv
-src/compressed_decoder.sv
-src/controller.sv
-src/csr_buffer.sv
-src/csr_regfile.sv
-src/decoder.sv
-src/ex_stage.sv
-src/instr_realign.sv
-src/frontend/btb.sv
-src/frontend/bht.sv
-src/frontend/ras.sv
-src/frontend/instr_scan.sv
-src/frontend/instr_queue.sv
-src/frontend/frontend.sv
-src/id_stage.sv
-src/issue_read_operands.sv
-src/issue_stage.sv
-src/load_unit.sv
-src/load_store_unit.sv
-src/mmu_sv39/mmu.sv
-src/mmu_sv32/cva6_mmu_sv32.sv
-src/mult.sv
-src/multiplier.sv
-src/serdiv.sv
-src/perf_counters.sv
-src/ptw.sv
-src/ariane_regfile_ff.sv
-src/re_name.sv
-src/scoreboard.sv
-src/store_buffer.sv
-src/amo_buffer.sv
-src/store_unit.sv
-src/tlb.sv
-src/commit_stage.sv
-src/cache_subsystem/wt_dcache_ctrl.sv
-src/cache_subsystem/wt_dcache_mem.sv
-src/cache_subsystem/wt_dcache_missunit.sv
-src/cache_subsystem/wt_dcache_wbuffer.sv
-src/cache_subsystem/wt_dcache.sv
-src/cache_subsystem/cva6_icache.sv
-src/cache_subsystem/wt_l15_adapter.sv
-src/cache_subsystem/wt_cache_subsystem.sv
-src/clint/clint.sv
-src/clint/axi_lite_interface.sv
-src/riscv-dbg/src/dm_csrs.sv
-src/riscv-dbg/src/dm_mem.sv
-src/riscv-dbg/src/dm_top.sv
-src/riscv-dbg/src/dmi_cdc.sv
-src/riscv-dbg/src/dmi_jtag.sv
-src/riscv-dbg/src/dm_sba.sv
-src/riscv-dbg/src/dmi_jtag_tap.sv
-src/riscv-dbg/debug_rom/debug_rom.sv
-openpiton/ariane_verilog_wrap.sv
-openpiton/riscv_peripherals.sv
-openpiton/bootrom/baremetal/bootrom.sv
-openpiton/bootrom/linux/bootrom_linux.sv
-src/rv_plic/rtl/rv_plic_target.sv
-src/rv_plic/rtl/rv_plic_gateway.sv
-src/rv_plic/rtl/plic_regmap.sv
-src/rv_plic/rtl/plic_top.sv
-fpga/src/axi2apb/src/axi2apb_wrap.sv
-fpga/src/axi2apb/src/axi2apb.sv
-fpga/src/axi2apb/src/axi2apb_64_32.sv
-fpga/src/axi_slice/src/axi_w_buffer.sv
-fpga/src/axi_slice/src/axi_b_buffer.sv
-fpga/src/axi_slice/src/axi_slice_wrap.sv
-fpga/src/axi_slice/src/axi_slice.sv
-fpga/src/axi_slice/src/axi_single_slice.sv
-fpga/src/axi_slice/src/axi_ar_buffer.sv
-fpga/src/axi_slice/src/axi_r_buffer.sv
-fpga/src/axi_slice/src/axi_aw_buffer.sv
++incdir+common/submodules/common_cells/include/
++incdir+common/local/util/
++incdir+corev_apu/register_interface/include/
+core/include/cv64a6_imafdc_sv39_config_pkg.sv
+core/include/riscv_pkg.sv
+corev_apu/riscv-dbg/src/dm_pkg.sv
+core/include/ariane_pkg.sv
+corev_apu/tb/ariane_soc_pkg.sv
+corev_apu/axi/src/axi_pkg.sv
+core/include/ariane_axi_pkg.sv
+core/include/wt_cache_pkg.sv
+core/include/axi_intf.sv
+core/fpu/src/fpnew_pkg.sv
+core/include/cvxif_pkg.sv
+common/submodules/common_cells/src/cf_math_pkg.sv
+core/include/instr_tracer_pkg.sv
+core/cvxif_example/include/cvxif_instr_pkg.sv
+corev_apu/rv_plic/rtl/rv_plic_reg_pkg.sv
+common/local/util/sram.sv
+common/submodules/common_cells/src/deprecated/rrarbiter.sv
+common/submodules/common_cells/src/deprecated/fifo_v1.sv
+common/submodules/common_cells/src/deprecated/fifo_v2.sv
+common/submodules/common_cells/src/fifo_v3.sv
+common/submodules/common_cells/src/shift_reg.sv
+common/submodules/common_cells/src/lfsr_8bit.sv
+common/submodules/common_cells/src/lfsr.sv
+common/submodules/common_cells/src/lzc.sv
+common/submodules/common_cells/src/exp_backoff.sv
+common/submodules/common_cells/src/rr_arb_tree.sv
+common/submodules/common_cells/src/rstgen_bypass.sv
+common/submodules/common_cells/src/cdc_2phase.sv
+common/submodules/common_cells/src/unread.sv
+common/submodules/common_cells/src/popcount.sv
+corev_apu/axi_mem_if/src/axi2mem.sv
+corev_apu/src/tech_cells_generic/src/deprecated/cluster_clk_cells.sv
+corev_apu/src/tech_cells_generic/src/deprecated/pulp_clk_cells.sv
+common/local/util/tc_sram_wrapper.sv
+corev_apu/src/tech_cells_generic/src/rtl/tc_sram.sv
+corev_apu/src/tech_cells_generic/src/rtl/tc_clk.sv
+core/axi_adapter.sv
+core/alu.sv
+core/fpu_wrap.sv
+core/ariane.sv
+core/cva6.sv
+core/branch_unit.sv
+core/compressed_decoder.sv
+core/controller.sv
+core/csr_buffer.sv
+core/csr_regfile.sv
+core/decoder.sv
+core/ex_stage.sv
+core/frontend/btb.sv
+core/frontend/bht.sv
+core/frontend/ras.sv
+core/frontend/instr_scan.sv
+core/frontend/instr_queue.sv
+core/frontend/frontend.sv
+core/id_stage.sv
+core/instr_realign.sv
+core/issue_read_operands.sv
+core/issue_stage.sv
+core/load_unit.sv
+core/load_store_unit.sv
+core/lsu_bypass.sv
+core/mmu_sv39/mmu.sv
+core/mult.sv
+core/multiplier.sv
+core/serdiv.sv
+core/perf_counters.sv
+core/mmu_sv39/ptw.sv
+core/ariane_regfile_ff.sv
+core/re_name.sv
+core/scoreboard.sv
+core/store_buffer.sv
+core/amo_buffer.sv
+core/store_unit.sv
+core/mmu_sv39/tlb.sv
+core/commit_stage.sv
+core/cache_subsystem/wt_dcache_ctrl.sv
+core/cache_subsystem/wt_dcache_mem.sv
+core/cache_subsystem/wt_dcache_missunit.sv
+core/cache_subsystem/wt_dcache_wbuffer.sv
+core/cache_subsystem/wt_dcache.sv
+core/cache_subsystem/cva6_icache.sv
+core/cache_subsystem/cva6_icache_axi_wrapper.sv
+core/cache_subsystem/wt_l15_adapter.sv
+core/cache_subsystem/wt_cache_subsystem.sv
+corev_apu/clint/clint.sv
+corev_apu/clint/axi_lite_interface.sv
+corev_apu/riscv-dbg/debug_rom/debug_rom.sv
+corev_apu/riscv-dbg/src/dm_csrs.sv
+corev_apu/riscv-dbg/src/dm_mem.sv
+corev_apu/riscv-dbg/src/dm_top.sv
+corev_apu/riscv-dbg/src/dmi_cdc.sv
+corev_apu/riscv-dbg/src/dmi_jtag.sv
+corev_apu/riscv-dbg/src/dm_sba.sv
+corev_apu/riscv-dbg/src/dmi_jtag_tap.sv
+corev_apu/openpiton/riscv_peripherals.sv
+corev_apu/openpiton/ariane_verilog_wrap.sv
+corev_apu/openpiton/bootrom/baremetal/bootrom.sv
+corev_apu/openpiton/bootrom/linux/bootrom_linux.sv
+corev_apu/rv_plic/rtl/rv_plic_target.sv
+corev_apu/rv_plic/rtl/rv_plic_gateway.sv
+corev_apu/rv_plic/rtl/plic_regmap.sv
+corev_apu/rv_plic/rtl/plic_top.sv
+corev_apu/fpga/src/axi2apb/src/axi2apb_wrap.sv
+corev_apu/fpga/src/axi2apb/src/axi2apb.sv
+corev_apu/fpga/src/axi2apb/src/axi2apb_64_32.sv
+corev_apu/fpga/src/axi_slice/src/axi_w_buffer.sv
+corev_apu/fpga/src/axi_slice/src/axi_b_buffer.sv
+corev_apu/fpga/src/axi_slice/src/axi_slice_wrap.sv
+corev_apu/fpga/src/axi_slice/src/axi_slice.sv
+corev_apu/fpga/src/axi_slice/src/axi_single_slice.sv
+corev_apu/fpga/src/axi_slice/src/axi_ar_buffer.sv
+corev_apu/fpga/src/axi_slice/src/axi_r_buffer.sv
+corev_apu/fpga/src/axi_slice/src/axi_aw_buffer.sv
+corev_apu/register_interface/src/apb_to_reg.sv
+corev_apu/register_interface/src/reg_intf.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
+core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
+core/fpu/src/fpnew_cast_multi.sv
+core/fpu/src/fpnew_classifier.sv
+core/fpu/src/fpnew_divsqrt_multi.sv
+core/fpu/src/fpnew_fma_multi.sv
+core/fpu/src/fpnew_fma.sv
+core/fpu/src/fpnew_noncomp.sv
+core/fpu/src/fpnew_opgroup_block.sv
+core/fpu/src/fpnew_opgroup_fmt_slice.sv
+core/fpu/src/fpnew_opgroup_multifmt_slice.sv
+core/fpu/src/fpnew_rounding.sv
+core/fpu/src/fpnew_top.sv
+core/pmp/src/pmp.sv
+core/pmp/src/pmp_entry.sv
+common/local/util/instr_tracer.sv
+common/local/util/instr_tracer_if.sv
+core/cvxif_example/cvxif_example_coprocessor.sv
+core/cvxif_example/instr_decoder.sv
+common/submodules/common_cells/src/counter.sv
+common/submodules/common_cells/src/delta_counter.sv
+core/cvxif_fu.sv
diff --git a/config_pkg_generator.py b/config_pkg_generator.py
index 1cca938c13..edc26ae32c 100644
--- a/config_pkg_generator.py
+++ b/config_pkg_generator.py
@@ -18,17 +18,27 @@ def setup_parser_config_generator():
parser = argparse.ArgumentParser()
parser.add_argument("--default_config", type=str, default="cv64a6_imafdc_sv39", required=True,
- choices=["cv32a6_imac_sv0","cv32a6_imac_sv32","cv32a6_imafc_sv32","cv64a6_imafdc_sv39"],
+ choices=["cv32a6_imac_sv0","cv32a6_imac_sv32","cv32a6_imafc_sv32","cv64a6_imafdc_sv39","cv32a60x"],
help="Default configuration is one of the 4 preexisting configuration: \
cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32, cv64a6_imafdc_sv39")
parser.add_argument("--isa", type=str, default=None, required=True,
help="RISC-V ISA subset")
parser.add_argument("--fpu", type=int, default=None, choices=[0,1],
help="FPU enable ? 1 : enable, 0 : disable")
+ parser.add_argument("--F16En", type=int, default=None, choices=[0,1],
+ help="F16En enable ? 1 : enable, 0 : disable")
+ parser.add_argument("--F16AltEn", type=int, default=None, choices=[0,1],
+ help="F16AltEn enable ? 1 : enable, 0 : disable")
+ parser.add_argument("--F8En", type=int, default=None, choices=[0,1],
+ help="F8En enable ? 1 : enable, 0 : disable")
+ parser.add_argument("--FVecEn", type=int, default=None, choices=[0,1],
+ help="FVecEn enable ? 1 : enable, 0 : disable")
parser.add_argument("--cvxif", type=int, default=None, choices=[0,1],
help="CoreV-X-Interface enable ? 1 : enable, 0 : disable")
parser.add_argument("--c_ext", type=int, default=None, choices=[0,1],
help="C extension enable ? 1 : enable, 0 : disable")
+ parser.add_argument("--a_ext", type=int, default=None, choices=[0,1],
+ help="A extension enable ? 1 : enable, 0 : disable")
parser.add_argument("--iuser_en", type=int, default=None, choices=[0,1],
help="Fetch User enable ? 1 : enable, 0 : disable")
parser.add_argument("--iuser_w", type=int, default=None, choices=list(range(1,64)),
@@ -37,6 +47,8 @@ def setup_parser_config_generator():
help="Data User enable ? 1 : enable, 0 : disable")
parser.add_argument("--duser_w", type=int, default=None, choices=list(range(1,64)),
help="Data User Width ? [1-64]")
+ parser.add_argument("--RenameEn", type=int, default=None, choices=[0,1],
+ help="RenameEn ? 1 : enable, 0 : disable")
return parser
ISA = ""
@@ -46,12 +58,18 @@ def setup_parser_config_generator():
MapArgsToParameter={
"xlen" : "CVA6ConfigXlen",
"fpu" : "CVA6ConfigFpuEn",
+ "F16En" : "CVA6ConfigF16En",
+ "F16AltEn" : "CVA6ConfigF16AltEn",
+ "F8En" : "CVA6ConfigF8En",
+ "FVecEn" : "CVA6ConfigFVecEn",
"cvxif" : "CVA6ConfigCvxifEn",
"c_ext" : "CVA6ConfigCExtEn",
+ "a_ext" : "CVA6ConfigAExtEn",
"iuser_en" : "CVA6ConfigFetchUserEn",
"iuser_w" : "CVA6ConfigFetchUserWidth",
"duser_en" : "CVA6ConfigDataUserEn",
- "duser_w" : "CVA6ConfigDataUserWidth"
+ "duser_w" : "CVA6ConfigDataUserWidth",
+ "RenameEn" : "CVA6ConfigRenameEn",
}
MapParametersToArgs = {i:k for k, i in MapArgsToParameter.items()} #reverse map
diff --git a/core/Flist.cv32a60x b/core/Flist.cv32a60x
new file mode 100644
index 0000000000..2524c94a01
--- /dev/null
+++ b/core/Flist.cv32a60x
@@ -0,0 +1,158 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2022 OpenHW Group
+//
+// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://solderpad.org/licenses/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
+//
+///////////////////////////////////////////////////////////////////////////////
+//
+// Manifest for the CVA6 CORE RTL model.
+// - This is a CORE-ONLY manifest.
+// - Relevent synthesis and simulation scripts/Makefiles must set the shell
+// ENV variable CVA6_REPO_DIR.
+//
+///////////////////////////////////////////////////////////////////////////////
+
++define+WT_DCACHE
+
++incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/include/
++incdir+${CVA6_REPO_DIR}/common/submodules/common_cells/src/
++incdir+${CVA6_REPO_DIR}/common/local/util/
+
+${CVA6_REPO_DIR}/core/include/cv32a6_imac_sv0_config_pkg.sv
+// Broken (?) dependencies in packages:
+// - include/ariane_pkg.sv is dependent on src/riscv-dbg/src/dm_pkg.sv
+// (ariane should not depend on debug-module)
+${CVA6_REPO_DIR}/core/include/riscv_pkg.sv
+// TODO: should not be needed.
+${CVA6_REPO_DIR}/corev_apu/riscv-dbg/src/dm_pkg.sv
+${CVA6_REPO_DIR}/core/include/ariane_pkg.sv
+// TODO: ariane_axi_pkg is dependent on this.
+${CVA6_REPO_DIR}/corev_apu/axi/src/axi_pkg.sv
+${CVA6_REPO_DIR}/core/include/ariane_rvfi_pkg.sv
+
+// Packages
+${CVA6_REPO_DIR}/core/include/ariane_axi_pkg.sv
+${CVA6_REPO_DIR}/core/include/wt_cache_pkg.sv
+${CVA6_REPO_DIR}/core/include/std_cache_pkg.sv
+${CVA6_REPO_DIR}/core/include/axi_intf.sv
+${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv
+
+//CVXIF
+${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
+${CVA6_REPO_DIR}/core/cvxif_fu.sv
+
+// Common Cells
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/cf_math_pkg.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/fifo_v3.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/lfsr.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/lzc.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/rr_arb_tree.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/shift_reg.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/unread.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/popcount.sv
+${CVA6_REPO_DIR}/common/submodules/common_cells/src/exp_backoff.sv
+
+// Floating point unit
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_pkg.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_cast_multi.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_classifier.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_divsqrt_multi.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma_multi.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_fma.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_noncomp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_block.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_fmt_slice.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_opgroup_multifmt_slice.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_rounding.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpnew_top.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
+${CVA6_REPO_DIR}/core/fpu/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
+
+// Top-level source files (not necessarily instantiated at the top of the cva6).
+${CVA6_REPO_DIR}/core/ariane.sv
+${CVA6_REPO_DIR}/core/cva6.sv
+${CVA6_REPO_DIR}/core/alu.sv
+// Note: depends on fpnew_pkg, above
+${CVA6_REPO_DIR}/core/fpu_wrap.sv
+${CVA6_REPO_DIR}/core/branch_unit.sv
+${CVA6_REPO_DIR}/core/compressed_decoder.sv
+${CVA6_REPO_DIR}/core/controller.sv
+${CVA6_REPO_DIR}/core/csr_buffer.sv
+${CVA6_REPO_DIR}/core/csr_regfile.sv
+${CVA6_REPO_DIR}/core/decoder.sv
+${CVA6_REPO_DIR}/core/ex_stage.sv
+${CVA6_REPO_DIR}/core/instr_realign.sv
+${CVA6_REPO_DIR}/core/id_stage.sv
+${CVA6_REPO_DIR}/core/issue_read_operands.sv
+${CVA6_REPO_DIR}/core/issue_stage.sv
+${CVA6_REPO_DIR}/core/load_unit.sv
+${CVA6_REPO_DIR}/core/load_store_unit.sv
+${CVA6_REPO_DIR}/core/lsu_bypass.sv
+${CVA6_REPO_DIR}/core/mult.sv
+${CVA6_REPO_DIR}/core/multiplier.sv
+${CVA6_REPO_DIR}/core/serdiv.sv
+${CVA6_REPO_DIR}/core/perf_counters.sv
+${CVA6_REPO_DIR}/core/ariane_regfile_ff.sv
+${CVA6_REPO_DIR}/core/re_name.sv
+// NOTE: scoreboard.sv modified for DSIM (unchanged for other simulators)
+${CVA6_REPO_DIR}/core/scoreboard.sv
+${CVA6_REPO_DIR}/core/store_buffer.sv
+${CVA6_REPO_DIR}/core/amo_buffer.sv
+${CVA6_REPO_DIR}/core/store_unit.sv
+${CVA6_REPO_DIR}/core/commit_stage.sv
+${CVA6_REPO_DIR}/core/axi_shim.sv
+
+// What is "frontend"?
+${CVA6_REPO_DIR}/core/frontend/btb.sv
+${CVA6_REPO_DIR}/core/frontend/bht.sv
+${CVA6_REPO_DIR}/core/frontend/ras.sv
+${CVA6_REPO_DIR}/core/frontend/instr_scan.sv
+${CVA6_REPO_DIR}/core/frontend/instr_queue.sv
+${CVA6_REPO_DIR}/core/frontend/frontend.sv
+
+// Cache subsystem
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_dcache_ctrl.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_dcache_mem.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_dcache_missunit.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_dcache_wbuffer.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_dcache.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/cva6_icache.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_cache_subsystem.sv
+${CVA6_REPO_DIR}/core/cache_subsystem/wt_axi_adapter.sv
+
+// Physical Memory Protection
+// NOTE: pmp.sv modified for DSIM (unchanged for other simulators)
+${CVA6_REPO_DIR}/core/pmp/src/pmp.sv
+${CVA6_REPO_DIR}/core/pmp/src/pmp_entry.sv
+
+// Tracer (behavioral code, not RTL)
+${CVA6_REPO_DIR}/common/local/util/instr_tracer_if.sv
+${CVA6_REPO_DIR}/common/local/util/instr_tracer.sv
+${CVA6_REPO_DIR}/common/local/util/tc_sram_wrapper.sv
+${CVA6_REPO_DIR}/corev_apu/src/tech_cells_generic/src/rtl/tc_sram.sv
+${CVA6_REPO_DIR}/common/local/util/sram.sv
+
+// MMU Sv32
+${CVA6_REPO_DIR}/core/mmu_sv32/cva6_mmu_sv32.sv
+${CVA6_REPO_DIR}/core/mmu_sv32/cva6_ptw_sv32.sv
+${CVA6_REPO_DIR}/core/mmu_sv32/cva6_tlb_sv32.sv
+
+// end of manifest
diff --git a/core/Flist.cv32a6_imac_sv0 b/core/Flist.cv32a6_imac_sv0
index c05630c63b..310cc070df 100644
--- a/core/Flist.cv32a6_imac_sv0
+++ b/core/Flist.cv32a6_imac_sv0
@@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
+${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv
diff --git a/core/Flist.cv32a6_imac_sv32 b/core/Flist.cv32a6_imac_sv32
index c05630c63b..310cc070df 100644
--- a/core/Flist.cv32a6_imac_sv32
+++ b/core/Flist.cv32a6_imac_sv32
@@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
+${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv
diff --git a/core/Flist.cv32a6_imafc_sv32 b/core/Flist.cv32a6_imafc_sv32
index c05630c63b..310cc070df 100644
--- a/core/Flist.cv32a6_imafc_sv32
+++ b/core/Flist.cv32a6_imafc_sv32
@@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
+${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv
diff --git a/core/Flist.cv64a6_imafdc_sv39 b/core/Flist.cv64a6_imafdc_sv39
index 71b327a51d..72a038bc14 100644
--- a/core/Flist.cv64a6_imafdc_sv39
+++ b/core/Flist.cv64a6_imafdc_sv39
@@ -112,6 +112,7 @@ ${CVA6_REPO_DIR}/core/issue_read_operands.sv
${CVA6_REPO_DIR}/core/issue_stage.sv
${CVA6_REPO_DIR}/core/load_unit.sv
${CVA6_REPO_DIR}/core/load_store_unit.sv
+${CVA6_REPO_DIR}/core/lsu_bypass.sv
${CVA6_REPO_DIR}/core/mult.sv
${CVA6_REPO_DIR}/core/multiplier.sv
${CVA6_REPO_DIR}/core/serdiv.sv
diff --git a/core/alu.sv b/core/alu.sv
index 11c771180b..52481a451f 100644
--- a/core/alu.sv
+++ b/core/alu.sv
@@ -31,6 +31,13 @@ module alu import ariane_pkg::*;(
logic [riscv::XLEN:0] operand_b_neg;
logic [riscv::XLEN+1:0] adder_result_ext_o;
logic less; // handles both signed and unsigned forms
+ logic [31:0] rolw; // Rotate Left Word
+ logic [31:0] rorw; // Rotate Right Word
+ logic [31:0] orcbw, rev8w;
+ logic [$clog2(riscv::XLEN) :0] cpop; // Count Population
+ logic [$clog2(riscv::XLEN)-1 :0] lz_tz_count; // Count Leading Zeros
+ logic [4:0] lz_tz_wcount; // Count Leading Zeros Word
+ logic lz_tz_empty, lz_tz_wempty;
// bit reverse operand_a for left shifts and bit counting
generate
@@ -49,6 +56,7 @@ module alu import ariane_pkg::*;(
logic adder_z_flag;
logic [riscv::XLEN:0] adder_in_a, adder_in_b;
riscv::xlen_t adder_result;
+ logic [riscv::XLEN-1:0] operand_a_bitmanip, bit_indx;
always_comb begin
adder_op_b_negate = 1'b0;
@@ -56,14 +64,33 @@ module alu import ariane_pkg::*;(
unique case (fu_data_i.operator)
// ADDER OPS
EQ, NE,
- SUB, SUBW: adder_op_b_negate = 1'b1;
-
+ SUB, SUBW,
+ ANDN, ORN, XNOR: adder_op_b_negate = 1'b1;
default: ;
endcase
end
+ always_comb begin
+ operand_a_bitmanip = fu_data_i.operand_a;
+
+ if (ariane_pkg::BITMANIP) begin
+ unique case (fu_data_i.operator)
+ SH1ADD : operand_a_bitmanip = fu_data_i.operand_a << 1;
+ SH2ADD : operand_a_bitmanip = fu_data_i.operand_a << 2;
+ SH3ADD : operand_a_bitmanip = fu_data_i.operand_a << 3;
+ SH1ADDUW : operand_a_bitmanip = fu_data_i.operand_a[31:0] << 1;
+ SH2ADDUW : operand_a_bitmanip = fu_data_i.operand_a[31:0] << 2;
+ SH3ADDUW : operand_a_bitmanip = fu_data_i.operand_a[31:0] << 3;
+ CTZ : operand_a_bitmanip = operand_a_rev;
+ CTZW : operand_a_bitmanip = operand_a_rev32;
+ ADDUW, CPOPW, CLZW : operand_a_bitmanip = fu_data_i.operand_a[31:0];
+ default : ;
+ endcase
+ end
+ end
+
// prepare operand a
- assign adder_in_a = {fu_data_i.operand_a, 1'b1};
+ assign adder_in_a = {operand_a_bitmanip, 1'b1};
// prepare operand b
assign operand_b_neg = {fu_data_i.operand_b, 1'b0} ^ {riscv::XLEN+1{adder_op_b_negate}};
@@ -152,26 +179,61 @@ module alu import ariane_pkg::*;(
if ((fu_data_i.operator == SLTS) ||
(fu_data_i.operator == LTS) ||
- (fu_data_i.operator == GES))
+ (fu_data_i.operator == GES) ||
+ (fu_data_i.operator == MAX) ||
+ (fu_data_i.operator == MIN))
sgn = 1'b1;
less = ($signed({sgn & fu_data_i.operand_a[riscv::XLEN-1], fu_data_i.operand_a}) < $signed({sgn & fu_data_i.operand_b[riscv::XLEN-1], fu_data_i.operand_b}));
end
+ if (ariane_pkg::BITMANIP) begin : gen_bitmanip
+ // Count Population + Count population Word
+
+ popcount #(
+ .INPUT_WIDTH(riscv::XLEN)
+ ) i_cpop_count (
+ .data_i (operand_a_bitmanip),
+ .popcount_o (cpop)
+ );
+
+ // Count Leading/Trailing Zeros
+ // 64b
+ lzc #(
+ .WIDTH(riscv::XLEN),
+ .MODE (1)
+ ) i_clz_64b (
+ .in_i (operand_a_bitmanip),
+ .cnt_o (lz_tz_count),
+ .empty_o (lz_tz_empty)
+ );
+ //32b
+ lzc #(
+ .WIDTH(32),
+ .MODE (1)
+ ) i_clz_32b (
+ .in_i (operand_a_bitmanip[31:0]),
+ .cnt_o (lz_tz_wcount),
+ .empty_o (lz_tz_wempty)
+ );
+ end
+
// -----------
// Result MUX
// -----------
always_comb begin
result_o = '0;
-
unique case (fu_data_i.operator)
// Standard Operations
- ANDL: result_o = fu_data_i.operand_a & fu_data_i.operand_b;
- ORL: result_o = fu_data_i.operand_a | fu_data_i.operand_b;
- XORL: result_o = fu_data_i.operand_a ^ fu_data_i.operand_b;
+ ANDL, ANDN: result_o = fu_data_i.operand_a & operand_b_neg[riscv::XLEN:1];
+ ORL, ORN : result_o = fu_data_i.operand_a | operand_b_neg[riscv::XLEN:1];
+ XORL, XNOR: result_o = fu_data_i.operand_a ^ operand_b_neg[riscv::XLEN:1];
// Adder Operations
- ADD, SUB: result_o = adder_result;
+ ADD, SUB,
+ ADDUW,
+ SH1ADD, SH2ADD, SH3ADD,
+ SH1ADDUW, SH2ADDUW, SH3ADDUW: result_o = adder_result;
// Add word: Ignore the upper bits and sign extend to 64 bit
ADDW, SUBW: result_o = {{riscv::XLEN-32{adder_result[31]}}, adder_result[31:0]};
// Shift Operations
@@ -186,5 +248,52 @@ module alu import ariane_pkg::*;(
default: ; // default case to suppress unique warning
endcase
+
+ if (ariane_pkg::BITMANIP) begin
+ // Index for Bitwise Rotation
+ bit_indx = 1 << (fu_data_i.operand_b & (riscv::XLEN-1));
+ orcbw = {{8{|fu_data_i.operand_a[31:24]}}, {8{|fu_data_i.operand_a[23:16]}}, {8{|fu_data_i.operand_a[15:8]}}, {8{|fu_data_i.operand_a[7:0]}}};
+ rev8w = {{fu_data_i.operand_a[7:0]}, {fu_data_i.operand_a[15:8]}, {fu_data_i.operand_a[23:16]}, {fu_data_i.operand_a[31:24]}};
+ // rolw, roriw, rorw
+ rolw = ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} << fu_data_i.operand_b[4:0]) | ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} >> (riscv::XLEN-32-fu_data_i.operand_b[4:0]));
+ rorw = ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} >> fu_data_i.operand_b[4:0]) | ({{riscv::XLEN-32{1'b0}},fu_data_i.operand_a[31:0]} << (riscv::XLEN-32-fu_data_i.operand_b[4:0]));
+ unique case (fu_data_i.operator)
+ // Left Shift 32 bit unsigned
+ SLLIUW: result_o = {{riscv::XLEN-32{1'b0}}, fu_data_i.operand_a[31:0]} << fu_data_i.operand_b[5:0];
+ // Integer minimum/maximum
+ MAX: result_o = less ? fu_data_i.operand_b : fu_data_i.operand_a;
+ MAXU: result_o = less ? fu_data_i.operand_b : fu_data_i.operand_a;
+ MIN: result_o = ~less ? fu_data_i.operand_b : fu_data_i.operand_a;
+ MINU: result_o = ~less ? fu_data_i.operand_b : fu_data_i.operand_a;
+
+ // Single bit instructions operations
+ BCLR, BCLRI: result_o = fu_data_i.operand_a & ~bit_indx;
+ BEXT, BEXTI: result_o = |(fu_data_i.operand_a & bit_indx);
+ BINV, BINVI: result_o = fu_data_i.operand_a ^ bit_indx;
+ BSET, BSETI: result_o = fu_data_i.operand_a | bit_indx;
+
+ // Count Leading/Trailing Zeros
+ CLZ, CTZ : result_o = (lz_tz_empty) ? (lz_tz_count + 1) : lz_tz_count;
+ CLZW, CTZW: result_o = (lz_tz_wempty) ? 32 : lz_tz_wcount;
+
+ // Count population
+ CPOP, CPOPW: result_o = cpop;
+
+ // Sign and Zero Extend
+ SEXTB: result_o = {{riscv::XLEN-8{fu_data_i.operand_a[7]}}, fu_data_i.operand_a[7:0]};
+ SEXTH: result_o = {{riscv::XLEN-16{fu_data_i.operand_a[15]}}, fu_data_i.operand_a[15:0]};
+ ZEXTH: result_o = {{riscv::XLEN-16{1'b0}}, fu_data_i.operand_a[15:0]};
+
+ // Bitwise Rotation
+ ROL: result_o = (riscv::XLEN == 64) ? ((fu_data_i.operand_a << fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a << fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a >> (riscv::XLEN-fu_data_i.operand_b[4:0])));
+ ROLW: result_o = {{riscv::XLEN-32{rolw[31]}}, rolw};
+ ROR, RORI: result_o = (riscv::XLEN == 64) ? ((fu_data_i.operand_a >> fu_data_i.operand_b[5:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[5:0]))) : ((fu_data_i.operand_a >> fu_data_i.operand_b[4:0]) | (fu_data_i.operand_a << (riscv::XLEN-fu_data_i.operand_b[4:0])));
+ RORW, RORIW: result_o = {{riscv::XLEN-32{rorw[31]}}, rorw};
+ ORCB: result_o = (riscv::XLEN == 64) ? ({{8{|fu_data_i.operand_a[63:56]}}, {8{|fu_data_i.operand_a[55:48]}}, {8{|fu_data_i.operand_a[47:40]}}, {8{|fu_data_i.operand_a[39:32]}}, orcbw}) : orcbw;
+ REV8: result_o = (riscv::XLEN == 64) ? ({rev8w , {fu_data_i.operand_a[39:32]}, {fu_data_i.operand_a[47:40]}, {fu_data_i.operand_a[55:48]}, {fu_data_i.operand_a[63:56]}}) : rev8w;
+
+ default: ; // default case to suppress unique warning
+ endcase
+ end
end
endmodule
diff --git a/core/ariane.sv b/core/ariane.sv
index 6a2d39f13d..043d751b7e 100644
--- a/core/ariane.sv
+++ b/core/ariane.sv
@@ -72,10 +72,11 @@ module ariane import ariane_pkg::*; #(
.cvxif_resp_i ( cvxif_resp ),
`ifdef PITON_ARIANE
.l15_req_o ( l15_req_o ),
- .l15_rtrn_i ( l15_rtrn_i ),
-`endif
+ .l15_rtrn_i ( l15_rtrn_i )
+`else
.axi_req_o ( axi_req_o ),
.axi_resp_i ( axi_resp_i )
+`endif
);
if (ariane_pkg::CVXIF_PRESENT) begin : gen_example_coprocessor
diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv
index e9facb1581..5e4c0c03b4 100644
--- a/core/csr_regfile.sv
+++ b/core/csr_regfile.sv
@@ -136,8 +136,8 @@ module csr_regfile import ariane_pkg::*; #(
logic wfi_d, wfi_q;
- riscv::xlen_t cycle_q, cycle_d;
- riscv::xlen_t instret_q, instret_d;
+ logic [63:0] cycle_q, cycle_d;
+ logic [63:0] instret_q, instret_d;
riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d;
logic [15:0][riscv::PLEN-3:0] pmpaddr_q, pmpaddr_d;
@@ -242,11 +242,15 @@ module csr_regfile import ariane_pkg::*; #(
riscv::CSR_MARCHID: csr_rdata = ARIANE_MARCHID;
riscv::CSR_MIMPID: csr_rdata = '0; // not implemented
riscv::CSR_MHARTID: csr_rdata = hart_id_i;
- riscv::CSR_MCYCLE: csr_rdata = cycle_q;
- riscv::CSR_MINSTRET: csr_rdata = instret_q;
// Counters and Timers
- riscv::CSR_CYCLE: csr_rdata = cycle_q;
- riscv::CSR_INSTRET: csr_rdata = instret_q;
+ riscv::CSR_MCYCLE: csr_rdata = cycle_q[riscv::XLEN-1:0];
+ riscv::CSR_MCYCLEH: if (riscv::XLEN == 32) csr_rdata = cycle_q[63:32]; else read_access_exception = 1'b1;
+ riscv::CSR_MINSTRET: csr_rdata = instret_q[riscv::XLEN-1:0];
+ riscv::CSR_MINSTRETH: if (riscv::XLEN == 32) csr_rdata = instret_q[63:32]; else read_access_exception = 1'b1;
+ riscv::CSR_CYCLE: csr_rdata = cycle_q[riscv::XLEN-1:0];
+ riscv::CSR_CYCLEH: if (riscv::XLEN == 32) csr_rdata = cycle_q[63:32]; else read_access_exception = 1'b1;
+ riscv::CSR_INSTRET: csr_rdata = instret_q[riscv::XLEN-1:0];
+ riscv::CSR_INSTRETH: if (riscv::XLEN == 32) csr_rdata = instret_q[63:32]; else read_access_exception = 1'b1;
riscv::CSR_ML1_ICACHE_MISS,
riscv::CSR_ML1_DCACHE_MISS,
riscv::CSR_MITLB_MISS,
@@ -322,7 +326,7 @@ module csr_regfile import ariane_pkg::*; #(
riscv::xlen_t mask;
always_comb begin : csr_update
automatic riscv::satp_t satp;
- automatic riscv::xlen_t instret;
+ automatic logic [63:0] instret;
satp = satp_q;
@@ -564,8 +568,10 @@ module csr_regfile import ariane_pkg::*; #(
mip_d = (mip_q & ~mask) | (csr_wdata & mask);
end
// performance counters
- riscv::CSR_MCYCLE: cycle_d = csr_wdata;
- riscv::CSR_MINSTRET: instret = csr_wdata;
+ riscv::CSR_MCYCLE: cycle_d[riscv::XLEN-1:0] = csr_wdata;
+ riscv::CSR_MCYCLEH: if (riscv::XLEN == 32) cycle_d[63:32] = csr_wdata; else update_access_exception = 1'b1;
+ riscv::CSR_MINSTRET: instret[riscv::XLEN-1:0] = csr_wdata;
+ riscv::CSR_MINSTRETH: if (riscv::XLEN == 32) instret[63:32] = csr_wdata; else update_access_exception = 1'b1;
riscv::CSR_ML1_ICACHE_MISS,
riscv::CSR_ML1_DCACHE_MISS,
riscv::CSR_MITLB_MISS,
@@ -1174,10 +1180,11 @@ module csr_regfile import ariane_pkg::*; #(
for(int i = 0; i < 16; i++) begin
if(i < NrPMPEntries) begin
// We only support >=8-byte granularity, NA4 is disabled
- if(pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1))
+ if(pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin
pmpcfg_q[i] <= pmpcfg_d[i];
- else
+ end else begin
pmpcfg_q[i] <= pmpcfg_q[i];
+ end
pmpaddr_q[i] <= pmpaddr_d[i];
end else begin
pmpcfg_q[i] <= '0;
diff --git a/core/cva6.sv b/core/cva6.sv
index 4781c87ee9..e04ebc9e33 100644
--- a/core/cva6.sv
+++ b/core/cva6.sv
@@ -927,27 +927,27 @@ module cva6 import ariane_pkg::*; #(
//pragma translate_on
`ifdef RVFI_TRACE
- always_comb
+ always_comb begin
for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
logic exception, mem_exception;
- exception = commit_instr_id_commit[i].valid && commit_instr_id_commit[i].ex.valid && ex_commit.valid;
+ exception = commit_instr_id_commit[i].valid && ex_commit.valid;
mem_exception = exception &&
- (commit_instr_id_commit[i].ex.cause == riscv::INSTR_ADDR_MISALIGNED ||
- commit_instr_id_commit[i].ex.cause == riscv::INSTR_ACCESS_FAULT ||
- commit_instr_id_commit[i].ex.cause == riscv::ILLEGAL_INSTR ||
- commit_instr_id_commit[i].ex.cause == riscv::LD_ADDR_MISALIGNED ||
- commit_instr_id_commit[i].ex.cause == riscv::LD_ACCESS_FAULT ||
- commit_instr_id_commit[i].ex.cause == riscv::ST_ADDR_MISALIGNED ||
- commit_instr_id_commit[i].ex.cause == riscv::ST_ACCESS_FAULT ||
- commit_instr_id_commit[i].ex.cause == riscv::INSTR_PAGE_FAULT ||
- commit_instr_id_commit[i].ex.cause == riscv::LOAD_PAGE_FAULT ||
- commit_instr_id_commit[i].ex.cause == riscv::STORE_PAGE_FAULT);
+ (ex_commit.cause == riscv::INSTR_ADDR_MISALIGNED ||
+ ex_commit.cause == riscv::INSTR_ACCESS_FAULT ||
+ ex_commit.cause == riscv::ILLEGAL_INSTR ||
+ ex_commit.cause == riscv::LD_ADDR_MISALIGNED ||
+ ex_commit.cause == riscv::LD_ACCESS_FAULT ||
+ ex_commit.cause == riscv::ST_ADDR_MISALIGNED ||
+ ex_commit.cause == riscv::ST_ACCESS_FAULT ||
+ ex_commit.cause == riscv::INSTR_PAGE_FAULT ||
+ ex_commit.cause == riscv::LOAD_PAGE_FAULT ||
+ ex_commit.cause == riscv::STORE_PAGE_FAULT);
// when rvfi_valid, the instruction is executed
- rvfi_o[i].valid = (commit_ack[i] && !commit_instr_id_commit[i].ex.valid) ||
- (exception && (commit_instr_id_commit[i].ex.cause == riscv::ENV_CALL_MMODE ||
- commit_instr_id_commit[i].ex.cause == riscv::ENV_CALL_SMODE ||
- commit_instr_id_commit[i].ex.cause == riscv::ENV_CALL_UMODE));
- rvfi_o[i].insn = commit_instr_id_commit[i].ex.tval[31:0];
+ rvfi_o[i].valid = (commit_ack[i] && !ex_commit.valid) ||
+ (exception && (ex_commit.cause == riscv::ENV_CALL_MMODE ||
+ ex_commit.cause == riscv::ENV_CALL_SMODE ||
+ ex_commit.cause == riscv::ENV_CALL_UMODE));
+ rvfi_o[i].insn = ex_commit.valid ? ex_commit.tval[31:0] : commit_instr_id_commit[i].ex.tval[31:0];
// when trap, the instruction is not executed
rvfi_o[i].trap = mem_exception;
rvfi_o[i].mode = debug_mode ? 2'b10 : priv_lvl;
@@ -958,6 +958,7 @@ module cva6 import ariane_pkg::*; #(
rvfi_o[i].rd_wdata = ariane_pkg::is_rd_fpr(commit_instr_id_commit[i].op) == 0 ? wdata_commit_id[i] : commit_instr_id_commit[i].result;
rvfi_o[i].pc_rdata = commit_instr_id_commit[i].pc;
end
+ end
`endif
endmodule // ariane
diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv
index baf0a94028..04ec25eea6 100644
--- a/core/cvxif_fu.sv
+++ b/core/cvxif_fu.sv
@@ -29,6 +29,10 @@ module cvxif_fu import ariane_pkg::*; (
input cvxif_pkg::cvxif_resp_t cvxif_resp_i
);
+ logic illegal_n, illegal_q;
+ logic [TRANS_ID_BITS-1:0] illegal_id_n, illegal_id_q;
+ logic [31:0] illegal_instr_n, illegal_instr_q;
+
always_comb begin
cvxif_req_o = '0;
cvxif_req_o.x_result_ready = 1'b1;
@@ -50,22 +54,44 @@ module cvxif_fu import ariane_pkg::*; (
end
always_comb begin
- if (~cvxif_resp_i.x_issue_resp.accept && cvxif_req_o.x_issue_valid && cvxif_resp_i.x_issue_ready) begin
- x_trans_id_o = cvxif_req_o.x_issue_req.id;
- x_result_o = 0;
- x_valid_o = 1;
+ illegal_n = illegal_q;
+ illegal_id_n = illegal_id_q;
+ illegal_instr_n = illegal_instr_q;
+ if (~cvxif_resp_i.x_issue_resp.accept && cvxif_req_o.x_issue_valid && cvxif_resp_i.x_issue_ready && ~illegal_n) begin
+ illegal_n = 1'b1;
+ illegal_id_n = cvxif_req_o.x_issue_req.id;
+ illegal_instr_n = cvxif_req_o.x_issue_req.instr;
+ end
+ x_valid_o = cvxif_resp_i.x_result_valid; //Read result only when CVXIF is enabled
+ x_trans_id_o = x_valid_o ? cvxif_resp_i.x_result.id : '0;
+ x_result_o = x_valid_o ? cvxif_resp_i.x_result.data : '0;
+ x_exception_o.cause = x_valid_o ? cvxif_resp_i.x_result.exccode : '0;
+ x_exception_o.valid = x_valid_o ? cvxif_resp_i.x_result.exc : '0;
+ x_exception_o.tval = '0;
+ x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0;
+ if (illegal_n) begin
+ if (~x_valid_o) begin
+ x_trans_id_o = illegal_id_n;
+ x_result_o = '0;
+ x_valid_o = 1'b1;
x_exception_o.cause = riscv::ILLEGAL_INSTR;
- x_exception_o.valid = 1;
- x_exception_o.tval = cvxif_req_o.x_issue_req.instr;
+ x_exception_o.valid = 1'b1;
+ x_exception_o.tval = illegal_instr_n;
x_we_o = '0;
+ illegal_n = '0; // Reset flag for illegal instr. illegal_id and illegal instr values are a don't care, no need to reset it.
+ end
+ end
+ end
+
+ always_ff @(posedge clk_i, negedge rst_ni) begin
+ if (~rst_ni) begin
+ illegal_q <= 1'b0;
+ illegal_id_q <= '0;
+ illegal_instr_q <= '0;
end else begin
- x_valid_o = cvxif_resp_i.x_result_valid; //Read result only when CVXIF is enabled
- x_trans_id_o = x_valid_o ? cvxif_resp_i.x_result.id : '0;
- x_result_o = x_valid_o ? cvxif_resp_i.x_result.data : '0;
- x_exception_o.cause = x_valid_o ? cvxif_resp_i.x_result.exccode : '0;
- x_exception_o.valid = x_valid_o ? cvxif_resp_i.x_result.exc : '0;
- x_exception_o.tval = '0;
- x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0;
+ illegal_q <= illegal_n;
+ illegal_id_q <= illegal_id_n;
+ illegal_instr_q <= illegal_instr_n;
end
end
diff --git a/core/decoder.sv b/core/decoder.sv
index 67a87def1e..1e316db4f4 100644
--- a/core/decoder.sv
+++ b/core/decoder.sv
@@ -42,6 +42,8 @@ module decoder import ariane_pkg::*; (
output logic is_control_flow_instr_o // this instruction will change the control flow
);
logic illegal_instr;
+ logic illegal_instr_bm;
+ logic illegal_instr_non_bm;
// this instruction is an environment call (ecall), it is handled like an exception
logic ecall;
// this instruction is a software break-point
@@ -69,6 +71,8 @@ module decoder import ariane_pkg::*; (
imm_select = NOIMM;
is_control_flow_instr_o = 1'b0;
illegal_instr = 1'b0;
+ illegal_instr_non_bm = 1'b0;
+ illegal_instr_bm = 1'b0;
instruction_o.pc = pc_i;
instruction_o.trans_id = '0;
instruction_o.fu = NONE;
@@ -132,7 +136,7 @@ module decoder import ariane_pkg::*; (
12'b111_1011_0010: begin
instruction_o.op = ariane_pkg::DRET;
// check that we are in debug mode when executing this instruction
- illegal_instr = (!debug_mode_i) ? 1'b1 : 1'b0;
+ illegal_instr = (!debug_mode_i) ? 1'b1 : illegal_instr;
end
// WFI
12'b1_0000_0101: begin
@@ -154,7 +158,7 @@ module decoder import ariane_pkg::*; (
if (instr.instr[31:25] == 7'b1001) begin
// check privilege level, SFENCE.VMA can only be executed in M/S mode
// otherwise decode an illegal instruction
- illegal_instr = (priv_lvl_i inside {riscv::PRIV_LVL_M, riscv::PRIV_LVL_S}) ? 1'b0 : 1'b1;
+ illegal_instr = ((priv_lvl_i inside {riscv::PRIV_LVL_M, riscv::PRIV_LVL_S}) && instr.itype.rd == '0) ? 1'b0 : 1'b1;
instruction_o.op = ariane_pkg::SFENCE_VMA;
// check TVM flag and intercept SFENCE.VMA call if necessary
if (priv_lvl_i == riscv::PRIV_LVL_S && tvm_i)
@@ -234,9 +238,6 @@ module decoder import ariane_pkg::*; (
default: illegal_instr = 1'b1;
endcase
-
- if (instr.stype.rs1 != '0 || instr.stype.imm0 != '0 || instr.instr[31:28] != '0)
- illegal_instr = 1'b1;
end
// --------------------------
@@ -475,7 +476,11 @@ module decoder import ariane_pkg::*; (
// Integer Reg-Reg Operations
// ---------------------------
end else begin
- instruction_o.fu = (instr.rtype.funct7 == 7'b000_0001) ? MULT : ALU;
+ if (ariane_pkg::BITMANIP) begin
+ instruction_o.fu = (instr.rtype.funct7 == 7'b000_0001 || ((instr.rtype.funct7 == 7'b000_0101) && !(instr.rtype.funct3[14]))) ? MULT : ALU;
+ end else begin
+ instruction_o.fu = (instr.rtype.funct7 == 7'b000_0001) ? MULT : ALU;
+ end
instruction_o.rs1 = instr.rtype.rs1;
instruction_o.rs2 = instr.rtype.rs2;
instruction_o.rd = instr.rtype.rd;
@@ -500,10 +505,44 @@ module decoder import ariane_pkg::*; (
{7'b000_0001, 3'b101}: instruction_o.op = ariane_pkg::DIVU;
{7'b000_0001, 3'b110}: instruction_o.op = ariane_pkg::REM;
{7'b000_0001, 3'b111}: instruction_o.op = ariane_pkg::REMU;
+ {7'b000_0100, 3'b100}: instruction_o.op = ariane_pkg::ZEXTH;
default: begin
- illegal_instr = 1'b1;
+ illegal_instr_non_bm = 1'b1;
end
endcase
+ if (ariane_pkg::BITMANIP) begin
+ unique case ({instr.rtype.funct7, instr.rtype.funct3})
+ //Logical with Negate
+ {7'b010_0000, 3'b111}: instruction_o.op = ariane_pkg::ANDN; // Andn
+ {7'b010_0000, 3'b110}: instruction_o.op = ariane_pkg::ORN; // Orn
+ {7'b010_0000, 3'b100}: instruction_o.op = ariane_pkg::XNOR; // Xnor
+ //Shift and Add (Bitmanip)
+ {7'b001_0000, 3'b010}: instruction_o.op = ariane_pkg::SH1ADD; // Sh1add
+ {7'b001_0000, 3'b100}: instruction_o.op = ariane_pkg::SH2ADD; // Sh2add
+ {7'b001_0000, 3'b110}: instruction_o.op = ariane_pkg::SH3ADD; // Sh3add
+ // Integer maximum/minimum
+ {7'b000_0101, 3'b110}: instruction_o.op = ariane_pkg::MAX; // max
+ {7'b000_0101, 3'b111}: instruction_o.op = ariane_pkg::MAXU; // maxu
+ {7'b000_0101, 3'b100}: instruction_o.op = ariane_pkg::MIN; // min
+ {7'b000_0101, 3'b101}: instruction_o.op = ariane_pkg::MINU; // minu
+ // Single bit instructions
+ {7'b010_0100, 3'b001}: instruction_o.op = ariane_pkg::BCLR; // bclr
+ {7'b010_0100, 3'b101}: instruction_o.op = ariane_pkg::BEXT; // bext
+ {7'b011_0100, 3'b001}: instruction_o.op = ariane_pkg::BINV; // binv
+ {7'b001_0100, 3'b001}: instruction_o.op = ariane_pkg::BSET; // bset
+ // Carry-Less-Multiplication (clmul, clmulh, clmulr)
+ {7'b000_0101, 3'b001}: instruction_o.op = ariane_pkg::CLMUL; // clmul
+ {7'b000_0101, 3'b011}: instruction_o.op = ariane_pkg::CLMULH; // clmulh
+ {7'b000_0101, 3'b010}: instruction_o.op = ariane_pkg::CLMULR; // clmulr
+ // Bitwise Shifting
+ {7'b011_0000, 3'b001}: instruction_o.op = ariane_pkg::ROL; // rol
+ {7'b011_0000, 3'b101}: instruction_o.op = ariane_pkg::ROR; // ror
+ default: begin
+ illegal_instr_bm = 1'b1;
+ end
+ endcase
+ end
+ illegal_instr = (ariane_pkg::BITMANIP) ? (illegal_instr_non_bm & illegal_instr_bm) : illegal_instr_non_bm;
end
end
@@ -528,8 +567,25 @@ module decoder import ariane_pkg::*; (
{7'b000_0001, 3'b101}: instruction_o.op = ariane_pkg::DIVUW;
{7'b000_0001, 3'b110}: instruction_o.op = ariane_pkg::REMW;
{7'b000_0001, 3'b111}: instruction_o.op = ariane_pkg::REMUW;
- default: illegal_instr = 1'b1;
+ default: illegal_instr_non_bm = 1'b1;
endcase
+ if (ariane_pkg::BITMANIP) begin
+ unique case ({instr.rtype.funct7, instr.rtype.funct3})
+ // Shift with Add (Unsigned Word)
+ {7'b001_0000, 3'b010}: instruction_o.op = ariane_pkg::SH1ADDUW; // sh1add.uw
+ {7'b001_0000, 3'b100}: instruction_o.op = ariane_pkg::SH2ADDUW; // sh2add.uw
+ {7'b001_0000, 3'b110}: instruction_o.op = ariane_pkg::SH3ADDUW; // sh3add.uw
+ // Unsigned word Op's
+ {7'b000_0100, 3'b000}: instruction_o.op = ariane_pkg::ADDUW; // add.uw
+ // Zero Extend Op
+ {7'b000_0100, 3'b100}: instruction_o.op = ariane_pkg::ZEXTH; // zext
+ // Bitwise Shifting
+ {7'b011_0000, 3'b001}: instruction_o.op = ariane_pkg::ROLW; // rolw
+ {7'b011_0000, 3'b101}: instruction_o.op = ariane_pkg::RORW; // rorw
+ default: illegal_instr_bm = 1'b1;
+ endcase
+ end
+ illegal_instr = (ariane_pkg::BITMANIP) ? (illegal_instr_non_bm & illegal_instr_bm) : illegal_instr_non_bm;
end else illegal_instr = 1'b1;
end
// --------------------------------
@@ -540,7 +596,6 @@ module decoder import ariane_pkg::*; (
imm_select = IIMM;
instruction_o.rs1[4:0] = instr.itype.rs1;
instruction_o.rd[4:0] = instr.itype.rd;
-
unique case (instr.itype.funct3)
3'b000: instruction_o.op = ariane_pkg::ADD; // Add Immediate
3'b010: instruction_o.op = ariane_pkg::SLTS; // Set to one if Lower Than Immediate
@@ -552,8 +607,8 @@ module decoder import ariane_pkg::*; (
3'b001: begin
instruction_o.op = ariane_pkg::SLL; // Shift Left Logical by Immediate
if (instr.instr[31:26] != 6'b0)
- illegal_instr = 1'b1;
- if (instr.instr[25] != 1'b0 && riscv::XLEN==32) illegal_instr = 1'b1;
+ illegal_instr_non_bm = 1'b1;
+ if (instr.instr[25] != 1'b0 && riscv::XLEN==32) illegal_instr_non_bm = 1'b1;
end
3'b101: begin
@@ -562,10 +617,50 @@ module decoder import ariane_pkg::*; (
else if (instr.instr[31:26] == 6'b010_000)
instruction_o.op = ariane_pkg::SRA; // Shift Right Arithmetically by Immediate
else
- illegal_instr = 1'b1;
- if (instr.instr[25] != 1'b0 && riscv::XLEN==32) illegal_instr = 1'b1;
+ illegal_instr_non_bm = 1'b1;
+ if (instr.instr[25] != 1'b0 && riscv::XLEN==32) illegal_instr_non_bm = 1'b1;
end
endcase
+ if (ariane_pkg::BITMANIP) begin
+ unique case (instr.itype.funct3)
+ 3'b001: begin
+ if (instr.instr[31:25] == 7'b0110000) begin
+ if (instr.instr[22:20] == 3'b100)
+ instruction_o.op = ariane_pkg::SEXTB;
+ else if (instr.instr[22:20] == 3'b101)
+ instruction_o.op = ariane_pkg::SEXTH;
+ else if (instr.instr[22:20] == 3'b010)
+ instruction_o.op = ariane_pkg::CPOP;
+ else if (instr.instr[22:20] == 3'b000)
+ instruction_o.op = ariane_pkg::CLZ;
+ else if (instr.instr[22:20] == 3'b001)
+ instruction_o.op = ariane_pkg::CTZ;
+ end
+ else if (instr.instr[31:26] == 6'b010010)
+ instruction_o.op = ariane_pkg::BCLRI;
+ else if (instr.instr[31:26] == 6'b011010)
+ instruction_o.op = ariane_pkg::BINVI;
+ else if (instr.instr[31:26] == 6'b001010)
+ instruction_o.op = ariane_pkg::BSETI;
+ else
+ illegal_instr_bm = 1'b1;
+ end
+ 3'b101: begin
+ if (instr.instr[31:20] == 12'b001010000111)
+ instruction_o.op = ariane_pkg::ORCB;
+ else if (instr.instr[31:20] == 12'b011010111000 || instr.instr[31:20] == 12'b011010011000)
+ instruction_o.op = ariane_pkg::REV8;
+ else if (instr.instr[31:26] == 6'b010_010)
+ instruction_o.op = ariane_pkg::BEXTI;
+ else if (instr.instr[31:26] == 6'b011_000)
+ instruction_o.op = ariane_pkg::RORI;
+ else
+ illegal_instr_bm = 1'b1;
+ end
+ default: illegal_instr_bm = 1'b1;
+ endcase
+ end
+ illegal_instr = (ariane_pkg::BITMANIP) ? (illegal_instr_non_bm & illegal_instr_bm) : illegal_instr_non_bm;
end
// --------------------------------
@@ -576,28 +671,50 @@ module decoder import ariane_pkg::*; (
imm_select = IIMM;
instruction_o.rs1[4:0] = instr.itype.rs1;
instruction_o.rd[4:0] = instr.itype.rd;
- if (riscv::IS_XLEN64)
- unique case (instr.itype.funct3)
- 3'b000: instruction_o.op = ariane_pkg::ADDW; // Add Immediate
-
- 3'b001: begin
- instruction_o.op = ariane_pkg::SLLW; // Shift Left Logical by Immediate
- if (instr.instr[31:25] != 7'b0)
- illegal_instr = 1'b1;
- end
-
- 3'b101: begin
- if (instr.instr[31:25] == 7'b0)
- instruction_o.op = ariane_pkg::SRLW; // Shift Right Logical by Immediate
- else if (instr.instr[31:25] == 7'b010_0000)
- instruction_o.op = ariane_pkg::SRAW; // Shift Right Arithmetically by Immediate
- else
- illegal_instr = 1'b1;
+ if (riscv::IS_XLEN64) begin
+ unique case (instr.itype.funct3)
+ 3'b000: instruction_o.op = ariane_pkg::ADDW; // Add Immediate
+ 3'b001: begin
+ instruction_o.op = ariane_pkg::SLLW; // Shift Left Logical by Immediate
+ if (instr.instr[31:25] != 7'b0)
+ illegal_instr_non_bm = 1'b1;
+ end
+ 3'b101: begin
+ if (instr.instr[31:25] == 7'b0)
+ instruction_o.op = ariane_pkg::SRLW; // Shift Right Logical by Immediate
+ else if (instr.instr[31:25] == 7'b010_0000)
+ instruction_o.op = ariane_pkg::SRAW; // Shift Right Arithmetically by Immediate
+ else
+ illegal_instr_non_bm = 1'b1;
+ end
+ default: illegal_instr_non_bm = 1'b1;
+ endcase
+ if (ariane_pkg::BITMANIP) begin
+ unique case (instr.itype.funct3)
+ 3'b001: begin
+ if (instr.instr[31:25] == 7'b0110000) begin
+ if (instr.instr[21:20] == 2'b10)
+ instruction_o.op = ariane_pkg::CPOPW;
+ else if (instr.instr[21:20] == 2'b00)
+ instruction_o.op = ariane_pkg::CLZW;
+ else if (instr.instr[21:20] == 2'b01)
+ instruction_o.op = ariane_pkg::CTZW;
+ else illegal_instr_bm = 1'b1;
+ end else if (instr.instr[31:26] == 6'b000010 )begin
+ instruction_o.op = ariane_pkg::SLLIUW; // Shift Left Logic by Immediate (Unsigned Word)
+ end else illegal_instr_bm = 1'b1;
+ end
+ 3'b101: begin
+ if (instr.instr[31:25] == 7'b011_0000)
+ instruction_o.op = ariane_pkg::RORIW;
+ else
+ illegal_instr_bm = 1'b1;
+ end
+ default: illegal_instr_bm = 1'b1;
+ endcase
end
-
- default: illegal_instr = 1'b1;
- endcase
- else illegal_instr = 1'b1;
+ illegal_instr = (ariane_pkg::BITMANIP) ? (illegal_instr_non_bm & illegal_instr_bm) : illegal_instr_non_bm;
+ end else illegal_instr = 1'b1;
end
// --------------------------------
// LSU
diff --git a/core/frontend/frontend.sv b/core/frontend/frontend.sv
index 6c965960ff..19e5333d41 100644
--- a/core/frontend/frontend.sv
+++ b/core/frontend/frontend.sv
@@ -129,7 +129,7 @@ module frontend import ariane_pkg::*; #(
// the prediction we saved from the previous fetch
assign bht_prediction_shifted[0] = (serving_unaligned) ? bht_q : bht_prediction[addr[0][1]];
assign btb_prediction_shifted[0] = (serving_unaligned) ? btb_q : btb_prediction[addr[0][1]];
-
+
if (ariane_pkg::RVC) begin : gen_btb_prediction_shifted
// for all other predictions we can use the generated address to index
// into the branch prediction data structures
@@ -138,7 +138,7 @@ module frontend import ariane_pkg::*; #(
assign btb_prediction_shifted[i] = btb_prediction[addr[i][$clog2(INSTR_PER_FETCH):1]];
end
end;
-
+
// for the return address stack it doens't matter as we have the
// address of the call/return already
logic bp_valid;
@@ -361,7 +361,9 @@ module frontend import ariane_pkg::*; #(
icache_ex_valid_q <= ariane_pkg::FE_INSTR_PAGE_FAULT;
end else if (icache_dreq_i.ex.cause == riscv::INSTR_ACCESS_FAULT) begin
icache_ex_valid_q <= ariane_pkg::FE_INSTR_ACCESS_FAULT;
- end else icache_ex_valid_q <= ariane_pkg::FE_NONE;
+ end else begin
+ icache_ex_valid_q <= ariane_pkg::FE_NONE;
+ end
// save the uppermost prediction
btb_q <= btb_prediction[INSTR_PER_FETCH-1];
bht_q <= bht_prediction[INSTR_PER_FETCH-1];
diff --git a/core/id_stage.sv b/core/id_stage.sv
index cb80b295d3..d91256c0b4 100644
--- a/core/id_stage.sv
+++ b/core/id_stage.sv
@@ -40,11 +40,12 @@ module id_stage (
input logic tsr_i
);
// ID/ISSUE register stage
- struct packed {
+ typedef struct packed {
logic valid;
ariane_pkg::scoreboard_entry_t sbe;
logic is_ctrl_flow;
- } issue_n, issue_q;
+ } issue_struct_t;
+ issue_struct_t issue_n, issue_q;
logic is_control_flow_instr;
ariane_pkg::scoreboard_entry_t decoded_instruction;
diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv
index 918f1ac26e..ddcd9dc0e7 100644
--- a/core/include/ariane_pkg.sv
+++ b/core/include/ariane_pkg.sv
@@ -135,7 +135,7 @@ package ariane_pkg;
localparam BITS_SATURATION_COUNTER = 2;
localparam NR_COMMIT_PORTS = 2;
- localparam ENABLE_RENAME = 1'b0;
+ localparam ENABLE_RENAME = cva6_config_pkg::CVA6ConfigRenameEn;
localparam ISSUE_WIDTH = 1;
// amount of pipeline registers inserted for load/store return path
@@ -166,13 +166,13 @@ package ariane_pkg;
localparam bit RVF = (riscv::IS_XLEN64 | riscv::IS_XLEN32) & riscv::FPU_EN; // Is F extension enabled for both 32 Bit and 64 bit CPU
localparam bit RVD = (riscv::IS_XLEN64 ? 1:0) & riscv::FPU_EN; // Is D extension enabled for only 64 bit CPU
`endif
- localparam bit RVA = 1'b1; // Is A extension enabled
+ localparam bit RVA = cva6_config_pkg::CVA6ConfigAExtEn; // Is A extension enabled
// Transprecision floating-point extensions configuration
- localparam bit XF16 = 1'b0; // Is half-precision float extension (Xf16) enabled
- localparam bit XF16ALT = 1'b0; // Is alternative half-precision float extension (Xf16alt) enabled
- localparam bit XF8 = 1'b0; // Is quarter-precision float extension (Xf8) enabled
- localparam bit XFVEC = 1'b0; // Is vectorial float extension (Xfvec) enabled
+ localparam bit XF16 = cva6_config_pkg::CVA6ConfigF16En; // Is half-precision float extension (Xf16) enabled
+ localparam bit XF16ALT = cva6_config_pkg::CVA6ConfigF16AltEn; // Is alternative half-precision float extension (Xf16alt) enabled
+ localparam bit XF8 = cva6_config_pkg::CVA6ConfigF8En; // Is quarter-precision float extension (Xf8) enabled
+ localparam bit XFVEC = cva6_config_pkg::CVA6ConfigFVecEn; // Is vectorial float extension (Xfvec) enabled
// Transprecision float unit
localparam int unsigned LAT_COMP_FP32 = 'd2;
@@ -301,6 +301,11 @@ package ariane_pkg;
localparam int unsigned INSTR_PER_FETCH = RVC == 1'b1 ? (FETCH_WIDTH / 16) : 1;
localparam int unsigned LOG2_INSTR_PER_FETCH = RVC == 1'b1 ? $clog2(ariane_pkg::INSTR_PER_FETCH) : 1;
+ // ---------------
+ // Enable BITMANIP
+ // ---------------
+ localparam bit BITMANIP = 1'b1;
+
// Only use struct when signals have same direction
// exception
typedef struct packed {
@@ -430,11 +435,14 @@ package ariane_pkg;
localparam int unsigned ICACHE_SET_ASSOC = `CONFIG_L1I_ASSOCIATIVITY;
localparam int unsigned ICACHE_INDEX_WIDTH = $clog2(`CONFIG_L1I_SIZE / ICACHE_SET_ASSOC);
localparam int unsigned ICACHE_TAG_WIDTH = riscv::PLEN - ICACHE_INDEX_WIDTH;
+ localparam int unsigned ICACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : 128; // in bit
// D$
localparam int unsigned DCACHE_LINE_WIDTH = `CONFIG_L1D_CACHELINE_WIDTH;
localparam int unsigned DCACHE_SET_ASSOC = `CONFIG_L1D_ASSOCIATIVITY;
localparam int unsigned DCACHE_INDEX_WIDTH = $clog2(`CONFIG_L1D_SIZE / DCACHE_SET_ASSOC);
localparam int unsigned DCACHE_TAG_WIDTH = riscv::PLEN - DCACHE_INDEX_WIDTH;
+ localparam int unsigned DCACHE_USER_LINE_WIDTH = (AXI_USER_WIDTH == 1) ? 4 : 128; // in bit
+ localparam int unsigned DCACHE_USER_WIDTH = DATA_USER_WIDTH;
`else
// I$
localparam int unsigned CONFIG_L1I_SIZE = 16*1024;
@@ -457,7 +465,8 @@ package ariane_pkg;
// ---------------
// EX Stage
// ---------------
- typedef enum logic [6:0] { // basic ALU op
+
+ typedef enum logic [7:0] { // basic ALU op
ADD, SUB, ADDW, SUBW,
// logic operations
XORL, ORL, ANDL,
@@ -494,7 +503,29 @@ package ariane_pkg;
// Vectorial Floating-Point Instructions that don't directly map onto the scalar ones
VFMIN, VFMAX, VFSGNJ, VFSGNJN, VFSGNJX, VFEQ, VFNE, VFLT, VFGE, VFLE, VFGT, VFCPKAB_S, VFCPKCD_S, VFCPKAB_D, VFCPKCD_D,
// Offload Instructions to be directed into cv_x_if
- OFFLOAD
+ OFFLOAD,
+ // Or-Combine and REV8
+ ORCB, REV8,
+ // Bitwise Rotation
+ ROL, ROLW, ROR, RORI, RORIW, RORW,
+ // Sign and Zero Extend
+ SEXTB, SEXTH, ZEXTH,
+ // Count population
+ CPOP, CPOPW,
+ // Count Leading/Training Zeros
+ CLZ, CLZW, CTZ, CTZW,
+ // Carry less multiplication Op's
+ CLMUL, CLMULH, CLMULR,
+ // Single bit instructions Op's
+ BCLR, BCLRI, BEXT, BEXTI, BINV, BINVI, BSET, BSETI,
+ // Integer minimum/maximum
+ MAX, MAXU, MIN, MINU,
+ // Shift with Add Unsigned Word and Unsigned Word Op's (Bitmanip)
+ SH1ADDUW, SH2ADDUW, SH3ADDUW, ADDUW, SLLIUW,
+ // Shift with Add (Bitmanip)
+ SH1ADD, SH2ADD, SH3ADD,
+ // Bitmanip Logical with negate op (Bitmanip)
+ ANDN, ORN, XNOR
} fu_op;
typedef struct packed {
diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv
new file mode 100644
index 0000000000..a9b2cb5efc
--- /dev/null
+++ b/core/include/cv32a60x_config_pkg.sv
@@ -0,0 +1,32 @@
+// Copyright 2022 Thales DIS design services SAS
+//
+// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
+// You may obtain a copy of the License at https://solderpad.org/licenses/
+//
+// Original Author: Jean-Roch COULON (jean-roch.coulon@thalesgroup.com)
+
+
+package cva6_config_pkg;
+
+ localparam CVA6ConfigXlen = 32;
+
+ localparam CVA6ConfigFpuEn = 0;
+ localparam CVA6ConfigF16En = 0;
+ localparam CVA6ConfigF16AltEn = 0;
+ localparam CVA6ConfigF8En = 0;
+ localparam CVA6ConfigFVecEn = 0;
+
+ localparam CVA6ConfigCvxifEn = 1;
+ localparam CVA6ConfigCExtEn = 1;
+ localparam CVA6ConfigAExtEn = 0;
+
+ localparam CVA6ConfigFetchUserEn = 0;
+ localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
+ localparam CVA6ConfigDataUserEn = 0;
+ localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
+
+ localparam CVA6ConfigRenameEn = 0;
+
+endpackage
diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv
index 40e0b9c18d..cc44603530 100644
--- a/core/include/cv32a6_imac_sv0_config_pkg.sv
+++ b/core/include/cv32a6_imac_sv0_config_pkg.sv
@@ -11,13 +11,22 @@
package cva6_config_pkg;
localparam CVA6ConfigXlen = 32;
+
localparam CVA6ConfigFpuEn = 0;
+ localparam CVA6ConfigF16En = 0;
+ localparam CVA6ConfigF16AltEn = 0;
+ localparam CVA6ConfigF8En = 0;
+ localparam CVA6ConfigFVecEn = 0;
+
localparam CVA6ConfigCvxifEn = 0;
localparam CVA6ConfigCExtEn = 1;
+ localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigFetchUserEn = 0;
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
localparam CVA6ConfigDataUserEn = 0;
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
+ localparam CVA6ConfigRenameEn = 0;
+
endpackage
diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv
index 40e0b9c18d..cc44603530 100644
--- a/core/include/cv32a6_imac_sv32_config_pkg.sv
+++ b/core/include/cv32a6_imac_sv32_config_pkg.sv
@@ -11,13 +11,22 @@
package cva6_config_pkg;
localparam CVA6ConfigXlen = 32;
+
localparam CVA6ConfigFpuEn = 0;
+ localparam CVA6ConfigF16En = 0;
+ localparam CVA6ConfigF16AltEn = 0;
+ localparam CVA6ConfigF8En = 0;
+ localparam CVA6ConfigFVecEn = 0;
+
localparam CVA6ConfigCvxifEn = 0;
localparam CVA6ConfigCExtEn = 1;
+ localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigFetchUserEn = 0;
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
localparam CVA6ConfigDataUserEn = 0;
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
+ localparam CVA6ConfigRenameEn = 0;
+
endpackage
diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv
index b5bdad9403..8f92b57231 100644
--- a/core/include/cv32a6_imafc_sv32_config_pkg.sv
+++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv
@@ -11,13 +11,22 @@
package cva6_config_pkg;
localparam CVA6ConfigXlen = 32;
+
localparam CVA6ConfigFpuEn = 1;
+ localparam CVA6ConfigF16En = 0;
+ localparam CVA6ConfigF16AltEn = 0;
+ localparam CVA6ConfigF8En = 0;
+ localparam CVA6ConfigFVecEn = 0;
+
localparam CVA6ConfigCvxifEn = 0;
localparam CVA6ConfigCExtEn = 1;
+ localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigFetchUserEn = 0;
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
localparam CVA6ConfigDataUserEn = 0;
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
+ localparam CVA6ConfigRenameEn = 0;
+
endpackage
diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv
index 7af57cb154..7693289921 100644
--- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv
+++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv
@@ -11,13 +11,22 @@
package cva6_config_pkg;
localparam CVA6ConfigXlen = 64;
+
localparam CVA6ConfigFpuEn = 1;
+ localparam CVA6ConfigF16En = 0;
+ localparam CVA6ConfigF16AltEn = 0;
+ localparam CVA6ConfigF8En = 0;
+ localparam CVA6ConfigFVecEn = 0;
+
localparam CVA6ConfigCvxifEn = 1;
localparam CVA6ConfigCExtEn = 1;
+ localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigFetchUserEn = 0;
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
localparam CVA6ConfigDataUserEn = 0;
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
+ localparam CVA6ConfigRenameEn = 0;
+
endpackage
diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv
index f1d56072a6..da40923c5b 100644
--- a/core/include/riscv_pkg.sv
+++ b/core/include/riscv_pkg.sv
@@ -398,7 +398,9 @@ package riscv;
CSR_MIMPID = 12'hF13,
CSR_MHARTID = 12'hF14,
CSR_MCYCLE = 12'hB00,
+ CSR_MCYCLEH = 12'hB80,
CSR_MINSTRET = 12'hB02,
+ CSR_MINSTRETH = 12'hB82,
// Performance counters (Machine Mode)
CSR_ML1_ICACHE_MISS = 12'hB03, // L1 Instr Cache Miss
CSR_ML1_DCACHE_MISS = 12'hB04, // L1 Data Cache Miss
@@ -445,8 +447,11 @@ package riscv;
CSR_DSCRATCH1 = 12'h7b3, // optional
// Counters and Timers (User Mode - R/O Shadows)
CSR_CYCLE = 12'hC00,
+ CSR_CYCLEH = 12'hC80,
CSR_TIME = 12'hC01,
+ CSR_TIMEH = 12'hC81,
CSR_INSTRET = 12'hC02,
+ CSR_INSTRETH = 12'hC82,
// Performance counters (User Mode - R/O Shadows)
CSR_L1_ICACHE_MISS = 12'hC03, // L1 Instr Cache Miss
CSR_L1_DCACHE_MISS = 12'hC04, // L1 Data Cache Miss
diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv
index 2edfc6b757..d50eeee0a7 100644
--- a/core/issue_read_operands.sv
+++ b/core/issue_read_operands.sv
@@ -212,11 +212,12 @@ module issue_read_operands import ariane_pkg::*; #(
operand_b_n = operand_b_regfile;
// immediates are the third operands in the store case
// for FP operations, the imm field can also be the third operand from the regfile
- if (NR_RGPR_PORTS == 3)
+ if (NR_RGPR_PORTS == 3) begin
imm_n = is_imm_fpr(issue_instr_i.op) ? {{riscv::XLEN-FLEN{1'b0}}, operand_c_regfile} :
issue_instr_i.op == OFFLOAD ? operand_c_regfile : issue_instr_i.result;
- else
+ end else begin
imm_n = is_imm_fpr(issue_instr_i.op) ? {{riscv::XLEN-FLEN{1'b0}}, operand_c_regfile} : issue_instr_i.result;
+ end
trans_id_n = issue_instr_i.trans_id;
fu_n = issue_instr_i.fu;
operator_n = issue_instr_i.op;
@@ -276,12 +277,15 @@ module issue_read_operands import ariane_pkg::*; #(
// we do not want to issue this instruction
if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin
case (issue_instr_i.fu)
- ALU:
+ ALU: begin
alu_valid_q <= 1'b1;
- CTRL_FLOW:
+ end
+ CTRL_FLOW: begin
branch_valid_q <= 1'b1;
- MULT:
+ end
+ MULT: begin
mult_valid_q <= 1'b1;
+ end
FPU : begin
fpu_valid_q <= 1'b1;
fpu_fmt_q <= orig_instr.rftype.fmt; // fmt bits from instruction
@@ -292,10 +296,12 @@ module issue_read_operands import ariane_pkg::*; #(
fpu_fmt_q <= orig_instr.rvftype.vfmt; // vfmt bits from instruction
fpu_rm_q <= {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction
end
- LOAD, STORE:
+ LOAD, STORE: begin
lsu_valid_q <= 1'b1;
- CSR:
+ end
+ CSR: begin
csr_valid_q <= 1'b1;
+ end
default:;
endcase
end
@@ -443,7 +449,7 @@ module issue_read_operands import ariane_pkg::*; #(
.raddr_i ( fp_raddr_pack ),
.rdata_o ( fprdata ),
.waddr_i ( waddr_pack ),
- .wdata_i ( wdata_pack ),
+ .wdata_i ( fp_wdata_pack ),
.we_i ( we_fpr_i ),
.*
);
diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv
index 609a09d6bb..acda1f44af 100644
--- a/core/load_store_unit.sv
+++ b/core/load_store_unit.sv
@@ -462,107 +462,3 @@ module load_store_unit import ariane_pkg::*; #(
endmodule
-// ------------------
-// LSU Control
-// ------------------
-// The LSU consists of two independent block which share a common address translation block.
-// The one block is the load unit, the other one is the store unit. They will signal their readiness
-// with separate signals. If they are not ready the LSU control should keep the last applied signals stable.
-// Furthermore it can be the case that another request for one of the two store units arrives in which case
-// the LSU control should sample it and store it for later application to the units. It does so, by storing it in a
-// two element FIFO. This is necessary as we only know very late in the cycle whether the load/store will succeed (address check,
-// TLB hit mainly). So we better unconditionally allow another request to arrive and store this request in case we need to.
-module lsu_bypass import ariane_pkg::*; (
- input logic clk_i,
- input logic rst_ni,
- input logic flush_i,
-
- input lsu_ctrl_t lsu_req_i,
- input logic lsu_req_valid_i,
- input logic pop_ld_i,
- input logic pop_st_i,
-
- output lsu_ctrl_t lsu_ctrl_o,
- output logic ready_o
- );
-
- lsu_ctrl_t [1:0] mem_n, mem_q;
- logic read_pointer_n, read_pointer_q;
- logic write_pointer_n, write_pointer_q;
- logic [1:0] status_cnt_n, status_cnt_q;
-
- logic empty;
- assign empty = (status_cnt_q == 0);
- assign ready_o = empty;
-
- always_comb begin
- automatic logic [1:0] status_cnt;
- automatic logic write_pointer;
- automatic logic read_pointer;
-
- status_cnt = status_cnt_q;
- write_pointer = write_pointer_q;
- read_pointer = read_pointer_q;
-
- mem_n = mem_q;
- // we've got a valid LSU request
- if (lsu_req_valid_i) begin
- mem_n[write_pointer_q] = lsu_req_i;
- write_pointer++;
- status_cnt++;
- end
-
- if (pop_ld_i) begin
- // invalidate the result
- mem_n[read_pointer_q].valid = 1'b0;
- read_pointer++;
- status_cnt--;
- end
-
- if (pop_st_i) begin
- // invalidate the result
- mem_n[read_pointer_q].valid = 1'b0;
- read_pointer++;
- status_cnt--;
- end
-
- if (pop_st_i && pop_ld_i)
- mem_n = '0;
-
- if (flush_i) begin
- status_cnt = '0;
- write_pointer = '0;
- read_pointer = '0;
- mem_n = '0;
- end
- // default assignments
- read_pointer_n = read_pointer;
- write_pointer_n = write_pointer;
- status_cnt_n = status_cnt;
- end
-
- // output assignment
- always_comb begin : output_assignments
- if (empty) begin
- lsu_ctrl_o = lsu_req_i;
- end else begin
- lsu_ctrl_o = mem_q[read_pointer_q];
- end
- end
-
- // registers
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (~rst_ni) begin
- mem_q <= '0;
- status_cnt_q <= '0;
- write_pointer_q <= '0;
- read_pointer_q <= '0;
- end else begin
- mem_q <= mem_n;
- status_cnt_q <= status_cnt_n;
- write_pointer_q <= write_pointer_n;
- read_pointer_q <= read_pointer_n;
- end
- end
-endmodule
-
diff --git a/core/lsu_bypass.sv b/core/lsu_bypass.sv
new file mode 100644
index 0000000000..fd60e4485e
--- /dev/null
+++ b/core/lsu_bypass.sv
@@ -0,0 +1,119 @@
+// Copyright 2018 ETH Zurich and University of Bologna.
+// Copyright and related rights are licensed under the Solderpad Hardware
+// License, Version 0.51 (the "License"); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+// or agreed to in writing, software, hardware and materials distributed under
+// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+//
+// Author: Florian Zaruba, ETH Zurich
+// Date: 19.04.2017
+// Description: Load Store Unit, handles address calculation and memory interface signals
+
+
+// ------------------
+// LSU Control
+// ------------------
+// The LSU consists of two independent block which share a common address translation block.
+// The one block is the load unit, the other one is the store unit. They will signal their readiness
+// with separate signals. If they are not ready the LSU control should keep the last applied signals stable.
+// Furthermore it can be the case that another request for one of the two store units arrives in which case
+// the LSU control should sample it and store it for later application to the units. It does so, by storing it in a
+// two element FIFO. This is necessary as we only know very late in the cycle whether the load/store will succeed (address check,
+// TLB hit mainly). So we better unconditionally allow another request to arrive and store this request in case we need to.
+module lsu_bypass import ariane_pkg::*; (
+ input logic clk_i,
+ input logic rst_ni,
+ input logic flush_i,
+
+ input lsu_ctrl_t lsu_req_i,
+ input logic lsu_req_valid_i,
+ input logic pop_ld_i,
+ input logic pop_st_i,
+
+ output lsu_ctrl_t lsu_ctrl_o,
+ output logic ready_o
+ );
+
+ lsu_ctrl_t [1:0] mem_n, mem_q;
+ logic read_pointer_n, read_pointer_q;
+ logic write_pointer_n, write_pointer_q;
+ logic [1:0] status_cnt_n, status_cnt_q;
+
+ logic empty;
+ assign empty = (status_cnt_q == 0);
+ assign ready_o = empty;
+
+ always_comb begin
+ automatic logic [1:0] status_cnt;
+ automatic logic write_pointer;
+ automatic logic read_pointer;
+
+ status_cnt = status_cnt_q;
+ write_pointer = write_pointer_q;
+ read_pointer = read_pointer_q;
+
+ mem_n = mem_q;
+ // we've got a valid LSU request
+ if (lsu_req_valid_i) begin
+ mem_n[write_pointer_q] = lsu_req_i;
+ write_pointer++;
+ status_cnt++;
+ end
+
+ if (pop_ld_i) begin
+ // invalidate the result
+ mem_n[read_pointer_q].valid = 1'b0;
+ read_pointer++;
+ status_cnt--;
+ end
+
+ if (pop_st_i) begin
+ // invalidate the result
+ mem_n[read_pointer_q].valid = 1'b0;
+ read_pointer++;
+ status_cnt--;
+ end
+
+ if (pop_st_i && pop_ld_i)
+ mem_n = '0;
+
+ if (flush_i) begin
+ status_cnt = '0;
+ write_pointer = '0;
+ read_pointer = '0;
+ mem_n = '0;
+ end
+ // default assignments
+ read_pointer_n = read_pointer;
+ write_pointer_n = write_pointer;
+ status_cnt_n = status_cnt;
+ end
+
+ // output assignment
+ always_comb begin : output_assignments
+ if (empty) begin
+ lsu_ctrl_o = lsu_req_i;
+ end else begin
+ lsu_ctrl_o = mem_q[read_pointer_q];
+ end
+ end
+
+ // registers
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (~rst_ni) begin
+ mem_q <= '0;
+ status_cnt_q <= '0;
+ write_pointer_q <= '0;
+ read_pointer_q <= '0;
+ end else begin
+ mem_q <= mem_n;
+ status_cnt_q <= status_cnt_n;
+ write_pointer_q <= write_pointer_n;
+ read_pointer_q <= read_pointer_n;
+ end
+ end
+endmodule
+
diff --git a/core/mmu_sv39/mmu.sv b/core/mmu_sv39/mmu.sv
index f98fdeff72..ba8174fcb2 100644
--- a/core/mmu_sv39/mmu.sv
+++ b/core/mmu_sv39/mmu.sv
@@ -207,7 +207,7 @@ module mmu import ariane_pkg::*; #(
// 2. We got an access error because of insufficient permissions -> throw an access exception
icache_areq_o.fetch_exception = '0;
// Check whether we are allowed to access this memory region from a fetch perspective
- iaccess_err = icache_areq_i.fetch_req && (((priv_lvl_i == riscv::PRIV_LVL_U) && ~itlb_content.u)
+ iaccess_err = icache_areq_i.fetch_req && enable_translation_i && (((priv_lvl_i == riscv::PRIV_LVL_U) && ~itlb_content.u)
|| ((priv_lvl_i == riscv::PRIV_LVL_S) && itlb_content.u));
// MMU enabled: address from TLB, request delayed until hit. Error when TLB
@@ -255,12 +255,12 @@ module mmu import ariane_pkg::*; #(
icache_areq_o.fetch_valid = ptw_error | ptw_access_exception;
if (ptw_error) icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, {{riscv::XLEN-riscv::VLEN{1'b0}}, update_vaddr}, 1'b1};
// TODO(moschn,zarubaf): What should the value of tval be in this case?
- else icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, {{riscv::XLEN-riscv::VLEN{1'b0}}, ptw_bad_paddr}, 1'b1};
+ else icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, {{riscv::XLEN-riscv::PLEN{1'b0}}, ptw_bad_paddr}, 1'b1};
end
end
// if it didn't match any execute region throw an `Instruction Access Fault`
// or: if we are not translating, check PMPs immediately on the paddr
- if (!match_any_execute_region || (!enable_translation_i && !pmp_instr_allow)) begin
+ if ((!match_any_execute_region && !ptw_error) || (!enable_translation_i && !pmp_instr_allow)) begin
icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, {{riscv::XLEN-riscv::PLEN{1'b0}}, icache_areq_o.fetch_paddr}, 1'b1};
end
end
@@ -326,8 +326,8 @@ module mmu import ariane_pkg::*; #(
// Check if the User flag is set, then we may only access it in supervisor mode
// if SUM is enabled
- daccess_err = (ld_st_priv_lvl_i == riscv::PRIV_LVL_S && !sum_i && dtlb_pte_q.u) || // SUM is not set and we are trying to access a user page in supervisor mode
- (ld_st_priv_lvl_i == riscv::PRIV_LVL_U && !dtlb_pte_q.u); // this is not a user page but we are in user mode and trying to access it
+ daccess_err = en_ld_st_translation_i && ((ld_st_priv_lvl_i == riscv::PRIV_LVL_S && !sum_i && dtlb_pte_q.u) || // SUM is not set and we are trying to access a user page in supervisor mode
+ (ld_st_priv_lvl_i == riscv::PRIV_LVL_U && !dtlb_pte_q.u)); // this is not a user page but we are in user mode and trying to access it
// translation is enabled and no misaligned exception occurred
if (en_ld_st_translation_i && !misaligned_ex_q.valid) begin
lsu_valid_o = 1'b0;
@@ -397,8 +397,12 @@ module mmu import ariane_pkg::*; #(
if (ptw_access_exception) begin
// an error makes the translation valid
lsu_valid_o = 1'b1;
- // the page table walker can only throw page faults
- lsu_exception_o = {riscv::LD_ACCESS_FAULT, {{riscv::XLEN-riscv::PLEN{1'b0}}, ptw_bad_paddr}, 1'b1};
+ // Any fault of the page table walk should be based of the original access type
+ if (lsu_is_store_q) begin
+ lsu_exception_o = {riscv::ST_ACCESS_FAULT, {{riscv::XLEN-riscv::VLEN{1'b0}}, lsu_vaddr_n}, 1'b1};
+ end else begin
+ lsu_exception_o = {riscv::LD_ACCESS_FAULT, {{riscv::XLEN-riscv::VLEN{1'b0}}, lsu_vaddr_n}, 1'b1};
+ end
end
end
end
diff --git a/core/mult.sv b/core/mult.sv
index a8814d76dc..5a3c3882f9 100644
--- a/core/mult.sv
+++ b/core/mult.sv
@@ -22,7 +22,9 @@ module mult import ariane_pkg::*; (
logic div_valid_op;
logic mul_valid_op;
// Input Arbitration
- assign mul_valid_op = ~flush_i && mult_valid_i && (fu_data_i.operator inside { MUL, MULH, MULHU, MULHSU, MULW });
+
+ assign mul_valid_op = ~flush_i && mult_valid_i && (fu_data_i.operator inside { MUL, MULH, MULHU, MULHSU, MULW, CLMUL, CLMULH, CLMULR });
+
assign div_valid_op = ~flush_i && mult_valid_i && (fu_data_i.operator inside { DIV, DIVU, DIVW, DIVUW, REM, REMU, REMW, REMUW });
// ---------------------
diff --git a/core/multiplier.sv b/core/multiplier.sv
index 893dbc9e41..a7d871bf60 100644
--- a/core/multiplier.sv
+++ b/core/multiplier.sv
@@ -28,6 +28,39 @@ module multiplier import ariane_pkg::*; (
output logic mult_ready_o,
output logic [TRANS_ID_BITS-1:0] mult_trans_id_o
);
+ // Carry-less multiplication
+ logic [riscv::XLEN-1:0] clmul_q, clmul_d, clmulr_q, clmulr_d, operand_a, operand_b, operand_a_rev, operand_b_rev;
+ logic clmul_rmode, clmul_hmode;
+
+ if (ariane_pkg::BITMANIP) begin : gen_bitmanip
+ // checking for clmul_rmode and clmul_hmode
+ assign clmul_rmode = (operator_i == CLMULR);
+ assign clmul_hmode = (operator_i == CLMULH);
+
+ // operand_a and b reverse generator
+ for (genvar i = 0; i < riscv::XLEN; i++) begin
+ assign operand_a_rev[i] = operand_a_i[(riscv::XLEN-1) -i];
+ assign operand_b_rev[i] = operand_b_i[(riscv::XLEN-1) -i];
+ end
+
+ // operand_a and operand_b selection
+ assign operand_a = (clmul_rmode | clmul_hmode) ? operand_a_rev : operand_a_i;
+ assign operand_b = (clmul_rmode | clmul_hmode) ? operand_b_rev : operand_b_i;
+
+ // implementation
+ always_comb begin
+ clmul_d = '0;
+ for (int i = 0; i <= riscv::XLEN; i++) begin
+ clmul_d = ((operand_b >> i) & 1) ? clmul_d ^ (operand_a << i) : clmul_d;
+ end
+ end
+
+ // clmulr + clmulh result generator
+ for (genvar i = 0; i < riscv::XLEN; i++) begin
+ assign clmulr_d[i] = clmul_d[(riscv::XLEN-1)-i];
+ end
+ end
+
// Pipeline register
logic [TRANS_ID_BITS-1:0] trans_id_q;
logic mult_valid_q;
@@ -43,10 +76,7 @@ module multiplier import ariane_pkg::*; (
assign mult_trans_id_o = trans_id_q;
assign mult_ready_o = 1'b1;
- assign mult_valid = mult_valid_i && (operator_i inside {MUL, MULH, MULHU, MULHSU, MULW});
- // datapath
- logic [riscv::XLEN*2-1:0] mult_result;
- assign mult_result = $signed({operand_a_i[riscv::XLEN-1] & sign_a, operand_a_i}) * $signed({operand_b_i[riscv::XLEN-1] & sign_b, operand_b_i});
+ assign mult_valid = mult_valid_i && (operator_i inside {MUL, MULH, MULHU, MULHSU, MULW, CLMUL, CLMULH, CLMULR});
// Sign Select MUX
always_comb begin
@@ -74,15 +104,29 @@ module multiplier import ariane_pkg::*; (
assign operator_d = operator_i;
+
always_comb begin : p_selmux
unique case (operator_q)
MULH, MULHU, MULHSU: result_o = mult_result_q[riscv::XLEN*2-1:riscv::XLEN];
MULW: result_o = sext32(mult_result_q[31:0]);
+ CLMUL: result_o = clmul_q;
+ CLMULH: result_o = clmulr_q >> 1;
+ CLMULR: result_o = clmulr_q;
// MUL performs an XLEN-bit×XLEN-bit multiplication and places the lower XLEN bits in the destination register
default: result_o = mult_result_q[riscv::XLEN-1:0];// including MUL
endcase
end
-
+ if (ariane_pkg::BITMANIP) begin
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (~rst_ni) begin
+ clmul_q <= '0;
+ clmulr_q <= '0;
+ end else begin
+ clmul_q <= clmul_d;
+ clmulr_q <= clmulr_d;
+ end
+ end
+ end
// -----------------------
// Output pipeline register
// -----------------------
diff --git a/core/perf_counters.sv b/core/perf_counters.sv
index fa43ec5522..c52bceb1e7 100644
--- a/core/perf_counters.sv
+++ b/core/perf_counters.sv
@@ -108,7 +108,12 @@ module perf_counters import ariane_pkg::*; (
end
// write after read
- data_o = perf_counter_q[{RegOffset,addr_i}];
+ if ({RegOffset,addr_i} >= riscv::CSR_ML1_ICACHE_MISS && {RegOffset,addr_i} <= riscv::CSR_MIF_EMPTY) begin
+ data_o = perf_counter_q[{RegOffset,addr_i}];
+ end else begin
+ // unimplemented counters are read-only 0
+ data_o = '0;
+ end
if (we_i) begin
perf_counter_d[{RegOffset,addr_i}] = data_i;
end
diff --git a/core/re_name.sv b/core/re_name.sv
index bfcf644538..eb0c336295 100644
--- a/core/re_name.sv
+++ b/core/re_name.sv
@@ -69,9 +69,9 @@ module re_name import ariane_pkg::*; (
issue_instr_o.rs2 = { ENABLE_RENAME & name_bit_rs2, issue_instr_i.rs2[4:0] };
// re-name the third operand in imm if it's actually an operand
- if (is_imm_fpr(issue_instr_i.op))
+ if (is_imm_fpr(issue_instr_i.op) || (issue_instr_i.op == OFFLOAD && ariane_pkg::NR_RGPR_PORTS == 3)) begin
issue_instr_o.result = { ENABLE_RENAME & name_bit_rs3, issue_instr_i.result[4:0]};
-
+ end
// re-name the destination register
issue_instr_o.rd = { ENABLE_RENAME & name_bit_rd, issue_instr_i.rd[4:0] };
diff --git a/corev_apu/bootrom/Makefile b/corev_apu/bootrom/Makefile
index 094481d14f..eca0b7333b 100644
--- a/corev_apu/bootrom/Makefile
+++ b/corev_apu/bootrom/Makefile
@@ -3,7 +3,7 @@ bootrom_img = bootrom.img bootrom.sv
RISCV_GCC?=riscv64-unknown-elf-gcc
RISCV_OBJCOPY?=riscv64-unknown-elf-objcopy
DTB=ariane.dtb
-PYTHON=python
+PYTHON=python3
all: $(bootrom_img)
@@ -14,7 +14,7 @@ all: $(bootrom_img)
$(RISCV_OBJCOPY) -O binary $< $@
%.elf: %.S linker.ld $(DTB)
- $(RISCV_GCC) -Tlinker.ld -march=rv32i -mabi=ilp32 $< -nostdlib -static -Wl,--no-gc-sections -o $@
+ $(RISCV_GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@
%.dtb: %.dts
dtc -I dts $< -O dtb -o $@
diff --git a/corev_apu/bootrom/gen_rom.py b/corev_apu/bootrom/gen_rom.py
index bb2abc356b..eed0d34c92 100755
--- a/corev_apu/bootrom/gen_rom.py
+++ b/corev_apu/bootrom/gen_rom.py
@@ -80,8 +80,8 @@
def read_bin():
with open(filename + ".img", 'rb') as f:
- rom = binascii.hexlify(f.read())
- rom = map(''.join, zip(rom[::2], rom[1::2]))
+ rom = str(binascii.hexlify(f.read()))
+ rom = list(map(''.join, zip(rom[2::2], rom[3::2])))
# align to 64 bit
diff --git a/corev_apu/fpga/Makefile b/corev_apu/fpga/Makefile
index b894e5d1b2..678e224438 100644
--- a/corev_apu/fpga/Makefile
+++ b/corev_apu/fpga/Makefile
@@ -40,7 +40,7 @@ program:
$(VIVADO) $(VIVADOFLAGS) -source scripts/program.tcl
clean:
- rm -rf *.log *.jou *.str *.mif *.xpr $(work-dir) ariane.cache ariane.hw ariane.ip_user_files
+ rm -rf *.log *.jou *.str *.mif *.xpr $(work-dir) ariane.cache ariane.hw ariane.ip_user_files scripts/vivado*
.PHONY:
clean
diff --git a/corev_apu/fpga/scripts/check_fpga_boot.sh b/corev_apu/fpga/scripts/check_fpga_boot.sh
new file mode 100644
index 0000000000..6be359c2c7
--- /dev/null
+++ b/corev_apu/fpga/scripts/check_fpga_boot.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Copyright 2022 Thales DIS design services SAS
+#
+# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
+# You may obtain a copy of the License at https://solderpad.org/licenses/
+#
+# Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com)
+
+
+BITSTREAM=../work-fpga/ariane_xilinx.bit
+
+if ! [ -n "$VIVADO_CMD" ]; then
+ echo "Error: VIVADO_CMD variable undefined.
+It most likely should be VIVADO_CMD=vivado_lab if you installed 2022's version of vivado."
+ return
+fi
+
+if [ -f "$BITSTREAM" ]; then
+ $VIVADO_CMD -mode batch -source program_genesys2.tcl &&\
+ python3 linux_boot.py
+fi
diff --git a/corev_apu/fpga/scripts/linux_boot.py b/corev_apu/fpga/scripts/linux_boot.py
new file mode 100644
index 0000000000..3ddf2b78cd
--- /dev/null
+++ b/corev_apu/fpga/scripts/linux_boot.py
@@ -0,0 +1,41 @@
+# Copyright 2022 Thales DIS design services SAS
+#
+# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
+# You may obtain a copy of the License at https://solderpad.org/licenses/
+#
+# Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com)
+
+# Check that linux boots by reading FPGA's UART.
+# If linux does not boot, this script will loop infinitely so it is recommended to kill it.
+# In Thales-CI it is killed from the timeout of the job triggering it.
+
+import sys
+import serial
+import os
+
+
+ser = serial.Serial(os.getenv("UART_SERIAL"), 115200, timeout=60)
+ser.baudrate = 115200
+
+with open("fpga_boot.rpt", "w") as f:
+ while True:
+ firstChar = ser.read().decode("utf-8")
+ line = ser.readline().decode("utf-8")
+ print(firstChar + line, end="")
+ f.write(firstChar + line)
+ # Check for command prompt
+ if firstChar == "#" and line == " ":
+ ser.write(b"uname -a\n")
+ elif firstChar == "" and line == "":
+ sys.exit(1)
+ break
+ if ("Linux buildroot" in firstChar + line) and (
+ "riscv" in firstChar + line
+ ):
+ break
+
+print("Successful Linux boot !")
+ser.close()
+sys.exit(0)
diff --git a/corev_apu/fpga/scripts/program_genesys2.tcl b/corev_apu/fpga/scripts/program_genesys2.tcl
new file mode 100644
index 0000000000..15b048ffcd
--- /dev/null
+++ b/corev_apu/fpga/scripts/program_genesys2.tcl
@@ -0,0 +1,20 @@
+# Copyright 2022 Thales DIS design services SAS
+#
+# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
+# You may obtain a copy of the License at https://solderpad.org/licenses/
+#
+# Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com)
+
+# Program Genesys2 FPGA board connected to $HW_SERVER_URL with bitstream ../work-fpga/ariane_xilinx.bit
+
+open_hw_manager
+# Connect to an HW_SERVER connected to the FPGA.
+# It is recommended to launch the hw_server before using this script to specify its URL.
+connect_hw_server -url $env(HW_SERVER_URL)
+open_hw_target
+current_hw_device [get_hw_devices xc7k325t_0]
+set_property PROGRAM.FILE {../work-fpga/ariane_xilinx.bit} [get_hw_device xc7k325t_0]
+program_hw_devices [get_hw_devices xc7k325t_0]
+refresh_hw_device [lindex [get_hw_devices xc7k325t_0] 0]
diff --git a/corev_apu/openpiton/bootrom/linux/Makefile b/corev_apu/openpiton/bootrom/linux/Makefile
index 6c56dc9a40..ed4f985a70 100644
--- a/corev_apu/openpiton/bootrom/linux/Makefile
+++ b/corev_apu/openpiton/bootrom/linux/Makefile
@@ -2,7 +2,7 @@ UART_FREQ ?= 30000000
MAX_HARTS ?= 1
CROSSCOMPILE ?= riscv64-unknown-elf-
CC = ${CROSSCOMPILE}gcc
-PYTHON=python
+PYTHON=python3
CFLAGS = -DMAX_HARTS=$(MAX_HARTS) -DUART_FREQ=$(UART_FREQ) -Os -ggdb -march=rv64imac -mabi=lp64 -Wall -mcmodel=medany -mexplicit-relocs
CCASFLAGS = -mcmodel=medany -mexplicit-relocs
diff --git a/corev_apu/openpiton/bootrom/linux/src/main.c b/corev_apu/openpiton/bootrom/linux/src/main.c
index 528fab8bf7..2e5a9dc4a1 100644
--- a/corev_apu/openpiton/bootrom/linux/src/main.c
+++ b/corev_apu/openpiton/bootrom/linux/src/main.c
@@ -11,7 +11,7 @@ int main()
print_uart("sd initialized!\r\n");
- int res = gpt_find_boot_partition((uint8_t *)0x80000000UL, 2 * 16384);
+ int res = gpt_find_boot_partition((uint8_t *)0x80000000UL, 2 * 32768);
return 0;
}
@@ -19,4 +19,4 @@ int main()
void handle_trap(void)
{
// print_uart("trap\r\n");
-}
\ No newline at end of file
+}
diff --git a/corev_apu/openpiton/riscv_peripherals.sv b/corev_apu/openpiton/riscv_peripherals.sv
index 701c08bb48..cb6cbfd7e8 100644
--- a/corev_apu/openpiton/riscv_peripherals.sv
+++ b/corev_apu/openpiton/riscv_peripherals.sv
@@ -24,6 +24,8 @@
// CLINT 0xfff1020000
// PLIC 0xfff1100000
//
+`include "register_interface/assign.svh"
+`include "register_interface/typedef.svh"
module riscv_peripherals #(
parameter int unsigned DataWidth = 64,
@@ -619,9 +621,10 @@ module riscv_peripherals #(
assign plic_master.ar_qos = '0;
assign plic_master.ar_region = '0;
-
- reg_intf::reg_intf_resp_d32 plic_resp;
- reg_intf::reg_intf_req_a32_d32 plic_req;
+ // define reg type according to REG_BUS above
+ `REG_BUS_TYPEDEF_ALL(plic, logic[31:0], logic[31:0], logic[3:0])
+ plic_req_t plic_req;
+ plic_rsp_t plic_resp;
enum logic [2:0] {Idle, WriteSecond, ReadSecond, WriteResp, ReadResp} state_d, state_q;
logic [31:0] rword_d, rword_q;
@@ -743,7 +746,10 @@ module riscv_peripherals #(
plic_top #(
.N_SOURCE ( NumSources ),
.N_TARGET ( 2*NumHarts ),
- .MAX_PRIO ( PlicMaxPriority )
+ .MAX_PRIO ( PlicMaxPriority ),
+ .reg_req_t ( plic_req_t ),
+ .reg_rsp_t ( plic_rsp_t )
+
) i_plic (
.clk_i,
.rst_ni,
diff --git a/corev_apu/tb/ariane_tb.cpp b/corev_apu/tb/ariane_tb.cpp
index afe6a807eb..8e210b2cc2 100644
--- a/corev_apu/tb/ariane_tb.cpp
+++ b/corev_apu/tb/ariane_tb.cpp
@@ -321,7 +321,7 @@ int main(int argc, char **argv) {
// Preload memory.
size_t mem_size = 0xFFFFFF;
memif.read(0x80000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram);
- // memif.read(0x84000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__gen_mem_user__DOT__i_ram_user__DOT__sram);
+ // memif.read(0x84000000, mem_size, (void *)top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem__DOT__gen_mem_user__DOT__i_tc_sram_wrapper_user__DOT__i_tc_sram__DOT__sram);
#ifndef DROMAJO
while (!dtm->done() && !jtag->done()) {
diff --git a/corev_apu/tb/ariane_tb.sv b/corev_apu/tb/ariane_tb.sv
index 256cc1b50f..6c37e48d0a 100644
--- a/corev_apu/tb/ariane_tb.sv
+++ b/corev_apu/tb/ariane_tb.sv
@@ -20,7 +20,7 @@ import uvm_pkg::*;
`include "uvm_macros.svh"
`define MAIN_MEM(P) dut.i_sram.gen_cut[0].gen_mem.i_tc_sram_wrapper.i_tc_sram.init_val[(``P``)]
-// `define USER_MEM(P) dut.i_sram.gen_user_cut[0].gen_user_mem.i_ram_user.sram[(``P``)]
+// `define USER_MEM(P) dut.i_sram.gen_cut[0].gen_mem.gen_mem_user.i_tc_sram_wrapper_user.i_tc_sram.init_val[(``P``)]
import "DPI-C" function read_elf(input string filename);
import "DPI-C" function byte get_section(output longint address, output longint len);
diff --git a/docs/specifications/cva6_requirement_specification.rst b/docs/specifications/cva6_requirement_specification.rst
index 75cb4a475a..a0524ede49 100644
--- a/docs/specifications/cva6_requirement_specification.rst
+++ b/docs/specifications/cva6_requirement_specification.rst
@@ -2,7 +2,7 @@
CVA6 requirement specification
==============================
-Revision 1.0.0
+Revision 1.0.1
.. __license:
@@ -128,25 +128,39 @@ These are not in the scope of this specification:
.. __verified_configurations:
-Verified configurations
------------------------
-
-It is not possible to verify all possible combinations of parameters.
-Below is the list of configurations that will undergo verification in
-the project and their main parameters. The full list of parameters for
-each configuration will be detailed in the users’ guide.
-
-+--------------------+---------+---------+---------+---------+---------+---------+
-| Config# | Target | 32/64 | FPU | MMU | L1 D$ | L1 I$ |
-+====================+=========+=========+=========+=========+=========+=========+
-| cv32a6_imacf_sv32 | FPGA | CV32A6 | F | Sv32 | 32 kB | 16 kB |
-+--------------------+---------+---------+---------+---------+---------+---------+
-| cv32a6_imac_sv32 | FPGA | CV32A6 | None | Sv32 | 32 kB | 16 kB |
-+--------------------+---------+---------+---------+---------+---------+---------+
-| cv64a6_imacfd_sv39 | ASIC | CV64A6 | FD | Sv39 | 16 kB | 16 kB |
-+--------------------+---------+---------+---------+---------+---------+---------+
-| cv32a6_imac_sv0 | ASIC | CV32A6 | None | None | None | 4 kB |
-+--------------------+---------+---------+---------+---------+---------+---------+
+Initial Release
+---------------
+
+The CVA6 is highly configurable via SystemVerilog parameters.
+It is not practical to fully document and verify all possible combinations of parameters, so a set of "viable IP configurations" has been defined.
+The full list of parameters for this configuration will be detailed in the users’ guide.
+
+Below is the configuration of the first release of the CVA6.
+
++--------------------+---------+---------+------+-------+---------+---------+---------+---------+
+| Release ID | Target | ISA | XLEN | FPU | CV-X-IF | MMU | L1 D$ | L1 I$ |
++====================+=========+=========+======+=======+=========+=========+=========+=========+
+| CV32A60X | ASIC | IMC | 32 | No | Yes | Sv32 | None | 16 kB |
++--------------------+---------+---------+------+-------+---------+---------+---------+---------+
+
+
+Possible Future Releases
+------------------------
+
+Below is a proposed list of configurations that could undergo verification and their main parameters.
+The full list of parameters for these configurations will be detailed in the users’ guide if and when these configurations are fully verified.
+
++--------------------+---------+--------+------+-------+---------+---------+---------+---------+
+| Configuation ID | Target | ISA | XLEN | FPU | CV-X-IF | MMU | L1 D$ | L1 I$ |
++====================+=========+========+======+=======+=========+=========+=========+=========+
+| cv32a6_imacf_sv32 | FPGA | IMACF | 32 | Yes | TBD | Sv32 | 32 kB | 16 kB |
++--------------------+---------+--------+------+-------+---------+---------+---------+---------+
+| cv32a6_imac_sv32 | FPGA | IMAC | 32 | No | TBD | Sv32 | 32 kB | 16 kB |
++--------------------+---------+--------+------+-------+---------+---------+---------+---------+
+| cv64a6_imacfd_sv39 | ASIC | IMACFD | 64 | Yes | Yes | Sv39 | 16 kB | 16 kB |
++--------------------+---------+--------+------+-------+---------+---------+---------+---------+
+| cv32a6_imac_sv0 | ASIC | IMAC | 32 | No | Yes | None | None | 4 kB |
++--------------------+---------+--------+------+-------+---------+---------+---------+---------+
.. __references:
diff --git a/pd/synth/Makefile b/pd/synth/Makefile
index c8ac9a1eee..109b14447c 100644
--- a/pd/synth/Makefile
+++ b/pd/synth/Makefile
@@ -36,7 +36,7 @@ cva6_synth: pre_cva6_synth
@echo $(PERIOD)
@export $(EXPORT_LIST); $(DC_SHELL_PATH)/dc_shell -f ./cva6_synth.tcl -output synthesis_batch.log
python scripts/gate_analysis.py '$(DESIGN_NAME)/reports/$(PERIOD)/$(DESIGN_NAME)_$(TECH_NAME)_synth_area.rpt' $(NAND2_AREA)
- sed 's/tc_sram_256_64_00000008_00000001_00000001_none_0 gen/tc_sram gen/' ariane_synth.v > ariane_synth_modified.v
+ sed 's/tc_sram_wrapper_256_64_00000008_00000001_00000001_none_0 gen/tc_sram_wrapper gen/' ariane_synth.v > ariane_synth_modified.v
cva6_read:
@export $(EXPORT_LIST); $(DC_SHELL_PATH)/dc_shell -f cva6_read.tcl -gui
diff --git a/pd/synth/cva6_synth.tcl b/pd/synth/cva6_synth.tcl
index 4febfb50ce..5ebaa2487a 100644
--- a/pd/synth/cva6_synth.tcl
+++ b/pd/synth/cva6_synth.tcl
@@ -52,10 +52,10 @@ set_input_delay -clock main_clk -max $input_delay i_cva6/i_cache_subsystem/i_wt_
set_input_delay -clock main_clk -max $input_delay i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__data_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/rdata_o[*]
set_input_delay -clock main_clk -max $input_delay i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__tag_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/rdata_o[*]
-set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_wt_dcache/i_wt_dcache_mem/gen_tag_srams_*__i_tag_sram/addr_i[*]
-set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_wt_dcache/i_wt_dcache_mem/gen_data_banks_*__i_data_sram/addr_i[*]
-set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__data_sram/addr_i[*]
-set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__tag_sram/addr_i[*]
+set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_wt_dcache/i_wt_dcache_mem/gen_tag_srams_*__i_tag_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*]
+set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_wt_dcache/i_wt_dcache_mem/gen_data_banks_*__i_data_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*]
+set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__data_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*]
+set_output_delay $output_delay -max -clock main_clk i_cva6/i_cache_subsystem/i_cva6_icache/gen_sram_*__tag_sram/gen_cut_*__gen_mem_i_tc_sram_wrapper/addr_i[*]
# Check the current design for consistency
check_design -summary > ${DCRM_CHECK_DESIGN_REPORT}