FPGA coding realized BT.1120

Studied the two-day BT1120 specifications, and CEA-861-D video timing, we found some correspondence between (see my other article "relationship with the BT1120 the video timing" ). So I wrote the following verilog code which can be connected sii9134 chip row inline field, wherein the configuration sii9134 C code as follows:

void sii9134_init(void)
{
      u8 u8Data = 0;
      I2C_WriteByte(0x05, 0x08, 0x72); //value reg_addr device_addr
      
      I2C_ReadByte(&u8Data, sizeof(u8), 0x33, 0x72);
      I2C_WriteByte(u8Data & 0x8f, 0x33, 0x72);
      
      I2C_WriteByte(0x6e, 0x40, 0x72);
      I2C_WriteByte(0x28, 0x44, 0x72);
      I2C_WriteByte(0x00, 0x45, 0x72);
      I2C_WriteByte(0x05, 0x46, 0x72);
      I2C_WriteByte(0x05, 0x47, 0x72);
      I2C_WriteByte(0x30, 0x48, 0x72);
 
      I2C_WriteByte(0x3d, 0x4a, 0x72);
}

 

Breadboard using the FPGA AV6045 development board black gold.

FPGA end bt1120 verilog code is as follows (horizontal and vertical sync signal is active high hsync and vsync):

Further, if it is found the pixel data is 0x00 or 0xff 0xfe and 0x01 need to be replaced, to prevent misjudgment end. (This article does not do this step)

 

/ **
 * author: [email protected]
 * Time: 2017/8/28
 * function: YCbCr 4: 2: 2 embed_hs_vs Encoder Module1, compatible BT.1120
 *
 * timing reference codes <0xFF 0x00 0x00 xxx>
 * where xxx is the following range:
 * 0. 1. 1. 1. 1 0 0 0 0. 1 0xAB (vertical blanking period, within the SAV)
 (vertical blanking period, within the EAV) * 0. 1. 1. 1. 1. 1 0 0 0 0 0xB6
 *. 1 0 0 0 0 0 0 0 0 0 0x80 ( video active region of time, within the SAV)
 *. 1 0 0. 1. 1. 1 0. 1 0 0 0x9d (video active region of time, within the EAV)
 * /
 
`timescale 1ns / 100ps
Module1 embed_hs_vs_enc (
  RST INPUT,
  
  INPUT yc422_pclk_i,
  INPUT [15: 0] yc422_data_i,
  INPUT yc422_de_i,
  INPUT yc422_vs_i,
  INPUT yc422_hs_i,
  
  // ------------------------------------------------ --------
  // video timing parameters, obtained by the CPU through i2c arranged
  INPUT [. 11: 0] width_i, // L
  INPUT [. 11: 0] height_i, //
  INPUT [. 11: 0] hs_rising_to_de_i,
  INPUT [. 11: 0] hor_total_g_i,
  INPUT [. 11: 0] vs_rising_to_de_i, // L2 of
  INPUT [. 11: 0] ver_total_g_i, L6 of //
  
  // ------------------- ---------------------------------------
  the INPUT video_pararm_enable_i, 
  // ------ -------------------------------------------------- -
  
  //bt.1120 Interface
  Output embed_hs_vs_pclk_o,
  Output REG [15: 0] embed_hs_vs_yc422_o
    );
 
  // state machine
  localparam  INVAILD_BLANKING  =  4'd0;
  localparam  VAILD_VIDEO = 4'd1;
  localparam  SYNC1_SAV =  4'd2;
  localparam  SYNC2_SAV =  4'd3;
  localparam  SYNC3_SAV =  4'd4;
  localparam  SYNC1_EAV =  4'd5;
  localparam  SYNC2_EAV =  4'd6;
  localparam  SYNC3_EAV =  4'd7;
  localparam  SAV_BKANKING = 4'd8;
  localparam  EAV_BKANKING = 4'd9;
  localparam  SAV_VIDEO = 4'd10;
  localparam  EAV_VIDEO = 4'd11;
  
  //在行场消隐区填充STUFF
  localparam  STUFF  = 16'h8010;
  
  wire hs_rising; //rising or falling
  wire vs_rising;
  
  reg [11:0] vs_cnt;//场计数器
  reg [11:0] hs_cnt;Line counter //
  
  // properly handle the reset signal, the register value is not initialized or
  REG [. 11: 0] width_g;
  REG [. 11: 0] height_g;
  REG [. 11: 0] hs_rising_to_de_g;
  REG [. 11: 0] hor_total_g;
  REG [. 11: 0] vs_rising_to_de_g;
  REG [. 11: 0] ver_total_g;
  
  REG [ 3: 0] state_cs; // should be noted that the current state variable register bit width, prevent overflow
  reg [3: 0] state_ns; // next state
  
  // to delay the operation of the signal, playing a beat
  // reg [15 : 0] yc422_data_d1;
  REG yc422_de_d1;
  REG yc422_vs_d1;
  REG yc422_hs_d1;
  
  Always @ (posedge yc422_pclk_i)
  the begin
    IF (RST) the begin
      // yc422_data_d1 <= 16'h00;
      yc422_de_d1 <= 1'b0;
      yc422_vs_d1 <= 1'b0;
      yc422_hs_d1 <= 1'b0;
    End the else the begin
      //yc422_data_d1  <=  yc422_data_i;
      yc422_de_d1    <=  yc422_de_i;
      yc422_vs_d1    <=  yc422_vs_i;
      yc422_hs_d1    <=  yc422_hs_i;
    end
   end
   
  assign embed_hs_vs_pclk_o = yc422_pclk_i;
 
  assign hs_rising = ~yc422_hs_d1 & yc422_hs_i; 
  assign vs_rising = ~yc422_vs_d1 & yc422_vs_i;
   
  always @(posedge yc422_pclk_i)
  begin
    if(rst) begin
      width_g <=              12'd1920;
      height_g <=             12'd1080;
      hs_rising_to_de_g <=    12'd192;
      hor_total_g <=          12'd2200;
      vs_rising_to_de_g <=    12'd41;
      ver_total_g <=          12'd1125;
    end else if(video_pararm_enable_i)begin
      width_g <= width_i;
      height_g <= height_i;
      hs_rising_to_de_g <= hs_rising_to_de_i;
      hor_total_g <= hor_total_g_i;
      vs_rising_to_de_g <= vs_rising_to_de_i;
      ver_total_g <= ver_total_g_i;
    end
  end
  
  //行计数
  always @(posedge yc422_pclk_i)
  begin
  if(rst) 
      hs_cnt <= 0;
  else if(hs_rising || video_pararm_enable_i)
    hs_cnt <= 0;
  else if(hs_cnt == hor_total_g - 1'b1)
    hs_cnt <= 0;
  else
    hs_cnt <= hs_cnt + 1'b1;   always @ (posedge yc422_pclk_i)   // frame count
  End
  


  begin
     if(rst) 
      vs_cnt <= 0;
    else if(vs_rising || video_pararm_enable_i) 
      vs_cnt <= 0;
    else if(hs_cnt == hor_total_g - 1'b1)
      if(vs_cnt == ver_total_g - 1'b1)
        vs_cnt <= 0;
      else
        vs_cnt <= vs_cnt + 1'b1;
    else 
      vs_cnt <= vs_cnt;
  end
 
  always @(posedge yc422_pclk_i)
  begin
    if(rst)
      state_cs  <=  INVAILD_BLANKING;
    else
      state_cs  <=  state_ns;
  end
  
  always @(*)
  begin
    case(state_cs)
    INVAILD_BLANKING : 
    begin
      if (hs_cnt == hs_rising_to_de_g - 3'd6) // SAV four clock cycles earlier, to include SAV and EAV as 4 clock cycles, and third and compensation state_cs brought 2-timer
        state_ns = SYNC1_SAV;
      the else IF (hs_cnt == hs_rising_to_de_g + width_g - 3'd2 ) // EAV does not require four clock cycles earlier, but requires compensation and third state_cs brought 2-timer
        state_ns = SYNC1_EAV;
      the else
        state_ns = INVAILD_BLANKING;
    End
    
    // the SAV part
    SYNC1_SAV: state_ns = SYNC2_SAV;
    SYNC2_SAV: state_ns = SYNC3_SAV;
    SYNC3_SAV: 
    IF ((vs_cnt> = vs_rising_to_de_g - 1'b1) && (vs_cnt <+ = height_g vs_rising_to_de_g - 1'b1)) // VILD_VIDEO
      state_ns = SAV_VIDEO;
    the else
      state_ns SAV_BKANKING =;
    
    // portion of the EAV
    SYNC1_EAV : state_ns = SYNC2_EAV;
    SYNC2_EAV : state_ns = SYNC3_EAV;
    SYNC3_EAV :
    if((vs_cnt >= vs_rising_to_de_g - 1'b1) && (vs_cnt <=  height_g + vs_rising_to_de_g - 1'b1))//VILD_VIDEO
      state_ns = EAV_VIDEO;
    else
      state_ns = EAV_BKANKING;
    
    SAV_BKANKING : state_ns = INVAILD_BLANKING;
    EAV_BKANKING : state_ns = INVAILD_BLANKING;
    SAV_VIDEO :     state_ns = VAILD_VIDEO;
    EAV_VIDEO :     state_ns = INVAILD_BLANKING;
    
    VAILD_VIDEO :
      if(hs_cnt == hs_rising_to_de_g + width_g - 1'b1 - 1'b1)
          state_ns = SYNC1_EAV;//去EAV部分
      else
        state_ns = VAILD_VIDEO;
    default :
      state_ns  = INVAILD_BLANKING;
    endcase
  end
  
  always @(posedge yc422_pclk_i)
  begin
    if(rst)
      embed_hs_vs_yc422_o  <=  STUFF;
    else begin
      if(state_cs == INVAILD_BLANKING)
        embed_hs_vs_yc422_o <= STUFF;
      else if(state_cs == VAILD_VIDEO)
        embed_hs_vs_yc422_o <= yc422_data_i; //yc422_data_d1
      else if((state_cs == SYNC1_SAV) || (state_cs == SYNC1_EAV))
        embed_hs_vs_yc422_o <= 16'hffff;
      else if((state_cs == SYNC2_SAV) || (state_cs == SYNC2_EAV))
        embed_hs_vs_yc422_o <= 16'h0000;
      else if((state_cs == SYNC3_SAV) || (state_cs == SYNC3_EAV))
        embed_hs_vs_yc422_o <= 16'h0000;
      else if(state_cs == SAV_BKANKING)
        embed_hs_vs_yc422_o <= 16'habab;
      else if(state_cs == EAV_BKANKING)
        embed_hs_vs_yc422_o <= 16'hb6b6;
      else if(state_cs == SAV_VIDEO)
        embed_hs_vs_yc422_o <= 16'h8080;
      else if(state_cs == EAV_VIDEO)
        embed_hs_vs_yc422_o <= 16'h9d9d;
      else
        embed_hs_vs_yc422_o <= STUFF;
    end
  end
 
endmodule

 

    U_embed_hs_vs_enc_0 embed_hs_vs_enc (
  . RST (RST),
  
  . yc422_pclk_i (video_clk_148m5),
  . yc422_data_i ({yc_c, yc_y}),
  . yc422_de_i (yc_de),
  . yc422_vs_i (yc_vs),
  . yc422_hs_i (yc_hs),
  
  // ----- -------------------------------------------------- -
  // video timing parameters, obtained from the CPU through the I2C configuration
  width_i (12'd1920), // L.
  height_i (12'd1080), //.
  hs_rising_to_de_i (12'd192),.
  hor_total_g_i (12'd2200),.
  . vs_rising_to_de_i (12'd41), L2 of //
  . ver_total_g_i (12'd1125), L6 of //
  
  // -------------------------- --------------------------------
  .      video_pararm_enable_i(video_pararm_enable), 
  //----------------------------------------------------------
  
  //bt.1120接口
  .         embed_hs_vs_pclk_o(bt1120_clk),
  .         embed_hs_vs_yc422_o(bt1120_yc)
    );

Published 68 original articles · won praise 85 · views 180 000 +

Guess you like

Origin blog.csdn.net/weiaipan1314/article/details/102845638