Zynq学习笔记--AXI4-Stream 图像数据从仿真输出到图像文件

目录

1. 简介

2. 构建工程

2.1 Vivado 工程

2.2 TestBench 代码

2.3 关键代码分析

3. VPG Background Pattern ID (0x0020) Register

4. 总结


1. 简介

使用 SystemVerilog 将 AXI4-Stream 图像数据从仿真输出到图像文件 (PPM)。

用到的函数包括 $fopen、$fwrite 和 $fclose。

PPM 格式

PPM (Portable Pixmap Format) 是一种简单的图像文件格式,用于存储彩色图像。PPM 格式很简单,主要用于科研或某些需要图像处理但不需要复杂图像格式的场合。PPM 文件通常较大,因为它们不使用压缩。一个 PPM 文件由一个文件头和图像数据体组成。文件头指定了图像的宽度、高度和最大颜色值,而数据体则包含按顺序排列的像素颜色值,每个像素颜色通常由红、绿、蓝三个颜色分量组成。

2. 构建工程

2.1 Vivado 工程

2.2 TestBench 代码

`timescale 1ns / 1psimport axi_vip_pkg::*;
import design_1_axi_vip_0_0_pkg::*;module tb_tpg();bit aclk = 0, aresetn = 0;
xil_axi_resp_t 	resp;
bit tpg_tready = 1, tpg_tuser, tpg_tvalid, tpg_tlast;
bit [23:0] tpg_tdata;
integer counter_width = 0, counter_height = 0;
integer final_width = 0, final_height = 0;
integer output_file;
integer img_writing = 1, img_start = 0;parameter integer tpg_base_address = 12'h000;parameter integer TPG_CONTROL_REG       = tpg_base_address;parameter integer TPG_ACTIVE_H_REG      = tpg_base_address + 8'h10;parameter integer TPG_ACTIVE_W_REG      = tpg_base_address + 8'h18;parameter integer TPG_BG_PATTERN_REG = tpg_base_address + 8'h20;
integer height=400, width=640;
integer pattern_id = 8'h09;always #10ns aclk = ~aclk;design_1_wrapper UUT (.aclk_50MHz     (aclk      ),.aresetn_0      (aresetn   ),.tpg_tdata      (tpg_tdata ),.tpg_tlast      (tpg_tlast ),.tpg_tready     (tpg_tready),.tpg_tuser      (tpg_tuser ),.tpg_tvalid     (tpg_tvalid));initial begin#350ns aresetn = 1;@(posedge tpg_tuser); // Start of the first frame@(posedge tpg_tuser); // Start of the second frame, stop the simulationwait (tpg_tuser == 1'b0);#20ns;if((final_height == height)&&(final_height == height))$display("Resolution match, test succeeded");else$display("Resolution do not match, test failed");$finish;
enddesign_1_axi_vip_0_0_mst_t      master_agent;
initial beginmaster_agent = new("master vip agent",UUT.design_1_i.axi_vip_0.inst.IF);master_agent.start_master();wait (aresetn == 1'b1);#200nsmaster_agent.AXI4LITE_WRITE_BURST(TPG_ACTIVE_H_REG, 0, height, resp);master_agent.AXI4LITE_WRITE_BURST(TPG_ACTIVE_W_REG, 0, width,  resp);master_agent.AXI4LITE_WRITE_BURST(TPG_BG_PATTERN_REG, 0, pattern_id, resp);#200nsmaster_agent.AXI4LITE_WRITE_BURST(TPG_CONTROL_REG, 0, 8'h81, resp);
endalways @(posedge aclk)
beginif((tpg_tvalid == 1) && (tpg_tready == 1)) beginif(tpg_tlast == 1) beginfinal_width = counter_width + 1;counter_width = 0;endelsecounter_width = counter_width + 1;end
endalways @(posedge aclk)
beginif((tpg_tvalid == 1) && (tpg_tready == 1)) beginif(tpg_tuser == 1) beginfinal_height =  counter_height;counter_height = 0;endelse if(tpg_tlast == 1)counter_height = counter_height + 1;end
endinitial beginoutput_file = $fopen("image_out_1.ppm", "w");$fwrite(output_file, "P3\n");$fwrite(output_file, "%0d %0d\n", width, height);$fwrite(output_file, "%0d\n", 2**8-1);while(img_writing == 1) begin@(posedge aclk)#1ns;if ((tpg_tvalid == 1) && (tpg_tready == 1)) beginif((tpg_tuser == 1) && (img_start == 1)) img_writing = 0;else beginif(tpg_tuser == 1) img_start = 1;$fwrite(output_file, "%0d\n%0d\n%0d\n", int'(tpg_tdata[23:16]), int'(tpg_tdata[7:0]), int'(tpg_tdata[15:8]));endendend$fclose(output_file);$display("Image written");
end
endmodule

2.3 关键代码分析

initial beginoutput_file = $fopen("image_out_1.ppm", "w");$fwrite(output_file, "P3\n");$fwrite(output_file, "%0d %0d\n", width, height);$fwrite(output_file, "%0d\n", 2**8-1);while(img_writing == 1) begin@(posedge aclk);#1ns;if ((tpg_tvalid == 1) && (tpg_tready == 1))beginif((tpg_tuser == 1) && (img_start == 1))img_writing = 0;else beginif(tpg_tuser == 1) img_start = 1;$fwrite(output_file, "%0d\n%0d\n%0d\n",int'(tpg_tdata[23:16]),int'(tpg_tdata[ 7: 0]),int'(tpg_tdata[15:8]));endendend$fclose(output_file);$display("Image written");
end

文件创建与头信息写入:

  • 使用 $fopen 函数打开(或创建)一个新的文件image_out_1.ppm,用于写入模式("w")。
  • 利用 $fwrite 函数向文件写入PPM图像的头信息:
    • "P3\n":PPM文件的格式标识,表示该文件是一个ASCII编码的彩色PPM图像。
    • "%0d %0d\n":接下来写入图像的宽度(width)和高度(height),这两个数值应该在代码的其他部分定义。
    • "%0d\n":写入颜色的最大值,这里是2**8-1,即255,表示每个颜色通道(红、绿、蓝)的最大值。

图像数据写入:

  • 代码进入一个while循环,循环条件是 img_writing 等于1,这意味着将在满足某些条件时写入图像数据。
  • 在每个时钟周期的上升沿(@(posedge aclk)),并在等待1纳秒(#1ns;)后,检查tpg_tvalid和tpg_tready信号。只有当这两个信号都为1时,才会执行数据写入的逻辑。
  • 如果tpg_tuser信号为1且img_start也为1,这表示图像数据的结束,将img_writing设置为0,退出循环。
  • 如果仅tpg_tuser为1,这意味着图像数据的开始,设置img_start为1。
  • 在其他情况下,使用$fwrite函数将图像数据(tpg_tdata)写入文件。这里的数据被分解为红、蓝、绿三个颜色通道,并按顺序写入文件。

文件关闭与信息显示:

  • 使用$fclose函数关闭文件。
  • 通过$display函数在仿真控制台显示“Image written”信息,表示图像数据已成功写入文件。
if ((tpg_tvalid == 1) && (tpg_tready == 1)) beginif((tpg_tuser == 1) && (img_start == 1)) img_writing = 0; // 第二帧开始后,img_writing标记为0else beginif(tpg_tuser == 1) img_start = 1; // 第一帧开始,img_start标记为1$fwrite(output_file, "%0d\n%0d\n%0d\n", xxx); // 第一、二帧之间,逐个像素写入endend

3. VPG Background Pattern ID (0x0020) Register

背景模式 ID 寄存器控制 TPG Core 生成的模式操作。

该寄存器根据以下值控制核心输出的模式:

  • 0x00 - 直接将视频输入传递到视频输出
  • 0x1 - 水平坡道,每个分量(RGB或Y)水平增加1
  • 0x2 - 垂直坡道,每个分量(RGB或Y)垂直增加1
  • 0x3 - 时间坡道,根据运动速度寄存器设置的值,每帧逐像素增加
  • 0x4 - 纯红色输出
  • 0x5 - 纯绿色输出
  • 0x6 - 纯蓝色输出
  • 0x7 - 纯黑色输出
  • 0x8 - 纯白色输出
  • 0x9 - 色条
  • 0xA - 区域板输出产生一个基于ROM的正弦模式。此选项依赖于运动速度、zplate水平起点、zplate水平增量、zplate垂直起点和zplate垂直增量寄存器。
  • 0xB - 方格色条
  • 0xC - 绘制十字交叉线模式
  • 0xD - 色彩扫描模式
  • 0xE - 组合的垂直和水平坡道
  • 0xF - 黑白棋盘
  • 0x10 - 伪随机模式
  • 0x11 - DisplayPort颜色坡道
  • 0x12 - DisplayPort黑白垂直线
  • 0x13 - DisplayPort彩色方块

4. 总结

本文介绍了如何使用 SystemVerilog 将 AXI4-Stream 图像数据输出到 PPM 格式的图像文件中。通过使用 $fopen、$fwrite 和 $fclose 函数,成功地将仿真生成的图像数据写入到文件中,实现了图像数据的输出。在 TestBench 代码中,设置了图像的分辨率和颜色模式,并通过循环逐像素地写入数据。通过这种方式,我们可以将仿真生成的图像数据保存为 PPM 格式的文件,方便后续的图像处理和分析。这种方法可以帮助开发人员在仿真过程中方便地将图像数据输出到文件中,以便进行后续的验证和分析工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/338939.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

五类数据容器对比总结 知道喔!

五类数据容器对比总结 1.五类数据容器的区别 是否支持下标索引 支持:列表、元组、字符串---序列类型 不支持:集合、字典---非序列类型 是否支持重复元素 支持:列表、元组、字符串---序列类型 不支持:集合、字典---非序列类型 是…

Nginx企业级负载均衡:技术详解系列(16)—— Nginx的try_files指令,你知道这个指令是干什么的吗?

你好,我是赵兴晨,97年文科程序员。 今天咱们来聊一聊Nginx的try_files指令,你知道这个指令是干什么的吗? 如果你对Web服务器配置有所了解,那么你可能会对try_files指令感到好奇。这个指令实际上是Nginx配置中的一项强…

Go跨平台编译

1.编译windows平台运行程序 # windows env GOOSwindows GOARCHamd64 go build main.go2.编译linux平台运行程序 # linux env GOOSlinux GOARCHamd64 go build main.go 3.编译macos平台运行程序 # macos env GOOSdarwin GOARCHamd64 go build main.go 编译结果:

java收徒、java面试辅导、java辅导、java就业辅导

💗博主介绍:✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还…

19.4-STM32接收数据-状态显示在屏幕 openMV寻迹与小车控制 Openmv+STM32F103C8T6视觉巡线小车

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 19.4-STM32接收数据-状态显示在屏幕 先通过串口上位机模拟发送、 STM32有视觉循迹模式、…

2024四川三支一扶“考生信息表”照着填❗

2024四川三支一扶“考生信息表”照着填❗ ☑️四川三支一扶开始报名,大家要按照提示如实、准确、完整填写《高校毕业生“三支一扶”计划招募考生信息表》哦~ ☑️不知道怎么填写的宝子们,可以参考图1。 ☑️毕业证书编号如实填写,若是应届生&…

VGGNet

VGGNet CNN卷积网络的发展史 1. LetNet5(1998) 2. AlexNet(2012) 3. ZFNet(2013) 4. VGGNet(2014) 5. GoogLeNet(2014) 6. ResNet(2015) 7. DenseNet(2017) 8. EfficientNet(2019) 9. Vision Transformers(2020) 10. 自适应卷积网络(2021) 上面列出了发展到现在CNN的一些经典…

WPF Binding对象、数据校验、数据转换

在WinForm中,我们要想对控件赋值,需要在后台代码中拿到控件对象进行操作,这种赋值形式,从根本上是无法实现界面与逻辑分离的。 在WPF中,微软引入了Binding对象,通过Binding,我们可以直接将控件与…

基于MingGW64 GCC编译Windows平台上的 libuvc

安装cmake 打开cmake官网 https://cmake.org/download/,下载安装包: 安装时选择将cmake加到系统环境变量里。安装完成后在新的CMD命令窗口执行cmake --version可看到输出: D:\>cmake --version cmake version 3.29.3 CMake suite mainta…

mac多媒体影音库:Emby for Mac 中文版

Emby软件是一款功能强大的媒体服务器软件,旨在为用户提供丰富的多媒体体验。以下是关于Emby软件的详细介绍: 下载地址:https://www.macz.com/mac/7964.html?idOTI2NjQ5Jl8mMjcuMTg2LjE1LjE4Mg%3D%3D 主要功能 媒体管理:Emby允许用…

Java反序列化漏洞与URLDNS利用链分析

前言 前面学习过 Java 反序列化漏洞的部分知识,总结过几篇文章: 文章发布日期内容概括《渗透测试-JBoss 5.x/6.x反序列化漏洞》2020-07-08JBoss 反序列化漏洞 CVE-2017-12149 的简单复现,使用了 ysoserial 和 CC5 链,未分析漏洞…

网络网络层

data: 2024/5/25 14:02:20 周六 limou3434 叠甲:以下文章主要是依靠我的实际编码学习中总结出来的经验之谈,求逻辑自洽,不能百分百保证正确,有错误、未定义、不合适的内容请尽情指出! 文章目录 1.协议结构2.封装分离3.…

搭建基于Django的博客系统增加广告轮播图(三)

上一篇:ChatGPT搭建博客Django的web网页添加用户系统(二) 下一篇:搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL(四) 功能概述 增加轮播图显示广告信息。 需求详细描述 1. 增加轮播图显示广告信…

领导让我调研CI/CD,我给他看了这个

一、概念解释 CI/CD是指持续集成(Continuous Integration)和持续交付/持续部署(Continuous Delivery/Continuous Deployment)的缩写,是现代软件开发中的重要实践。它们旨在通过自动化和持续化的方式改善软件开发、测试…

轻松拿捏C语言——【文件操作】

🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🎉创作不易,请多多支持🎉 🌈感谢大家的阅读、点赞、收藏和关注💕 🌹如有问题,欢迎指正 目录 &#x1f…

论文阅读:Correcting Motion Distortion for LIDAR HD-Map Localization

目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址:http://arxiv.org/pdf/2308.13694.pdf 代码地址:https://github.com/mcdermatt/VICET 概要 激光雷达的畸变矫正是一个非常重要的工作。由于扫描式激光雷达传感器需要有限的时间来创建…

LeetCode 算法:找到字符串中所有字母异位词c++

原题链接🔗:找到字符串中所有字母异位词 难度:中等⭐️⭐️ 题目 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符…

Nginx实战:防盗链

防盗链的概念 内容不在自己的服务器上,通过技术手段将其他网站的内容(比如 一些音乐、图片、软件的下载地址)放置在自己的网站中,通过这 种方法盗取其他网站的空间和流量 防盗链技术背景 防止第三方引用链接访问我们的图片&#x…

mysql面试之分库分表总结

文章目录 1.为什么要分库分表2.分库分表有哪些中间件,不同的中间件都有什么优点和缺点?3.分库分表的方式(水平分库,垂直分库,水平分表,垂直分表)3.1 水平分库3.2 垂直分库3.3 水平分表3.4 垂直分表 4.分库分表带来的问题4.1 事务一致性问题4.2 跨节点关联…

UE_地编教程_创建地形洞材质

个人学习笔记,不喜勿喷。侵权立删! 使用地形洞材质来遮罩地形上特定位置的可视性和碰撞。如要在山脉侧面创建进入洞穴的入口,此操作将非常有用。可使用地形材质和地形洞材质的相同材质,但注意:对比不使用不透明蒙版的…