summaryrefslogtreecommitdiff
path: root/fpga/sim/line_buffer_tb.cpp
blob: 2b89221722afd3ec761431a496abbfe3ec12022b (plain)
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
#include <cstdio>
#include <cstdlib>

#include "Vline_buffer.h"
#include "verilated_vcd_c.h"

using namespace std;

Vline_buffer* top;

vluint64_t main_time = 0;

double sc_time_stamp() {
    return main_time;
}

const int IMAGE_SIZE = 5;  // Number of columns in the test image
const int ROWS = 5;        // Number of rows in the test image
const int NUM_LINES = 3;   // Number of lines in the sliding window
const int DATA_WIDTH = 8;  // Pixel width in bits
const int PADDING = 1;     // Enable padding

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);

    top = new Vline_buffer;

    // Enable waveform tracing
    Verilated::traceEverOn(true);
    VerilatedVcdC* tfp = new VerilatedVcdC;
    top->trace(tfp, 99);
    tfp->open("line_buffer.vcd");

    // Initialize signals
    top->clk = 0;
    top->rst = 1;
    top->pixel_in = 0;
    top->pixel_valid = 0;

    // Apply reset
    printf("Applying Reset\n");
    for (int i = 0; i < 10; i++) {
        top->clk = !top->clk;
        top->eval();
        tfp->dump(main_time);
        main_time++;
    }
    top->rst = 0; // Deassert reset

    // Test image data
    uint8_t test_data[ROWS][IMAGE_SIZE] = {
        {0x01, 0x02, 0x03, 0x04, 0x05},
        {0x06, 0x07, 0x08, 0x09, 0x0A},
        {0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
        {0x10, 0x11, 0x12, 0x13, 0x14},
        {0x15, 0x16, 0x17, 0x18, 0x19}
    };

    printf("Feeding pixel data into the line buffer\n");

    // Feed data row by row
    for (int row = 0; row < ROWS; row++) {
        for (int col = 0; col < IMAGE_SIZE; col++) {
            // Load pixel into pixel_in and set valid
            top->pixel_in = test_data[row][col];
            top->pixel_valid = 1;

            // Toggle clock for one cycle
            for (int i = 0; i < 2; i++) {
                top->clk = !top->clk;
                top->eval();
                tfp->dump(main_time);
                main_time++;
            }

            // Print window contents when valid
            if (top->window_valid) {
                printf("Window at row %d, col %d:\n", row, col);
                for (int i = 0; i < NUM_LINES; i++) {
                    for (int j = 0; j < NUM_LINES; j++) {
                        int idx = (i * NUM_LINES + j);
                        int arrayIndex = (idx * DATA_WIDTH) / 32;
                        int bitOffset = (idx * DATA_WIDTH) % 32;
                        uint32_t value = (top->window[arrayIndex] >> bitOffset) & ((1 << DATA_WIDTH) - 1);
                        printf("%02x ", value);
                    }
                    printf("\n");
                }
                printf("\n");
            }
        }
    }

    // Add additional simulation cycles with valid=0
    printf("Running additional simulation cycles...\n");
    top->pixel_valid = 0;
    for (int i = 0; i < 60; i++) {
        // Toggle clock
        for (int j = 0; j < 2; j++) {
            top->clk = !top->clk;
            top->eval();
            tfp->dump(main_time);
            main_time++;
        }
        
        // Print window contents if valid
        if (top->window_valid) {
            printf("Extra cycle %d - Window Output:\n", i);
            for (int i = 0; i < NUM_LINES; i++) {
                for (int j = 0; j < NUM_LINES; j++) {
                    int idx = (i * NUM_LINES + j);
                    int arrayIndex = (idx * DATA_WIDTH) / 32;
                    int bitOffset = (idx * DATA_WIDTH) % 32;
                    uint32_t value = (top->window[arrayIndex] >> bitOffset) & ((1 << DATA_WIDTH) - 1);
                    printf("%02x ", value);
                }
                printf("\n");
            }
            printf("\n");
        }
    }

    printf("Simulation complete. Final time: %lu\n", main_time);

    // Close trace file and clean up
    tfp->close();
    top->final();
    delete top;

    return 0;
}