视频处理|Syetem Verilog 将视频流输出写入 BMP 图片文件 testbench 激励代码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_46621272/article/details/126441149

【视频处理|Syetem Verilog 将视频流输出写入 BMP 图片文件 testbench 激励代码】Syetem Verilog 将视频流输出写入 BMP 图片文件 testbench 激励代码
前言
  • Verilog 做图像视频算法仿真时,只能看见相关波形,不能直观查看计算后的图像视频效果。本文以临近缩放算法为例,用 BMP 图片文件代替视频数据来做图像视频缩放算法仿真。最终输出缩放后的 BMP 图片文件。可以通过查看图片的办法直观显示图像缩放算法产生的效果。
  • 本文中阐述的仿真环境适合很多采用 Verilog FPGA 实现的视频图像算法的仿真。比如各种视频缩放、旋转、拉伸等算法,比如视频滤波、降噪等算法。
一、 testbench 激励文件 bmp_for_videoStream.sv 代码
//bmp_for_videoStream.sv //将视频流输出写入 BMP 图片文件 //本模块不能被综合,只能用来当仿真module bmp_for_videoStream # ( parameter iREADY= 10,//插入 0-10 级流控信号, 10 是满级全速无等待 parameter iBMP_FILE_PATH = "" ) ( inputclk, inputrst_n, inputframe_sync_n,//输入视频帧同步复位,低有效 outputvin_ready, input [2:0][7:0]vin_dat,//输入视频数据 inputvin_valid,//输入视频数据有效 input [15:0]vin_xres,//输入视频水平分辨率 input [15:0]vin_yres//输入视频垂直分辨率 ); string FILE_NAME; logic [7:0]fn = 0; //帧计数 logic [0:53][7:0] bmp_header; //BMP 图像文件头 logic [31:0]offsetBits; //BMP 图像数据位置 logic [31:0]width; //BMP 图像宽度 logic [31:0]height; //BMP 图像高度 logic [31:0]sizeImage; //BMP 图像大小(字节) logic [31:0]sizePixel; //BMP 像素数量(像素个数) logic [31:0]sizeBmpFile; //BMP 图像文件大小(字节) logic [31:0]pixel_cnt = 0; //像素计数器 logicwr_end_flag = 0; //写文件结束标记 logic [3:0]cnt = '1; //延时计数器,在帧同步脉冲到来后,延时一段时间再输出视频流数据 logic [15:0]sx; //水平像素计数器 logic [15:0]sy; //垂直像素计数器 logic [15:0]addr_cnt; //图片数据水平线地址计数器 integerbmp_wp = 0; //文件指针 integeri; assign offsetBits = $bits(bmp_header)/8; assign vin_ready = vin_ready_r; //流控信号 always_ff@(posedge clk) begin if(rst_n == 0) cnt <= '1; //延时计数器,在帧同步脉冲到来后,延时一段时间再输出视频流数据 else if(frame_sync_n == 0) cnt <= 0; else if( cnt != '1 ) cnt <= cnt + 1; end always_ff@(posedge clk) begin case(cnt) 1: begin width= vin_xres; height= vin_yres; sizePixel = width*height; sizeImage = ((width*3+3)&16'hfffc)*height; //BMP 像素占用内存大小,必须是4的倍数 sizeBmpFile = offsetBits + sizeImage; {bmp_header[01],bmp_header[00]}= 16'h4d42; //BM TYPE {bmp_header[05],bmp_header[04],bmp_header[03],bmp_header[02]} = sizeBmpFile; //SizeBmpFile {bmp_header[09],bmp_header[08],bmp_header[07],bmp_header[06]} = '0; //Reserverd {bmp_header[13],bmp_header[12],bmp_header[11],bmp_header[10]} = offsetBits; //OffsetBits{bmp_header[17],bmp_header[16],bmp_header[15],bmp_header[14]} = 32'h0000_0028; //Size {bmp_header[21],bmp_header[20],bmp_header[19],bmp_header[18]} = width; //Width {bmp_header[25],bmp_header[24],bmp_header[23],bmp_header[22]} = height; //Height {bmp_header[27],bmp_header[26]}= 16'h0001; //Planes {bmp_header[29],bmp_header[28]}= 16'h0018; //Bitcount {bmp_header[33],bmp_header[32],bmp_header[31],bmp_header[30]} = '0; //Compression {bmp_header[37],bmp_header[36],bmp_header[35],bmp_header[34]} = '0; //sizeImage; //SizeImage {bmp_header[41],bmp_header[40],bmp_header[39],bmp_header[38]} = 32'h0000_c40e; //XPelsPermeter {bmp_header[45],bmp_header[44],bmp_header[43],bmp_header[42]} = 32'h0000_c40e; //YPelsPermeter {bmp_header[49],bmp_header[48],bmp_header[47],bmp_header[46]} = '0; //ClrUsed {bmp_header[53],bmp_header[52],bmp_header[51],bmp_header[50]} = '0; //ClrImportant fn<= fn + 1; end 2: begin $display("vout BMP File Size= 0x%h",sizeBmpFile); $display("vout Image data offset= 0x%h",offsetBits); $display("vout Image width= 0x%h",width); $display("vout Image heigh= 0x%h",height); $display("vout Image size= 0x%h\n",sizeImage); FILE_NAME = $sformatf("%svout_%03d%s",iBMP_FILE_PATH,fn,".bmp"); //BMP 图片文件名 $display("bmp file name = %s !",FILE_NAME); end 3: begin bmp_wp = $fopen(FILE_NAME,"wb+"); if(bmp_wp == 0)begin//文件建立打开失败 ? $display("%s file open error !",FILE_NAME); $stop; end end 4: begin for(i=0; i sizePixel -1)begin//判断像素计数器是否到结束 wr_end_flag <= 1; //置写文件结束标记 $fclose(bmp_wp); //$stop; end end // always_ff logic [15:0] ready_cnt = 0; logicvin_ready_r = 0; always_ff@(posedge clk) begin if(frame_sync_n == 0 || rst_n == 0 || ready_cnt >= 9 || cnt != '1)begin ready_cnt <= 0; end else if(ready_cnt < 9) ready_cnt <= ready_cnt + 1; end always_ff@(posedge clk) begin if(frame_sync_n == 0 || rst_n == 0 || cnt != '1)begin vin_ready_r <= 0; end else if(ready_cnt < iREADY || iREADY == 10) vin_ready_r <= 1; else vin_ready_r <= 0; endendmodule

二、相关连接
  • System Verilog 视频缩放图像缩放 vivado 仿真 https://blog.csdn.net/qq_46621272/article/details/126439519
三、本仿真工程文件下载,采用 Xilinx vivado 2017.4 版本
  • https://download.csdn.net/download/qq_46621272/86406386

    推荐阅读