zoukankan      html  css  js  c++  java
  • BT.656 NTSC制式彩条生成模块(verilog)

    BT.656 NTSC制式彩条生成模块(verilog)

    1.知识储备

    隔行扫描是将一副图像分成两场扫描,第一场扫描第1,2,5,7...等奇数行,第二场扫描2,4,6,8...等偶数行,并把扫奇数行的场称为奇数场,扫偶数行的场称为偶数场,一幅图像经过两次扫描即可。由左到右的扫描称为行扫描,由上到下的扫描称为场扫描。

    对于标准的8bit BT656(YUV4:2:2)标清制式来说,一帧图像的格式定义如下:

     

    一行是由4个部分组成:行 = 结束码(EAV) + 水平消隐(Horizontal Vertical Blanking) + 起始码(SAV) + 有效数据(Active Video)

     

    注意:实际的工程中彩条每一行像素点的排列并不是这样的,而是(SAV Code ->Active video->EAV Code->Blanking video)

    2.代码分析

    TPG端口说明:

    reset_in:由SDI播出工程内部信号提供。

    pclk_in:与播出时钟tx_usrclk对接。

    data_out:输出图像数据。

    tx_sd_ce:门控时钟(SD-SDI,5/6/5/6)

    并且初识化像素位置pixels=1,行位置lines=1,即图像扫描的初始位置。

        彩条中各种色彩值设定(忽略十进制的数字,部分有误),同时定义了用来存储当前颜色的寄存器cur_color

     定义常数,总共有多少行,多少列(1716 525

     

     

    彩条颜色分配函数,通过像素点的位置来分配当前位置的颜色。

     

    有效像素点的排列如下图所示:

     

    pixels初始值为1,则

    01:Cb

    10:Y

    11:Cr

    00:Y

    01:Cb

    通过pixels[0],pixels[1:0]来分割cur_color,得到colorValue.

    以下always块里面是行扫描和场扫描控制,当一行扫描完成后,pixels回到初始位置,line加1.

     

    根据行来控制F,V的值:

     

    每一行的像素排列,一定要注意顺序SAVFF,00,00,XY,接下来的是Active video,然后是EAVFF,00,00,XY),最后是Blanking video,80,10填充。

     

    视频数据的输出:

    颜色数据是8位的,SDI工程接收的是10bit的数据,如果要对接,就需要进行低位填充,当数据是ff时,低2位填充11,当数据不是ff时,低2位填充00.

     

    module tpg(
      reset_in,
      pclk_in,
      pclk_out,
      data_out,
      pixels_out,
      tx_sd_ce
     );
    
    input  reset_in;
    input  pclk_in;
    input  tx_sd_ce;
    output pclk_out;
    output [9:0]data_out;
    output [10:0]pixels_out;
    
    reg [10:0] pixels = 1;
    reg [9:0] lines = 1;
    reg [7:0] data;
    reg F, V;
    
    wire [10:0] pixels_w;
    
    
    `define V_TOTAL_SIZE 525
    `define V_ACTIVE_SIZE 239 //* 240 line
    `define V_BLANK_SIZE 22 //* 22 line
    
    `define H_TOTAL_SIZE 1716
    `define H_ACTIVE_SIZE 1444 //* 1444 pixel (4(SAV) + 720*2(Y+Cr/Cb))
    `define H_BLANK_SIZE 272 //* 272 pixel (4(EAV) + 268)
    
    `define H_COUNT_ADD_ONE 11'b1
    `define V_COUNT_ADD_ONE 10'b1
    
    //* Y, Cb, Cr values for test pattern colours
    //* 75% amplitude, 100% saturated
    //* Values from "Video De-mystified" book, chapter 3
    reg [23:0] white =   {8'heb, 8'h80, 8'h80};//{8'd235, 8'd128, 8'd128};
    reg [23:0] black =   {8'h10, 8'h80, 8'h80};//{8'd16,  8'd128, 8'd128};
    reg [23:0] blue =    {8'h29, 8'hf0, 8'h6e};//{8'd35,  8'd212, 8'd114};
    reg [23:0] green =   {8'h91, 8'h36, 8'h22};//{8'd112, 8'd72,  8'd58};
    reg [23:0] red =     {8'h51, 8'h5a, 8'hf0};//{8'd65,  8'd100, 8'd212};
    reg [23:0] cyan =    {8'haa, 8'ha6, 8'h10};//{8'd131, 8'd156, 8'd44};
    reg [23:0] yellow =  {8'hd2, 8'h10, 8'h92};//{8'd162, 8'd44,  8'd142};
    reg [23:0] magenta = {8'h6a, 8'hca, 8'hde};//{8'd84,  8'd184, 8'd198};
    reg [23:0] cur_color;
    
    //产生图像数据,数据8个8个出
    function [7:0] colorValue;
    input [10:0] pixels;
    begin
       if(452 > pixels)
          cur_color = white;
       else if(632 > pixels)
          cur_color = black;
       else if(812 > pixels)
          cur_color = blue;
       else if(992 > pixels)
          cur_color = green;
       else if(1172 > pixels)
          cur_color = red;
       else if(1352 > pixels)
          cur_color = cyan;
       else if(1532 > pixels)
          cur_color = yellow;
       else
          cur_color = magenta;
       
       //* Y
       if(pixels[0] == 1'h0)
          colorValue = cur_color[23:16];
       //* Cr and Cb
       else if(pixels[1:0] == 2'h1)
          colorValue = cur_color[15:8]; //* Cb
       else
          colorValue = cur_color[7:0]; //* Cr
    end
    endfunction
    
    
    //复位,pixels和lines都归1,像素值逐渐增加,当一行的像素填充完后
    //继续扫描下一行,即lines加1
    always @ (posedge pclk_in)
        if(reset_in)
            begin
                pixels <= 1;
                  lines <= 1;
            end
        else if(tx_sd_ce)
            begin
                if(pixels < `H_TOTAL_SIZE)
                    pixels <= pixels + `H_COUNT_ADD_ONE;
                else 
                    begin
                        pixels <= 1;
                        if(lines < `V_TOTAL_SIZE)
                            lines <= lines + `V_COUNT_ADD_ONE;
                        else
                            lines <= 1;    
                    end
            end
    
    
    //通过bt656标准,行结构的分布来确定F,V
    always @ (posedge pclk_in)
        if(reset_in)
            data <= 10'h00;
      else if(tx_sd_ce)
            begin
                //* even field is 1
                if(lines<4 || lines>265)
                    F <= 1;
                else
                    F <= 0;
    
            //* vertical blank is 1
            if(lines<20 || (lines>263 && lines<283))
              V <= 1;
            else
              V <= 0;
    
    /*
            if(pixels <=1440)
              begin
                  if( V== 1)
                    data <= (pixels[0] == 1) ? 8'h80 : 8'h10;
                  else
                    data <= colorValue(pixels);
              end
            else if(pixels == 1441)  
              data <= 8'hFF;
            else if(pixels == 1442)
              data <= 8'h00;
            else if(pixels == 1443)
              data <= 8'h00;
            else if(pixels == 1444)
              begin
                //* EAV is 1   
                //H <= 1;
                //data <= { 1'b1, F, V, H, (V ^ H), (F ^ H), (F ^V ), (F ^ V ^ H) };
                data <= { 1'b1, F, V, 1'b1, (V ^ 1'b1), (F ^ 1'b1), (F ^ V ), (F ^ V ^ 1'b1) };
              end
            else if(pixels <= 1712)
                data <= (pixels[0] == 1) ? 8'h80 : 8'h10;
            else if(pixels == 1713)
              data <= 8'hFF;
            else if(pixels == 1714)
              data <= 8'h00;
            else if(pixels == 1715)
              data <= 8'h00;
            else if(pixels == 1716)
                  begin
                    //* SAV is 0    
                    //H <= 0;
                    //data <= { 1'b1, F, V, H, (V ^ H), (F ^ H), (F ^V ), (F ^ V ^ H) };
                    data <= { 1'b1, F, V, 1'b0, (V ^ 1'b1), (F ^ 1'b1), (F ^ V ), (F ^ V ^ 1'b1) };
                  end
            end
    */
            if(pixels == 1)
              data <= 8'hFF;
            else if(pixels == 2)
              data <= 8'h00;
            else if(pixels == 3)
              data <= 8'h00;
            else if(pixels == 4)
                  begin
                    //* EAV is 1    //换成sav
                    //H <= 1;
                    //data <= { 1'b1, F, V, H, (V ^ H), (F ^ H), (F ^V ), (F ^ V ^ H) };
                    data <= { 1'b1, F, V, 1'b0, (V ^ 1'b1), (F ^ 1'b1), (F ^ V ), (F ^ V ^ 1'b1) };
                  end
            else if(pixels <= 1444) //* horizontal blanking pixel
                    begin
                        if( V== 1)
                          data <= (pixels[0] == 1) ? 8'h80 : 8'h10;
                        else
                          data <= colorValue(pixels);
                    end              
            else if(pixels == 1445)
                    data <= 8'hFF;
            else if(pixels == 1446)
                    data <= 8'h00;
            else if(pixels == 1447)
                    data <= 8'h00;
            else if(pixels == 1448)
                  begin
                    //* SAV is 0 //换成eav
                    //H <= 0;
                    //data <= { 1'b1, F, V, H, (V ^ H), (F ^ H), (F ^V ), (F ^ V ^ H) };
                    data <= { 1'b1, F, V, 1'b1, (V ^ 1'b0), (F ^ 1'b0), (F ^ V ), (F ^ V ^ 1'b0) };
                  end
            else //* horizontal active pixel
                //* if vertical blank, fill with 0x80, 0x10
                  data <= (pixels[0] == 1) ? 8'h80 : 8'h10;
            end
    
    assign pclk_out = pclk_in;
    assign data_out = (data == 8'hff) ? {data, 2'b11} : {data, 2'b00};
    assign pixels_out = pixels;
    
    assign pixels_w = pixels;
    endmodule

     

  • 相关阅读:
    Scars To Your Beautiful
    【BZOJ1833】【ZJOI2010】数字计数(数位DP)
    滑块拼图
    神经元(prufer序列+dp)
    sequence(dp+hash+二分搜索+前缀和优化)
    循环移位(后缀自动机)
    MST(最小生成树+倍增)
    nyoj 845【水】
    分割问题【知识点】
    扩展欧几里得【知识点】
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/7323940.html
Copyright © 2011-2022 走看看