File size: 8,859 Bytes
0ba037b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | // Testbench for Bit-String Hardware Accelerator
// Comprehensive functional verification of all operations and edge cases
module tb_bit_accelerator ();
// Parameters
localparam int ADDR_WIDTH = 64;
localparam int WORD_WIDTH = 64;
localparam int WORD_BYTES = WORD_WIDTH / 8;
localparam int READ_LATENCY = 2;
// Clock and Reset
logic clk;
logic reset;
// DUT: Operation Interface
logic op_valid;
logic op_ready;
logic [63:0] base_address;
logic [63:0] bit_offset;
logic [2:0] operation;
// DUT: Response Interface
logic result_valid;
logic result_bit;
logic error;
// DUT: Memory Interface
logic mem_req_valid;
logic mem_req_ready;
logic [ADDR_WIDTH-1:0] mem_addr;
logic mem_read;
logic mem_write;
logic [WORD_BYTES-1:0] mem_wstrb;
logic [WORD_WIDTH-1:0] mem_wdata;
logic mem_rvalid;
logic [WORD_WIDTH-1:0] mem_rdata;
logic mem_fault;
// DUT Instantiation
bit_accelerator dut (
.clk (clk),
.reset (reset),
.op_valid (op_valid),
.op_ready (op_ready),
.base_address(base_address),
.bit_offset (bit_offset),
.operation (operation),
.result_valid(result_valid),
.result_bit (result_bit),
.error (error),
.mem_req_valid(mem_req_valid),
.mem_req_ready(mem_req_ready),
.mem_addr (mem_addr),
.mem_read (mem_read),
.mem_write (mem_write),
.mem_wstrb (mem_wstrb),
.mem_wdata (mem_wdata),
.mem_rvalid (mem_rvalid),
.mem_rdata (mem_rdata),
.mem_fault (mem_fault)
);
// Memory Model
behavioral_memory #(
.ADDR_WIDTH (ADDR_WIDTH),
.WORD_WIDTH (WORD_WIDTH),
.READ_LATENCY(READ_LATENCY)
) memory_model (
.clk (clk),
.reset (reset),
.req_valid(mem_req_valid),
.req_ready(mem_req_ready),
.addr (mem_addr),
.is_read (mem_read),
.is_write(mem_write),
.wstrb (mem_wstrb),
.wdata (mem_wdata),
.rvalid (mem_rvalid),
.rdata (mem_rdata),
.fault (mem_fault)
);
// Clock generation (10ns period = 100 MHz)
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
// Test vector structure
typedef struct packed {
logic [63:0] base_addr;
logic [63:0] bit_offset;
logic [2:0] op;
logic [63:0] expected_word;
logic expected_bit;
string test_name;
} test_vec_t;
// Test counters
int test_count = 0;
int pass_count = 0;
int fail_count = 0;
// Helper tasks
task automatic write_memory(logic [63:0] byte_addr, logic [63:0] data);
logic [63:0] word_addr = byte_addr >> 3;
// Direct write to memory model's memory array
// (In real simulation, use the memory interface)
endtask
task automatic init_memory();
// Initialize memory with test pattern
// Word at byte address 0x00: 64'h0123456789ABCDEF
// Word at byte address 0x08: 64'hFEDCBA9876543210
// Word at byte address 0x10: 64'hAAAAAAAAAAAAAAAA
// Word at byte address 0x18: 64'h5555555555555555
automatic logic [63:0] init_data[4];
init_data[0] = 64'h0123456789ABCDEF;
init_data[1] = 64'hFEDCBA9876543210;
init_data[2] = 64'hAAAAAAAAAAAAAAAA;
init_data[3] = 64'h5555555555555555;
// Write to memory via operation (requires memory to be functional)
// For now, directly access memory_model.memory
for (int i = 0; i < 4; i++) begin
memory_model.memory[i] = init_data[i];
end
endtask
task automatic run_operation(
input logic [63:0] base_addr,
input logic [63:0] bit_off,
input logic [2:0] op,
output logic result_bit_out,
output logic error_out
);
logic done = 1'b0;
int cycles = 0;
// Assert operation request
op_valid <= 1'b1;
base_address <= base_addr;
bit_offset <= bit_off;
operation <= op;
// Wait for acceptance
@(posedge clk);
while (!op_ready && cycles < 100) begin
@(posedge clk);
cycles++;
end
op_valid <= 1'b0;
// Wait for result
cycles = 0;
while (!result_valid && cycles < 200) begin
@(posedge clk);
cycles++;
end
if (result_valid) begin
result_bit_out = result_bit;
error_out = error;
end else begin
result_bit_out = 1'bX;
error_out = 1'b1;
end
endtask
task automatic test_bit_get(logic [63:0] base_addr, logic [63:0] bit_off, logic expected_bit, string test_name);
logic result_bit_out;
logic error_out;
$display("[%0d] Testing BIT_GET: %s", test_count, test_name);
run_operation(base_addr, bit_off, 3'b000, result_bit_out, error_out);
if (error_out) begin
$display(" FAIL: Operation returned error");
fail_count++;
end else if (result_bit_out === expected_bit) begin
$display(" PASS: Got expected bit value %b", expected_bit);
pass_count++;
end else begin
$display(" FAIL: Expected %b, got %b", expected_bit, result_bit_out);
fail_count++;
end
test_count++;
@(posedge clk);
endtask
task automatic test_bit_set(logic [63:0] base_addr, logic [63:0] bit_off, string test_name);
logic result_bit_out;
logic error_out;
$display("[%0d] Testing BIT_SET: %s", test_count, test_name);
run_operation(base_addr, bit_off, 3'b010, result_bit_out, error_out);
if (error_out) begin
$display(" FAIL: Operation returned error");
fail_count++;
end else begin
$display(" PASS: BIT_SET completed, result=%b", result_bit_out);
pass_count++;
end
test_count++;
@(posedge clk);
endtask
task automatic test_bit_clear(logic [63:0] base_addr, logic [63:0] bit_off, string test_name);
logic result_bit_out;
logic error_out;
$display("[%0d] Testing BIT_CLEAR: %s", test_count, test_name);
run_operation(base_addr, bit_off, 3'b011, result_bit_out, error_out);
if (error_out) begin
$display(" FAIL: Operation returned error");
fail_count++;
end else begin
$display(" PASS: BIT_CLEAR completed, result=%b", result_bit_out);
pass_count++;
end
test_count++;
@(posedge clk);
endtask
// Main Testbench
initial begin
// Initialize signals
op_valid = 1'b0;
base_address = 64'h0;
bit_offset = 64'h0;
operation = 3'h0;
reset = 1'b0;
// Reset sequence
#20;
reset = 1'b1;
#20;
$display("\n========================================");
$display(" BIT ACCELERATOR FUNCTIONAL TEST ");
$display("========================================\n");
// Initialize memory
init_memory();
// Test 1: BIT_GET at various offsets (single word)
$display("\n--- Test Group 1: Single-Word Bit Extraction ---");
// Word 0 = 0x0123456789ABCDEF
// Bit 0 (LSB of byte 0): 1
test_bit_get(64'h00, 64'h0, 1'b1, "bit 0 of word 0");
// Bit 1: 1
test_bit_get(64'h00, 64'h1, 1'b1, "bit 1 of word 0");
// Bit 7: 0
test_bit_get(64'h00, 64'h7, 1'b0, "bit 7 of word 0");
// Bit 8 (LSB of byte 1): 1
test_bit_get(64'h00, 64'h8, 1'b1, "bit 8 of word 0");
// Bit 31: 0
test_bit_get(64'h00, 64'h1F, 1'b0, "bit 31 of word 0");
// Bit 32: 1
test_bit_get(64'h00, 64'h20, 1'b1, "bit 32 of word 0");
// Bit 63 (MSB of word): 0
test_bit_get(64'h00, 64'h3F, 1'b0, "bit 63 of word 0");
// Test 2: Cross-word boundary
$display("\n--- Test Group 2: Cross-Word Boundary ---");
// Word 1 = 0xFEDCBA9876543210
// Bit 64 (bit 0 of word 1): 0
test_bit_get(64'h00, 64'h40, 1'b0, "bit 64 (bit 0 of word 1)");
// Bit 65: 0
test_bit_get(64'h00, 64'h41, 1'b0, "bit 65 (bit 1 of word 1)");
// Test 3: Base address offset
$display("\n--- Test Group 3: Non-Zero Base Address ---");
// Base address = 0x08 (word 1)
// Bit offset = 0 (bit 0 of word 1)
test_bit_get(64'h08, 64'h0, 1'b0, "base=0x08, offset=0");
// Test 4: Modify operations
$display("\n--- Test Group 4: Modify Operations ---");
test_bit_set(64'h10, 64'h0, "BIT_SET at bit 0 of word 2");
test_bit_clear(64'h10, 64'h0, "BIT_CLEAR at bit 0 of word 2");
// Summary
$display("\n========================================");
$display(" TEST SUMMARY ");
$display("========================================");
$display("Total Tests: %0d", test_count);
$display("Passed: %0d", pass_count);
$display("Failed: %0d", fail_count);
if (fail_count == 0) begin
$display("\n✓ All tests PASSED!");
end else begin
$display("\n✗ %0d tests FAILED!", fail_count);
end
$display("========================================\n");
#100;
$finish;
end
endmodule : tb_bit_accelerator
|