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;
}
|