Xilinx 7serial:RGB转TMDS

`timescale 1ns / 1ps
//
module encode (
  input            clkin,    // pixel clock input
  input            rstin,    // async. reset input (active high)
  input      [7:0] din,      // data inputs: expect registered
  input            c0,       // c0 input
  input            c1,       // c1 input
  input            de,       // de input
  output reg [9:0] dout      // data outputs
);

  
  // Counting number of 1s and 0s for each incoming pixel
  // component. Pipe line the result.
  // Register Data Input so it matches the pipe lined adder
  // output
  
  reg [3:0] n1d; //number of 1s in din
  reg [7:0] din_q;

  always @ (posedge clkin) begin
    n1d <= din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];

    din_q <= din;
  end

  ///
  // Stage 1: 8 bit -> 9 bit
  // Refer to DVI 1.0 Specification, page 29, Figure 3-5
  ///
  wire decision1;

  assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
/*
  reg [8:0] q_m;
  always @ (posedge clkin) begin
    q_m[0] <=#1 din_q[0];
    q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
    q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
    q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
    q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
    q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
    q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
    q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
    q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
  end
*/
  wire [8:0] q_m;
  assign q_m[0] = din_q[0];
  assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
  assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
  assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
  assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
  assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
  assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
  assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
  assign q_m[8] = (decision1) ? 1'b0 : 1'b1;

  /
  // Stage 2: 9 bit -> 10 bit
  // Refer to DVI 1.0 Specification, page 29, Figure 3-5
  /
  reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
  always @ (posedge clkin) begin
    n1q_m  <= q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
    n0q_m  <= 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
  end

  parameter CTRLTOKEN0 = 10'b1101010100;
  parameter CTRLTOKEN1 = 10'b0010101011;
  parameter CTRLTOKEN2 = 10'b0101010100;
  parameter CTRLTOKEN3 = 10'b1010101011;

  reg [4:0] cnt; //disparity counter, MSB is the sign bit
  wire decision2, decision3;

  assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
  /
  // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
  /
  assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));

  
  // pipe line alignment
  
  reg       de_q, de_reg;
  reg       c0_q, c1_q;
  reg       c0_reg, c1_reg;
  reg [8:0] q_m_reg;

  always @ (posedge clkin) begin
    de_q    <= de;
    de_reg  <= de_q;

    c0_q    <= c0;
    c0_reg  <= c0_q;
    c1_q    <= c1;
    c1_reg  <= c1_q;

    q_m_reg <= q_m;
  end

  ///
  // 10-bit out
  // disparity counter
  ///
  always @ (posedge clkin or posedge rstin) begin
    if(rstin) begin
      dout <= 10'h0;
      cnt <= 5'h0;
    end else begin
      if (de_reg) begin
        if(decision2) begin
          dout[9]   <= ~q_m_reg[8];
          dout[8]   <= q_m_reg[8];
          dout[7:0] <= (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];

          cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
        end else begin
          if(decision3) begin
            dout[9]   <= 1'b1;
            dout[8]   <= q_m_reg[8];
            dout[7:0] <= ~q_m_reg[7:0];

            cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
          end else begin
            dout[9]   <= 1'b0;
            dout[8]   <= q_m_reg[8];
            dout[7:0] <= q_m_reg[7:0];

            cnt <= cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
          end
        end
      end else begin
        case ({c1_reg, c0_reg})
          2'b00:   dout <= CTRLTOKEN0;
          2'b01:   dout <= CTRLTOKEN1;
          2'b10:   dout <= CTRLTOKEN2;
          default: dout <= CTRLTOKEN3;
        endcase

        cnt <= 5'h0;
      end
    end
  end
  
endmodule
module rgb2dvi(

       input    [7:0] rgb_r,
       input    [7:0] rgb_g,
       input    [7:0] rgb_b,
       input    rgb_valid,
       input    hsync,
       input    vsync,
       input    clk,
       input    clk_5x,
       input    rst_n,
       
       output   [2:0]tmds_p,
       output   [2:0]tmds_n,
       output   tmds_clk_p,
       output   tmds_clk_n
       
    );
    
    wire  [9:0]rgb_10bit_r;
    wire  [9:0]rgb_10bit_g;
    wire  [9:0]rgb_10bit_b;
      
    encode  encode_r
    (
    .clkin       (clk),              
    .rstin       (!rst_n),            
    .din         (rgb_b),            
    .c1          (1'b0),    
    .c0          (1'b0),        
    .de          (rgb_valid),
    .dout        (rgb_10bit_r)  
    );

    encode  encode_g
    (
    .clkin       (clk),              
    .rstin       (!rst_n),            
    .din         (rgb_b),            
    .c1          (1'b0),    
    .c0          (1'b0),        
    .de          (rgb_valid),
    .dout        (rgb_10bit_g)  
    );
    
    encode  encode_b
    (
    .clkin       (clk),              
    .rstin       (!rst_n),            
    .din         (rgb_b),            
    .c1          (vsync),    
    .c0          (hsync),        
    .de          (rgb_valid),
    .dout        (rgb_10bit_b)                      
    );                                
    
    serial_10to1bit  serial_10bit2tmds_inst1
    (
    .clk      (clk),
    .clk_5x   (clk_5x),
    .rst_n    (rst_n),
    .par_data (rgb_10bit_r),
    .tmds_p   (tmds_p[2]),
    .tmds_n   (tmds_n[2])
    );  

    serial_10to1bit  serial_10bit2tmds_inst2
    (
    .clk      (clk),
    .clk_5x   (clk_5x),
    .rst_n    (rst_n),
    .par_data (rgb_10bit_g),
    .tmds_p   (tmds_p[1]),
    .tmds_n   (tmds_n[1])
    ); 
    
    serial_10to1bit  serial_10bit2tmds_inst3
    (
    .clk      (clk),
    .clk_5x   (clk_5x),
    .rst_n    (rst_n),
    .par_data (rgb_10bit_b),
    .tmds_p   (tmds_p[0]),
    .tmds_n   (tmds_n[0])
    );   
           
  OBUFDS #(
      .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
      .SLEW("SLOW")           // Specify the output slew rate
   ) OBUFDS_inst (
      .O(tmds_clk_p),     // Diff_p output (connect directly to top-level port)
      .OB(tmds_clk_n),   // Diff_n output (connect directly to top-level port)
      .I(clk)      // Buffer input
   );

    
endmodule
 module serial_10to1bit
 (      
        input wire clk,
        input wire clk_5x,
        input wire rst_n,
        input wire [9:0] par_data , //输入并行数据       
//        output data,
        output wire tmds_p,
        output wire tmds_n

 );
 wire data;  
 wire shiftin1;
 wire shiftin2;
 //********************************************************************//
 //**************************** Instantiate ***************************//
 //********************************************************************//
    OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // Parallel data width (2-8,10,14)
      .INIT_OQ(1'b1),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b1),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("MASTER"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB(),             // 1-bit output: Feedback path for data
      .OQ(data),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(),
      .SHIFTOUT2(),
      .TBYTEOUT(),   // 1-bit output: Byte group tristate
      .TFB(),             // 1-bit output: 3-state control
      .TQ(),               // 1-bit output: 3-state control
      .CLK(clk_5x),             // 1-bit input: High speed clock
      .CLKDIV(clk),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(par_data[0]),
      .D2(par_data[1]),
      .D3(par_data[2]),
      .D4(par_data[3]),
      .D5(par_data[4]),
      .D6(par_data[5]),
      .D7(par_data[6]),
      .D8(par_data[7]),
      .OCE(1'b1),             // 1-bit input: Output data clock enable
      .RST(!rst_n),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(shiftin1),
      .SHIFTIN2(shiftin2),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0),
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate
      .TCE(1'b0)              // 1-bit input: 3-state clock enable
   );

   // End of OSERDESE2_inst instantiation
   
       OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // Parallel data width (2-8,10,14)
      .INIT_OQ(1'b1),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b1),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("SLAVE"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   OSERDESE2_inst2 (
      .OFB(),             // 1-bit output: Feedback path for data
      .OQ(),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(shiftin1),
      .SHIFTOUT2(shiftin2),
      .TBYTEOUT(),   // 1-bit output: Byte group tristate
      .TFB(),             // 1-bit output: 3-state control
      .TQ(),               // 1-bit output: 3-state control
      .CLK(clk_5x),             // 1-bit input: High speed clock
      .CLKDIV(clk),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(1'b0),
      .D2(1'b0),
      .D3(par_data[8]),
      .D4(par_data[9]),
      .D5(1'b0),
      .D6(1'b0),
      .D7(1'b0),
      .D8(1'b0),
      .OCE(1'b1),             // 1-bit input: Output data clock enable
      .RST(!rst_n),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(1'b0),
      .SHIFTIN2(1'b0),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0),
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate
      .TCE(1'b0)              // 1-bit input: 3-state clock enable
   );

   // End of OSERDESE2_inst instantiation

      OBUFDS #(
      .IOSTANDARD("TMDS_33") //约束电平为 TMDS33
      ) OBUFDS_inst (
      .O (tmds_p), //差分信号正极性输出
      .OB(tmds_n), //差分信号正极性输出
      .I (data ) //单端信号输入
      );
 
 endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值