RGB接口转LVDS

时间:2024-02-22 20:13:25

1;功能:完成RGB接口转换成LVDS接口输出!

2;下图是FITI79001H的 8位LVDS时序图

3;下图是我写出来的模块的仿真结果

4;顶层代码

  1  module RGB_LVDS(
  2                      reset,
  3                      ttl_clk,
  4                      ttl_data_in,
  5                      clkpn,
  6                 lvds_data
  7                      );
  8 
  9 input  wire reset;
 10 input wire ttl_clk;//50Mhz
 11 input wire [27:0] ttl_data_in;//{k,hs,vs,de,r[7:0],g[7:0],b[7:0]}
 12 output  [7:0] lvds_data;
 13 output  [1:0] clkpn;
 14 
 15 reg [27:0] ttldata_r;
 16 wire lvds_71clk;
 17 wire lvds_72clk;
 18 wire clk;
 19 wire [7:0]  lvds_datah;
 20 wire [7:0]  lvds_datal;
 21 reg [2:0] clk_conter;
 22 
 23 wire n_reset;
 24 
 25 reg [1:0] lvdsclkh;
 26 reg [1:0] lvdsclkl;
 27 
 28 assign n_reset=!reset;
 29 
 30 always @(negedge ttl_clk or negedge reset )
 31          begin
 32                 if(!reset)
 33                     ttldata_r<=28\'b0;
 34                 else
 35                    ttldata_r<=ttl_data_in;
 36          
 37          end
 38 
 39 
 40 always @(negedge lvds_71clk or negedge reset )
 41      begin
 42         if(!reset)
 43             clk_conter<=3\'b0;
 44         else if(clk_conter>=3\'d6)
 45                 clk_conter<=3\'b0;
 46              else
 47                 clk_conter<=clk_conter+3\'b1;
 48         
 49      end
 50  always @(negedge lvds_71clk or negedge reset )
 51      begin
 52         if(!reset)
 53                 begin
 54                   lvdsclkh<=2\'b0;
 55                     lvdsclkl<=2\'b0;
 56                 end
 57         else if(clk_conter<=3\'d1)
 58                 begin
 59                             lvdsclkh<=2\'b10;
 60                             lvdsclkl<=2\'b10;
 61                      end
 62         else if(clk_conter>3\'d1 && clk_conter<5)
 63                 begin
 64                             lvdsclkh<=2\'b01;
 65                             lvdsclkl<=2\'b01;
 66                      end
 67           else if(clk_conter>=3\'d5)
 68                 begin
 69                             lvdsclkh<=2\'b10;
 70                             lvdsclkl<=2\'b10;
 71                      end
 72         
 73      end
 74 
 75 PLL7B clk_inst(
 76                     .areset(n_reset),
 77                     .inclk0(ttl_clk),
 78                     .c0(lvds_71clk),
 79                     .c1(lvds_72clk),
 80                     .c2(clk),
 81                     .locked()
 82 
 83                     );
 84                     
 85 P28toS7   P28TOS7_INST(
 86                 .rst(reset),
 87                 .ttlclk(clk),
 88                 .lvdsclk71(lvds_71clk),
 89                 .ttl_dataw(ttldata_r),
 90                 .lvds_datah(lvds_datah),
 91                 .lvds_datal(lvds_datal)
 92 
 93                 );
 94                 
 95 lvds_data4  LVDS_DATA_INST(        
 96                         .datain_h(lvds_datah),
 97                         .datain_l(lvds_datal),
 98                         .outclock(lvds_72clk),
 99                         .dataout(lvds_data)
100                   );
101                       
102 LVDSCLK_PN   CLKPN_INST(
103                                 .aclr(),
104                                 .datain_h(lvdsclkh),
105                                 .datain_l(lvdsclkl),
106                                 .outclock(lvds_71clk),
107                                 .dataout(clkpn)
108                                 );                
109 
110 endmodule

5;顶层仿真代码

`timescale 10ns/1ns

module RGB_LVDS_TB;

reg  reset;
reg ttl_clk;//50Mhz
reg [27:0] ttl_data;//{k,hs,vs,de,r[7:0],g[7:0],b[7:0]}
reg  hsync,vsync,enable;
reg  [7:0] rdata,gdata,bdata;
wire [7:0] lvds_data;
wire [1:0] clkpn;

initial  begin
                reset=0;
                ttl_clk=0;
                hsync=1;
                vsync=1;
                enable=1;
                rdata=8\'b1111_1111;
                gdata=8\'b0000_0000;
                bdata=8\'b0000_0000;
                ttl_data<=28\'b0;
                #120;
                reset=1;
                ttl_data={0,hsync,vsync,enable,rdata,gdata,bdata};
                #160;
                $stop;

            end

always #1  ttl_clk<=!ttl_clk;




RGB_LVDS  RGB_LVDS_INST(
             .reset(reset),
             .ttl_clk(ttl_clk),
             .ttl_data_in(ttl_data),
             .clkpn(clkpn),
             .lvds_data(lvds_data)
                 );
                     
                     
endmodule            

6;时钟锁向环设置

7;4通道的差分数据线输出IP(ALTDDIO_OUT)

8;由于LVDS差分时钟信号的频率与LVDS差分数据信号的频率不一样,所以不能共用一个IP

9;28位并行数据转串行数据模块代码

// Convert 28BIT parallel data to serial data
module P28toS7(
                    rst,                
                    ttlclk,
                    lvdsclk71,
                    ttl_dataw,
                    lvds_datah,
                    lvds_datal        
                );
                
input rst;
input ttlclk;
input lvdsclk71;
input [27:0] ttl_dataw;
reg [27:0] ttl_data;//{k,hs,vs,de,r[7:0],g[7:0],b[7:0]}
output reg [7:0] lvds_datah;
output reg [7:0] lvds_datal;

reg [7:0]  ttl_data8;
reg [3:0]  lvds_data4;

reg [3:0]  temp_data0;
reg [3:0]  temp_data1;
reg [3:0]  temp_data2;
reg [3:0]  temp_data3;
reg [3:0]  temp_data4;
reg [3:0]  temp_data5;
reg [3:0]  temp_data6;

reg [2:0]  conter;
reg  start_sig1,start_sig2,start_sig3;
wire pclk_sig;
reg [0:0]  hl_conter;


    
always @(negedge ttlclk or negedge rst)
       begin
            if(!rst) 
                    ttl_data<=8\'b0;
            else
                 ttl_data<=ttl_dataw;
            
       end

always @(negedge ttlclk or negedge rst)
       begin
            if(!rst) 
              begin                 
                  temp_data0<=4\'b0; 
                  temp_data1<=4\'b0;
                  temp_data2<=4\'b0;
                  temp_data3<=4\'b0;
                  temp_data4<=4\'b0;
                  temp_data5<=4\'b0;
                  temp_data6<=4\'b0;
              end               
            else
                  begin
                    temp_data0 <= {ttl_data[16],ttl_data[9],ttl_data[2],ttl_data[22]}; //R0 G1 B2 R6
                    temp_data1 <= {ttl_data[17],ttl_data[10],ttl_data[3],ttl_data[23]};// R1 G2 B3 R7
                    temp_data2 <= {ttl_data[18],ttl_data[11],ttl_data[4],ttl_data[14]};//R2 G3 B4 G6
                    temp_data3 <= {ttl_data[19],ttl_data[12],ttl_data[5],ttl_data[15]};//R3 G4 B5 G7
                    temp_data4 <= {ttl_data[20],ttl_data[13],ttl_data[26],ttl_data[6]};//R4 G5 HS B6
                    temp_data5 <= {ttl_data[21],ttl_data[0],ttl_data[25],ttl_data[7]};//R5 B0 VS B7
                    temp_data6 <= {ttl_data[8],ttl_data[1],ttl_data[24],ttl_data[27]};//G0 B1 DE
                  end
                          
           
       end
         
assign pclk_sig= start_sig3 && start_sig2 && start_sig1;
         
always @(negedge lvdsclk71 or negedge rst )
     begin
                 if(!rst)
                    begin
                        start_sig1<=1\'b0;
                         start_sig2<=1\'b0;
                         start_sig3<=1\'b0;
                     end                   
                 else 
                     begin
                       start_sig1<=ttlclk;
                         start_sig2<=start_sig1;
                         start_sig3<=start_sig2;                
                    end    
     
     end         
     
         
always @(negedge lvdsclk71 or negedge rst )
     begin
                 if(rst==1\'b0 )
                    conter<=3\'b0;
                else if(pclk_sig)
                        conter<=3\'b0;  
                      else
                         conter<=conter+3\'b1;   
     
     end
     
always @(negedge lvdsclk71 or negedge rst)
     begin
                 if(!rst)    
                    lvds_data4<=3\'b0;
                 else 
                         begin
                                 case(conter)
                                   3\'b000  : lvds_data4<=temp_data0;
                                   3\'b001  : lvds_data4<=temp_data1;
                                   3\'b010  : lvds_data4<=temp_data2;
                                   3\'b011  : lvds_data4<=temp_data3;
                                   3\'b100  : lvds_data4<=temp_data4;
                                   3\'b101  : lvds_data4<=temp_data5;
                                   3\'b110  : lvds_data4<=temp_data6;                             
                                   default : lvds_data4<=temp_data0;
                                 endcase
                         end
     end
always @ (negedge lvdsclk71 or negedge rst)
         begin
                 if(!rst)
                    ttl_data8<=8\'b0;
                 else 
                    begin
                        case(lvds_data4)
                                    4\'B0000   :  ttl_data8<=8\'b01_01_01_01;//0123
                                      4\'B0001   :  ttl_data8<=8\'b01_01_01_10;//0123
                                      4\'B0010   :  ttl_data8<=8\'b01_01_10_01;//0123
                                      4\'B0011   :  ttl_data8<=8\'b01_01_10_10;//0123
                                      4\'B0100   :  ttl_data8<=8\'b01_10_01_01;//0123
                                      4\'B0101   :  ttl_data8<=8\'b01_10_01_10;//0123
                                      4\'B0110   :  ttl_data8<=8\'b01_10_10_01;//0123
                                      4\'B0111   :  ttl_data8<=8\'b01_10_10_10;//0123
                                      4\'B1000   :  ttl_data8<=8\'b10_01_01_01;//0123
                                      4\'B1001   :  ttl_data8<=8\'b10_01_01_10;//0123
                                      4\'B1010   :  ttl_data8<=8\'b10_01_10_01;//0123
                                      4\'B1011   :  ttl_data8<=8\'b10_01_10_10;//0123
                                      4\'B1100   :  ttl_data8<=8\'b10_10_01_01;//0123
                                      4\'B1101   :  ttl_data8<=8\'b10_10_01_10;//0123
                                      4\'B1110   :  ttl_data8<=8\'b10_10_10_01;//0123
                                      4\'B1111   :  ttl_data8<=8\'b10_10_10_10;//0123                                        
                                  default   :  ttl_data8<=8\'b01_01_01_01;//0123        
                         endcase
                    end                  
     
          end     

always @(negedge lvdsclk71 or negedge rst)
     begin
                 if(!rst)
                    hl_conter<=1\'b0;
                 else 
                    hl_conter<=!hl_conter;
            
     end
always @(negedge lvdsclk71 or negedge rst)
     begin
          if(!rst)
               begin
                lvds_datah<=8\'b0;
                lvds_datal<=8\'b0;
                end
            else    begin
                        if(!hl_conter)
                            lvds_datah<=ttl_data8;
                        else
                            lvds_datal<=ttl_data8;
                    end
     end    
      
endmodule