From f6441a2e6f901748b504ef93872649c9463a404e Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sun, 15 Mar 2026 16:07:39 +0800 Subject: initial commit: project architecture --- rv64cpu/CMakeLists.txt | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 rv64cpu/CMakeLists.txt (limited to 'rv64cpu/CMakeLists.txt') diff --git a/rv64cpu/CMakeLists.txt b/rv64cpu/CMakeLists.txt new file mode 100644 index 0000000..1242a58 --- /dev/null +++ b/rv64cpu/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.20) +project(richard_cpu + VERSION 0.1.0 + DESCRIPTION "RV64IMAZicsr_Zifencei Five-Stage Pipelined CPU SoC" + LANGUAGES CXX C +) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# ─── Options ──────────────────────────────────────────────────────────────────── +option(ENABLE_TRACE "Enable VCD waveform tracing" ON) +option(ENABLE_COVERAGE "Enable code coverage for RTL" OFF) +option(BUILD_SW "Build software targets (requires riscv64 toolchain)" OFF) + +# ─── Locate Verilator ──────────────────────────────────────────────────────────── +find_package(verilator REQUIRED HINTS $ENV{VERILATOR_ROOT}) +message(STATUS "Found Verilator: ${verilator_DIR}") + +# ─── RTL Source Directories ────────────────────────────────────────────────────── +set(RTL_DIR ${CMAKE_SOURCE_DIR}/rtl) +set(RTL_CORE_DIR ${RTL_DIR}/core) +set(RTL_CACHE_DIR ${RTL_DIR}/cache) +set(RTL_BUS_DIR ${RTL_DIR}/bus) +set(RTL_PERIPS_DIR ${RTL_DIR}/perips) +set(RTL_SOC_DIR ${RTL_DIR}/soc) +set(RTL_INCLUDE_DIR ${RTL_CORE_DIR}/include) + +# ─── Common Verilator Flags ────────────────────────────────────────────────────── +set(VERILATOR_COMMON_FLAGS + --sv + -Wall + -Wno-DECLFILENAME + -Wno-UNUSED + --x-initial unique + --x-assign unique +) + +if(ENABLE_TRACE) + list(APPEND VERILATOR_COMMON_FLAGS --trace) + add_compile_definitions(VM_TRACE=1) +endif() + +if(ENABLE_COVERAGE) + list(APPEND VERILATOR_COMMON_FLAGS --coverage) +endif() + +# ─── Include Verilator CMake Helper ────────────────────────────────────────────── +include(${CMAKE_SOURCE_DIR}/tools/verilator.cmake) + +# ─── Waveform Output Directory ────────────────────────────────────────────────── +file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/waves) + +# ─── Testbench Subdirectory ───────────────────────────────────────────────────── +add_subdirectory(tb) + +# ─── Software Subdirectory (optional) ─────────────────────────────────────────── +if(BUILD_SW) + add_subdirectory(sw) +endif() + +# ─── Summary ──────────────────────────────────────────────────────────────────── +message(STATUS "") +message(STATUS "╔══════════════════════════════════════════════╗") +message(STATUS "║ richard-cpu build configuration ║") +message(STATUS "╠══════════════════════════════════════════════╣") +message(STATUS "║ Trace: ${ENABLE_TRACE}") +message(STATUS "║ Coverage: ${ENABLE_COVERAGE}") +message(STATUS "║ Software: ${BUILD_SW}") +message(STATUS "╚══════════════════════════════════════════════╝") +message(STATUS "") -- cgit v1.2.3 From ba535e24e0aaf2fcefa1196dc4d12ad241f349d3 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sun, 15 Mar 2026 23:30:38 +0800 Subject: Add and test alu unit --- rv64cpu/.gitignore | 3 ++ rv64cpu/CMakeLists.txt | 3 ++ rv64cpu/rtl/core/alu.sv | 65 ++++++++++++++++++++++++ rv64cpu/rtl/core/include/rv64_pkg.sv | 95 ++++++++++++++++++++++++++++++++++++ rv64cpu/tb/CMakeLists.txt | 16 +++--- rv64cpu/tb/unit/tb_alu.cc | 67 +++++++++++++++++++++++++ 6 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 rv64cpu/rtl/core/alu.sv create mode 100644 rv64cpu/rtl/core/include/rv64_pkg.sv create mode 100644 rv64cpu/tb/unit/tb_alu.cc (limited to 'rv64cpu/CMakeLists.txt') diff --git a/rv64cpu/.gitignore b/rv64cpu/.gitignore index e5b9664..57710b6 100644 --- a/rv64cpu/.gitignore +++ b/rv64cpu/.gitignore @@ -28,3 +28,6 @@ fpga/gowin/*.fs # OS .DS_Store Thumbs.db + +# Cache +.cache/ \ No newline at end of file diff --git a/rv64cpu/CMakeLists.txt b/rv64cpu/CMakeLists.txt index 1242a58..4649abb 100644 --- a/rv64cpu/CMakeLists.txt +++ b/rv64cpu/CMakeLists.txt @@ -52,6 +52,9 @@ include(${CMAKE_SOURCE_DIR}/tools/verilator.cmake) # ─── Waveform Output Directory ────────────────────────────────────────────────── file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/waves) +# ─── Testing ──────────────────────────────────────────────────────────────────── +enable_testing() + # ─── Testbench Subdirectory ───────────────────────────────────────────────────── add_subdirectory(tb) diff --git a/rv64cpu/rtl/core/alu.sv b/rv64cpu/rtl/core/alu.sv new file mode 100644 index 0000000..ac2e9c9 --- /dev/null +++ b/rv64cpu/rtl/core/alu.sv @@ -0,0 +1,65 @@ +// Richard CPU +// Copyright (C) 2026 Richard Qin + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// File path: rtl/core/alu.sv +// Description: 64-bit Arithmetic Logic Unit (ALU) + +module alu + import rv64_pkg::*; +( + input alu_op_t alu_op, // ALU operation select (from decoder) + input logic [XLEN-1:0] rs1_val, // Operand 1 (register rs1 value or PC) + input logic [XLEN-1:0] rs2_val, // Operand 2 (register rs2 value or immediate) + + output logic [XLEN-1:0] alu_res // ALU result +); + + // Shift amount: RV64I uses lower 6 bits of rs2 (shamt[5:0]) + logic [5:0] shamt; + assign shamt = rs2_val[5:0]; + + always_comb begin + alu_res = '0; + + case (alu_op) + ALU_ADD: alu_res = rs1_val + rs2_val; + ALU_SUB: alu_res = rs1_val - rs2_val; + + // Logical left shift: the shift amount is the lower 6 bits of rs2 + ALU_SLL: alu_res = rs1_val << shamt; + + // Set less than (signed) + ALU_SLT: alu_res = {63'b0, $signed(rs1_val) < $signed(rs2_val)}; + + // Set less than (unsigned) + ALU_SLTU: alu_res = {63'b0, rs1_val < rs2_val}; + + ALU_XOR: alu_res = rs1_val ^ rs2_val; + + // Logical right shift: the shift amount is the lower 6 bits of rs2 + ALU_SRL: alu_res = rs1_val >> shamt; + + // Arithmetic right shift: the shift amount is the lower 6 bits of rs2 + ALU_SRA: alu_res = $unsigned($signed(rs1_val) >>> shamt); + + ALU_OR: alu_res = rs1_val | rs2_val; + ALU_AND: alu_res = rs1_val & rs2_val; + + default: alu_res = '0; + endcase + end + +endmodule diff --git a/rv64cpu/rtl/core/include/rv64_pkg.sv b/rv64cpu/rtl/core/include/rv64_pkg.sv new file mode 100644 index 0000000..984a93b --- /dev/null +++ b/rv64cpu/rtl/core/include/rv64_pkg.sv @@ -0,0 +1,95 @@ +// Richard CPU +// Copyright (C) 2026 Richard Qin + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// File path: rtl/core/include/rv64_pkg.sv +// Description: RISC-V 64-bit base instruction set global definition package + +package rv64_pkg; + + localparam XLEN = 64; + localparam INST_WIDTH = 32; + + // RISC-V Base Opcode Map (inst[6:0]) + // Reference: RISC-V Unprivileged ISA V20240411, Table 34 + typedef enum logic [6:0] { + // Loads + OPCODE_LOAD = 7'b000_0011, // LB/LH/LW/LD/LBU/LHU/LWU + OPCODE_LOAD_FP = 7'b000_0111, // FLW/FLD + + // Misc-Mem + OPCODE_MISC_MEM = 7'b000_1111, // FENCE / FENCE.I (Zifencei) + + // Immediate ALU + OPCODE_OP_IMM = 7'b001_0011, // ADDI/SLTI/ANDI/ORI/XORI/SLLI/SRLI/SRAI... + OPCODE_OP_IMM_32 = 7'b001_1011, // ADDIW/SLLIW/SRLIW/SRAIW (RV64 only) + + // Upper Immediate + OPCODE_AUIPC = 7'b001_0111, // AUIPC + OPCODE_LUI = 7'b011_0111, // LUI + + // Stores + OPCODE_STORE = 7'b010_0011, // SB/SH/SW/SD + OPCODE_STORE_FP = 7'b010_0111, // FSW/FSD + + // Atomic (A extension) + OPCODE_AMO = 7'b010_1111, // LR/SC/AMOSWAP/AMOADD/... + + // Register ALU + OPCODE_OP = 7'b011_0011, // ADD/SUB/AND/OR/XOR/SLL/SRL/SRA/SLT/SLTU/MUL/DIV... + OPCODE_OP_32 = 7'b011_1011, // ADDW/SUBW/SLLW/SRLW/SRAW/MULW/DIVW... (RV64 only) + + // Floating-point fused multiply-add + OPCODE_MADD = 7'b100_0011, // FMADD.S/D + OPCODE_MSUB = 7'b100_0111, // FMSUB.S/D + OPCODE_NMSUB = 7'b100_1011, // FNMSUB.S/D + OPCODE_NMADD = 7'b100_1111, // FNMADD.S/D + + // Floating-point arithmetic + OPCODE_OP_FP = 7'b101_0011, // FADD/FSUB/FMUL/FDIV/FSQRT/FCMP/FCVT/FMV/FCLASS... + + // Branches + OPCODE_BRANCH = 7'b110_0011, // BEQ/BNE/BLT/BGE/BLTU/BGEU + + // Jumps + OPCODE_JALR = 7'b110_0111, // JALR + OPCODE_JAL = 7'b110_1111, // JAL + + // System + OPCODE_SYSTEM = 7'b111_0011, // ECALL/EBREAK/CSR*/MRET/SRET/WFI/SFENCE.VMA + + // Custom (reserved for extensions) + OPCODE_CUSTOM_0 = 7'b000_1011, + OPCODE_CUSTOM_1 = 7'b010_1011, + OPCODE_CUSTOM_2 = 7'b101_1011, + OPCODE_CUSTOM_3 = 7'b111_1011 + } opcode_t; + + // ALU Operation Encoding + // Derived from funct3 + funct7[5] of R-type / I-type instructions + typedef enum logic [3:0] { + ALU_ADD = 4'b0000, // Add + ALU_SUB = 4'b1000, // Subtract + ALU_SLL = 4'b0001, // Shift Left Logical + ALU_SLT = 4'b0010, // Set Less Than (signed) + ALU_SLTU = 4'b0011, // Set Less Than (unsigned) + ALU_XOR = 4'b0100, // Exclusive Or + ALU_SRL = 4'b0101, // Shift Right Logical + ALU_SRA = 4'b1101, // Shift Right Arithmetic + ALU_OR = 4'b0110, // Or + ALU_AND = 4'b0111 // And + } alu_op_t; + +endpackage diff --git a/rv64cpu/tb/CMakeLists.txt b/rv64cpu/tb/CMakeLists.txt index 8679562..73df088 100644 --- a/rv64cpu/tb/CMakeLists.txt +++ b/rv64cpu/tb/CMakeLists.txt @@ -30,14 +30,14 @@ file(GLOB_RECURSE ALL_RTL_SOURCES # # Uncomment and fill in as you implement each module, for example: # -# add_verilator_target( -# NAME tb_alu -# TOP_MODULE alu -# SOURCES ${RTL_CORE_DIR}/include/rv64_pkg.sv -# ${RTL_CORE_DIR}/alu.sv -# INCLUDE_DIRS ${RTL_COMMON_INCLUDES} -# TB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/unit/tb_alu.cpp -# ) +add_verilator_target( + NAME tb_alu + TOP_MODULE alu + SOURCES ${RTL_CORE_DIR}/include/rv64_pkg.sv + ${RTL_CORE_DIR}/alu.sv + INCLUDE_DIRS ${RTL_COMMON_INCLUDES} + TB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/unit/tb_alu.cc +) # # add_verilator_target( # NAME tb_decoder diff --git a/rv64cpu/tb/unit/tb_alu.cc b/rv64cpu/tb/unit/tb_alu.cc new file mode 100644 index 0000000..b783815 --- /dev/null +++ b/rv64cpu/tb/unit/tb_alu.cc @@ -0,0 +1,67 @@ +#include "Valu.h" +#include +#include +#include +#include + +enum AluOp { + ALU_ADD = 0b0000, + ALU_SUB = 0b1000, + ALU_SLL = 0b0001, + ALU_SLT = 0b0010, + ALU_SLTU = 0b0011, + ALU_XOR = 0b0100, + ALU_SRL = 0b0101, + ALU_SRA = 0b1101, + ALU_OR = 0b0110, + ALU_AND = 0b0111 +}; + +void test_alu(Valu* alu, uint8_t op, uint64_t rs1, uint64_t rs2, uint64_t expected, const char* test_name) { + alu->alu_op = op; + alu->rs1_val = rs1; + alu->rs2_val = rs2; + + alu->eval(); + + if (alu->alu_res == expected) { + std::cout << "\033[32m"; + std::cout << "[PASS] " << test_name << " | " + << rs1 << " op " << rs2 << " = " << expected << std::endl; + std::cout << "\033[0m"; + } else { + std::cout << "\033[31m"; + std::cerr << "[FAIL] " << test_name << " | " + << "Expected: " << expected << ", Got: " << alu->alu_res << std::endl; + std::cout << "\033[0m"; + assert(false); + } +} + +int main(int argc, char** argv) { + Verilated::commandArgs(argc, argv); + Valu* alu = new Valu; + + std::cout << "Running ALU Unit Test ..." << std::endl; + + test_alu(alu, ALU_ADD, 100, 50, 150, "ADD_Positive"); + test_alu(alu, ALU_SUB, 100, 50, 50, "SUB_Positive"); + + test_alu(alu, ALU_ADD, (uint64_t)-5, 10, 5, "ADD_Negative"); + + test_alu(alu, ALU_AND, 0xFF00, 0x0F0F, 0x0F00, "AND_Mask"); + test_alu(alu, ALU_XOR, 0xAAAA, 0xFFFF, 0x5555, "XOR_Invert"); + + test_alu(alu, ALU_SLL, 1, 10, 1024, "SLL_By_10"); + + uint64_t minus_one = (uint64_t)-1; + uint64_t five = 5; + + test_alu(alu, ALU_SLTU, minus_one, five, 0, "SLTU (Unsigned: -1 < 5 is False)"); + test_alu(alu, ALU_SLT, minus_one, five, 1, "SLT (Signed: -1 < 5 is True)"); + + std::cout << "All tests passed!" << std::endl; + + delete alu; + return 0; +} \ No newline at end of file -- cgit v1.2.3 From 328d4ef7537a98bab8f6891a0280cda9e03b0cee Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Tue, 7 Apr 2026 21:21:03 +0800 Subject: feat(tlb): enhance TLB functionality with ASID-targeted flush and additional test cases --- rv64cpu/CMakeLists.txt | 6 +++++ rv64cpu/rtl/core/mmu/tlb.sv | 2 +- rv64cpu/tb/unit/tb_tlb.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) (limited to 'rv64cpu/CMakeLists.txt') diff --git a/rv64cpu/CMakeLists.txt b/rv64cpu/CMakeLists.txt index 4649abb..da146d5 100644 --- a/rv64cpu/CMakeLists.txt +++ b/rv64cpu/CMakeLists.txt @@ -1,4 +1,9 @@ cmake_minimum_required(VERSION 3.20) + +if(POLICY CMP0144) + cmake_policy(SET CMP0144 NEW) +endif() + project(richard_cpu VERSION 0.1.0 DESCRIPTION "RV64IMAZicsr_Zifencei Five-Stage Pipelined CPU SoC" @@ -54,6 +59,7 @@ file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/waves) # ─── Testing ──────────────────────────────────────────────────────────────────── enable_testing() +include(CTest) # ─── Testbench Subdirectory ───────────────────────────────────────────────────── add_subdirectory(tb) diff --git a/rv64cpu/rtl/core/mmu/tlb.sv b/rv64cpu/rtl/core/mmu/tlb.sv index 521b08a..f466cb3 100644 --- a/rv64cpu/rtl/core/mmu/tlb.sv +++ b/rv64cpu/rtl/core/mmu/tlb.sv @@ -341,7 +341,7 @@ module tlb logic mode_match; logic [44:0] mask; - asid_match = !flush_asid_valid || entries[i].g || (entries[i].asid == flush_asid); + asid_match = !flush_asid_valid || (!entries[i].g && (entries[i].asid == flush_asid)); mode_match = !flush_vpn_valid || (entries[i].mode == flush_mode); if (flush_vpn_valid) begin mask = make_vpn_mask(entries[i].mode, entries[i].level); diff --git a/rv64cpu/tb/unit/tb_tlb.cc b/rv64cpu/tb/unit/tb_tlb.cc index ba6af6d..f244fbe 100644 --- a/rv64cpu/tb/unit/tb_tlb.cc +++ b/rv64cpu/tb/unit/tb_tlb.cc @@ -409,6 +409,69 @@ int main(int argc, char** argv) { issue_req(dut, va13, 18, MODE_SV48, 1, true, false, false, false); check(dut->resp_page_fault == 1, "ABit_FetchFault_WhenA0"); + // 22) ASID-targeted flush must preserve global entries + const uint64_t va14 = 0x0000'0000'8888'0600ULL; + do_refill(dut, sv48_vpn(va14), 0x88000ULL, 0, MODE_SV48, 33, true, false, true, true, false, true, true); + apply_flush_asid(dut, 33); + issue_load(dut, va14, 99, MODE_SV48); + check(dut->resp_hit == 1, "FlushAsid_GlobalPreserved"); + + // 23) Refill pressure should eventually evict oldest entry (round-robin) + apply_flush_all(dut); + const uint64_t va15 = 0x0000'0000'9000'1000ULL; + do_refill(dut, sv48_vpn(va15), 0x90001ULL, 0, MODE_SV48, 40, false, false, true, true, false, true, true); + for (int n = 0; n < 32; ++n) { + const uint64_t va_fill = 0x0000'0001'0000'0000ULL + (static_cast(n) << 12); + const uint64_t ppn_fill = 0x91000ULL + static_cast(n); + do_refill(dut, sv48_vpn(va_fill), ppn_fill, 0, MODE_SV48, static_cast(50 + n), false, false, true, true, false, true, true); + } + issue_load(dut, va15, 40, MODE_SV48); + check(dut->resp_hit == 0, "ReplacementPressure_OldestEvicted"); + + // 24) Newest refill remains accessible after pressure + const uint64_t va16 = 0x0000'0001'0001'F000ULL; + do_refill(dut, sv48_vpn(va16), 0xA001FULL, 0, MODE_SV48, 77, false, false, true, true, false, true, true); + issue_load(dut, va16, 77, MODE_SV48); + check(dut->resp_hit == 1, "ReplacementPressure_NewestEntryHits"); + + // 25) flush_vpn should invalidate Sv48 level-1 superpage for any VPN within same range + apply_flush_all(dut); + const uint64_t va17_base = 0x0000'0001'2340'0000ULL; + const uint64_t va17_same_superpage = 0x0000'0001'2341'2ABCULL; + const uint64_t va17_other_superpage = 0x0000'0001'2440'0555ULL; + do_refill(dut, sv48_vpn(va17_base), 0xB1000ULL, 1, MODE_SV48, 88, false, false, true, true, false, true, true); + do_refill(dut, sv48_vpn(va17_other_superpage), 0xB2000ULL, 1, MODE_SV48, 88, false, false, true, true, false, true, true); + apply_flush_vpn(dut, sv48_vpn(va17_same_superpage), MODE_SV48); + issue_load(dut, va17_base, 88, MODE_SV48); + check(dut->resp_hit == 0, "FlushVpn_Sv48L1_SameSuperpageInvalidated"); + issue_load(dut, va17_other_superpage, 88, MODE_SV48); + check(dut->resp_hit == 1, "FlushVpn_Sv48L1_OtherSuperpagePreserved"); + + // 26) flush_vpn should invalidate Sv57 level-2 superpage with 18-bit VPN wildcard + apply_flush_all(dut); + const uint64_t va18_base = 0x0012'3456'7800'1000ULL; + const uint64_t va18_same_superpage = 0x0012'3456'7BFF'8FFFULL; + const uint64_t va18_other_superpage = 0x0012'345A'0000'2000ULL; + do_refill(dut, sv57_vpn(va18_base), 0xC1234ULL, 2, MODE_SV57, 99, false, false, true, true, false, true, true); + do_refill(dut, sv57_vpn(va18_other_superpage), 0xC5678ULL, 2, MODE_SV57, 99, false, false, true, true, false, true, true); + apply_flush_vpn(dut, sv57_vpn(va18_same_superpage), MODE_SV57); + issue_load(dut, va18_base, 99, MODE_SV57); + check(dut->resp_hit == 0, "FlushVpn_Sv57L2_SameSuperpageInvalidated"); + issue_load(dut, va18_other_superpage, 99, MODE_SV57); + check(dut->resp_hit == 1, "FlushVpn_Sv57L2_OtherSuperpagePreserved"); + + // 27) flush_vpn with exact-page entry must not over-invalidate neighboring pages + apply_flush_all(dut); + const uint64_t va19_a = 0x0000'0000'9900'1000ULL; + const uint64_t va19_b = 0x0000'0000'9900'2000ULL; + do_refill(dut, sv48_vpn(va19_a), 0xD1000ULL, 0, MODE_SV48, 120, false, false, true, true, false, true, true); + do_refill(dut, sv48_vpn(va19_b), 0xD2000ULL, 0, MODE_SV48, 120, false, false, true, true, false, true, true); + apply_flush_vpn(dut, sv48_vpn(va19_a), MODE_SV48); + issue_load(dut, va19_a, 120, MODE_SV48); + check(dut->resp_hit == 0, "FlushVpn_Level0_OnlyTargetInvalidated"); + issue_load(dut, va19_b, 120, MODE_SV48); + check(dut->resp_hit == 1, "FlushVpn_Level0_NeighborPreserved"); + std::cout << "\n----------------------------------\n"; std::cout << "TLB tests passed: " << g_pass_count << "\n"; std::cout << "----------------------------------\n"; -- cgit v1.2.3 From 36ee7251fbb4350a5eee2549857e81291413e25d Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sat, 7 Nov 2026 04:11:58 +0800 Subject: build: reorganize CMake configuration --- rv64cpu/CMakeLists.txt | 53 ++++++++++------------------------------------ rv64cpu/rtl/CMakeLists.txt | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 42 deletions(-) create mode 100644 rv64cpu/rtl/CMakeLists.txt (limited to 'rv64cpu/CMakeLists.txt') diff --git a/rv64cpu/CMakeLists.txt b/rv64cpu/CMakeLists.txt index da146d5..f16aa14 100644 --- a/rv64cpu/CMakeLists.txt +++ b/rv64cpu/CMakeLists.txt @@ -4,35 +4,22 @@ if(POLICY CMP0144) cmake_policy(SET CMP0144 NEW) endif() -project(richard_cpu +project(rv64cpu VERSION 0.1.0 - DESCRIPTION "RV64IMAZicsr_Zifencei Five-Stage Pipelined CPU SoC" - LANGUAGES CXX C + DESCRIPTION "RV64 RISC-V processor core written in SystemVerilog" + LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# ─── Options ──────────────────────────────────────────────────────────────────── -option(ENABLE_TRACE "Enable VCD waveform tracing" ON) -option(ENABLE_COVERAGE "Enable code coverage for RTL" OFF) -option(BUILD_SW "Build software targets (requires riscv64 toolchain)" OFF) +option(ENABLE_TRACE "Enable VCD waveform tracing" OFF) +option(ENABLE_COVERAGE "Enable RTL code coverage" OFF) -# ─── Locate Verilator ──────────────────────────────────────────────────────────── find_package(verilator REQUIRED HINTS $ENV{VERILATOR_ROOT}) message(STATUS "Found Verilator: ${verilator_DIR}") -# ─── RTL Source Directories ────────────────────────────────────────────────────── -set(RTL_DIR ${CMAKE_SOURCE_DIR}/rtl) -set(RTL_CORE_DIR ${RTL_DIR}/core) -set(RTL_CACHE_DIR ${RTL_DIR}/cache) -set(RTL_BUS_DIR ${RTL_DIR}/bus) -set(RTL_PERIPS_DIR ${RTL_DIR}/perips) -set(RTL_SOC_DIR ${RTL_DIR}/soc) -set(RTL_INCLUDE_DIR ${RTL_CORE_DIR}/include) - -# ─── Common Verilator Flags ────────────────────────────────────────────────────── set(VERILATOR_COMMON_FLAGS --sv -Wall @@ -51,31 +38,13 @@ if(ENABLE_COVERAGE) list(APPEND VERILATOR_COMMON_FLAGS --coverage) endif() -# ─── Include Verilator CMake Helper ────────────────────────────────────────────── -include(${CMAKE_SOURCE_DIR}/tools/verilator.cmake) - -# ─── Waveform Output Directory ────────────────────────────────────────────────── -file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/waves) - -# ─── Testing ──────────────────────────────────────────────────────────────────── -enable_testing() -include(CTest) +include(${CMAKE_SOURCE_DIR}/cmake/verilator.cmake) -# ─── Testbench Subdirectory ───────────────────────────────────────────────────── -add_subdirectory(tb) - -# ─── Software Subdirectory (optional) ─────────────────────────────────────────── -if(BUILD_SW) - add_subdirectory(sw) -endif() +add_subdirectory(rtl) -# ─── Summary ──────────────────────────────────────────────────────────────────── message(STATUS "") -message(STATUS "╔══════════════════════════════════════════════╗") -message(STATUS "║ richard-cpu build configuration ║") -message(STATUS "╠══════════════════════════════════════════════╣") -message(STATUS "║ Trace: ${ENABLE_TRACE}") -message(STATUS "║ Coverage: ${ENABLE_COVERAGE}") -message(STATUS "║ Software: ${BUILD_SW}") -message(STATUS "╚══════════════════════════════════════════════╝") +message(STATUS "RV64CPU configuration") +message(STATUS " Trace: ${ENABLE_TRACE}") +message(STATUS " Coverage: ${ENABLE_COVERAGE}") +message(STATUS " RTL files: ${RV64CPU_RTL_SOURCE_COUNT}") message(STATUS "") diff --git a/rv64cpu/rtl/CMakeLists.txt b/rv64cpu/rtl/CMakeLists.txt new file mode 100644 index 0000000..96560fc --- /dev/null +++ b/rv64cpu/rtl/CMakeLists.txt @@ -0,0 +1,44 @@ +set(RV64CPU_RTL_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/packages/rv64_pkg.sv + ${CMAKE_CURRENT_SOURCE_DIR}/packages/csr_pkg.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/execute/integer_alu.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/execute/branch_unit.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/execute/instruction_decoder.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/execute/compressed_decoder.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/execute/hazard_unit.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/registers/gpr_file.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/registers/fpr_file.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/if_stage.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/if_id_reg.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/id_stage.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/id_ex_reg.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/ex_stage.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/ex_mem_reg.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/mem_stage.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/mem_wb_reg.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/pipeline/wb_stage.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/privileged/csr_unit.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/privileged/trap_controller.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/privileged/pmp_checker.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/mmu/tlb.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/mmu/ptw.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/mmu/mmu.sv + + ${CMAKE_CURRENT_SOURCE_DIR}/core/fpu/fpu.sv + ${CMAKE_CURRENT_SOURCE_DIR}/core/rv64_core.sv +) + +set(RV64CPU_RTL_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/packages +) + +list(LENGTH RV64CPU_RTL_SOURCES RV64CPU_RTL_SOURCE_COUNT) + +set(RV64CPU_RTL_SOURCES ${RV64CPU_RTL_SOURCES} PARENT_SCOPE) +set(RV64CPU_RTL_INCLUDE_DIRS ${RV64CPU_RTL_INCLUDE_DIRS} PARENT_SCOPE) +set(RV64CPU_RTL_SOURCE_COUNT ${RV64CPU_RTL_SOURCE_COUNT} PARENT_SCOPE) -- cgit v1.2.3