Zynq学习笔记--AXI4-Stream 图像数据从仿真输出到图像文件
目录1. 简介2. 构建工程2.1 Vivado 工程2.2 TestBench 代码2.3 关键代码分析3. VPG Background Pattern ID (0x0020) Register4. 总结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 / 1ps import 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 12h000; parameter integer TPG_CONTROL_REG tpg_base_address; parameter integer TPG_ACTIVE_H_REG tpg_base_address 8h10; parameter integer TPG_ACTIVE_W_REG tpg_base_address 8h18; parameter integer TPG_BG_PATTERN_REG tpg_base_address 8h20; integer height400, width640; integer pattern_id 8h09; 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 simulation wait (tpg_tuser 1b0); #20ns; if((final_height height)(final_height height)) $display(Resolution match, test succeeded); else $display(Resolution do not match, test failed); $finish; end design_1_axi_vip_0_0_mst_t master_agent; initial begin master_agent new(master vip agent,UUT.design_1_i.axi_vip_0.inst.IF); master_agent.start_master(); wait (aresetn 1b1); #200ns master_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); #200ns master_agent.AXI4LITE_WRITE_BURST(TPG_CONTROL_REG, 0, 8h81, resp); end always (posedge aclk) begin if((tpg_tvalid 1) (tpg_tready 1)) begin if(tpg_tlast 1) begin final_width counter_width 1; counter_width 0; end else counter_width counter_width 1; end end always (posedge aclk) begin if((tpg_tvalid 1) (tpg_tready 1)) begin if(tpg_tuser 1) begin final_height counter_height; counter_height 0; end else if(tpg_tlast 1) counter_height counter_height 1; end end initial begin output_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)) begin if((tpg_tuser 1) (img_start 1)) img_writing 0; else begin if(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])); end end end $fclose(output_file); $display(Image written); end endmodule2.3 关键代码分析initial begin output_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)) begin if((tpg_tuser 1) (img_start 1)) img_writing 0; else begin if(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])); end end end $fclose(output_file); $display(Image written); end文件创建与头信息写入使用 $fopen 函数打开或创建一个新的文件image_out_1.ppm用于写入模式w。利用 $fwrite 函数向文件写入PPM图像的头信息P3\nPPM文件的格式标识表示该文件是一个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)) begin if((tpg_tuser 1) (img_start 1)) img_writing 0; // 第二帧开始后img_writing标记为0 else begin if(tpg_tuser 1) img_start 1; // 第一帧开始img_start标记为1 $fwrite(output_file, %0d\n%0d\n%0d\n, xxx); // 第一、二帧之间逐个像素写入 end end3. VPG Background Pattern ID (0x0020) Register背景模式 ID 寄存器控制 TPG Core 生成的模式操作。该寄存器根据以下值控制核心输出的模式0x00 - 直接将视频输入传递到视频输出0x1 - 水平坡道每个分量RGB或Y水平增加10x2 - 垂直坡道每个分量RGB或Y垂直增加10x3 - 时间坡道根据运动速度寄存器设置的值每帧逐像素增加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 格式的文件方便后续的图像处理和分析。这种方法可以帮助开发人员在仿真过程中方便地将图像数据输出到文件中以便进行后续的验证和分析工作。

相关新闻

深度对比:TencentDB Agent Memory vs 传统向量数据库,谁才是AI记忆最佳选择?

深度对比:TencentDB Agent Memory vs 传统向量数据库,谁才是AI记忆最佳选择?

深度对比:TencentDB Agent Memory vs 传统向量数据库,谁才是AI记忆最佳选择? 【免费下载链接】TencentDB-Agent-Memory TencentDB Agent Memory is a team-level memory hub for AI Agents — turning conversations, docs, and code into fo…

2026/10/16 17:14:09 阅读更多 →
大规模AWS迁移实战:GoDaddy和Atlassian的云转型之路

大规模AWS迁移实战:GoDaddy和Atlassian的云转型之路

大规模AWS迁移实战:GoDaddy和Atlassian的云转型之路 【免费下载链接】howtheyaws A curated collection of publicly available resources on how technology and tech-savvy organizations around the world use Amazon Web Services (AWS) 项目地址: https://gi…

2026/10/17 8:42:55 阅读更多 →
Unity随机数系统深度解析:从Random.Range到确定性模拟与高性能随机

Unity随机数系统深度解析:从Random.Range到确定性模拟与高性能随机

1. 项目概述:为什么Unity开发者需要重新审视Random.Range? 如果你在Unity项目里写过 Random.Range(0, 10) ,然后觉得随机数生成这事儿已经搞定了,那这篇文章就是为你准备的。我见过太多项目,从简单的敌人随机刷新&am…

2026/10/17 8:43:20 阅读更多 →

最新新闻

BrowserSkill:基于Chrome DevTools Protocol的轻量级浏览器CLI自动化工具

BrowserSkill:基于Chrome DevTools Protocol的轻量级浏览器CLI自动化工具

1. 项目概述:BrowserSkill不是插件,而是一套浏览器自动化能力的CLI封装体系BrowserSkill这个词最近在开发者社区里频繁出现,但它既不是Chrome商店里某个新上架的视频下载插件,也不是Edge浏览器内置的Copilot功能升级包。我第一次在…

2026/10/18 19:24:21 阅读更多 →
新能源汽车数据集源码解析:从标注转换到训练落地全攻略

新能源汽车数据集源码解析:从标注转换到训练落地全攻略

简介:面向人工智能与新能源交叉领域研究者的数据索引型源码包,围绕新能源汽车健康度、充电站运营、充电桩布设、充电需求时空、电池异常检测、公交驾驶、车牌识别等八个细分方向,整理并说明了各数据集的数据背景、应用领域、目录结构及用途&a…

2026/10/18 19:24:21 阅读更多 →
充电桩平台源码解析:国标协议解耦与高并发状态同步

充电桩平台源码解析:国标协议解耦与高并发状态同步

简介:这是一套面向Java开发者与新能源智能充电系统学习者的完整充电桩平台源码资源,聚焦于云快充协议对接、多租户运营及分时计费等核心业务场景,助力快速构建可商用的充电管理SaaS系统。资源包共13个文件,含10个Java核心类&#…

2026/10/18 19:24:21 阅读更多 →
Agent Skills实战:从工具调用到技能化智能体开发指南

Agent Skills实战:从工具调用到技能化智能体开发指南

做AI应用这两年,我踩过一个很大的坑:给大模型接了一堆工具,结果它真正跑起来的时候,反而不知道什么时候该用哪一个,经常在无关的工具之间来回横跳。后来我把整套交互方式改成了Agent Skills——把每一个工具变成一份带…

2026/10/18 19:24:21 阅读更多 →
Octop:Python依赖治理CLI工具,解决包名漂移与环境不可复现问题

Octop:Python依赖治理CLI工具,解决包名漂移与环境不可复现问题

1. 项目概述:Octop 是什么?它解决的不是“安装 Python”这个表层问题Octop 这个名字乍看像某个开源工具、库名,甚至有人会联想到章鱼(octopus)——毕竟“octo-”前缀在技术圈里常暗示“八路”“多线程”“分布式”或“…

2026/10/18 19:24:21 阅读更多 →
从需求拆解到部署:基于深度学习的口罩识别系统实战

从需求拆解到部署:基于深度学习的口罩识别系统实战

口罩识别这种项目,这几年几乎成了目标检测入门的标准练手题。但说实话,真正把它做成一个能稳定跑的落地系统,和跑通一个开源notebook之间的差距,比很多人想象得大得多。这篇文章就从我实际做完一个基于深度学习的口罩识别系统出发…

2026/10/18 19:23:20 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →