From a5152b03a52354f8a1599c433d1a8252265078cc Mon Sep 17 00:00:00 2001 From: Guillaume Chauvon <94678394+Gchauvon@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:58:09 +0200 Subject: [PATCH] Add support for cv32a65x dedicated synthesis (#2178) --- .gitignore | 1 + .gitlab-ci.yml | 56 +- .gitlab-ci/expected_synth.yml | 2 +- .gitlab-ci/scripts/report_synth.py | 5 + Makefile | 13 +- common/local/util/sram.sv | 14 +- common/local/util/sram_cache.sv | 126 +++++ .../util/tc_sram_wrapper_cache_techno.sv | 64 +++ core/Flist.cva6 | 2 + core/Flist.cva6_gate | 47 +- core/cache_subsystem/cva6_icache.sv | 20 +- core/cache_subsystem/wt_dcache_mem.sv | 20 +- core/include/build_config_pkg.sv | 1 + core/include/config_pkg.sv | 3 + core/include/cv32a60x_config_pkg.sv | 1 + core/include/cv32a65x_config_pkg.sv | 9 +- core/include/cv32a6_embedded_config_pkg.sv | 1 + .../cv32a6_ima_sv32_fpga_config_pkg.sv | 1 + core/include/cv32a6_imac_sv0_config_pkg.sv | 1 + core/include/cv32a6_imac_sv32_config_pkg.sv | 1 + core/include/cv32a6_imafc_sv32_config_pkg.sv | 1 + .../cv64a6_imadfcv_sv39_polara_config_pkg.sv | 1 + core/include/cv64a6_imafdc_sv39_config_pkg.sv | 1 + .../cv64a6_imafdc_sv39_hpdcache_config_pkg.sv | 1 + ...cv64a6_imafdc_sv39_openpiton_config_pkg.sv | 1 + .../cv64a6_imafdc_sv39_wb_config_pkg.sv | 1 + .../include/cv64a6_imafdch_sv39_config_pkg.sv | 1 + .../cv64a6_imafdch_sv39_wb_config_pkg.sv | 1 + .../include/cv64a6_imafdcv_sv39_config_pkg.sv | 1 + core/include/cv64a6_mmu_config_pkg.sv | 1 + corev_apu/tb/ariane_gate_tb.sv | 480 ++++++++++++++++++ corev_apu/tb/ariane_tb.cpp | 8 + corev_apu/tb/ariane_tb.sv | 12 +- pd/synth/.gitignore | 5 +- pd/synth/Makefile | 40 +- ...che_sram_1rw_00000006_0000001a_00000040.sv | 60 +++ ...teenable_1rw_00000007_00000040_00000080.sv | 64 +++ pd/synth/scripts/dc_setup.tcl | 1 + pd/synth/scripts/dc_setup_filenames.tcl | 29 +- spyglass/reference_summary.rpt | 2 + util/init_gate.do | 1 + verif/sim/Makefile | 10 +- verif/sim/cva6.yaml | 9 +- verif/sim/link.ld | 31 ++ verif/tb/uvmt/cva6_tb_wrapper.sv | 8 +- 45 files changed, 1072 insertions(+), 86 deletions(-) create mode 100644 common/local/util/sram_cache.sv create mode 100644 common/local/util/tc_sram_wrapper_cache_techno.sv create mode 100644 corev_apu/tb/ariane_gate_tb.sv create mode 100644 pd/synth/hpdcache_sram_1rw_00000006_0000001a_00000040.sv create mode 100644 pd/synth/hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080.sv create mode 100644 util/init_gate.do diff --git a/.gitignore b/.gitignore index 95fe18e071..4ceeee9048 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ build/* /Bender.local build/ *.vcd +*.fsdb *.log *.out *.jou diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 407093de9e..98153edd01 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -228,24 +228,24 @@ asic-synthesis: DASHBOARD_JOB_DESCRIPTION: "Synthesis indicator with specific Techno" DASHBOARD_SORT_INDEX: 5 DASHBOARD_JOB_CATEGORY: "Synthesis" - INPUT_DELAY: "0.46" - OUTPUT_DELAY: "0.11" - PERIOD: "0.85" - DV_TARGET: "cv32a6_embedded" + PERIOD: "15" + DV_TARGET: cv32a65x script: - - echo $SYNTH_PERIOD - - echo $INPUT_DELAY - - echo $OUTPUT_DELAY - - echo $NAND2_AREA - - echo $FOUNDRY_PATH - echo $PERIOD - - echo $TECH_NAME - echo $DV_TARGET - source ./verif/sim/setup-env.sh + - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} + - cp -r ${SYNTH_SCRIPT_PATH}/cva6/ ../ + - git apply ${SYNTH_SCRIPT_PATH}/patches/*.patch - echo $SYN_DCSHELL_BASHRC; source $SYN_DCSHELL_BASHRC - - make -C pd/synth cva6_synth TARGET="$DV_TARGET" - - mv pd/synth/cva6_${DV_TARGET}_synth_modified.v artifacts/cva6_${DV_TARGET}_synth_modified.v - - python3 .gitlab-ci/scripts/report_synth.py pd/synth/cva6_${DV_TARGET}/reports/$PERIOD/cva6_$(echo $TECH_NAME)_synth_area.rpt pd/synth/synthesis_batch.log + - cp -r ${SYNTH_FLOW} ./ + - python3 ${SYNTH_SCRIPT_PATH}/scharm -p configs/modules/CVA6.yml --runner=True --compaign="only-synth" + - export NAND2_AREA=$(cat pd/synth/cva6_${DV_TARGET}/nand2area.txt) + - python3 .gitlab-ci/scripts/report_synth.py pd/synth/cva6_${DV_TARGET}/$PERIOD/reports/cva6_${DV_TARGET}_synth_area.rpt pd/synth/cva6_${DV_TARGET}/$PERIOD/reports/cva6_${DV_TARGET}_synthesis.log + - mv ${SYNTH_SCRIPT_PATH}/artifacts/ artifacts/artifacts_synth/ + - mv pd/synth/cva6_${DV_TARGET}/ artifacts/ + - mv pd/synth/cva6_${DV_TARGET}_synth.v artifacts/ + - mv pd/synth/cva6_${DV_TARGET}_synth.sdf artifacts/ fpga-build: extends: @@ -454,33 +454,41 @@ csr_embedded_tests: - mkdir -p artifacts/{reports,logs} - python3 .gitlab-ci/scripts/report_fail.py -smoke-gate: +simu-gate: + timeout : 4 hours extends: - .backend_test needs: - build_tools - asic-synthesis + parallel: + matrix: + - SIMU_PERIOD: ["20"] # 50 Mhz + PERIOD: ["15"] # 66 Mhz variables: - DV_TARGET: cv32a6_embedded - DASHBOARD_JOB_TITLE: "Smoke Gate $DV_TARGET" - DASHBOARD_JOB_DESCRIPTION: "Simple test to check netlist from ASIC synthesis" + DASHBOARD_JOB_TITLE: "Gate Level Simulation $DV_TARGET" + DASHBOARD_JOB_DESCRIPTION: "Tests to check netlist from ASIC synthesis and power consumption over different patterns" DASHBOARD_SORT_INDEX: 6 DASHBOARD_JOB_CATEGORY: "Post Synthesis" + DV_TARGET: cv32a65x + TARGET: $DV_TARGET script: - git -C verif/core-v-verif fetch --unshallow - mkdir -p tools - mv artifacts/tools/spike tools - echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC - - echo $LIB_VERILOG - - echo $FOUNDRY_PATH - echo $PERIOD - - echo $TECH_NAME - source ./verif/sim/setup-env.sh + - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} + - cp -r ${SYNTH_SCRIPT_PATH}/cva6/ ../ + - git apply ${SYNTH_SCRIPT_PATH}/patches/*.patch - source verif/regress/install-riscv-tests.sh - - mv artifacts/cva6_${DV_TARGET}_synth_modified.v pd/synth/cva6_${DV_TARGET}_synth_modified.v - - cd verif/sim - - make vcs_clean_all - - python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-lw --iss_yaml cva6.yaml --target $DV_TARGET --iss=spike,vcs-gate $DV_OPTS + - mv artifacts/cva6_${DV_TARGET} pd/synth/ + - mv artifacts/cva6_${DV_TARGET}_synth.v pd/synth/ + - mv artifacts/cva6_${DV_TARGET}_synth.sdf pd/synth/ + - mkdir -p pd/synth/cva6_${DV_TARGET}/outputs/ + - python3 ${SYNTH_SCRIPT_PATH}/scharm -p configs/modules/CVA6.yml --runner=True --compaign="simu-gate" --name=$PROG_NAME + - mv ${SYNTH_SCRIPT_PATH}/artifacts/ artifacts/artifacts_gate/ after_script: *simu_after_script fpga-boot: diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index a746dd7d19..50d70c3f69 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,4 +1,4 @@ cv32a6_embedded: gates: 110095 cv32a65x: - gates: 109555 + gates: 128136 diff --git a/.gitlab-ci/scripts/report_synth.py b/.gitlab-ci/scripts/report_synth.py index 7917dc309b..06cf9833b0 100644 --- a/.gitlab-ci/scripts/report_synth.py +++ b/.gitlab-ci/scripts/report_synth.py @@ -20,6 +20,9 @@ with open(str(sys.argv[2]), 'r') as f: synthesis_log = f.read() +ignored_warning = ["RM-Error", "TFCHK-014", "TFCHK-012", "TFCHK-049", + "MV-021", "MV-028", "TLUP-004", "TLUP-005", + "TIM-164", "PWR-890", "PWR-80", "OPT-1413"] kgate_ratio = int(os.environ["NAND2_AREA"]) path_re = r'^pd/synth/cva6_([^/]+)' with open(".gitlab-ci/expected_synth.yml", "r") as f: @@ -30,6 +33,8 @@ error_log = [] warning_log = [] for line in synthesis_log.splitlines(): + if any (el in line for el in ignored_warning): + continue if os.environ['FOUNDRY_PATH'] in line: continue if os.environ['TECH_NAME'] in line: diff --git a/Makefile b/Makefile index e7b4ff5920..54208aa8e3 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,8 @@ vcs-library ?= work-vcs dpi-library ?= work-dpi # Top level module to compile top_level ?= ariane_tb +# Top level path +top_level_path ?= corev_apu/tb/$(top_level).sv # Maximum amount of cycles for a successful simulation run max_cycles ?= 10000000 # Test case to run @@ -222,7 +224,7 @@ fpga_src := $(wildcard corev_apu/fpga/src/*.sv) $(wildcard corev_apu/fpga/src/a fpga_src := $(addprefix $(root-dir), $(fpga_src)) src/bootrom/bootrom_$(XLEN).sv # look for testbenches -tbs := corev_apu/tb/ariane_tb.sv corev_apu/tb/ariane_testharness.sv core/cva6_rvfi.sv +tbs := $(top_level_path) corev_apu/tb/ariane_testharness.sv core/cva6_rvfi.sv tbs := $(addprefix $(root-dir), $(tbs)) @@ -258,7 +260,7 @@ compile_flag += -incr -64 -nologo -quiet -suppress 13262 -suppress 8607 -per vopt_flag += -suppress 2085 -suppress 7063 -suppress 2698 -suppress 13262 uvm-flags += +UVM_NO_RELNOTES +UVM_VERBOSITY=UVM_LOW -questa-flags += -t 1ns -64 $(gui-sim) $(QUESTASIM_FLAGS) +tohost_addr=$(tohost_addr) +define+QUESTA -suppress 3356 +questa-flags += -t 1ns -64 $(gui-sim) $(QUESTASIM_FLAGS) +tohost_addr=$(tohost_addr) +define+QUESTA -suppress 3356 -suppress 3579 compile_flag_vhd += -64 -nologo -quiet -2008 # Iterate over all include directories and write them with +incdir+ prefixed @@ -298,16 +300,19 @@ else questa-cmd += +jtag_rbb_enable=0 endif +flist ?= core/Flist.cva6 + vcs_build: $(dpi-library)/ariane_dpi.so mkdir -p $(vcs-library) cd $(vcs-library) &&\ - vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) -assert svaext -f ../core/Flist.cva6 $(list_incdir) &&\ + vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) -assert svaext -f $(flist) $(list_incdir) ../corev_apu/tb/common/mock_uart.sv -timescale=1ns/1ns &&\ vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog +define+$(defines) $(filter %.sv,$(ariane_pkg)) +incdir+core/include/+$(VCS_HOME)/etc/uvm-1.2/dpi &&\ vhdlan $(if $(VERDI), -kdb,) -full64 -nc $(filter %.vhd,$(uart_src)) &&\ vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -assert svaext +define+$(defines) +incdir+$(VCS_HOME)/etc/uvm/src $(VCS_HOME)/etc/uvm/src/uvm_pkg.sv $(filter %.sv,$(src)) $(list_incdir) &&\ vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 &&\ vlogan $(if $(VERDI), -kdb,) -full64 -nc -sverilog -ntb_opts uvm-1.2 $(tbs) +define+$(defines) $(list_incdir) &&\ - vcs $(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb),) $(if $(TRACE_COMPACT),+vcs+fsdbon) -full64 -timescale=1ns/1ns -ntb_opts uvm-1.2 work.ariane_tb -error="IWNF" + vcs $(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb),) $(if $(TRACE_COMPACT),+vcs+fsdbon) -ignore initializer_driver_checks -timescale=1ns/1ns -ntb_opts uvm-1.2 work.$(top_level) -error="IWNF" \ + $(if $(gate), -sdf Max:ariane_gate_tb.i_ariane.i_cva6:$(CVA6_REPO_DIR)/pd/synth/cva6_$(TARGET)_synth.sdf +neg_tchk, +notimingcheck) vcs: vcs_build cd $(vcs-library) && \ diff --git a/common/local/util/sram.sv b/common/local/util/sram.sv index 4c0f2d25ad..f8dd934256 100644 --- a/common/local/util/sram.sv +++ b/common/local/util/sram.sv @@ -48,6 +48,7 @@ logic [BE_WIDTH_ALIGNED-1:0] be_aligned; logic [DATA_WIDTH_ALIGNED-1:0] rdata_aligned; logic [USER_WIDTH_ALIGNED-1:0] ruser_aligned; + // align to 64 bits for inferrable macro below always_comb begin : p_align wdata_aligned ='0; @@ -100,8 +101,17 @@ end .addr_i ( addr_i ), .rdata_o ( ruser_aligned[k*64 +: 64] ) ); - end else begin - assign ruser_aligned[k*64 +: 64] = '0; + end else begin : gen_mem_user + assign ruser_aligned[k*64 +: 64] = '0; + // synthesis translate_off + begin: i_tc_sram_wrapper_user + begin: i_tc_sram + logic init_val; + localparam type data_t = logic [63:0]; + data_t sram [NUM_WORDS-1:0] /* verilator public_flat */; + end + end + // synthesis translate_on end end endmodule : sram diff --git a/common/local/util/sram_cache.sv b/common/local/util/sram_cache.sv new file mode 100644 index 0000000000..7ca7559b7c --- /dev/null +++ b/common/local/util/sram_cache.sv @@ -0,0 +1,126 @@ +// 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 +// Michael Schaffner , ETH Zurich +// Date: 15.08.2018 +// Description: SRAM wrapper for FPGA (requires the fpga-support submodule) +// +// Note: the wrapped module contains two different implementations for +// ALTERA and XILINX tools, since these follow different coding styles for +// inferrable RAMS with byte enable. define `FPGA_TARGET_XILINX or +// `FPGA_TARGET_ALTERA in your build environment (default is ALTERA) + +module sram_cache #( + parameter DATA_WIDTH = 64, + parameter USER_WIDTH = 1, + parameter USER_EN = 0, + parameter NUM_WORDS = 1024, + parameter SIM_INIT = "none", + parameter BYTE_ACCESS = 1, + parameter TECHNO_CUT = 0, + parameter OUT_REGS = 0 // enables output registers in FPGA macro (read lat = 2) +)( + input logic clk_i, + input logic rst_ni, + input logic req_i, + input logic we_i, + input logic [$clog2(NUM_WORDS)-1:0] addr_i, + input logic [USER_WIDTH-1:0] wuser_i, + input logic [DATA_WIDTH-1:0] wdata_i, + input logic [(DATA_WIDTH+7)/8-1:0] be_i, + output logic [USER_WIDTH-1:0] ruser_o, + output logic [DATA_WIDTH-1:0] rdata_o +); + localparam DATA_AND_USER_WIDTH = USER_EN ? DATA_WIDTH + USER_WIDTH : DATA_WIDTH; + if (TECHNO_CUT) begin : gen_techno_cut + if (USER_EN > 0) begin + logic [DATA_WIDTH + USER_WIDTH-1:0] wdata_user; + logic [DATA_WIDTH + USER_WIDTH-1:0] rdata_user; + logic [(DATA_WIDTH+7)/8+(DATA_WIDTH+7)/8-1:0] be; + + always_comb begin + wdata_user = {wdata_i, wuser_i}; + be = {be_i, be_i}; + rdata_o = rdata_user[DATA_AND_USER_WIDTH-1:DATA_WIDTH]; + ruser_o = rdata_user[USER_WIDTH-1:0]; + end + tc_sram_wrapper_cache_techno #( + .NumWords(NUM_WORDS), // Number of Words in data array + .DataWidth(DATA_AND_USER_WIDTH),// Data signal width + .ByteWidth(32'd8), // Width of a data byte + .NumPorts(32'd1), // Number of read and write ports + .Latency(32'd1), // Latency when the read data is available + .SimInit(SIM_INIT), // Simulation initialization + .BYTE_ACCESS(BYTE_ACCESS), // ACCESS byte or full word + .PrintSimCfg(1'b0) // Print configuration + ) i_tc_sram_wrapper ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req_i ), + .we_i ( we_i ), + .be_i ( be ), + .wdata_i ( wdata_user ), + .addr_i ( addr_i ), + .rdata_o ( rdata_user ) + ); + end else begin + logic [DATA_WIDTH-1:0] wdata_user; + logic [DATA_WIDTH-1:0] rdata_user; + logic [(DATA_WIDTH+7)/8-1:0] be; + + always_comb begin + wdata_user = wdata_i; + be = be_i; + rdata_o = rdata_user; + ruser_o = '0; + end + tc_sram_wrapper_cache_techno #( + .NumWords(NUM_WORDS), // Number of Words in data array + .DataWidth(DATA_AND_USER_WIDTH),// Data signal width + .ByteWidth(32'd8), // Width of a data byte + .NumPorts(32'd1), // Number of read and write ports + .Latency(32'd1), // Latency when the read data is available + .SimInit(SIM_INIT), // Simulation initialization + .BYTE_ACCESS(BYTE_ACCESS), // ACCESS byte or full word + .PrintSimCfg(1'b0) // Print configuration + ) i_tc_sram_wrapper ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req_i ), + .we_i ( we_i ), + .be_i ( be ), + .wdata_i ( wdata_user ), + .addr_i ( addr_i ), + .rdata_o ( rdata_user ) + ); + end + end else begin + sram #( + .USER_WIDTH (USER_WIDTH), + .DATA_WIDTH (DATA_WIDTH), + .USER_EN (USER_EN), + .NUM_WORDS (NUM_WORDS) + ) data_sram ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .req_i (req_i), + .we_i (we_i), + .addr_i (addr_i), + .wuser_i(wuser_i), + .wdata_i(wdata_i), + .be_i (be_i), + .ruser_o(ruser_o), + .rdata_o(rdata_o) + ); + end + + +endmodule : sram_cache diff --git a/common/local/util/tc_sram_wrapper_cache_techno.sv b/common/local/util/tc_sram_wrapper_cache_techno.sv new file mode 100644 index 0000000000..31868b5457 --- /dev/null +++ b/common/local/util/tc_sram_wrapper_cache_techno.sv @@ -0,0 +1,64 @@ +// 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 - Thales + +// Copy of tc_sram_wrapper_cache +// To be replaced by the wrapper of the technology used to avoid having black box at synthesis + +module tc_sram_wrapper_cache_techno #( + parameter int unsigned NumWords = 32'd1024, // Number of Words in data array + parameter int unsigned DataWidth = 32'd128, // Data signal width + parameter int unsigned ByteWidth = 32'd8, // Width of a data byte + parameter int unsigned NumPorts = 32'd2, // Number of read and write ports + parameter int unsigned Latency = 32'd1, // Latency when the read data is available + parameter SimInit = "none", // Simulation initialization + parameter BYTE_ACCESS = 1, + parameter bit PrintSimCfg = 1'b0, // Print configuration + // DEPENDENT PARAMETERS, DO NOT OVERWRITE! + parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1, + parameter int unsigned BeWidth = (DataWidth + ByteWidth - 32'd1) / ByteWidth, // ceil_div + parameter type addr_t = logic [AddrWidth-1:0], + parameter type data_t = logic [DataWidth-1:0], + parameter type be_t = logic [BeWidth-1:0] +) ( + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + // input ports + input logic [NumPorts-1:0] req_i, // request + input logic [NumPorts-1:0] we_i, // write enable + input addr_t [NumPorts-1:0] addr_i, // request address + input data_t [NumPorts-1:0] wdata_i, // write data + input be_t [NumPorts-1:0] be_i, // write byte enable + // output ports + output data_t [NumPorts-1:0] rdata_o // read data +); + +// synthesis translate_off + + tc_sram #( + .NumWords(NumWords), + .DataWidth(DataWidth), + .ByteWidth(ByteWidth), + .NumPorts(NumPorts), + .Latency(Latency), + .SimInit(SimInit), + .PrintSimCfg(PrintSimCfg) + ) i_tc_sram ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req_i ), + .we_i ( we_i ), + .be_i ( be_i ), + .wdata_i ( wdata_i ), + .addr_i ( addr_i ), + .rdata_o ( rdata_o ) + ); + +// synthesis translate_on + +endmodule diff --git a/core/Flist.cva6 b/core/Flist.cva6 index e39026e8ed..71f9f42d38 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -180,8 +180,10 @@ ${CVA6_REPO_DIR}/core/pmp/src/pmp_entry.sv // Tracer (behavioral code, not RTL) ${CVA6_REPO_DIR}/common/local/util/instr_tracer.sv ${CVA6_REPO_DIR}/common/local/util/tc_sram_wrapper.sv +${CVA6_REPO_DIR}/common/local/util/tc_sram_wrapper_cache_techno.sv ${CVA6_REPO_DIR}/vendor/pulp-platform/tech_cells_generic/src/rtl/tc_sram.sv ${CVA6_REPO_DIR}/common/local/util/sram.sv +${CVA6_REPO_DIR}/common/local/util/sram_cache.sv // MMU ${CVA6_REPO_DIR}/core/cva6_mmu/cva6_mmu.sv diff --git a/core/Flist.cva6_gate b/core/Flist.cva6_gate index 55cc6c32dd..4b743fa19c 100644 --- a/core/Flist.cva6_gate +++ b/core/Flist.cva6_gate @@ -9,6 +9,10 @@ # +incdir+${CVA6_REPO_DIR}/core/include/ ++incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/include/ ++incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/ ++incdir+${CVA6_REPO_DIR}/vendor/pulp-platform/axi/include/ ++incdir+${CVA6_REPO_DIR}/common/local/util/ ${CVA6_REPO_DIR}/core/include/config_pkg.sv ${CVA6_REPO_DIR}/core/include/${TARGET_CFG}_config_pkg.sv @@ -16,17 +20,54 @@ ${CVA6_REPO_DIR}/core/include/riscv_pkg.sv ${CVA6_REPO_DIR}/core/include/ariane_pkg.sv ${CVA6_REPO_DIR}/vendor/pulp-platform/axi/src/axi_pkg.sv -${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv - +// Packages ${CVA6_REPO_DIR}/core/include/wt_cache_pkg.sv ${CVA6_REPO_DIR}/core/include/std_cache_pkg.sv ${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv ${CVA6_REPO_DIR}/core/include/build_config_pkg.sv +//CVXIF +${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv +${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv +${CVA6_REPO_DIR}/core/cvxif_fu.sv +${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv +${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv +${CVA6_REPO_DIR}/core/cva6_fifo_v3.sv + + +// Common Cells +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/fifo_v3.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lfsr_8bit.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/stream_arbiter.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/stream_arbiter_flushable.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/stream_mux.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/stream_demux.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/lzc.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/rr_arb_tree.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/shift_reg.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/unread.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/popcount.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/exp_backoff.sv + +// Common Cells for example coprocessor +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/counter.sv +${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/delta_counter.sv + +${CVA6_REPO_DIR}/core/cache_subsystem/axi_adapter.sv + ${LIB_VERILOG} -${CVA6_REPO_DIR}/pd/synth/cva6_${TARGET_CFG}_synth_modified.v +${CVA6_REPO_DIR}/pd/synth/cva6_${TARGET_CFG}_synth.v +# Dedicated to black box in caches, cv32a65x only ${CVA6_REPO_DIR}/pd/synth/tc_sram_wrapper_256_64_00000008_00000001_00000001_none_0.sv +${CVA6_REPO_DIR}/pd/synth/hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080.sv +${CVA6_REPO_DIR}/pd/synth/hpdcache_sram_1rw_00000006_0000001a_00000040.sv + ${CVA6_REPO_DIR}/common/local/util/tc_sram_wrapper.sv +${CVA6_REPO_DIR}/common/local/util/tc_sram_wrapper_cache_techno.sv + ${CVA6_REPO_DIR}/vendor/pulp-platform/tech_cells_generic/src/rtl/tc_sram.sv ${CVA6_REPO_DIR}/common/local/util/sram.sv +${CVA6_REPO_DIR}/common/local/util/sram_cache.sv diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index e3f539afa1..d97fed369a 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -457,10 +457,12 @@ module cva6_icache for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_sram // Tag RAM - sram #( + sram_cache #( // tag + valid bit - .DATA_WIDTH(CVA6Cfg.ICACHE_TAG_WIDTH + 1), - .NUM_WORDS (ICACHE_NUM_WORDS) + .DATA_WIDTH (CVA6Cfg.ICACHE_TAG_WIDTH + 1), + .BYTE_ACCESS(0), + .TECHNO_CUT (CVA6Cfg.TechnoCut), + .NUM_WORDS (ICACHE_NUM_WORDS) ) tag_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -480,11 +482,13 @@ module cva6_icache assign vld_rdata[i] = cl_tag_valid_rdata[i][CVA6Cfg.ICACHE_TAG_WIDTH]; // Data RAM - sram #( - .USER_WIDTH(CVA6Cfg.ICACHE_USER_LINE_WIDTH), - .DATA_WIDTH(CVA6Cfg.ICACHE_LINE_WIDTH), - .USER_EN (CVA6Cfg.FETCH_USER_EN), - .NUM_WORDS (ICACHE_NUM_WORDS) + sram_cache #( + .USER_WIDTH (CVA6Cfg.ICACHE_USER_LINE_WIDTH), + .DATA_WIDTH (CVA6Cfg.ICACHE_LINE_WIDTH), + .USER_EN (CVA6Cfg.FETCH_USER_EN), + .BYTE_ACCESS(0), + .TECHNO_CUT (CVA6Cfg.TechnoCut), + .NUM_WORDS (ICACHE_NUM_WORDS) ) data_sram ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/cache_subsystem/wt_dcache_mem.sv b/core/cache_subsystem/wt_dcache_mem.sv index f801defd63..e20320de24 100644 --- a/core/cache_subsystem/wt_dcache_mem.sv +++ b/core/cache_subsystem/wt_dcache_mem.sv @@ -305,11 +305,13 @@ module wt_dcache_mem for (genvar k = 0; k < DCACHE_NUM_BANKS; k++) begin : gen_data_banks // Data RAM - sram #( - .USER_WIDTH(CVA6Cfg.DCACHE_SET_ASSOC * CVA6Cfg.DCACHE_USER_WIDTH), - .DATA_WIDTH(CVA6Cfg.DCACHE_SET_ASSOC * CVA6Cfg.XLEN), - .USER_EN (CVA6Cfg.DATA_USER_EN), - .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) + sram_cache #( + .USER_WIDTH (CVA6Cfg.DCACHE_SET_ASSOC * CVA6Cfg.DCACHE_USER_WIDTH), + .DATA_WIDTH (CVA6Cfg.DCACHE_SET_ASSOC * CVA6Cfg.XLEN), + .USER_EN (CVA6Cfg.DATA_USER_EN), + .BYTE_ACCESS(1), + .TECHNO_CUT (CVA6Cfg.TechnoCut), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) i_data_sram ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -330,10 +332,12 @@ module wt_dcache_mem assign rd_vld_bits_o[i] = vld_tag_rdata[i][CVA6Cfg.DCACHE_TAG_WIDTH]; // Tag RAM - sram #( + sram_cache #( // tag + valid bit - .DATA_WIDTH(CVA6Cfg.DCACHE_TAG_WIDTH + 1), - .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) + .DATA_WIDTH (CVA6Cfg.DCACHE_TAG_WIDTH + 1), + .BYTE_ACCESS(0), + .TECHNO_CUT (CVA6Cfg.TechnoCut), + .NUM_WORDS (CVA6Cfg.DCACHE_NUM_WORDS) ) i_tag_sram ( .clk_i (clk_i), .rst_ni (rst_ni), diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index c31f0e11f9..e9e6fccfe3 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -42,6 +42,7 @@ package build_config_pkg; cfg.VMID_WIDTH = (CVA6Cfg.XLEN == 64) ? 14 : 1; cfg.FpgaEn = CVA6Cfg.FpgaEn; + cfg.TechnoCut = CVA6Cfg.TechnoCut; cfg.NrCommitPorts = CVA6Cfg.NrCommitPorts; cfg.NrLoadPipeRegs = CVA6Cfg.NrLoadPipeRegs; cfg.NrStorePipeRegs = CVA6Cfg.NrStorePipeRegs; diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 3b590736b4..119293b4c6 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -162,6 +162,8 @@ package config_pkg; int unsigned FetchUserWidth; // Is FPGA optimization of CV32A6 bit FpgaEn; + // Is Techno Cut instanciated + bit TechnoCut; // Number of commit ports int unsigned NrCommitPorts; // Load cycle latency number @@ -202,6 +204,7 @@ package config_pkg; int unsigned VMID_WIDTH; bit FpgaEn; + bit TechnoCut; /// Number of commit ports, i.e., maximum number of instructions that the /// core can retire per cycle. It can be beneficial to have more commit /// ports than issue ports, for the scoreboard to empty out in case one diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index 2989daa775..1845844ad1 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index acffa590b9..d00b0c8f10 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -25,6 +25,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(0), + TechnoCut: bit'(1), NrCommitPorts: unsigned'(1), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), @@ -80,13 +81,13 @@ package cva6_config_pkg; IcacheSetAssoc: unsigned'(2), IcacheLineWidth: unsigned'(128), DCacheType: config_pkg::HPDCACHE, - DcacheByteSize: unsigned'(32768), - DcacheSetAssoc: unsigned'(8), + DcacheByteSize: unsigned'(2028), + DcacheSetAssoc: unsigned'(2), DcacheLineWidth: unsigned'(128), - DataUserEn: unsigned'(0), + DataUserEn: unsigned'(1), WtDcacheWbufDepth: int'(2), FetchUserWidth: unsigned'(32), - FetchUserEn: unsigned'(0), + FetchUserEn: unsigned'(1), InstrTlbEntries: int'(2), DataTlbEntries: int'(2), UseSharedTlb: bit'(1), diff --git a/core/include/cv32a6_embedded_config_pkg.sv b/core/include/cv32a6_embedded_config_pkg.sv index 8956923d62..adb9e987ac 100644 --- a/core/include/cv32a6_embedded_config_pkg.sv +++ b/core/include/cv32a6_embedded_config_pkg.sv @@ -76,6 +76,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index 6d2543fe2b..c41e880c0a 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 34e2977012..a8a609f940 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 17c098ffcb..d8931d65a0 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 17b646d758..4f8e63c072 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index b060a62ee4..233b85f317 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index 7fe5382642..32bf8cc963 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv index 5035dafd12..c5874cd5f8 100644 --- a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @@ -84,6 +84,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 68af62733d..431b862ea1 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv index ff16818f72..cd24267261 100644 --- a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdch_sv39_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_config_pkg.sv index eefe47dcb4..41e00edeb3 100644 --- a/core/include/cv64a6_imafdch_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv index 1807fcf9c9..5a685c9171 100644 --- a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(CVA6ConfigTechnoCut), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index a22ce62bc1..066414588d 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -77,6 +77,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(CVA6ConfigFpgaEn), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/core/include/cv64a6_mmu_config_pkg.sv b/core/include/cv64a6_mmu_config_pkg.sv index 1d9a2639de..00950df843 100644 --- a/core/include/cv64a6_mmu_config_pkg.sv +++ b/core/include/cv64a6_mmu_config_pkg.sv @@ -29,6 +29,7 @@ package cva6_config_pkg; localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(0), + TechnoCut: bit'(0), NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), diff --git a/corev_apu/tb/ariane_gate_tb.sv b/corev_apu/tb/ariane_gate_tb.sv new file mode 100644 index 0000000000..615d2bcf30 --- /dev/null +++ b/corev_apu/tb/ariane_gate_tb.sv @@ -0,0 +1,480 @@ +// Copyright 2024 Thales DIS France 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 - Thales +// + +import uvm_pkg::*; + +`include "axi/assign.svh" +`include "rvfi_types.svh" + +`ifdef VERILATOR +`include "custom_uvm_macros.svh" +`else +`include "uvm_macros.svh" +`endif + +`define MAIN_MEM(P) i_sram.gen_cut[0].i_tc_sram_wrapper.i_tc_sram.init_val[(``P``)] +`define USER_MEM(P) i_sram.gen_cut[0].gen_mem_user.i_tc_sram_wrapper_user.i_tc_sram.init_val[(``P``)] + +`timescale 1ns/1ns + +import "DPI-C" function void read_elf(input string filename); +import "DPI-C" function byte get_section(output longint address, output longint len); +import "DPI-C" context function read_section_sv(input longint address, inout byte buffer[]); +import "DPI-C" function string getenv(input string env_name); + +module ariane_gate_tb; + + // cva6 configuration + localparam config_pkg::cva6_cfg_t CVA6Cfg = build_config_pkg::build_config(cva6_config_pkg::cva6_cfg); + static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst(); + + localparam int unsigned AXI_USER_WIDTH = CVA6Cfg.AxiUserWidth; + localparam int unsigned AXI_USER_EN = CVA6Cfg.AXI_USER_EN; + localparam int unsigned AXI_ADDRESS_WIDTH = 64; + localparam int unsigned AXI_DATA_WIDTH = 64; + + + localparam NrSlaves = 1; + localparam NB_PERIPHERALS = 3; + localparam IdWidthSlave = ariane_axi_soc::IdWidth + $clog2(NrSlaves); + + localparam NUM_WORDS = 2**16; + int unsigned CLOCK_PERIOD = 20ns; + logic clk_i; + logic rst_ni; + + longint unsigned cycles; + longint unsigned max_cycles; + + logic [31:0] exit_o; + localparam [7:0] hart_id = '0; + + // RVFI + localparam type rvfi_instr_t = `RVFI_INSTR_T(CVA6Cfg); + localparam type rvfi_csr_elmt_t = `RVFI_CSR_ELMT_T(CVA6Cfg); + localparam type rvfi_csr_t = `RVFI_CSR_T(CVA6Cfg, rvfi_csr_elmt_t); + + // RVFI PROBES + localparam type rvfi_probes_instr_t = `RVFI_PROBES_INSTR_T(CVA6Cfg); + localparam type rvfi_probes_csr_t = `RVFI_PROBES_CSR_T(CVA6Cfg); + localparam type rvfi_probes_t = struct packed { + logic csr; + rvfi_probes_instr_t instr; + }; + + string binary = ""; + + + typedef enum int unsigned { + DRAM = 0, + UART = 1, + ROM = 2 + } axi_slaves_t; + + AXI_BUS #( + .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI_ID_WIDTH ( ariane_axi_soc::IdWidth ), + .AXI_USER_WIDTH ( AXI_USER_WIDTH ) + ) slave[NrSlaves-1:0](); + + AXI_BUS #( + .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI_ID_WIDTH ( IdWidthSlave ), + .AXI_USER_WIDTH ( AXI_USER_WIDTH ) + ) master[NB_PERIPHERALS-1:0](); + + // --------------- + // Core + // --------------- + ariane_axi::req_t axi_ariane_req; + ariane_axi::resp_t axi_ariane_resp; + rvfi_probes_t rvfi_probes; + rvfi_csr_t rvfi_csr; + rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr; + + ariane #( + .CVA6Cfg ( CVA6Cfg ), + .rvfi_probes_instr_t ( rvfi_probes_instr_t ), + .rvfi_probes_csr_t ( rvfi_probes_csr_t ), + .rvfi_probes_t ( rvfi_probes_t ), + .noc_req_t ( ariane_axi::req_t ), + .noc_resp_t ( ariane_axi::resp_t ) + ) i_ariane ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .boot_addr_i ( ariane_soc::ROMBase), // start fetching from ROM + .hart_id_i ( {56'h0, hart_id} ), + .irq_i ( 2'b00 /*irqs*/ ), + .ipi_i ( 1'b0 /*ipi*/ ), + .time_irq_i ( 1'b0 /*timer_irq*/ ), + .debug_req_i ( 1'b0 ), + .rvfi_probes_o ( rvfi_probes ), + .noc_req_o ( axi_ariane_req ), + .noc_resp_i ( axi_ariane_resp ) + ); + + `AXI_ASSIGN_FROM_REQ(slave[0], axi_ariane_req) + `AXI_ASSIGN_TO_RESP(axi_ariane_resp, slave[0]) + // ------------- + // Simulation Helper Functions + // ------------- + // check for response errors + always_ff @(posedge clk_i) begin : p_assert + if (axi_ariane_req.r_ready && + axi_ariane_resp.r_valid && + axi_ariane_resp.r.resp inside {axi_pkg::RESP_DECERR, axi_pkg::RESP_SLVERR}) begin + $warning("R Response Errored"); + end + if (axi_ariane_req.b_ready && + axi_ariane_resp.b_valid && + axi_ariane_resp.b.resp inside {axi_pkg::RESP_DECERR, axi_pkg::RESP_SLVERR}) begin + $warning("B Response Errored"); + end + end + + cva6_rvfi #( + .CVA6Cfg (CVA6Cfg), + .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(rvfi_csr_t), + .rvfi_probes_instr_t(rvfi_probes_instr_t), + .rvfi_probes_csr_t(rvfi_probes_csr_t), + .rvfi_probes_t(rvfi_probes_t) + ) i_cva6_rvfi ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rvfi_probes_i(rvfi_probes), + .rvfi_instr_o(rvfi_instr), + .rvfi_csr_o(rvfi_csr) + ); + + rvfi_tracer #( + .CVA6Cfg(CVA6Cfg), + .rvfi_instr_t(rvfi_instr_t), + .rvfi_csr_t(rvfi_csr_t), + // + .HART_ID(hart_id), + .DEBUG_START(0), + .DEBUG_STOP(0) + ) i_rvfi_tracer ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .rvfi_i(rvfi_instr), + .rvfi_csr_i(rvfi_csr), + .end_of_test_o(rvfi_exit) + ); + + assign exit_o = rvfi_exit; + + + // ------------------------------ + // Memory + Exclusive Access + // ------------------------------ + + logic req; + logic we; + logic [AXI_ADDRESS_WIDTH-1:0] addr; + logic [AXI_DATA_WIDTH/8-1:0] be; + logic [AXI_DATA_WIDTH-1:0] wdata; + logic [AXI_DATA_WIDTH-1:0] rdata; + logic [AXI_USER_WIDTH-1:0] wuser; + logic [AXI_USER_WIDTH-1:0] ruser; + + axi2mem #( + .AXI_ID_WIDTH ( IdWidthSlave ), + .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI_USER_WIDTH ( AXI_USER_WIDTH ) + ) i_axi2mem ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .slave ( master[DRAM] ), // dram_delayed ? + .req_o ( req ), + .we_o ( we ), + .addr_o ( addr ), + .be_o ( be ), + .user_o ( wuser ), + .data_o ( wdata ), + .user_i ( ruser ), + .data_i ( rdata ) + ); + + sram #( + .DATA_WIDTH ( AXI_DATA_WIDTH ), + .USER_WIDTH ( AXI_USER_WIDTH ), + .USER_EN ( AXI_USER_EN ), + `ifdef VERILATOR + .SIM_INIT ( "none" ), + `else + .SIM_INIT ( "zeros" ), + `endif + .NUM_WORDS ( NUM_WORDS ) + ) i_sram ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .req_i ( req ), + .we_i ( we ), + .addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ), + .wuser_i ( wuser ), + .wdata_i ( wdata ), + .be_i ( be ), + .ruser_o ( ruser ), + .rdata_o ( rdata ) + ); + + // --------------- + // ROM + // --------------- + logic rom_req; + logic [AXI_ADDRESS_WIDTH-1:0] rom_addr; + logic [AXI_DATA_WIDTH-1:0] rom_rdata; + + axi2mem #( + .AXI_ID_WIDTH ( IdWidthSlave ), + .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI_USER_WIDTH ( AXI_USER_WIDTH ) + ) i_axi2rom ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .slave ( master[ROM] ), + .req_o ( rom_req ), + .we_o ( ), + .addr_o ( rom_addr ), + .be_o ( ), + .user_o ( ), + .data_o ( ), + .user_i ( '0 ), + .data_i ( rom_rdata ) + ); + + bootrom i_bootrom ( + .clk_i ( clk_i ), + .req_i ( rom_req ), + .addr_i ( rom_addr ), + .rdata_o ( rom_rdata ) + ); + + // --------------- + // AXI Xbar + // --------------- + + axi_pkg::xbar_rule_64_t [NB_PERIPHERALS-1:0] addr_map; + + assign addr_map = '{ + '{ idx: ROM, start_addr: ariane_soc::ROMBase, end_addr: ariane_soc::ROMBase + ariane_soc::ROMLength }, + '{ idx: UART, start_addr: ariane_soc::UARTBase, end_addr: ariane_soc::UARTBase + ariane_soc::UARTLength }, + '{ idx: DRAM, start_addr: ariane_soc::DRAMBase, end_addr: ariane_soc::DRAMBase + ariane_soc::DRAMLength } + }; + + localparam axi_pkg::xbar_cfg_t AXI_XBAR_CFG = '{ + NoSlvPorts: unsigned'(NrSlaves), + NoMstPorts: unsigned'(NB_PERIPHERALS), + MaxMstTrans: unsigned'(1), // Probably requires update + MaxSlvTrans: unsigned'(1), // Probably requires update + FallThrough: 1'b0, + LatencyMode: axi_pkg::NO_LATENCY, + AxiIdWidthSlvPorts: unsigned'(ariane_axi_soc::IdWidth), + AxiIdUsedSlvPorts: unsigned'(ariane_axi_soc::IdWidth), + UniqueIds: 1'b0, + AxiAddrWidth: unsigned'(AXI_ADDRESS_WIDTH), + AxiDataWidth: unsigned'(AXI_DATA_WIDTH), + NoAddrRules: unsigned'(NB_PERIPHERALS) + }; + + axi_xbar_intf #( + .AXI_USER_WIDTH ( AXI_USER_WIDTH ), + .Cfg ( AXI_XBAR_CFG ), + .rule_t ( axi_pkg::xbar_rule_64_t ) + ) i_axi_xbar ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .test_i ( '0 ), + .slv_ports ( slave ), + .mst_ports ( master ), + .addr_map_i ( addr_map ), + .en_default_mst_port_i ( '0 ), + .default_mst_port_i ( '0 ) + ); + + + + // --------------- + // 2. UART + // --------------- + logic uart_penable; + logic uart_pwrite; + logic [31:0] uart_paddr; + logic uart_psel; + logic [31:0] uart_pwdata; + logic [31:0] uart_prdata; + logic uart_pready; + logic uart_pslverr; + + axi2apb_64_32 #( + .AXI4_ADDRESS_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI4_RDATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI4_WDATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI4_ID_WIDTH ( IdWidthSlave ), + .AXI4_USER_WIDTH ( AXI_USER_WIDTH ), + .BUFF_DEPTH_SLAVE ( 2 ), + .APB_ADDR_WIDTH ( 32 ) + ) i_axi2apb_64_32_uart ( + .ACLK ( clk_i ), + .ARESETn ( rst_ni ), + .test_en_i ( 1'b0 ), + .AWID_i ( master[UART].aw_id ), + .AWADDR_i ( master[UART].aw_addr ), + .AWLEN_i ( master[UART].aw_len ), + .AWSIZE_i ( master[UART].aw_size ), + .AWBURST_i ( master[UART].aw_burst ), + .AWLOCK_i ( master[UART].aw_lock ), + .AWCACHE_i ( master[UART].aw_cache ), + .AWPROT_i ( master[UART].aw_prot ), + .AWREGION_i( master[UART].aw_region ), + .AWUSER_i ( master[UART].aw_user ), + .AWQOS_i ( master[UART].aw_qos ), + .AWVALID_i ( master[UART].aw_valid ), + .AWREADY_o ( master[UART].aw_ready ), + .WDATA_i ( master[UART].w_data ), + .WSTRB_i ( master[UART].w_strb ), + .WLAST_i ( master[UART].w_last ), + .WUSER_i ( master[UART].w_user ), + .WVALID_i ( master[UART].w_valid ), + .WREADY_o ( master[UART].w_ready ), + .BID_o ( master[UART].b_id ), + .BRESP_o ( master[UART].b_resp ), + .BVALID_o ( master[UART].b_valid ), + .BUSER_o ( master[UART].b_user ), + .BREADY_i ( master[UART].b_ready ), + .ARID_i ( master[UART].ar_id ), + .ARADDR_i ( master[UART].ar_addr ), + .ARLEN_i ( master[UART].ar_len ), + .ARSIZE_i ( master[UART].ar_size ), + .ARBURST_i ( master[UART].ar_burst ), + .ARLOCK_i ( master[UART].ar_lock ), + .ARCACHE_i ( master[UART].ar_cache ), + .ARPROT_i ( master[UART].ar_prot ), + .ARREGION_i( master[UART].ar_region ), + .ARUSER_i ( master[UART].ar_user ), + .ARQOS_i ( master[UART].ar_qos ), + .ARVALID_i ( master[UART].ar_valid ), + .ARREADY_o ( master[UART].ar_ready ), + .RID_o ( master[UART].r_id ), + .RDATA_o ( master[UART].r_data ), + .RRESP_o ( master[UART].r_resp ), + .RLAST_o ( master[UART].r_last ), + .RUSER_o ( master[UART].r_user ), + .RVALID_o ( master[UART].r_valid ), + .RREADY_i ( master[UART].r_ready ), + .PENABLE ( uart_penable ), + .PWRITE ( uart_pwrite ), + .PADDR ( uart_paddr ), + .PSEL ( uart_psel ), + .PWDATA ( uart_pwdata ), + .PRDATA ( uart_prdata ), + .PREADY ( uart_pready ), + .PSLVERR ( uart_pslverr ) + ); + + mock_uart i_mock_uart ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .penable_i ( uart_penable ), + .pwrite_i ( uart_pwrite ), + .paddr_i ( uart_paddr ), + .psel_i ( uart_psel ), + .pwdata_i ( uart_pwdata ), + .prdata_o ( uart_prdata ), + .pready_o ( uart_pready ), + .pslverr_o ( uart_pslverr ) + ); + + + + + // Clock process + initial begin + + string SIMU_PERIOD = {getenv("SIMU_PERIOD"),"ns"}; + if (SIMU_PERIOD != "ns") + CLOCK_PERIOD = SIMU_PERIOD.atoi(); + + clk_i = 1'b0; + rst_ni = 1'b0; + repeat(8) + #(CLOCK_PERIOD/2) clk_i = ~clk_i; + rst_ni = 1'b1; + forever begin + #(CLOCK_PERIOD/2) clk_i = 1'b1; + #(CLOCK_PERIOD/2) clk_i = 1'b0; + + //if (cycles > max_cycles) + // $fatal(1, "Simulation reached maximum cycle count of %d", max_cycles); + + cycles++; + end + end + + + initial begin + forever begin + + wait (exit_o[0]); + + if ((exit_o >> 1)) begin + `uvm_error( "Core Test", $sformatf("*** FAILED *** (tohost = %0d)", (exit_o >> 1))) + end else begin + `uvm_info( "Core Test", $sformatf("*** SUCCESS *** (tohost = %0d)", (exit_o >> 1)), UVM_LOW) + end + + $finish(); + end + end + + // for faster simulation we can directly preload the ELF + // Note that we are loosing the capabilities to use risc-fesvr though + initial begin + automatic logic [7:0][7:0] mem_row; + longint address, len; + byte buffer[]; + void'(uvcl.get_arg_value("+elf_file=", binary)); + + if (binary != "") begin + `uvm_info( "Core Test", $sformatf("Preloading ELF: %s", binary), UVM_LOW) + + void'(read_elf(binary)); + // wait with preloading, otherwise randomization will overwrite the existing value + wait(clk_i); + + // while there are more sections to process + while (get_section(address, len)) begin + automatic int num_words = (len+7)/8; + `uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len),UVM_LOW) + buffer = new [num_words*8]; + void'(read_section_sv(address, buffer)); + // preload memories + // 64-bit + for (int i = 0; i < num_words; i++) begin + mem_row = '0; + for (int j = 0; j < 8; j++) begin + mem_row[j] = buffer[i*8 + j]; + end + if (address[31:0] < 'h84000000) begin + `MAIN_MEM((address[23:0] >> 3) + i) = mem_row; + end else begin + `USER_MEM((address[23:0] >> 3) + i) = mem_row; + end + end + end + end + end +endmodule diff --git a/corev_apu/tb/ariane_tb.cpp b/corev_apu/tb/ariane_tb.cpp index 565f210663..8de0c5b20f 100644 --- a/corev_apu/tb/ariane_tb.cpp +++ b/corev_apu/tb/ariane_tb.cpp @@ -333,9 +333,11 @@ int main(int argc, char **argv) { #if (VERILATOR_VERSION_INTEGER >= 5000000) // Verilator v5: Use rootp pointer and .data() accessor. #define MEM top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram.m_storage +#define MEM_USER top->rootp->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem_user__DOT__i_tc_sram_wrapper_user__DOT__i_tc_sram__DOT__sram.m_storage #else // Verilator v4 #define MEM top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__i_tc_sram_wrapper__DOT__i_tc_sram__DOT__sram +#define MEM_USER top->ariane_testharness__DOT__i_sram__DOT__gen_cut__BRA__0__KET____DOT__gen_mem_user__DOT__i_tc_sram_wrapper_user__DOT__i_tc_sram__DOT__sram #endif long long addr; long long len; @@ -345,6 +347,12 @@ int main(int argc, char **argv) { { if (addr == 0x80000000) read_section_void(addr, (void *) MEM , mem_size); + if (addr == 0x84000000) + try { + read_section_void(addr, (void *) MEM_USER , mem_size); + } catch (...){ + std::cerr << "No user memory instanciated ...\n"; + } } while (!dtm->done() && !jtag->done() && !(top->exit_o & 0x1)) { diff --git a/corev_apu/tb/ariane_tb.sv b/corev_apu/tb/ariane_tb.sv index 5e03e65175..d45d7673ee 100644 --- a/corev_apu/tb/ariane_tb.sv +++ b/corev_apu/tb/ariane_tb.sv @@ -21,7 +21,7 @@ import uvm_pkg::*; `include "rvfi_types.svh" `define MAIN_MEM(P) dut.i_sram.gen_cut[0].i_tc_sram_wrapper.i_tc_sram.init_val[(``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``)] +`define USER_MEM(P) dut.i_sram.gen_cut[0].gen_mem_user.i_tc_sram_wrapper_user.i_tc_sram.init_val[(``P``)] `ifndef READ_ELF_T `define READ_ELF_T @@ -140,7 +140,7 @@ module ariane_tb; // while there are more sections to process while (get_section(address, len)) begin automatic int num_words = (len+7)/8; - `uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_LOW) + `uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_NONE) buffer = new [num_words*8]; void'(read_section_sv(address, buffer)); // preload memories @@ -152,10 +152,14 @@ module ariane_tb; end load_address = (address[23:0] >> 3) + i; if (load_address != last_load_address) begin - `MAIN_MEM(load_address) = mem_row; + if (address[31:0] < 'h84000000) begin + `MAIN_MEM(load_address) = mem_row; + end else begin + `USER_MEM(load_address) = mem_row; + end last_load_address = load_address; end else begin - `uvm_info( "Debug info", $sformatf(" Address: %x Already Loaded! ELF file might have less than 64 bits granularity on segments.", load_address), UVM_LOW) + `uvm_info( "Debug info", $sformatf(" Address: %x Already Loaded! ELF file might have less than 64 bits granularity on segments.", load_address), UVM_NONE) end end diff --git a/pd/synth/.gitignore b/pd/synth/.gitignore index 9f9e8d922e..2f847184a4 100644 --- a/pd/synth/.gitignore +++ b/pd/synth/.gitignore @@ -5,4 +5,7 @@ alib-52 command.tcl command_read.tcl default.svf -ariane +cva6_* +Flist.* +pes.bat +simv* diff --git a/pd/synth/Makefile b/pd/synth/Makefile index d66ceee647..c56c6e4282 100644 --- a/pd/synth/Makefile +++ b/pd/synth/Makefile @@ -8,18 +8,18 @@ # Original Author: Jean-Roch COULON - Thales # -DESIGN_NAME = cva6 +DESIGN_NAME ?= cva6 PERIOD ?= 17 FOUNDRY_PATH ?= -TECH_NAME ?= +LOCAL_LIB_PATH ?=/shares/common/tools/RAMs/ TARGET_LIBRARY_FILES = $(TECH_NAME).db INPUT_DELAY ?= 0.46 OUTPUT_DELAY ?= 0.11 DC_SHELL_PATH ?= /opt/synopsys/syn/Q-2019.12/bin/ NAND2_AREA ?= 1120 -TARGET ?= cv64a6_imafdc_sv39 +TARGET ?= cv32a65x -EXPORT_LIST=SNPSLMD_QUEUE=TRUE TECH_NAME=$(TECH_NAME) DESIGN_NAME=$(DESIGN_NAME) TARGET=$(TARGET) TERM=vt100 PERIOD=$(PERIOD) FOUNDRY_PATH=$(FOUNDRY_PATH) TARGET_LIBRARY_FILES=$(TARGET_LIBRARY_FILES) INPUT_DELAY=$(INPUT_DELAY) OUTPUT_DELAY=$(OUTPUT_DELAY) +EXPORT_LIST=SNPSLMD_QUEUE=TRUE TECH_NAME=$(TECH_NAME) DESIGN_NAME=$(DESIGN_NAME) TARGET=$(TARGET) TERM=vt100 PERIOD=$(PERIOD) FOUNDRY_PATH=$(FOUNDRY_PATH) LOCAL_LIB_PATH=$(LOCAL_LIB_PATH) TARGET_LIBRARY_FILES=$(TARGET_LIBRARY_FILES) INPUT_DELAY=$(INPUT_DELAY) OUTPUT_DELAY=$(OUTPUT_DELAY) ifndef FOUNDRY_PATH $(error "Please provide FOUNDRY techno") @@ -28,18 +28,40 @@ ifndef TECH_NAME $(error "Please provide TECH_NAME techno") endif +# Create Flist with good compilation order for synthesis +# - config_pkg.sv +# - hpdcache_params_pkg.sv before hdpcache_pkg.sv +# - pkg before rtl pre_cva6_synth: - grep "CVA6_REPO_DIR\}" ../../core/Flist.cva6|grep -v "instr_tracer"|grep -v "incdir" > Flist.cva6_synth - sed -i "s/^/analyze -f sverilog -lib ariane_lib /" Flist.cva6_synth + grep "{\w*}" ../../core/Flist.cva6|grep -v "instr_tracer"|grep -v "incdir"|grep -v "hpdcache.Flist" > Flist.cva6_synth + grep "{\w*}" ../../core/cache_subsystem/hpdcache/rtl/hpdcache.Flist|grep -v "incdir" >> Flist.cva6_synth + grep "hpdcache_pkg.sv" Flist.cva6_synth > hpdcache_pkg.tmp + grep "_pkg.sv" Flist.cva6_synth | grep -v "hpdcache_pkg.sv" > packages.tmp + grep -v "hpdcache_pkg.sv" Flist.cva6_synth | grep -v "HPDCACHE_TARGET_CFG" | grep -v "_pkg.sv" > rtl.tmp + cat packages.tmp > Flist.cva6_synth + cat hpdcache_pkg.tmp >> Flist.cva6_synth + cat rtl.tmp >> Flist.cva6_synth + sed -i "s/^/analyze -f sverilog -lib ariane_lib -define HPDCACHE_ASSERT_OFF /" Flist.cva6_synth + sed -i -e 's/behav/blackbox/g' Flist.cva6_synth +# Deprecated 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)_$(TARGET)/reports/$(PERIOD)/$(DESIGN_NAME)_$(TECH_NAME)_synth_area.rpt' $(NAND2_AREA) + python scripts/gate_analysis.py '$(DESIGN_NAME)_$(TARGET)/$(PERIOD)/reports/$(DESIGN_NAME)_$(TECH_NAME)_synth_area.rpt' $(NAND2_AREA) mv $(DESIGN_NAME)_synth.v $(DESIGN_NAME)_$(TARGET)_synth.v mv $(DESIGN_NAME)_synth.v.sdf $(DESIGN_NAME)_$(TARGET)_synth.v.sdf - sed -n -e '/module tc_sram_wrapper_256_64_00000008_00000001_00000001_none_0/,/endmodule/!p' $(DESIGN_NAME)_$(TARGET)_synth.v > $(DESIGN_NAME)_$(TARGET)_synth_modified.v - sed -i 's/cva6_ /cva6 /g' $(DESIGN_NAME)_$(TARGET)_synth_modified.v + sed -i 's/cva6_ /cva6 /g' $(DESIGN_NAME)_$(TARGET)_synth.v + echo $(NAND2_AREA) > $(DESIGN_NAME)_$(TARGET)/nand2area.txt + +# Supported for cv32a65x +rm_synth: pre_cva6_synth + @echo $(PERIOD) + cp Flist.cva6_synth ../../$(SYNTH_FLOW_NAME)/synth/ + CVA6_REPO_DIR=$(CVA6_REPO_DIR) make -C ../../$(SYNTH_FLOW_NAME)/synth/ platform_synth_topo + sed -i -n -e '/module hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080/,/endmodule/!p' $(DESIGN_NAME)_$(TARGET)_synth.v + sed -i -n -e '/module hpdcache_sram_1rw_00000006_0000001a_00000040/,/endmodule/!p' $(DESIGN_NAME)_$(TARGET)_synth.v + echo $(NAND2_AREA) > $(DESIGN_NAME)_$(TARGET)/nand2area.txt cva6_read: @export $(EXPORT_LIST); $(DC_SHELL_PATH)/dc_shell -f cva6_read.tcl -gui diff --git a/pd/synth/hpdcache_sram_1rw_00000006_0000001a_00000040.sv b/pd/synth/hpdcache_sram_1rw_00000006_0000001a_00000040.sv new file mode 100644 index 0000000000..138cfdea5e --- /dev/null +++ b/pd/synth/hpdcache_sram_1rw_00000006_0000001a_00000040.sv @@ -0,0 +1,60 @@ +/* + * Copyright 2023 CEA* + * *Commissariat a l'Energie Atomique et aux Energies Alternatives (CEA) + * + * SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + * + * Licensed under the Solderpad Hardware License v 2.1 (the “License”); you + * may not use this file except in compliance with the License, or, at your + * option, the Apache License version 2.0. You may obtain a copy of the + * License at + * + * https://solderpad.org/licenses/SHL-2.1/ + * + * Unless required by applicable law or agreed to in writing, any work + * 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. + */ +/* + * Authors : Cesar Fuguet + * Creation Date : March, 2020 + * Description : SRAM behavioral model + * History : + */ +module hpdcache_sram_1rw_00000006_0000001a_00000040 +#( + parameter int unsigned ADDR_SIZE = 6, + parameter int unsigned DATA_SIZE = 26, + parameter int unsigned DEPTH = 2**ADDR_SIZE +) +( + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [DATA_SIZE-1:0] wdata, + output logic [DATA_SIZE-1:0] rdata +); + + /* + * Internal memory array declaration + */ + typedef logic [DATA_SIZE-1:0] mem_t [DEPTH]; + mem_t mem; + + /* + * Process to update or read the memory array + */ + always_ff @(posedge clk) + begin : mem_update_ff + if (cs == 1'b1) begin + if (we == 1'b1) begin + mem[addr] <= wdata; + end + rdata <= mem[addr]; + end + end : mem_update_ff +endmodule : hpdcache_sram_1rw_00000006_0000001a_00000040 diff --git a/pd/synth/hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080.sv b/pd/synth/hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080.sv new file mode 100644 index 0000000000..cd294ca955 --- /dev/null +++ b/pd/synth/hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080.sv @@ -0,0 +1,64 @@ +/* + * Copyright 2023 CEA* + * *Commissariat a l'Energie Atomique et aux Energies Alternatives (CEA) + * + * SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + * + * Licensed under the Solderpad Hardware License v 2.1 (the “License”); you + * may not use this file except in compliance with the License, or, at your + * option, the Apache License version 2.0. You may obtain a copy of the + * License at + * + * https://solderpad.org/licenses/SHL-2.1/ + * + * Unless required by applicable law or agreed to in writing, any work + * 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. + */ +/* + * Authors : Cesar Fuguet + * Creation Date : March, 2020 + * Description : Behavioral model of a 1RW SRAM with write byte enable + * History : + */ +module hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080 + +#( + parameter int unsigned ADDR_SIZE = 7, + parameter int unsigned DATA_SIZE = 64, + parameter int unsigned DEPTH = 2**ADDR_SIZE +) +( + input logic clk, + input logic rst_n, + input logic cs, + input logic we, + input logic [ADDR_SIZE-1:0] addr, + input logic [DATA_SIZE-1:0] wdata, + input logic [DATA_SIZE/8-1:0] wbyteenable, + output logic [DATA_SIZE-1:0] rdata +); + + /* + * Internal memory array declaration + */ + typedef logic [DATA_SIZE-1:0] mem_t [DEPTH]; + mem_t mem; + + /* + * Process to update or read the memory array + */ + always_ff @(posedge clk) + begin : mem_update_ff + if (cs == 1'b1) begin + if (we == 1'b1) begin + for (int i = 0; i < DATA_SIZE/8; i++) begin + if (wbyteenable[i]) mem[addr][i*8 +: 8] <= wdata[i*8 +: 8]; + end + end + rdata <= mem[addr]; + end + end : mem_update_ff +endmodule : hpdcache_sram_wbyteenable_1rw_00000007_00000040_00000080 diff --git a/pd/synth/scripts/dc_setup.tcl b/pd/synth/scripts/dc_setup.tcl index a80d4bd690..fa73a6cb49 100644 --- a/pd/synth/scripts/dc_setup.tcl +++ b/pd/synth/scripts/dc_setup.tcl @@ -18,6 +18,7 @@ set FOUNDRY_PATH [getenv FOUNDRY_PATH]; set TARGET_LIBRARY_FILES [getenv TARGET_LIBRARY_FILES]; set INPUT_DELAY [getenv INPUT_DELAY]; set OUTPUT_DELAY [getenv OUTPUT_DELAY]; +set LOCAL_LIB_PATH [getenv LOCAL_LIB_PATH]; set ADDITIONAL_LINK_LIB_FILES " ";# Extra link logical libraries not included in TARGET_LIBRARY_FILES diff --git a/pd/synth/scripts/dc_setup_filenames.tcl b/pd/synth/scripts/dc_setup_filenames.tcl index 7d8d93edd1..3d98b1a229 100644 --- a/pd/synth/scripts/dc_setup_filenames.tcl +++ b/pd/synth/scripts/dc_setup_filenames.tcl @@ -18,11 +18,17 @@ puts "RM-Info: Running script [info script]\n" ################################################################################# set INPUTS_DIR ${DESIGN_NAME}_${TARGET}/inputs/ -set REPORTS_DIR ${DESIGN_NAME}_${TARGET}/reports/${PERIOD}/ -set OUTPUTS_DIR ${DESIGN_NAME}_${TARGET}/outputs/${PERIOD}/ +set REPORTS_DIR ${DESIGN_NAME}_${TARGET}/${PERIOD}/reports/ +set OUTPUTS_DIR ${DESIGN_NAME}_${TARGET}/${PERIOD}/outputs/ +set RESULTS_DIR ${DESIGN_NAME}_${TARGET}/${PERIOD}/netlist/ + +set SCENARIO mode_norm_ws0_wc_125 + file mkdir ${INPUTS_DIR} file mkdir ${REPORTS_DIR} file mkdir ${OUTPUTS_DIR} +file mkdir ${RESULTS_DIR} + ############### # Input Files # @@ -55,15 +61,16 @@ set DCRM_FINAL_POWER_REPORT ${REPORTS_DIR}/${DESIGN_ # Output Files # ################ -set DCRM_AUTOREAD_RTL_SCRIPT ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}.autoread_rtl.tcl -set DCRM_ELABORATED_DESIGN_DDC_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}.elab.ddc -set DCRM_COMPILE_ULTRA_DDC_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}.compile_ultra.ddc -set DCRM_FINAL_DDC_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.ddc -set DCRM_FINAL_VERILOG_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.v -set DCRM_FINAL_SDC_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.sdc -set DCRM_FINAL_SPEF_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.spef -set DCRM_FINAL_FSDB_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.fsdb -set DCRM_FINAL_VCD_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TECH}_synth.vcd +set DCRM_AUTOREAD_RTL_SCRIPT ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}.autoread_rtl.tcl +set DCRM_ELABORATED_DESIGN_DDC_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}.elab.ddc +set DCRM_COMPILE_ULTRA_DDC_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}.compile_ultra.ddc +set DCRM_FINAL_DDC_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.ddc +set DCRM_FINAL_VERILOG_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.v +set DCRM_FINAL_SDC_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.${SCENARIO}.sdc +set DCRM_FINAL_SPEF_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.${SCENARIO}.spef +set DCRM_FINAL_FSDB_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.fsdb +set DCRM_FINAL_VCD_OUTPUT_FILE ${OUTPUTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.vcd +set DCRM_FINAL_SDF_OUTPUT_FILE ${RESULTS_DIR}/${DESIGN_NAME}_${TARGET}_${TECH}_synth.${SCENARIO}.sdf puts "RM-Info: Completed script [info script]\n" diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index 881f01c48d..3f38f4311d 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -58,6 +58,8 @@ INFO HdlLibDuCheck_03 1 Reports that 'hdllibdu' is not required +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Severity Rule Name Count Short Help =============================================================================== +ERROR SYNTH_5251 1 This gets flagged for out-of-range for + Part-Select Operations. ERROR SYNTH_5273 1 Number of bits for net/variable exceeds the mthresh value WARNING SYNTH_12605 1 Used Priority/Unique Type case/if diff --git a/util/init_gate.do b/util/init_gate.do new file mode 100644 index 0000000000..b64ba17ab9 --- /dev/null +++ b/util/init_gate.do @@ -0,0 +1 @@ +fsdbDumpvars 0 "ariane_gate_tb" +all +trace_process diff --git a/verif/sim/Makefile b/verif/sim/Makefile index c2e8615272..7a9d7d333a 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -32,8 +32,9 @@ FLIST_TB := $(CVA6_TB_DIR)/Flist.cva6_tb # target takes one of the following cva6 hardware configuration: # cv64a6_imafdc_sv39, cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32 target ?= cv64a6_imafdc_sv39 -FLIST_CORE := $(if $(gate), $(CVA6_REPO_DIR)/core/Flist.cva6_gate,$(CVA6_REPO_DIR)/core/Flist.cva6) - +FLIST_CORE = $(if $(gate),$(CVA6_REPO_DIR)/core/Flist.cva6_gate,$(CVA6_REPO_DIR)/core/Flist.cva6) +th_top_level := $(if $(gate),ariane_gate_tb,ariane_tb) +do_file := $(if $(gate),init_gate,init_testharness) TRACE_FAST ?= TRACE_COMPACT ?= VERDI ?= @@ -246,6 +247,7 @@ vcs_uvm_comp: -f $(FLIST_CORE) -f $(FLIST_TB) \ -f $(CVA6_UVMT_DIR)/uvmt_cva6.flist \ $(cov-comp-opt) +define+UNSUPPORTED_WITH+ $(isscomp_opts)\ + -ignore initializer_driver_checks \ -top uvmt_cva6_tb vcs_uvm_run: vcs_uvm_comp @@ -323,8 +325,8 @@ vcs_clean_all: # testharness specific commands, variables ############################################################################### vcs-testharness: - make -C $(path_var) vcs_build target=$(target) defines=$(subst +define+,,$(isscomp_opts))$(if $(spike-tandem),SPIKE_TANDEM=1) - $(path_var)/work-vcs/simv $(if $(VERDI), -verdi -do $(path_var)/util/init_testharness.do,) +permissive \ + make -C $(path_var) vcs_build target=$(target) gate=$(gate) top_level=$(th_top_level) flist=$(FLIST_CORE) defines=$(subst +define+,,$(isscomp_opts))$(if $(spike-tandem),SPIKE_TANDEM=1) + $(path_var)/work-vcs/simv $(if $(VERDI), -verdi -do $(path_var)/util/$(do_file).do,) +permissive \ +permissive-off $(COMMON_RUN_ARGS) # If present, move default waveform files to log directory. # Keep track of target in waveform file name. diff --git a/verif/sim/cva6.yaml b/verif/sim/cva6.yaml index b266a5a47b..219781391d 100644 --- a/verif/sim/cva6.yaml +++ b/verif/sim/cva6.yaml @@ -45,7 +45,14 @@ tool_path: SPIKE_PATH tb_path: TB_PATH cmd: > - make vcs-uvm target= gate=1 cov=${cov} variant= elf= tool_path= isscomp_opts= issrun_opts= isspostrun_opts= log= + make vcs-testharness target= gate=1 cov=${cov} variant= elf= path_var= tool_path= isscomp_opts= issrun_opts= isspostrun_opts= log= + +- iss: vcs-gate-tb + path_var: RTL_PATH + tool_path: SPIKE_PATH + tb_path: TB_PATH + cmd: > + make vcs-testharness target= th_top_level=ariane_gate_tb do_file=init_gate cov=${cov} variant= elf= path_var= tool_path= isscomp_opts= issrun_opts= isspostrun_opts= log= - iss: vcs-uvm path_var: RTL_PATH diff --git a/verif/sim/link.ld b/verif/sim/link.ld index ad50f56e2e..d064469c6b 100644 --- a/verif/sim/link.ld +++ b/verif/sim/link.ld @@ -19,17 +19,48 @@ ENTRY(_start) SECTIONS { . = 0x80000000; + _start_text = .; .text.init : { *(.text.init) } . = ALIGN(0x1000); .tohost : { *(.tohost) } . = ALIGN(0x1000); .text : { *(.text) } . = ALIGN(0x1000); + .text.startup : { *(.text.startup) } + . = ALIGN(0x1000); + _end_text = .; + . = ALIGN(0x1000); + .rodata : { *(.rodata*)} + . = ALIGN(0x8); + . = ALIGN(0x1000); .page_table : { *(.page_table) } .user_stack : { *(.user_stack) } .kernel_data : { *(.kernel_data) } .kernel_stack : { *(.kernel_stack) } .data : { *(.data) } + .sdata : { + __global_pointer$ = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + + /* bss segment */ +/* .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + }*/ .bss : { *(.bss) } + .tdata : + { + _tdata_begin = .; + *(.tdata) + _tdata_end = .; + } + .tbss : + { + *(.tbss) + _tbss_end = .; + } + _end = .; } diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index 79987b2530..e1d60de852 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -299,8 +299,12 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( end load_address = (address[23:0] >> 3) + i; if (load_address != last_load_address) begin - `MAIN_MEM(load_address) = mem_row; - last_load_address = load_address; + if (address[31:0] < 'h84000000) begin + `MAIN_MEM(load_address) = mem_row; + end else begin + `USER_MEM(load_address) = mem_row; + end + last_load_address = load_address; end else begin `uvm_info( "Debug info", $sformatf(" Address: %x Already Loaded! ELF file might have less than 64 bits granularity on segments.", load_address), UVM_LOW) end