Download bit_accelerator/testbenches/tb_bit_accelerator.sv from Snapkitty/bit-string-accelerator: direct link, hf CLI and curl.
- Browser
- Download file 8.86 kB
-
https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/bit_accelerator/testbenches/tb_bit_accelerator.sv
- Command line
-
hf download hf://Snapkitty/bit-string-accelerator/bit_accelerator/testbenches/tb_bit_accelerator.sv
-
curl -L -o tb_bit_accelerator.sv https://huggingface.co/Snapkitty/bit-string-accelerator/resolve/main/bit_accelerator/testbenches/tb_bit_accelerator.sv
8.86 kB
| // 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 | |