色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

圖像流AXI-Stream生成BMP文件的實(shí)現(xiàn)思路

冬至子 ? 來(lái)源:小何的芯像石頭 ? 作者:五線譜是偶然來(lái)的 ? 2023-06-27 11:20 ? 次閱讀

實(shí)現(xiàn)思路

在實(shí)現(xiàn)上,由于bmp除去文件頭后也只是把圖像流數(shù)據(jù)按順序放而已,所以這里

  1. 先用一個(gè)fifo緩存圖像數(shù)據(jù)
  2. 寫(xiě)一個(gè)狀態(tài)機(jī)控制按順序輸出文件頭和數(shù)據(jù)。
  3. 注意fifo的讀寫(xiě)和AXIS之間的握手和控制邏輯。因?yàn)榭雌饋?lái)fifo是暫存數(shù)據(jù)的,但可預(yù)見(jiàn)fifo應(yīng)該是有可能周期性空的,因?yàn)樵诿啃械慕Y(jié)束后tlast都是讓valid拉低一個(gè)周期,這一小個(gè)周期在行多了之后一點(diǎn)會(huì)抵消文件頭的大小。

生成緩存fifo

聲明:

  1. 命名并不規(guī)范
  2. 可以用原語(yǔ)(xpm)或其他同類型IP生成,這里不多贅述。

在IP catalog的搜索框中寫(xiě)fifo,選FIFO Generator:

圖片

具體按下面設(shè)置:

圖片

這里注意必須選擇First Word Fall Through

選25位是因?yàn)椋跀?shù)據(jù)結(jié)構(gòu)上是1tuser + 2*8 data,選擇把幀開(kāi)始標(biāo)志也丟進(jìn)fifo可以避免錯(cuò)幀。

總體端口

生成的BMP文件依然以AXIS格式輸出,在tb中再以二進(jìn)制格式寫(xiě)進(jìn)文件:

module axis2bmp#(
    parameter PIC_HEIGHT = 1080,
    parameter PIC_WIDTH  = 1920
)(
    // global signal
    input clk_i,    // clock
    input rst_n_i,  // reset

    // axi stream (slave) interface signal - > pixel data
    input  [23:0] s_axis_video_tdata,   // DATA
    input  [0:0] s_axis_video_tvalid,  // VALID
    output [0:0] s_axis_video_tready,  // READY
    input  [0:0] s_axis_video_tuser,   // SOF
    input  [0:0] s_axis_video_tlast,    // EOL

    // axi stream (master) interface signal - > bmp
    output reg [23:0] m_axis_video_tdata,   // DATA
    output [ 0:0] m_axis_video_tvalid,  // VALID
    input  [ 0:0] m_axis_video_tready,  // (meaningless)
    output [ 0:0] m_axis_video_tlast    // end of file stream
);

slave端為圖像數(shù)據(jù),master端為輸出BMP文件流,這里需要注意master流中并不處理反壓?jiǎn)栴}(即沒(méi)有ready信號(hào),懶得加fifo)

fifo接口邏輯

// image pixel fifo dw=24, BRAM cap=512
wire [24:0] bmp_header_din;
wire [0:0] bmp_header_wr;
wire [0:0] bmp_header_full;

wire [0:0] bmp_header_empty;
wire [0:0] bmp_header_rd;
wire [24:0] bmp_header_dout;

bmp_header bmp_header_inst (
    .clk(clk_i),      // input wire clk
    .srst(~rst_n_i),    // input wire srst
    .din(bmp_header_din),      // input wire [23 : 0] din
    .wr_en(bmp_header_wr),  // input wire wr_en
    .rd_en(bmp_header_rd),  // input wire rd_en
    .dout(bmp_header_dout),    // output wire [23 : 0] dout
    .full(bmp_header_full),    // output wire full
    .empty(bmp_header_empty)  // output wire empty
);

// pixel fifo assignment
assign bmp_header_din = {s_axis_video_tuser,s_axis_video_tdata};
assign s_axis_video_tready = ~bmp_header_full;
assign bmp_header_wr = s_axis_video_tready && s_axis_video_tvalid;

fifo的讀使能放到后面再講,這里先處理好數(shù)據(jù)進(jìn)來(lái)就可以了

文件流處理狀態(tài)機(jī)

經(jīng)典三板斧,不展開(kāi)

包頭數(shù)據(jù)準(zhǔn)備

需要搬回第一篇中的BMP文件格式,由于是輸出,所以我們就不考慮調(diào)色板了:

圖片

這里先用一些localparam存起來(lái),(這里考慮大小不變)

//--------------------------寫(xiě)B(tài)MP狀態(tài)機(jī)------------------------

// local parameter
localparam [15:0] bfType = 16'h4d42;
localparam [31:0] bfReserved = 32'h0000_0000;
localparam [31:0] biSizeImage = PIC_HEIGHT * PIC_WIDTH * 3;
localparam [31:0] biSizeImage_cnt = PIC_HEIGHT * PIC_WIDTH;
localparam [31:0] bfOffset = 32'd54;
localparam [31:0] bfSize = biSizeImage + bfOffset;

localparam [31:0] biSize = 32'h28;
localparam [31:0] biWidth = PIC_WIDTH;
localparam [31:0] biHeight = PIC_HEIGHT;

localparam [15:0] biPlanes = 16'd1;
localparam [15:0] biBitCount = 16'd24;
localparam [31:0] biCompression = 32'd0;
localparam [127:0] biUseless = 128'd0;

localparam   CNT_PIXEL  = $clog2(PIC_HEIGHT*PIC_WIDTH);

轉(zhuǎn)移狀態(tài)

//轉(zhuǎn)移狀態(tài)
localparam S_WAIT               = 3'b001 ;  // 等待SOF標(biāo)記
localparam S_WRITE_HEADER       = 3'b010 ;  // 寫(xiě)B(tài)MP包頭
localparam S_WRITE_DATA         = 3'b100 ;  // 寫(xiě)B(tài)MP數(shù)據(jù)

狀態(tài)轉(zhuǎn)移變量

//狀態(tài)轉(zhuǎn)移變量
reg [2:0] state, n_state;       // 狀態(tài)寄存器
reg [4:0] header_cnt;           // 包頭計(jì)數(shù)器
reg [CNT_PIXEL-1:0] pixel_cnt;  // 像素計(jì)數(shù)器

wire frame_start = bmp_header_dout[24];    // SOF flag
wire write_header_done = (header_cnt == 5'd17);     // 18 -1 - > 18*3
wire write_pixel_done = (pixel_cnt == biSizeImage_cnt -1'b1);

這里需要注意 : 兩個(gè)狀態(tài)只由計(jì)數(shù)器指定跳轉(zhuǎn)

狀態(tài)轉(zhuǎn)移

//狀態(tài)機(jī)初始化
always @ (posedge clk_i) begin
    if(~rst_n_i)
        state <= S_WAIT;
    else
        state <= n_state;
end

狀態(tài)機(jī) 狀態(tài)轉(zhuǎn)移

always @ (*) begin
    case(state)
        S_WAIT :
            if(frame_start)
                n_state = S_WRITE_HEADER;
        else
            n_state = S_WAIT;
        S_WRITE_HEADER:
            if(write_header_done)
                n_state = S_WRITE_DATA;
        else
            n_state = S_WRITE_HEADER;
        S_WRITE_DATA:
            if(write_pixel_done)
                n_state = S_WAIT;
        else
            n_state = S_WRITE_DATA;
        default:
            n_state = S_WAIT;
    endcase
end

寫(xiě)B(tài)MP包頭 處理邏輯

這里直接按照文件格式,用計(jì)數(shù)器懟進(jìn)去進(jìn)行:

always @(posedge clk_i or negedge  rst_n_i) begin
    if (~rst_n_i)
        header_cnt <= 5'd0;
    else if(state == S_WRITE_HEADER && header_cnt < 5'd17)
        header_cnt <= header_cnt + 1'd1;
    else
        header_cnt <= 5'd0;
end

在數(shù)據(jù)上,可參考(注意數(shù)據(jù)以小端輸出):

case (header_cnt)
    5'd0 :
        m_axis_video_tdata = {bfSize[0+:8], bfType};
    5'd1 :
        m_axis_video_tdata = bfSize[8+:24];
    5'd2 :
        m_axis_video_tdata = bfReserved[0 +:24];
    5'd3 :
        m_axis_video_tdata = {bfOffset[0+:16],bfReserved[24+:8]};
    5'd4 :
        m_axis_video_tdata = {biSize[0+:8], bfOffset[16+:16]};
    5'd5 :
        m_axis_video_tdata = biSize[8+:24];
    5'd6 :
        m_axis_video_tdata = biWidth[0+:24];
    5'd7 :
        m_axis_video_tdata = {biHeight[0+:16],biWidth[24+:8]};
    5'd8 :
        m_axis_video_tdata = {biPlanes[0+:8],biHeight[16+:16]};
    5'd9 :
        m_axis_video_tdata = {biBitCount[0+:16],biPlanes[8+:8]};
    5'd10 :
        m_axis_video_tdata = biCompression[0+:24];
    5'd11 :
        m_axis_video_tdata = {biSizeImage[0+:16],biCompression[24+:8]};
    5'd12 :
        m_axis_video_tdata = {biUseless[0+:8], biSizeImage[16+:16]};
    5'd13 :
        m_axis_video_tdata = biUseless[8+:24];
    5'd14 :
        m_axis_video_tdata = biUseless[32+:24];
    5'd15 :
        m_axis_video_tdata = biUseless[56+:24];
    5'd16 :
        m_axis_video_tdata = biUseless[80+:24];
    5'd17 :
        m_axis_video_tdata = biUseless[104+:24];
    default:
        m_axis_video_tdata = 24'heeeeee;
endcase

其中+:和-:語(yǔ)法簡(jiǎn)介可以翻看筆者之前的文章或自行百度。這里這樣寫(xiě)是為了看位寬方便一點(diǎn)

寫(xiě)圖像數(shù)據(jù)

這里直接放開(kāi)fifo數(shù)據(jù)就可以了,注意握手邏輯:

計(jì)數(shù)器邏輯:

always @(posedge clk_i or negedge  rst_n_i) begin
    if (~rst_n_i)
        pixel_cnt <= 'd0;
    else if(state == S_WRITE_DATA && pixel_cnt < biSizeImage_cnt-1) begin
        if(bmp_header_empty)
            pixel_cnt <= pixel_cnt;
        else
            pixel_cnt <= pixel_cnt + 1'd1;
    end
    else
        pixel_cnt <= 'd0;
end

數(shù)據(jù)放行:

assign bmp_header_rd = ((state == S_WRITE_DATA) && ~bmp_header_empty) 
           || ((state == S_WAIT) && ~frame_start);

………………
else if(state == S_WRITE_DATA) begin
    m_axis_video_tdata = bmp_header_dout;
end
………………

這里上下兩塊合成一個(gè)組合邏輯就變成m_axis_video_tdata的完整控制邏輯了

仿真tb編寫(xiě)

這里由前面的積累就比較簡(jiǎn)單,直接將上一節(jié)生成的AXIS輸入例化即可:

定義localparam

// Parameters
localparam  data_out = "./a_ch.txt";
localparam  bmp_path = "./test.bmp";
localparam  bmp_path_out = "./test_out.bmp";
localparam  height = 1080;
localparam  width = 1920;

這里如果輸入輸出不一樣可以在tb中分開(kāi)定義

簡(jiǎn)單引個(gè)線

// AXI-Stream Ports
wire [0:0] m_axis_tvalid;
wire [0:0] m_axis_tready;
wire [23:0] m_axis_tdata;
wire [0:0] m_axis_tlast;
wire [0:0] m_axis_tuser;

bmp_tb
#(
    .data_out(data_out ),
    .bmp_path(bmp_path ),
    .height(height ),
    .width (width )
)
bmp_tb_dut (
    .clk_i (clk_i ),
    .rst_n_i (rst_n_i ),
    .m_axis_tvalid (m_axis_tvalid ),
    .m_axis_tready (m_axis_tready ),
    .m_axis_tdata (m_axis_tdata ),
    .m_axis_tlast (m_axis_tlast ),
    .m_axis_tuser  ( m_axis_tuser)
);


wire [23:0] m_axis_video_tdata;  //這才是想要的信號(hào)
wire [ 0:0] m_axis_video_tvalid;
wire [ 0:0] m_axis_video_tlast;

axis2bmp
#(
    .PIC_HEIGHT(height ),
    .PIC_WIDTH (width )
)
axis2bmp_dut (
    .clk_i (clk_i ),
    .rst_n_i (rst_n_i ),
    .s_axis_video_tdata (m_axis_tdata ),
    .s_axis_video_tvalid (m_axis_tvalid ),
    .s_axis_video_tready (m_axis_tready ),
    .s_axis_video_tuser (m_axis_tuser ),
    .s_axis_video_tlast (m_axis_tlast ),
    .m_axis_video_tdata (m_axis_video_tdata ),
    .m_axis_video_tvalid (m_axis_video_tvalid ),
    .m_axis_video_tready (1'b1 ),
    .m_axis_video_tlast  ( m_axis_video_tlast)
);

文件流寫(xiě)入

這里直接用$fwrite一個(gè)一個(gè)字節(jié)寫(xiě)進(jìn)去就可以了:

integer iBmpFileId;
initial begin
    begin
        iBmpFileId = $fopen(bmp_path_out,"wb");
        #10 rst_n_i = 1'b0;
        #200 rst_n_i = 1'b1;

        while (!m_axis_video_tlast) begin
            @(negedge clk_i) ;
            if(m_axis_video_tvalid==1'b1)begin
                $fwrite(iBmpFileId, "%c", m_axis_video_tdata[7-:8]) ;
                $fwrite(iBmpFileId, "%c", m_axis_video_tdata[15-:8]) ;
                $fwrite(iBmpFileId, "%c", m_axis_video_tdata[23-:8]);
            end
        end
        $fclose(iBmpFileId);
        #2000;
        $finish;
    end
end

然后在sim_x-> behav -> xsim下面放好圖像就可以了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 仿真器
    +關(guān)注

    關(guān)注

    14

    文章

    1018

    瀏覽量

    83777
  • 計(jì)數(shù)器
    +關(guān)注

    關(guān)注

    32

    文章

    2256

    瀏覽量

    94641
  • BMP
    BMP
    +關(guān)注

    關(guān)注

    0

    文章

    48

    瀏覽量

    17074
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27552
  • FIFO存儲(chǔ)
    +關(guān)注

    關(guān)注

    0

    文章

    103

    瀏覽量

    5999
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Zynq中AXI4-Lite和AXI-Stream功能介紹

    等于b0000(非緩沖和非緩存)。 5) 不支持互斥性操作。 Zynq中AXI-Stream功能 AXI-Stream協(xié)議作為一個(gè)標(biāo)準(zhǔn)接口,用于連接數(shù)據(jù)交換元
    的頭像 發(fā)表于 09-27 11:33 ?8925次閱讀
    Zynq中<b class='flag-5'>AXI</b>4-Lite和<b class='flag-5'>AXI-Stream</b>功能介紹

    新手求助,HLS實(shí)現(xiàn)opencv算法加速的IP在vivado的使用

    是video in to AXI4-Stream,接到DMA,而HLS生成的算法IP是AXI4-Stream in and out。我想把AXI-Stream信號(hào)輸出接到HLS輸出的I
    發(fā)表于 01-16 09:22

    請(qǐng)問(wèn)AXI4-Stream到Video核心的技巧有什么?

    ,這是一個(gè)由數(shù)據(jù)視頻生成器卡攜帶的模塊。在這種情況下,我只使用了四個(gè)內(nèi)核來(lái)實(shí)現(xiàn)簡(jiǎn)單設(shè)計(jì),即(1)。視頻輸入到Axi4-Stream核心,(2)視頻縮放器核心,(3)。 AXI4-Stream
    發(fā)表于 11-08 09:53

    請(qǐng)問(wèn)可以使用AXI-Stream Broadcaster作為AXI開(kāi)關(guān)嗎?

    我們可以使用AXI-Stream Broadcaster作為AXI開(kāi)關(guān)嗎?如果可能,我們需要控制切換哪個(gè)信號(hào)?我想開(kāi)發(fā)小型應(yīng)用程序,它涉及廣播AXI數(shù)據(jù)并將
    發(fā)表于 05-07 09:42

    AXI-stream數(shù)據(jù)傳輸過(guò)程

    AXI4-Stream的核心思想在于流式處理數(shù)據(jù)。    圖 4?58 AXI-Stream Interface  全局信號(hào)  1.ACLK 全局時(shí)鐘信號(hào),在上升沿時(shí)對(duì)信號(hào)采樣。所有的輸入信號(hào)都通過(guò)上升沿采集,所有
    發(fā)表于 01-08 16:52

    ZYNQ中不同應(yīng)用的DMA總結(jié)

    到 PL 高速傳輸高速通道 AXI-HP<---->AXI-Stream 的轉(zhuǎn)換AXI-FIFO-MM2S:實(shí)現(xiàn)從 PS 內(nèi)存到 PL 通用傳輸通道
    發(fā)表于 03-31 11:39

    AXI4Stream總線的FPGA視頻系統(tǒng)的開(kāi)發(fā)研究

    基于AXI4Stream總線協(xié)議,在Xilinx公司提供的FPGA上實(shí)現(xiàn)了一個(gè)具有缺陷像素校正、色彩濾波陣列插值、圖像降噪實(shí)時(shí)圖像采集與顯示功能的視頻系統(tǒng)。
    發(fā)表于 11-17 08:58 ?4641次閱讀

    一文詳解ZYNQ中的DMA與AXI4總線

    在ZYNQ中,支持AXI-Lite,AXI4和AXI-Stream三種總線,但PS與PL之間的接口卻只支持前兩種,AXI-Stream只能在PL中實(shí)
    的頭像 發(fā)表于 09-24 09:50 ?5330次閱讀
    一文詳解ZYNQ中的DMA與<b class='flag-5'>AXI</b>4總線

    ZYNQ中DMA與AXI4總線

    和接口的構(gòu)架 在ZYNQ中,支持AXI-Lite,AXI4和AXI-Stream三種總線,但PS與PL之間的接口卻只支持前兩種,AXI-Stream只能在PL中
    的頭像 發(fā)表于 11-02 11:27 ?4341次閱讀
    ZYNQ中DMA與<b class='flag-5'>AXI</b>4總線

    AXI-Stream代碼

    AXI-Stream代碼詳解 AXI4-StreamAXI4的區(qū)別在于AXI4-Stream沒(méi)有ADDR接口,這樣就不涉及讀寫(xiě)數(shù)據(jù)的概念了,只有簡(jiǎn)單的發(fā)送與接收說(shuō)法,減少了延時(shí),允許
    的頭像 發(fā)表于 11-05 17:40 ?3569次閱讀
    <b class='flag-5'>AXI-Stream</b>代碼

    SystemVerilog常用可綜合IP模塊庫(kù)

    了解決這個(gè)復(fù)雜的問(wèn)題,設(shè)計(jì)了這個(gè)庫(kù),它可以幫助您簡(jiǎn)化設(shè)計(jì)流程。使用一些簡(jiǎn)單的 API 可以輕松地在測(cè)試臺(tái)中讀取和寫(xiě)入標(biāo)準(zhǔn)位圖文件 (.BMP)。并且,使用 AXI-Stream Video
    的頭像 發(fā)表于 05-05 09:48 ?1766次閱讀

    關(guān)于AXI4-Stream協(xié)議總結(jié)分享

    XI4-StreamAXI4的區(qū)別就是AXI4-Stream去除了地址線,這樣就不涉及讀寫(xiě)數(shù)據(jù)的概念了,只有簡(jiǎn)單的發(fā)送與接收說(shuō)法,減少了延時(shí)。由于AXI4-Stream協(xié)議(amba
    的頭像 發(fā)表于 06-23 10:08 ?2320次閱讀

    AXI4-Stream Video 協(xié)議和AXI_VDMA的IP核介紹

    本文主要介紹關(guān)于AXI4-Stream Video 協(xié)議和AXI_VDMA的IP核相關(guān)內(nèi)容。為后文完成使用帶有HDMI接口的顯示器構(gòu)建圖像視頻顯示的測(cè)試工程做準(zhǔn)備。
    的頭像 發(fā)表于 07-03 16:11 ?8380次閱讀

    AXI4 、 AXI4-Lite 、AXI4-Stream接口

    AXI4 是一種高性能memory-mapped總線,AXI4-Lite是一只簡(jiǎn)單的、低通量的memory-mapped 總線,而 AXI4-Stream 可以傳輸高速數(shù)據(jù)。從字面意
    的頭像 發(fā)表于 07-04 09:40 ?8617次閱讀

    AXI傳輸數(shù)據(jù)的過(guò)程

    AXI-Stream,其中AXI-Lite和AXI-Full都是基于memory map的形式實(shí)現(xiàn)數(shù)據(jù)傳輸(即包括地址總線),而AXI-Stream
    的頭像 發(fā)表于 10-31 15:37 ?1159次閱讀
    <b class='flag-5'>AXI</b>傳輸數(shù)據(jù)的過(guò)程
    主站蜘蛛池模板: 人妻插B视频一区二区三区| 在线播放一区| 午夜视频在线网站| 亚洲精品久久久一区| 有码在线播放| a视频在线观看免费| 国产精品免费一区二区区| 黄色三级三级三级免费看| 免费人成在线观看视频不卡| 色狼亚洲色图| 伊人狠狠丁香婷婷综合尤物| PORN白嫩内射合集| 国产亚洲视频在线| 免费韩伦影院在线观看| 天天躁日日躁狠狠躁午夜剧场| 野花社区WWW韩国日本| WRITEAS检查身体| 很很射影院| 热久久视久久精品2015| 亚洲色在线| 成年美女黄网站色app| 黄色精品视频| 日本无码毛片一区二区手机看| 亚洲一区二区女搞男| 岛国大片在线观看免费版| 久久久精品免费免费直播| 色AV色婷婷66人妻久久久| 在线 | 果冻国产传媒61国产免费| 草莓在线观看| 久久婷婷色一区二区三区| 四虎视频最新视频在线观看| 中文字幕福利视频在线一区| 国产精品久久久久久日本| 男人扒开添女人下部口述| 亚洲精品视频在线免费| 超污视频带污疼免费视频| 久久视频这里只精品6国产| 偷偷鲁青春草原视频| 99热视频这里只有久久精品| 精品人妻一区二区三区视频53 | 免费特黄一区二区三区视频一|