aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/tb/unit/tb_regfile.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-07 03:30:17 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-07 03:31:03 +0800
commit2a4c290c55b683352a16747432a7fc4635597cc6 (patch)
treea150caea2ade12af4c5dcd70f09bacd3318f4d43 /rv64cpu/tb/unit/tb_regfile.cc
parente0948e3fc10029ba4bb4d48d7b5daae94fe575b9 (diff)
downloadrcc-project-2a4c290c55b683352a16747432a7fc4635597cc6.tar.gz
rcc-project-2a4c290c55b683352a16747432a7fc4635597cc6.tar.xz
refactor: reset software and test directories
Diffstat (limited to 'rv64cpu/tb/unit/tb_regfile.cc')
-rw-r--r--rv64cpu/tb/unit/tb_regfile.cc192
1 files changed, 0 insertions, 192 deletions
diff --git a/rv64cpu/tb/unit/tb_regfile.cc b/rv64cpu/tb/unit/tb_regfile.cc
deleted file mode 100644
index 8e210ec..0000000
--- a/rv64cpu/tb/unit/tb_regfile.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// 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 <https://www.gnu.org/licenses/>.
-
-// File path: tb/unit/tb_regfile.cc
-// Description: Register file unit test
-
-#include <iostream>
-#include <cassert>
-#include <verilated.h>
-#include "Vregfile.h"
-
-void tick(Vregfile* dut) {
- dut->clk = 0;
- dut->eval();
- dut->clk = 1;
- dut->eval();
- dut->clk = 0;
- dut->eval();
-}
-
-int main(int argc, char** argv) {
- Verilated::commandArgs(argc, argv);
- Vregfile* dut = new Vregfile;
-
- dut->clk = 0;
- dut->rst = 0;
- dut->reg_write_en = 0;
- dut->rd_addr = 0;
- dut->rd_wdata = 0;
- dut->rs1_addr = 0;
- dut->rs2_addr = 0;
-
- std::cout << "----------------------------------" << std::endl;
- std::cout << " Register File Unit Test" << std::endl;
- std::cout << "----------------------------------" << std::endl;
-
- // Test 1: Reset
- dut->rst = 1;
- tick(dut);
- dut->rst = 0;
- std::cout << "\033[32m[PASS] Reset complete\033[0m" << std::endl;
-
- // Test 2: Write and read
- dut->reg_write_en = 1;
- dut->rd_addr = 5;
- dut->rd_wdata = 0xDEADBEEF;
- tick(dut);
-
- dut->reg_write_en = 0;
- dut->rs1_addr = 5;
- dut->eval();
- assert(dut->rs1_rdata == 0xDEADBEEF);
- std::cout << "\033[32m[PASS] Write and read (x5) complete\033[0m" << std::endl;
-
- // Test 3: x0
- dut->reg_write_en = 1;
- dut->rd_addr = 0;
- dut->rd_wdata = 0x12345678;
- tick(dut);
-
- dut->reg_write_en = 0;
- dut->rs2_addr = 0;
- dut->eval();
- assert(dut->rs2_rdata == 0);
- std::cout << "\033[32m[PASS] Write and read (x0) complete\033[0m" << std::endl;
-
- // Test 4: Dual-port simultaneous read
- dut->reg_write_en = 1;
- dut->rd_addr = 6;
- dut->rd_wdata = 0x87654321;
- tick(dut);
-
- dut->reg_write_en = 1;
- dut->rd_addr = 7;
- dut->rd_wdata = 0x11223344;
- tick(dut);
-
- dut->rs1_addr = 6;
- dut->rs2_addr = 7;
- dut->eval();
-
- assert(dut->rs1_rdata == 0x87654321 && dut->rs2_rdata == 0x11223344);
- std::cout << "\033[32m[PASS] Dual-port simultaneous read complete\033[0m" << std::endl;
-
-
- // Test 5: Write enable = 0 (Data should not change)
- dut->reg_write_en = 1;
- dut->rd_addr = 10;
- dut->rd_wdata = 0xCAFEBABE;
- tick(dut);
-
- dut->reg_write_en = 0; // Disable write
- dut->rd_addr = 10;
- dut->rd_wdata = 0x11111111; // Attempt to overwrite
- tick(dut);
-
- dut->rs1_addr = 10;
- dut->eval();
- assert(dut->rs1_rdata == 0xCAFEBABE);
- std::cout << "\033[32m[PASS] Write enable = 0 correctly ignores write\033[0m" << std::endl;
-
- // Test 6: Verify full reset behavior
- // First, dirty up some registers
- for (int i = 1; i < 32; i += 5) {
- dut->reg_write_en = 1;
- dut->rd_addr = i;
- dut->rd_wdata = 0x1000 + i;
- tick(dut);
- }
-
- // Apply reset
- dut->rst = 1;
- dut->reg_write_en = 0; // Clear write enable from previous test
- tick(dut);
- dut->rst = 0;
-
- // Check all are zero
- bool reset_ok = true;
- for (int i = 1; i < 32; i++) {
- dut->rs1_addr = i;
- dut->eval();
- if (dut->rs1_rdata != 0) {
- reset_ok = false;
- std::cerr << "\033[31m[FAIL] Reset failed on register x" << i << std::endl;
- }
- }
- assert(reset_ok);
- std::cout << "\033[32m[PASS] Full memory reset verified\033[0m" << std::endl;
-
- // Test 7: Read-After-Write (Same cycle collision check)
- // With internal bypass added, combinational read should return the NEW bypassed value immediately.
- dut->reg_write_en = 0;
- dut->rd_addr = 15;
- dut->rd_wdata = 0x55555555;
- tick(dut); // Write 0x55555555 to x15 to set old value
-
- // Setup for RAW
- dut->reg_write_en = 1;
- dut->rd_addr = 15;
- dut->rd_wdata = 0x99999999;
-
- // Before tick, read should be the new bypassed value (0x99999999)
- dut->rs1_addr = 15;
- dut->eval();
- assert(dut->rs1_rdata == 0x99999999);
-
- tick(dut); // Clock edge happens
-
- dut->reg_write_en = 0; // Turn off write
- dut->eval(); // Combinational read update
- assert(dut->rs1_rdata == 0x99999999);
- std::cout << "\033[32m[PASS] Read-After-Write (RAW) behavior verified\033[0m" << std::endl;
-
- // Test 8: Sweep all registers (Write and Read distinct values)
- for (int i = 1; i < 32; i++) {
- dut->reg_write_en = 1;
- dut->rd_addr = i;
- dut->rd_wdata = 0xABCDE000 + i;
- tick(dut);
- }
-
- dut->reg_write_en = 0;
- bool sweep_ok = true;
- for (int i = 1; i < 32; i++) {
- dut->rs1_addr = i;
- dut->eval();
- if (dut->rs1_rdata != (0xABCDE000 + i)) {
- sweep_ok = false;
- }
- }
- assert(sweep_ok);
- std::cout << "\033[32m[PASS] All 31 mutable registers write/read successfully without collision\033[0m" << std::endl;
-
- std::cout << "----------------------------------" << std::endl;
- std::cout << "\033[32mAll 8 tests passed!\033[0m" << std::endl;
- std::cout << "----------------------------------" << std::endl;
-
- delete dut;
- exit(0);
-} \ No newline at end of file