-
Notifications
You must be signed in to change notification settings - Fork 4
/
axi_stream_video_image_out_vip.sv
152 lines (128 loc) · 5.96 KB
/
axi_stream_video_image_out_vip.sv
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
// System verilog package file
// AXI-Stream video stream image output verification IP (VIP) package
// Designer: Deng LiWei
// Date: 2022/04
// Description: This VIP can read a single image and make standard AXI-Stream video stream
// to verify the video or image processing IPs.
// Note: This VIP using 32BPP RGB stream, the format is BGRA (BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA)
// Note: If the channel order (like RGBA, ARGB, ARBG, etc.) is different from Xilinx standard,
// you can simply use the slicer to change its order.
// Note: For more information of the design of AXI-Stream Video Processing System,
// or the video transmission protocol on AXI-Stream, please see UG934
// "AXI4-Stream Video IP and System Design Guide" from Xilinx.
import bitmap_processing::*;
import axi_stream_video_image::*;
module axis_video_img_out_vip
#(
// Image size
parameter IMAGE_WIDTH = 960,
parameter IMAGE_HEIGHT = 540,
// Pixel per clock, can be 1, 2, 4 or 8
parameter PIXEL_PER_CLK = 1,
// Bits per pixel, fixed 32bpp
parameter BITS_PER_PIXEL = 32
)
(
// Target bitmap
ref Bitmap frameBitmap,
// Callback class
ref AxisVideoImageCallback callbacks,
// Clock
input logic clk,
// AXI-Stream video input
// Note: Functions of each wire
// TDATA: Pixel data
// TVALID & TREADY: Handshake signal, transfer will enable when they both 1
// TLAST: End of line
// TUSER: Start of frame
// Note: This is a AXI-Stream Slave Monitor interface,
// which both TVALID & TREADY are input direction.
// When they both 1, the monitor received a valid transmission.
// Waveform
// +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
// CLK --+ +-+ +-+ +-+ +-//-+ +-+ +-+ +-+ +-+ +-//--+ +-+ +-+ +-+ +--
//
// +---+---+---//-+---+---+ --+---+---+---+
// TDATA ------+0,0|1,0|2,0 |y,0|z,0+-----------// |x,1|y,1|z,1+-----
// +---+---+---//-+---+---+ --+---+---+---+
// End of line 0 End of line 1
// +-------+ +-----------+ +-----------+
// TVALID --+ +-------//-+ +-------//--+ +-----
//
// +-------+ +-------+ +-----------+
// TREADY ------+ +---//-+ +-----------//--+ +-----
//
// +---+
// TUSER ------+ +-------//---------------------//--------------------
//
// +--+ +--+
// TLAST ------------------//------+ +-----------//-----------+ +-----
input logic [BITS_PER_PIXEL * PIXEL_PER_CLK - 1:0] s_axis_video_in_tdata,
input logic s_axis_video_in_tvalid,
input logic s_axis_video_in_tready,
input logic s_axis_video_in_tlast,
input logic s_axis_video_in_tuser
);
bit inFrame;
logic [BITS_PER_PIXEL * PIXEL_PER_CLK - 1:0] pixel_buffer;
// Bitmap frameBitmap;
// Receive and save the bitmap to a bitmap file
// If the filename is empty, do not save the file, but in the frameBitmap object
task ReceiveAndSaveBitmap(input string fileName);
fork begin
automatic bit[31:0] color;
inFrame = 0;
frameBitmap = new();
frameBitmap.create(IMAGE_WIDTH, IMAGE_HEIGHT);
for (int y = 0; y < IMAGE_HEIGHT; y++) begin
for (int x = 0; x < IMAGE_WIDTH; ) begin
@(posedge clk);
if (s_axis_video_in_tvalid & s_axis_video_in_tready) begin
if (s_axis_video_in_tuser) begin
inFrame = 1; // This is the first pixel of frame
$display("Get a valid frame @%t", $time);
end
if (inFrame) begin
pixel_buffer = s_axis_video_in_tdata;
// Get the pixel
if (PIXEL_PER_CLK > 1) begin
for (int i = 0; i < PIXEL_PER_CLK; i++) begin
color = pixel_buffer[(i + 1) * BITS_PER_PIXEL - 1 -: BITS_PER_PIXEL];
frameBitmap.setPixel(x + i, y, color);
end
end
else begin
color = pixel_buffer;
frameBitmap.setPixel(x, y, color);
end
if(s_axis_video_in_tlast) begin
if (x != IMAGE_WIDTH - PIXEL_PER_CLK) begin
// When a unexpected end of line occurs,
// give a warning
$display("Warning: Unexpected end of line @%t", $time);
end
end // TLAST
if (x == IMAGE_WIDTH - PIXEL_PER_CLK) begin
if (!s_axis_video_in_tlast) begin
// When a unexpected end of line occurs,
// give a warning
$display("Warning: No end of line (%d) @%t", y, $time);
end
end // TLAST
// Increase X
x = x + PIXEL_PER_CLK;
end // In frame
end // TVALID
end // X
end // Y
if (fileName != "") begin
if (frameBitmap.write(fileName) != BMPW_ERR_OK) begin
$display("Error when writing the bitmap file.");
end
end
callbacks.ReceivedCallback();
$display("A frame of bitmap received, and saved to a bitmap file %s.", fileName);
end
join_none
endtask
endmodule