[X]关闭
1

(非AXI4)S02-CH02_DDR_IMAGE_TEST(4 片 DDR 三缓存)

摘要: 2.1 概述 本节课的设计内容是完成图像数据在DDR 的缓存然后输出,课程内容将会采用step by step 的方式,教会大家一步步掌握MIG 控制器在图像数据缓存方便的应用。掌握了图像数据的缓存应用,读者可以把这种方案移 ...

2.1 概述

      本节课的设计内容是完成图像数据在 DDR 的缓存然后输出,课程内容将会采用 step by step 的方式,教会大家一步步掌握 MIG 控制器在图像数据缓存方便的应用。掌握了图像数据的缓存应用,

读者可以把这种方案移植到自己的项目中。具备非常强的实用价值。  

       有句老话叫做心急吃不了热豆腐,在前面的课程中,小编详细讲解了基于 7 系列 FPGA 的 MIG

内存控制器的读写测试,读者务必仔细学习完前面一个章节课程,掌握好 MIG 控制器 IP 的使用基础 后再来做这实验,因为本节课中不会再对前面章节的已经讲解过的基础部分再做详细的解释。 

2.2 构架设计

       对于稍微复杂一点的工程项目必须要有优秀的构架设计,优秀的设计构架的意义比具体写代码 更有价值,所以小编建议读者在以后自己的项目中要多学习和思考构架的设计。小编设计了一种基于 消息缓存模式的构架,可以广泛用于图像缓存,数据采集缓存,通信数据缓存等项目中。 

      如下图 所示 ,数据 经过 image_data_gen 模块 产生 测试数 据和测 试时 序输入 到 MIG_BURTS_IMAGE,然后再流出来到 vga_lcd_driver 模块,vga_lcd_driver 模块输出的是 RGB 时序 (VGA 时序)。 


1)、Testbench 波形测试文件:里面包含了 DDR3 仿真模型可以模拟 DDR3 的运行情况  

2)、Sensor_data_gen 模块:产生 RGB(VGA)测试时序,为了观察数据方便,可以用行计数器hcounter作为图形测试数据,如下。

       assign r <= hcounter[7:0];               

       assign g <= hcounter[7:0];

       assign b <= hcounter[7:0];

        当然小编在完成功能测试后,可以让 sensor_data_gen 产生彩条、方格、纯色等测试方案进行进一步测试。 

3)、vga_lcd_driver 模块:产生 RGB(VGA)输出时序 

4)、MIG_BURST_IMAGE 模块:管理图像数据和内存管理,MIG_BURST_IMAGE 模块中包括了 CH0_FIFO 模 块、CH6_FIFO 模块、MIG_DDR 控制器、MSG_FIFO 消息盒、M_S 内存管理状态机,此外还包括 CH0_FIFO 的读请求,以及 CH6_FIFO 的写请求。FIFO 实现MIG位宽和像素位宽的转换以及缓存作用。 

2.3 主要模块源码分析

2.3.1 Image_data_gen.v

module  sensor_data_gen (

    input clk,

    output [7:0] r,

    output [7:0] g,

    output [7:0] b,

    output de,

    output vsync,

    output hsync    );


   reg  [23:0] colour=24'd0;

   reg  [11:0] hcounter=12'd0;

   reg  [11:0] vcounter=12'd0;

    

// Colours converted using The RGB -> YCbCr converter app found on Google Gadgets

                                //   Y    Cb   Cr

   `define C_BLACK 24'h000000;  //  16   128  128

   `define C_RED   24'hFF0000;  //  81   90   240

   `define C_GREEN 24'h00FF00;  //  172  42   27

   `define C_BLUE  24'h0000FF;  //  32   240  118

   `define C_WHITE 24'hFFFFFF;  //  234  128  128



// -- Set the video mode to 1920x1080x60Hz (150MHz pixel clock needed)

/*    parameter hVisible  = 1920;

   parameter hStartSync = 1920+88;

   parameter hEndSync   = 1920+88+44;

   parameter hMax       = 1920+88+44+148; //2200

   

   parameter vVisible    = 1080;

   parameter vStartSync  = 1080+4;

   parameter vEndSync    = 1080+4+5;

   parameter vMax        = 1080+4+5+36; //1125

 */


// -- Set the video mode to 1440x900x60Hz (106.47MHz pixel clock needed)

/*   parameter hVisible   = 1440;

   parameter hStartSync = 1440+80;

   parameter hEndSync   = 1440+80+152;

   parameter hMax       = 1440+80+152+232; //1904

   

   parameter vVisible    = 900;

   parameter vStartSync  = 900+1;

   parameter vEndSync    = 900+1+3;

   parameter vMax        = 900+1+3+28; //932

   */


    

// -- Set the video mode to 1280x720x60Hz (75MHz pixel clock needed)

  /*parameter hVisible   = 1280;

   parameter hStartSync = 1280+72;

   parameter hEndSync   = 1280+72+80;

   parameter hMax       = 1280+72+80+216; //1647

   

   parameter vVisible    = 720;

   parameter vStartSync  = 720+3;

   parameter vEndSync    = 720+3+5;

   parameter vMax        = 720+3+5+22; //749

*/


// -- Set the video mode to 800x600x60Hz (40MHz pixel clock needed)

/*   parameter hVisible   = 800;

   parameter hStartSync = 840; //800+40

   parameter hEndSync   = 968; //800+40+128

   parameter hMax       = 1056; //800+40+128+88

   

   parameter vVisible    = 600;

   parameter vStartSync  = 601; //600+1

   parameter vEndSync    = 605; //600+1+4

   parameter vMax        = 628; //600+1+4+23      



*/

// -- Set the video mode to 640x480x60Hz (25MHz pixel clock needed)


   parameter hVisible   = 640;

   parameter hStartSync = 656; //640+16

   parameter hEndSync   = 752; //640+16+96

   parameter hMax       = 800; //640+16+96+48

   

   parameter vVisible    = 480;

   parameter vStartSync  = 490; //480+10

   parameter vEndSync    = 492; //480+10+2

   parameter vMax        = 525; //480+10+2+33


//------------------------------------------

//v_sync counter & generator


always@(posedge clk) begin

if(hcounter < hMax - 12'd1)        //line over

hcounter <= hcounter + 12'd1;

else

hcounter <= 12'd0;

end


always@(posedge clk) begin

if(hcounter == hMax - 12'd1) begin

if(vcounter < vMax - 12'd1)  //frame over

vcounter <= vcounter + 12'd1;

else

vcounter <= 12'd0;

end

end


assign hsync = ((hcounter >= (hStartSync - 2'd2))&&(hcounter < (hEndSync - 2'd2)))? 1'b0:1'b1;  //Generate the hSync Pulses

assign vsync = ((vcounter >= (vStartSync - 1'b1))&&(vcounter < (vEndSync - 1'b1)))? 1'b0:1'b1; //Generate the vSync Pulses

  

        

 always@(posedge clk) begin

    if (hcounter <= hVisible/5) begin colour <= `C_RED; end

    else if(hcounter <= 2*hVisible/5) begin colour <= `C_GREEN; end

    else if(hcounter <= 3*hVisible/5) begin colour <= `C_BLUE; end

    else if(hcounter <= 4*hVisible/5) begin colour <= `C_WHITE; end

    else  begin colour <= `C_BLACK; end

 end

/*  

  assign r = colour[23:16];

  assign g = colour[15:8];

  assign b = colour[7:0];

  */


reg [7:0]VGA_R_reg;

reg [7:0]VGA_G_reg;

reg [7:0]VGA_B_reg;

reg [10:0] dis_mode=11'd0;

always @(posedge clk) begin

    if((vcounter == vMax - 12'd1)&&(hcounter == hMax - 12'd1))

        dis_mode <= dis_mode +1'b1;


end


reg[7:0] grid_data_1=8'd0;

reg[7:0] grid_data_2=8'd0;

always @(posedge clk) //格子图像

begin

if((hcounter[4]==1'b1)^(vcounter[4]==1'b1))

grid_data_1 <= 8'h00;

else

grid_data_1 <= 8'hff;


if((hcounter[6]==1'b1)^(vcounter[6]==1'b1))

grid_data_2 <= 8'h00;

else

grid_data_2 <= 8'hff;

end


reg[23:0] color_bar;

always @(posedge clk)

begin

if(hcounter==260)

color_bar <= 24'hff0000;

else if(hcounter==420)

color_bar <= 24'h00ff00;

else if(hcounter==580)

color_bar <= 24'h0000ff;

else if(hcounter==740)

color_bar <= 24'hff00ff;

else if(hcounter==900)

color_bar <= 24'hffff00;

else if(hcounter==1060)

color_bar <= 24'h00ffff;

else if(hcounter==1220)

color_bar <= 24'hffffff;

else if(hcounter==1380)

color_bar <= 24'h000000;

else

color_bar <= color_bar;

end

always @(posedge clk)

begin  

if(1'b0)

begin

   VGA_R_reg<=0;

   VGA_G_reg<=0;

   VGA_B_reg<=0;  

end

   else

     case(dis_mode[10:7])

         4'd0:begin

     VGA_R_reg<=0;            

                 VGA_G_reg<=0;

                 VGA_B_reg<=0;

end

4'd1:begin

     VGA_R_reg<=8'b11111111;                 //LCD显示全白

                 VGA_G_reg<=8'b11111111;

                 VGA_B_reg<=8'b11111111;

end

4'd2:begin

     VGA_R_reg<=8'b11111111;                //LCD显示全红

                 VGA_G_reg<=0;

                 VGA_B_reg<=0;  

             end   

       4'd3:begin

     VGA_R_reg<=0;                          //LCD显示全绿

                 VGA_G_reg<=8'b11111111;

                 VGA_B_reg<=0;

            end   

             4'd4:begin     

     VGA_R_reg<=0;                         //LCD显示全蓝

                 VGA_G_reg<=0;

                 VGA_B_reg<=8'b11111111;

end

             4'd5:begin     

     VGA_R_reg<=grid_data_1;               // LCD显示方格1

                 VGA_G_reg<=grid_data_1;

                 VGA_B_reg<=grid_data_1;

            end   

            4'd6:begin     

     VGA_R_reg<=grid_data_2;               // LCD显示方格2

                 VGA_G_reg<=grid_data_2;

                 VGA_B_reg<=grid_data_2;

end

    4'd7:begin     

     VGA_R_reg<=hcounter[7:0];                //LCD显示水平渐变色

                 VGA_G_reg<=hcounter[7:0];

                 VGA_B_reg<=hcounter[7:0];

 end

     4'd8:begin     

     VGA_R_reg<=vcounter[8:1];                 //LCD显示垂直渐变色

                 VGA_G_reg<=hcounter[8:1];

                 VGA_B_reg<=hcounter[8:1];

end

     4'd9:begin     

     VGA_R_reg<=hcounter[7:0];                 //LCD显示红水平渐变色

                 VGA_G_reg<=0;

                 VGA_B_reg<=0;

end

     4'd10:begin     

     VGA_R_reg<=0;                          //LCD显示绿水平渐变色

                 VGA_G_reg<=hcounter[7:0];

                 VGA_B_reg<=0;

end

     4'd11:begin     

     VGA_R_reg<=0;                          //LCD显示蓝水平渐变色

                 VGA_G_reg<=0;

                 VGA_B_reg<=hcounter[7:0];

end

     4'd12:begin     

     VGA_R_reg<=color_bar[23:16];            //LCD显示彩色条

                 VGA_G_reg<=color_bar[15:8];

                 VGA_B_reg<=color_bar[7:0];

end

   default:begin

     VGA_R_reg<=8'b11111111;                //LCD显示全白

                 VGA_G_reg<=8'b11111111;

                 VGA_B_reg<=8'b11111111;

end   

         endcase

end


  assign de = (vcounter >= vVisible || hcounter >= hVisible) ? 1'b0 : 1'b1;

  assign r = VGA_R_reg;

  assign g = VGA_G_reg;

  assign b = VGA_B_reg;

  

  //assign r = hcounter[7:0];

  //assign g = hcounter[7:0];

  //assign b = hcounter[7:0];

  

 endmodule

       Sensor_data_gen模块的作用是产生一副 640X480 分辨率的测试图形,未来观察数据的方便,在 最后部分红色标记的代码中,小编取 pixel 的低 8bit 复制给 r/g/b 作为测试数据输出。所以后面我 们观察 MIG_BURST_IMAGE 模块工作的时候只要观察 r/g/数据是否从 0-256 有序增加。读者可以移植 本代码,设置不同分辨率,不同测试图形做更多测试。另外需要注意,在使用4片DDR的情况下,由于FIFO不支持从512bit 转换为32bit 但是支持从512bit 转换为64bit所以这里需要把32bit的图像数据转换为64bit提供给FIFO。

always @(posedge clk) begin

   de_cnt <= data_en ?  de_cnt + 1'b1 : 1'b0 ;

   de <= de_cnt;

   if(data_en) begin

      data64 <= {data64[31:0],{8'd0,VGA_R_reg,VGA_G_reg,VGA_B_reg}};

   end  

end


2.3.2 vga_lcd_driver.v

module vga_lcd_driver(

    input  clk,

    input  [7:0]  r_i,

    input  [7:0]  g_i,

    input  [7:0]  b_i,

    output [7:0]  r_o,

    output [7:0]  g_o,

    output [7:0]  b_o,

    output de,

    output vsync,

    output hsync

    );


   reg  [11:0] hcounter;

   reg  [11:0] vcounter;

    

// Colours converted using The RGB


// -- Set the video mode to 1920x1080x60Hz (150MHz pixel clock needed)

 /*    parameter hVisible  = 1920;

   parameter hStartSync = 1920+88;

   parameter hEndSync   = 1920+88+44;

   parameter hMax       = 1920+88+44+148; //2200

   

   parameter vVisible    = 1080;

   parameter vStartSync  = 1080+4;

   parameter vEndSync    = 1080+4+5;

   parameter vMax        = 1080+4+5+36; //1125

*/


// -- Set the video mode to 1440x900x60Hz (106.47MHz pixel clock needed)

/*   parameter hVisible   = 1440;

   parameter hStartSync = 1440+80;

   parameter hEndSync   = 1440+80+152;

   parameter hMax       = 1440+80+152+232; //1904

   

   parameter vVisible    = 900;

   parameter vStartSync  = 900+1;

   parameter vEndSync    = 900+1+3;

   parameter vMax        = 900+1+3+28; //932

   */


    

// -- Set the video mode to 1280x720x60Hz (75MHz pixel clock needed)


路过

雷人

握手

鲜花

鸡蛋
发表评论

最新评论

引用 白果 2020-11-30 09:11
请问使用 fifo 的这个信号 rd_data_count(CH0_rusdw_o) 会不会有问题,感觉这个信号不是很精确,有时变化有点奇怪。

查看全部评论(1)

本文作者
2019-10-16 11:03
  • 1
    粉丝
  • 2196
    阅读
  • 1
    回复

米联客UIsrc

独家课程 硬核科技

销售电话:18921033576
EMAIL:tjy@uisrc.com
地址:常州溧阳市天目云谷3号楼北楼
热门评论
排行榜