FPGA实战开发-基于DDR的图像缓存(下)

文章目录

    • 概要
    • 整体架构流程
    • 技术名词解释
    • 技术细节
    • 小结

概要

例如:

基于米联科的学习资料,分享和学习同步,欢迎大家一起探讨。

整体架构流程

提示:这里可以添加技术整体架构

例如:

FPGA实战开发-基于DDR的图像缓存(下)_第1张图片

      image_data_gen产生了测试图片,之后进入过W0 FIFO进行视频缓存。每次缓存1024个像素,就往通过FDMA往DDR里面搬运数据。另外VS信号经过滤波采集后用于启动一次写状态机。同理对于图像的输出部分采用HDMI输出,用Vga_lcd_driver产生输出的时序。视频经过R0 FIFO缓存后输出。R0 FIFO也是每次缓存1024个像素数据。 

技术名词解释

FIFO: First in, First out

代表先进的数据先出 ,后进的数据后出。

DMA:全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高。

技术细节

提示:这里可以添加技术细节

//--------一帧图像写入DDR------------

 always @(posedge ui_clk) begin

    if(!ui_rstn)begin

        W_MS <= S_IDLE;

        W0_addr <= 21'd0;

        pkg_wr_areq <= 1'd0;

        W0_FIFO_Rst <= 1'b1;

        W0_fcnt <= 0;

        W0_bcnt <= 0;

        W0_s_rdy <= 1'b0;

        W0_Fbuf <= 7'd0;

    end

    else begin

      case(W_MS)

       S_IDLE:begin

          W0_addr <= 21'd0;

          W0_fcnt <= 0;

          W0_bcnt <= 11'd0;

          W0_s_rdy <= 1'b1;

          if(W0_FS) W_MS <= S_RST;

       end

       S_RST:begin

           W0_s_rdy <= 1'b0;  

          if(W0_fcnt > 8'd30 ) W_MS <= S_DATA1;

          W0_FIFO_Rst <= (W0_fcnt < 8'd20);

          W0_fcnt <= W0_fcnt +1'd1;

        end          

        S_DATA1:begin

            if(W0_bcnt == BURST_TIMES) begin

                if(W0_Fbuf == FBUF_SIZE)

                    W0_Fbuf <= 7'd0;

                 else

                    W0_Fbuf <= W0_Fbuf + 1'b1;

                 W_MS <= S_IDLE;

            end

            else if(W0_REQ) begin

                W0_fcnt <=0;

                pkg_wr_areq <= 1'b1;

                W_MS <= S_DATA2;  

            end           

         end

         S_DATA2:begin

            pkg_wr_areq <= 1'b0;

            if(pkg_wr_last)begin

                W_MS <= S_DATA1;

                W0_bcnt <= W0_bcnt + 1'd1;

                W0_addr <= W0_addr + BURST_SIZE;

            end

         end

       endcase

    end

 end

//--------一帧图像读出DDR------------

 always @(posedge ui_clk) begin

   if(!ui_rstn)begin

       R_MS <= S_IDLE;

       R0_addr <= 21'd0;

       pkg_rd_areq <= 1'd0;

       R0_fcnt <=0;

       R0_bcnt <=0;

       R0_FIFO_Rst <= 1'b1;

       R0_s_rdy <= 1'b0;

       R0_Fbuf <= 7'd0;       

   end

   else begin

     case(R_MS)

       S_IDLE:begin

         R0_addr <= 21'd0;

         R0_fcnt <=0;

         R0_bcnt <=0;

         R0_s_rdy <= 1'b1;

         if(R0_FS) R_MS <= S_RST;

       end

       S_RST:begin

         R0_s_rdy <= 1'b0;

         if(R0_fcnt > 8'd30 ) R_MS <= S_DATA1;

         R0_FIFO_Rst <= (R0_fcnt < 8'd20);

         R0_fcnt <= R0_fcnt + 1'd1;

       end  

       S_DATA1:begin

           if(R0_bcnt == BURST_TIMES ) begin

               R_MS <= S_IDLE;

               if(W0_Fbuf == 7'd0)

                    R0_Fbuf <= FBUF_SIZE;

                else

                    R0_Fbuf <= W0_Fbuf - 1'b1;   

           end

           else if(R0_REQ) begin

               pkg_rd_areq <= 1'b1;

               R_MS <= S_DATA2;  

           end           

        end

        S_DATA2:begin

           pkg_rd_areq <= 1'b0;   

           if(pkg_rd_last)begin

               R_MS <= S_DATA1;

               R0_bcnt <= R0_bcnt + 1'd1;

               R0_addr <= R0_addr + BURST_SIZE;

           end

        end

      endcase

   end

end

 always@(posedge ui_clk)

 begin     

     W0_REQ    <= (W0_rcnt    >= PKG_SIZE);

     R0_REQ    <= (R0_wcnt    <= PKG_SIZE);

 end

上面两端代码,分别表示帧写入和帧写出DDR的代码

截取上面完整代码中部分代码如下:可以看到控制高地址,轻松完成缓存地址切换。

assign pkg_wr_addr = {W0_Fbuf,W0_addr}+ADDR_OFFSET;

assgin pkg_rd_addr ={R0_Fbuf,R0_addr}+ADDR_OFFSET;

小结

提示:这里可以添加总结

例如:

本文主要基于FDMA的ddr图像缓存做了设计。

你可能感兴趣的:(FPGA设计-基础篇,fpga开发,缓存)