The linear testbench approach expects the test writer to create combinations of input stimuli. The same stimuli can be applied by also reading a file
However, a file I/O based testbench is a type of verification testbench in which the test stimuli and expected results are read from files rather than being generated dynamically. This approach can be useful for testing complex designs where generating input stimuli and expected results programmatically may be time-consuming or impractical. Here is an example of a file I/O based testbench for a simple digital circuit that performs a bitwise AND operation:
The circuit takes two 4-bit binary inputs (A and B) and performs a bitwise AND operation, producing a 4-bit binary output (C). The testbench reads the input vectors and expected output values from a file, applies the input vectors to the circuit, and compares the output values produced by the circuit to the expected output values.
Assuming the input and expected output values are stored in a file named "test_data.txt" in the following format:
# Input A, Input B, Expected C 0000,0000,0000 0001,0000,0000 0000,0001,0000 0001,0001,0001
The testbench code might look something like this:
module tb_and; // Declare input and output signals reg [3:0] A, B; wire [3:0] C; // Instantiate the circuit under test and_4bit dut ( .A(A), .B(B), .C(C) ); // Open the input/output file integer test_file; initial begin test_file = $fopen("test_data.txt", "r"); if (test_file == 0) begin $fatal("ERROR: Could not open test_data.txt"); end end // Read and apply the input vectors and expected output values integer line_num = 0; integer errors = 0; initial begin while (!$feof(test_file)) begin line_num++; $fscanf(test_file, "%b,%b,%b", A, B, C); #1; if (C !== A & B) begin $display("ERROR in line %d: Expected C=%b, but got C=%b", line_num, A & B, C); errors++; end end if (errors == 0) begin $display("All tests passed!"); end else begin $display("%d errors found in %d tests", errors, line_num); end end // Close the input/output file initial begin $fclose(test_file); end endmodule
In this example, the testbench reads each line of the input/output file, which contains the input values and the expected output value. The
$fscanf system task is used to read the input values and expected output value from the file, and the
#1 delay is used to allow the circuit time to produce the output value.
The expected output value is compared to the actual output value produced by the circuit using the
!== operator. If the expected and actual output values do not match, an error message is displayed indicating the line number and expected/actual output values. If all tests pass, a message indicating that all tests passed is displayed.
File-based testbenches have some limitations, including:
- Limited Stimulus Control: File-based testbenches offer limited control over the stimulus being applied to the DUT since the input stimuli are pre-defined in a file. This can be limiting in situations where the stimulus needs to be generated dynamically, based on feedback from the DUT.
- Limited Debugging Capabilities: Since the input stimuli and expected results are read from a file, it can be difficult to debug issues that arise during simulation, especially if the issue is related to the input stimuli or expected results.
- Overhead of File Operations: File-based testbenches have additional overhead associated with file operations, which can slow down simulation performance. In addition, the testbench code can become more complex due to the need to manage file I/O operations.
- Limited Reusability: File-based testbenches are often specific to a particular design or set of test cases, and may not be easily reusable for other designs or test cases.
Despite these limitations, file-based testbenches can be useful in some situations, such as when testing complex designs with a large number of input stimuli and expected results. They can also be useful for test cases where generating input stimuli and expected results programmatically may be time-consuming or impractical.