首页 > 其他分享 >Zynq学习笔记--AXI4-Stream 图像数据从仿真输出到图像文件

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

时间:2024-05-30 09:02:18浏览次数:24  
标签:tpg begin end Stream img -- height Zynq 0d

目录

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 / 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 = 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 simulation
    wait (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;
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 == 1'b1);

    #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, 8'h81, 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
endmodule

2.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\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)) 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
 end

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 格式的文件,方便后续的图像处理和分析。这种方法可以帮助开发人员在仿真过程中方便地将图像数据输出到文件中,以便进行后续的验证和分析工作。

标签:tpg,begin,end,Stream,img,--,height,Zynq,0d
From: https://blog.csdn.net/DongDong314/article/details/139283688

相关文章

  • 《计算机网络微课堂》第六章 应用层
    6-1应用层概述从本节课开始,我们进入第6章应用层的学习。本节课我们对应用层进行概述,在之前的课程中,我们按计算机网络体系结构,由低到高的顺序,依次学习了物理层、数据链路层、网络层、运输层。物理层解决使用何种信号来传输比特的问题数据链路层解决分组在一个网络或一段链路......
  • Android基础-初识Android系统架构
    Android系统架构详解Android系统作为一款广泛应用于智能手机、平板电脑等设备的操作系统,其架构的设计对于系统的稳定性、可扩展性和用户体验至关重要。Android系统架构是一个复杂的层次结构,旨在实现硬件与软件之间的高效协同工作,为用户提供丰富的功能和良好的体验。以下是对An......
  • css20 CSS Text
    https://www.w3schools.com/css/css_text.aspCSShasalotofpropertiesforformattingtext. <!DOCTYPEhtml><html><head><style>div{border:1pxsolidgray;padding:8px;}h1{text-align:center;text-transform:u......
  • Android基础-Activity的介绍
    在Android系统中,Activity是一个重要的组件,它承载了用户与应用之间的交互界面。以下是关于Activity的功能、作用以及生命周期的详细介绍。Activity的功能和作用提供用户界面:Activity是Android应用程序中用于表示一个屏幕或用户界面的组件。它负责展示应用程序的用户界面,如......
  • 网站外链交换的优势与方法
    在当今竞争激烈的网络环境中,网站的权重和流量对于各个网站主来说都是非常重要的。而网站外链交换是一种有效的方法,可以帮助网站提升权重和流量。本文将为您介绍网站外链交换的优势与方法。在进行网站外链交换之前,我们首先要了解什么是外链。外链是指其他网站将链接指向我们的网站......
  • CV每日论文--2024.5.29
    1、GaussianFormer:SceneasGaussiansforVision-Based3DSemanticOccupancyPrediction中文标题:GaussianFormer:将场景作为高斯分布进行基于视觉的3D语义占有率预测简介:3D语义占空比预测是自动驾驶等视觉系统中一个重要的任务,目的是获取周围场景的3D几何和语义信......
  • C#去掉字符串首尾字符
    以下是多种不同的实现方法来去除C#字符串的首尾字符:1、使用Substring方法:stringinput="HelloWorld!";stringoutput=input.Substring(1,input.Length-2);2、使用Remove方法:stringinput="HelloWorld!";stringoutput=input.Remove(0,1).Remove(input.Leng......
  • 多企业AI智能名片商城系统小程序在品牌塑造与流量管理中的应用研究
    摘要:在数字化浪潮中,品牌塑造与流量管理成为企业发展的重要驱动力。本文将通过具体案例,探讨多企业AI智能名片商城系统小程序在品牌塑造与流量管理中的应用,分析其在企业成功转型中的关键作用。一、引言假设有一家高端时尚品牌“悦尚”,在市场竞争日益激烈的环境下,它面临着品牌......
  • Android基础-Service的介绍
    在Android系统中,Service是一个重要的后台组件,用于执行长时间运行的操作,而不需要提供用户界面。以下是对Service的功能、作用以及生命周期的详细介绍。Service的功能和作用后台执行:Service允许应用程序在后台执行操作,即使用户没有与应用进行直接交互。这使得Service成为处......
  • 开源AI智能名片商城系统小程序:构建企业敏捷性与创新力的新引擎
    摘要:在数字化时代,企业正面临前所未有的市场变革。客户需求日新月异,市场竞争日趋激烈。为了在这场变革中立足,企业必须寻求新的解决方案,以提升自身的敏捷性和创新力。开源AI智能名片商城系统小程序,作为一种新兴的技术工具,正以其独特的优势,助力企业迅速响应市场变化,推动产品和服......