diff --git a/README.md b/README.md index 691a46a047..545f067e3f 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,7 @@ python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv64a6_imafdc_sv39-p.ya # COREV-APU FPGA Emulation -We currently provide support for the [Genesys 2 board](https://reference.digilentinc.com/reference/programmable-logic/genesys-2/reference-manual) and the [Agilex 7 Development Kit](https://www.intel.la/content/www/xl/es/products/details/fpga/development-kits/agilex/agf014.html). +We currently provide support for the [Genesys 2 board](https://reference.digilentinc.com/reference/programmable-logic/genesys-2/reference-manual) and the [Agilex 7 Development Kit](https://www.intel.la/content/www/xl/es/products/details/fpga/development-kits/agilex/agf014.html). In order the run the FPGA build scripts you will need to use Xilinx 2018.2. - **Genesys 2** diff --git a/ci/install-verilator.sh b/ci/install-verilator.sh index b100a656de..d9415fcbe7 100755 --- a/ci/install-verilator.sh +++ b/ci/install-verilator.sh @@ -10,7 +10,7 @@ fi VERILATOR_REPO="https://github.com/verilator/verilator.git" VERILATOR_BRANCH="master" # Use the release tag instead of a full SHA1 hash. -VERILATOR_HASH="v5.008" +VERILATOR_HASH="v5.028" VERILATOR_PATCH="$ROOT/verif/regress/verilator-v5.patch" VERILATOR_BUILD_DIR=$PWD/verilator-$VERILATOR_HASH/verilator diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 7bbf529048..9a2977cfd0 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -170,7 +170,9 @@ module csr_regfile // RVFI output rvfi_probes_csr_t rvfi_csr_o, //jvt output - output jvt_t jvt_o + output jvt_t jvt_o, + // Data endianness output + output bit endian ); localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg); @@ -1390,7 +1392,9 @@ module csr_regfile mstatus_d.wpri1 = 1'b0; mstatus_d.wpri2 = 1'b0; mstatus_d.wpri0 = 1'b0; - mstatus_d.ube = 1'b0; // CVA6 is little-endian + // Mirror MBE + mstatus_d.sbe = mstatus_d.mbe; + mstatus_d.ube = mstatus_d.mbe; // this register has side-effects on other registers, flush the pipeline flush_o = 1'b1; end @@ -2535,6 +2539,8 @@ module csr_regfile assign single_step_o = CVA6Cfg.DebugEn ? dcsr_q.step : 1'b0; assign mcountinhibit_o = {{29 - MHPMCounterNum{1'b0}}, mcountinhibit_q}; + assign endian = mstatus_q.mbe; + // sequential process always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin diff --git a/core/cva6.sv b/core/cva6.sv index 6c341da5bc..98efe8524f 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -164,6 +164,7 @@ module cva6 fu_t fu; fu_op operation; logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; + logic endian; }, localparam type fu_data_t = struct packed { @@ -207,6 +208,7 @@ module cva6 logic [CVA6Cfg.DcacheIdWidth-1:0] data_id; logic kill_req; logic tag_valid; + logic endian; }, localparam type dcache_req_o_t = struct packed { @@ -1200,7 +1202,8 @@ module cva6 .mcountinhibit_o (mcountinhibit_csr_perf), .jvt_o (jvt), //RVFI - .rvfi_csr_o (rvfi_csr) + .rvfi_csr_o (rvfi_csr), + .endian (rvfi_lsu_ctrl.endian) ); // ------------------------ diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index e965b1e093..396ae5b301 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -121,6 +121,7 @@ package ariane_pkg; | riscv::SSTATUS_UPIE | riscv::SSTATUS_SPIE | riscv::SSTATUS_UXL + | riscv::SSTATUS_SBE | riscv::sstatus_sd(Cfg.IS_XLEN64); endfunction @@ -815,4 +816,19 @@ package ariane_pkg; return (n < 0) ? 0 : n; endfunction : avoid_neg + function automatic [CVA6Cfg.XLEN-1:0] byte_swap; + input [CVA6Cfg.XLEN-1:0] data; + input int width; + input bit swap; + begin + if (!swap) begin + byte_swap = data; + end else begin + byte_swap = '0; + for (int i = 0; i < width; i += 8) begin + byte_swap[i +: 8] = data[width - 8 - i +: 8]; + end + end + end + endfunction endpackage diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index e9dbc65a18..28063b726e 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -726,6 +726,8 @@ package riscv; localparam logic [63:0] SSTATUS_MXR = 'h00080000; localparam logic [63:0] SSTATUS_UPIE = 'h00000010; localparam logic [63:0] SSTATUS_UXL = 64'h0000000300000000; + localparam logic [63:0] SSTATUS_SBE = 'h1000000000; + localparam logic [63:0] SSTATUS_UBE = 'h40; // CSR Bit Implementation Masks function automatic logic [63:0] sstatus_sd(logic IS_XLEN64); @@ -762,6 +764,9 @@ package riscv; localparam logic [63:0] MSTATUS_TVM = 'h00100000; localparam logic [63:0] MSTATUS_TW = 'h00200000; localparam logic [63:0] MSTATUS_TSR = 'h00400000; + localparam logic [63:0] MSTATUS_MBE = 'h2000000000; + localparam logic [63:0] MSTATUS_SBE = 'h1000000000; + localparam logic [63:0] MSTATUS_UBE = 'h40; function automatic logic [63:0] mstatus_uxl(logic IS_XLEN64); return {30'h0000000, IS_XLEN64, IS_XLEN64, 32'h00000000}; endfunction diff --git a/core/load_unit.sv b/core/load_unit.sv index 0a66c51062..7e869a810c 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -242,6 +242,7 @@ module load_unit req_port_o.kill_req = 1'b0; req_port_o.tag_valid = 1'b0; req_port_o.data_be = lsu_ctrl_i.be; + req_port_o.endian = lsu_ctrl_i.endian; req_port_o.data_size = extract_transfer_size(lsu_ctrl_i.operation); pop_ld_o = 1'b0; @@ -467,9 +468,11 @@ module load_unit // Sign Extend // --------------- logic [CVA6Cfg.XLEN-1:0] shifted_data; + logic [CVA6Cfg.XLEN-1:0] endian_correct_data; // realign as needed assign shifted_data = req_port_i.data_rdata >> {ldbuf_rdata.address_offset, 3'b000}; + assign endian_correct_data = byte_swap(shifted_data, req_port_o.data_size, req_port_o.endian); /* // result mux (leaner code, but more logic stages. // can be used instead of the code below (in between //result mux fast) if timing is not so critical) @@ -511,30 +514,30 @@ module load_unit always_comb begin unique case (ldbuf_rdata.operation) ariane_pkg::LW, ariane_pkg::LWU, ariane_pkg::HLV_W, ariane_pkg::HLV_WU, ariane_pkg::HLVX_WU: - result_o = {{CVA6Cfg.XLEN - 32{rdata_sign_bit}}, shifted_data[31:0]}; + result_o = {{CVA6Cfg.XLEN - 32{rdata_sign_bit}}, endian_correct_data[31:0]}; ariane_pkg::LH, ariane_pkg::LHU, ariane_pkg::HLV_H, ariane_pkg::HLV_HU, ariane_pkg::HLVX_HU: - result_o = {{CVA6Cfg.XLEN - 32 + 16{rdata_sign_bit}}, shifted_data[15:0]}; + result_o = {{CVA6Cfg.XLEN - 32 + 16{rdata_sign_bit}}, endian_correct_data[15:0]}; ariane_pkg::LB, ariane_pkg::LBU, ariane_pkg::HLV_B, ariane_pkg::HLV_BU: - result_o = {{CVA6Cfg.XLEN - 32 + 24{rdata_sign_bit}}, shifted_data[7:0]}; + result_o = {{CVA6Cfg.XLEN - 32 + 24{rdata_sign_bit}}, endian_correct_data[7:0]}; default: begin // FLW, FLH and FLB have been defined here in default case to improve Code Coverage if (CVA6Cfg.FpPresent) begin unique case (ldbuf_rdata.operation) ariane_pkg::FLW: begin - result_o = {{CVA6Cfg.XLEN - 32{rdata_sign_bit}}, shifted_data[31:0]}; + result_o = {{CVA6Cfg.XLEN - 32{rdata_sign_bit}}, endian_correct_data[31:0]}; end ariane_pkg::FLH: begin - result_o = {{CVA6Cfg.XLEN - 32 + 16{rdata_sign_bit}}, shifted_data[15:0]}; + result_o = {{CVA6Cfg.XLEN - 32 + 16{rdata_sign_bit}}, endian_correct_data[15:0]}; end ariane_pkg::FLB: begin - result_o = {{CVA6Cfg.XLEN - 32 + 24{rdata_sign_bit}}, shifted_data[7:0]}; + result_o = {{CVA6Cfg.XLEN - 32 + 24{rdata_sign_bit}}, endian_correct_data[7:0]}; end default: begin - result_o = shifted_data[CVA6Cfg.XLEN-1:0]; + result_o = endian_correct_data[CVA6Cfg.XLEN-1:0]; end endcase end else begin - result_o = shifted_data[CVA6Cfg.XLEN-1:0]; + result_o = endian_correct_data[CVA6Cfg.XLEN-1:0]; end end endcase diff --git a/core/store_unit.sv b/core/store_unit.sv index 141763dda7..1beb57b7fa 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -138,6 +138,8 @@ module store_unit logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; + logic [CVA6Cfg.XLEN-1:0] endian_correct_data; + // output assignments assign vaddr_o = lsu_ctrl_i.vaddr; // virtual address assign hs_ld_st_inst_o = CVA6Cfg.RVH ? lsu_ctrl_i.hs_ld_st_inst : 1'b0; @@ -251,9 +253,12 @@ module store_unit always_comb begin st_be_n = lsu_ctrl_i.be; // don't shift the data if we are going to perform an AMO as we still need to operate on this data - st_data_n = (CVA6Cfg.RVA && instr_is_amo) ? lsu_ctrl_i.data[CVA6Cfg.XLEN-1:0] : - data_align(lsu_ctrl_i.vaddr[2:0], {{64 - CVA6Cfg.XLEN{1'b0}}, lsu_ctrl_i.data}); + st_data_n = ((CVA6Cfg.RVA && instr_is_amo) ? lsu_ctrl_i.data[CVA6Cfg.XLEN-1:0] : + data_align(lsu_ctrl_i.vaddr[2:0], {{64 - CVA6Cfg.XLEN{1'b0}}, lsu_ctrl_i.data})); st_data_size_n = extract_transfer_size(lsu_ctrl_i.operation); + + assign endian_correct_data = byte_swap(st_data_n, st_data_size_n, lsu_ctrl_i.endian); + // save AMO op for next cycle if (CVA6Cfg.RVA) begin case (lsu_ctrl_i.operation) @@ -356,7 +361,7 @@ module store_unit end else begin state_q <= state_d; st_be_q <= st_be_n; - st_data_q <= st_data_n; + st_data_q <= endian_correct_data; trans_id_q <= trans_id_n; st_data_size_q <= st_data_size_n; amo_op_q <= amo_op_d; diff --git a/docs/scripts/classes.py b/docs/scripts/classes.py index cfc79cb145..f11b5ec8b0 100644 --- a/docs/scripts/classes.py +++ b/docs/scripts/classes.py @@ -7,7 +7,7 @@ # # Original Author: Jean-Roch COULON - Thales -#!/usr/bin/python3 +#!/usr/bin/env python3 class Parameter: diff --git a/docs/scripts/define_blacklist.py b/docs/scripts/define_blacklist.py index bdee4b2fdf..2ed886339c 100644 --- a/docs/scripts/define_blacklist.py +++ b/docs/scripts/define_blacklist.py @@ -7,7 +7,7 @@ # # Original Author: Jean-Roch COULON - Thales -#!/usr/bin/python3 +#!/usr/bin/env python3 def define_blacklist(parameters): diff --git a/docs/scripts/parameters_extractor.py b/docs/scripts/parameters_extractor.py index 09365c263d..e5ef4dd766 100644 --- a/docs/scripts/parameters_extractor.py +++ b/docs/scripts/parameters_extractor.py @@ -7,7 +7,7 @@ # # Original Author: Jean-Roch COULON - Thales -#!/usr/bin/python3 +#!/usr/bin/env python3 import sys import os diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index 261e2d2435..1abb760dd1 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -7,7 +7,7 @@ # # Original Author: Jean-Roch COULON - Thales -#!/usr/bin/python3 +#!/usr/bin/env python3 import re import sys diff --git a/verif/regress/install-verilator.sh b/verif/regress/install-verilator.sh index a70fc145f6..b1c4e5ef49 100755 --- a/verif/regress/install-verilator.sh +++ b/verif/regress/install-verilator.sh @@ -18,7 +18,7 @@ fi VERILATOR_REPO="https://github.com/verilator/verilator.git" VERILATOR_BRANCH="master" # Use the release tag instead of a full SHA1 hash. -VERILATOR_HASH="v5.008" +VERILATOR_HASH="v5.028" VERILATOR_PATCH="$ROOT_PROJECT/verif/regress/verilator-v5.patch" # Unset historical variable VERILATOR_ROOT as it collides with the build process. diff --git a/verif/sim/cva6.py b/verif/sim/cva6.py index 4c5075ec89..9ff991f69e 100644 --- a/verif/sim/cva6.py +++ b/verif/sim/cva6.py @@ -1004,7 +1004,7 @@ def check_spike_version(): logging.info(f"- stderr:\n\n{user_spike_stderr_string}") # Run 'ldd' on Spike binary and print contents of stdout and stderr. spike_ldd = subprocess.run( - "/bin/ldd $SPIKE_PATH/spike", capture_output=True, text=True, shell=True + "ldd $SPIKE_PATH/spike", capture_output=True, text=True, shell=True ) spike_ldd_stdout = spike_ldd.stdout.strip() spike_ldd_stderr = spike_ldd.stderr.strip() @@ -1030,7 +1030,7 @@ def check_spike_version(): def check_verilator_version(): - REQUIRED_VERILATOR_VERSION = "5.008" + REQUIRED_VERILATOR_VERSION = "5.028" verilator_version_string = run_cmd("verilator --version") logging.info(f"Verilator Version: {verilator_version_string.strip()}")