// tb_storage.cpp - Verilator C++ testbench for storage (sd_bram top) // // Reads test vectors from +VECTOR_FILE= hex file. // Format: "ADDR DATA" per line (addr in 2-char hex, data in 12-char hex). // Writes values via sd_bram, reads back, prints "RESULT: VAL_HEX". // s_bram is compiled as rtl_dep. // // Clock: 10ns period. W=48, D=64, A=6 (default sd_bram parameters). #include #include #include #include #include #include #include "Vsd_bram.h" #include "verilated.h" #define CLK_HALF_PS 5000 static vluint64_t main_time = 0; double sc_time_stamp() { return (double)main_time / 1000.0; } static void tick(Vsd_bram* dut) { dut->clk = 1; main_time += CLK_HALF_PS; dut->eval(); dut->clk = 0; main_time += CLK_HALF_PS; dut->eval(); } int main(int argc, char** argv) { Verilated::commandArgs(argc, argv); const char* vector_file = NULL; for (int i = 1; i < argc; i++) { std::string arg(argv[i]); if (arg.rfind("+VECTOR_FILE=", 0) == 0) { vector_file = argv[i] + 13; break; } } if (!vector_file) { std::cerr << "ERROR: +VECTOR_FILE= not specified" << std::endl; return 1; } std::ifstream infile(vector_file); if (!infile.is_open()) { std::cerr << "ERROR: Cannot open vector file: " << vector_file << std::endl; return 1; } struct Vec { int addr; uint64_t data; }; std::vector vectors; std::string line; while (std::getline(infile, line)) { if (line.empty() || line[0] == '#') continue; std::istringstream iss(line); int a; uint64_t d; if (!(iss >> std::hex >> a >> d)) continue; if (a < 0 || a > 63) continue; vectors.push_back({a, d & 0xFFFFFFFFFFFFULL}); } infile.close(); if (vectors.empty()) { std::cerr << "ERROR: No valid vectors in file" << std::endl; return 1; } Vsd_bram* dut = new Vsd_bram; dut->clk = 0; dut->rd_addr = 0; dut->wr_en = 0; dut->wr_addr = 0; dut->wr_data = 0; dut->eval(); main_time += CLK_HALF_PS; dut->eval(); // --- WRITE PHASE --- for (size_t i = 0; i < vectors.size(); i++) { dut->wr_en = 1; dut->wr_addr = vectors[i].addr & 0x3F; dut->wr_data = vectors[i].data & 0xFFFFFFFFFFFFULL; tick(dut); } dut->wr_en = 0; dut->wr_addr = 0; dut->wr_data = 0; tick(dut); // --- READ PHASE --- for (size_t i = 0; i < vectors.size(); i++) { dut->rd_addr = vectors[i].addr & 0x3F; tick(dut); printf("RESULT: %012lX\n", (unsigned long)(dut->rd_data & 0xFFFFFFFFFFFFULL)); } delete dut; return 0; }