实现1sym转换成2个sym送给CVI(VGA数据)

CVI的时序如下 :de指示数据有效。

从下面的程序看,同步码的长度不会影响对有效数据的判断。同步码的作用更多的是用于计算行及一行的像素数目。
方案一:
1
module vga_1sym_2_2sym( 2 input clk_i, 3 input rst_p, 4 input [15:0] data_i, 5 input h_sync_i, 6 input v_sync_i, 7 input de_i , 8 9 output [31:0] data_o, 10 output [1:0] h_sync_o, 11 output [1:0] v_sync_o, 12 output [1:0] de_o, 13 output vga_clk_o 14 15 ); 16 17 18 19 20 wire ctrl_clk; 21 wire vga_clk; 22 wire vga_clk_dvi2; 23 clkctrl u0_clkctrl ( 24 .inclk (clk_i), // altclkctrl_input.inclk 25 .outclk (ctrl_clk) // altclkctrl_output.outclk 26 ); 27 iopll u0 ( 28 .rst (rst_p), // reset.reset 29 .refclk (ctrl_clk), // refclk.clk 30 .locked (), // locked.export 31 .outclk_0 (vga_clk), // outclk0.clk 32 .outclk_1 (vga_clk_dvi2) // outclk0.clk 33 ); 34 35 36 reg [15:0] data_r; 37 reg [15:0] vga_data_dly2; 38 reg [15:0] vga_data_dly3; 39 reg h_sync_r = 0; 40 reg v_sync_r = 0; 41 reg de_r = 0; 42 always @( posedge vga_clk ) 43 begin 44 data_r <= data_i; 45 h_sync_r <= h_sync_i; 46 v_sync_r <= v_sync_i; 47 de_r <= de_i; 48 end 49 // reg [1:0] de_dly = 2'b00; 50 // always @( posedge vga_clk ) 51 // begin 52 // de_dly[1:0] <= {de_dly[0],de_i}; 53 // end 54 // wire pos_de = (de_dly[1:0] == 2'b01 ); 55 reg h_l_cnt = 1'b0; 56 always @( posedge vga_clk ) 57 begin 58 // if( pos_de ) 59 // h_l_cnt <= 1'b1; 60 // else 61 h_l_cnt <= ~h_l_cnt; 62 end 63 reg [31:0]data_r2 = 0; 64 reg [1:0] h_sync_r2 = 2'b00; 65 reg [1:0] v_sync_r2 = 2'b00; 66 reg [1:0] de_r2 = 2'b00; 67 always @( posedge vga_clk ) 68 begin 69 if( h_l_cnt ) begin 70 data_r2[15:0] <= data_r; 71 h_sync_r2[0] <= h_sync_r; 72 v_sync_r2[0] <= v_sync_r; 73 de_r2[0] <= de_r; 74 75 76 end else begin 77 78 data_r2[31:16] <= data_r; 79 h_sync_r2[1] <= h_sync_r; 80 v_sync_r2[1] <= v_sync_r; 81 de_r2[1] <= de_r; 82 end 83 end 84 reg vga_cvi_valid = 0; 85 always @( posedge vga_clk ) 86 begin 87 if( ~h_l_cnt ) 88 vga_cvi_valid <= 1'b1; 89 else 90 vga_cvi_valid <= 1'b0; 91 92 end 93 94 // assign data_o = data_r2; 95 // assign h_sync_o = h_sync_r2; 96 // assign v_sync_o = v_sync_r2; 97 // assign de_o = de_r2; 98 99 wire rd_empty; 100 wire [37:0] fifo_dout; 101 reg [1:0] rd_empty_r = 2'b00; 102 wire rd_en ; 103 fifo_w22 u0_fifo_w22 ( 104 .data ({data_r2,h_sync_r2,v_sync_r2,de_r2}), // fifo_input.datain 105 .wrreq (vga_cvi_valid), // .wrreq 106 .rdreq (rd_en), // .rdreq 107 .wrclk (vga_clk), // .wrclk 108 .rdclk (vga_clk_dvi2), // .rdclk 109 .q (fifo_dout), // fifo_output.dataout 110 .rdempty (rd_empty), // .rdempty 111 .wrfull () // .wrfull 112 ); 113 always @( posedge vga_clk_dvi2 ) 114 begin 115 rd_empty_r <= {rd_empty_r[0],rd_empty}; 116 end 117 assign rd_en = ~rd_empty_r[1]; 118 assign {data_o,h_sync_o,v_sync_o,de_o} = fifo_dout; 119 assign vga_clk_o = vga_clk_dvi2; 120 endmodule 121

 现在用一种更简单的方式即可实现,

方案二:

module vga_1sym_2_2sym(
    input clk_i,
    input rst_p,
    input [15:0] data_i,
    input h_sync_i,  
    input v_sync_i,    
    input de_i ,
    
    output [31:0] data_o,
    output [1:0] h_sync_o,
    output [1:0] v_sync_o,
    output [1:0] de_o,
    output vga_clk_o,
    output vga_valid_o
    
    );reg [15:0] data_r;
    reg [15:0] vga_data_dly2;
    reg [15:0] vga_data_dly3;
    reg h_sync_r = 0;
    reg v_sync_r = 0;
    reg de_r  = 0;
    always @( posedge vga_clk )
    begin
            data_r <= data_i;
            h_sync_r <= h_sync_i;
            v_sync_r <= v_sync_i;
            de_r <= de_i;
    end
//    reg [1:0] de_dly = 2'b00;
//    always @( posedge vga_clk )
//    begin
//                    de_dly[1:0] <= {de_dly[0],de_i};
//    end
//    wire pos_de = (de_dly[1:0] == 2'b01 );
    reg h_l_cnt = 1'b0;
    always @( posedge vga_clk )
    begin
//            if( pos_de )
//                    h_l_cnt <= 1'b1;
//            else
                    h_l_cnt <= ~h_l_cnt;
    end
    reg [31:0]data_r2 = 0;
    reg [1:0] h_sync_r2 = 2'b00;
    reg [1:0] v_sync_r2 = 2'b00;
    reg [1:0] de_r2 = 2'b00;
    always @( posedge vga_clk )
    begin
            if( h_l_cnt ) begin
                    data_r2[15:0] <= data_r;
                    h_sync_r2[0] <= h_sync_r;
                    v_sync_r2[0] <= v_sync_r;
                    de_r2[0] <= de_r;
                    
                    
            end else begin
                    
                    data_r2[31:16] <= data_r;
                    h_sync_r2[1] <= h_sync_r;
                    v_sync_r2[1] <= v_sync_r;
                    de_r2[1] <= de_r;
            end
    end
    reg vga_cvi_valid = 0;
    always @( posedge vga_clk )
    begin
            if( ~h_l_cnt )
                    vga_cvi_valid <= 1'b1;
            else
                    vga_cvi_valid <= 1'b0;        
            
    end
    
    assign data_o =  data_r2 ;
    assign h_sync_o =  h_sync_r2 ;
    assign v_sync_o = v_sync_r2 ;
    assign de_o = de_r2 ;
    assign vga_clk_o = vga_clk;
    assign vga_valid_o = vga_cvi_valid;
end

该实现过程与方案一相比,节省了PLL和FIFO,但输出了一个vga_valid_o信号,该信号连接到CVI的vid_datavalid信号。以下是vid_datavalid信号的定义:

意思是,CVI II IP核只在vid_datavalid为高电平时,才会读取vid信号,该信号用于CVI支持视频信号的过采样。也就是同一个像素对应多个时钟的情况下,只需要一个时钟的数据即可。

  原本我的想法是让vid_datavalid始终保持高电平状态,通过vga_cvi_valid信号控制de_o翻转,间隔一个时钟数据有效一次(其实在实现时v_sync_o,h_sync_o都有翻转,目前觉得可能不翻转h,v信号也许可行),但是画面很不正常。de_o的作用是指示vid_data是有效数据。

方案三:

尝试上面提到的h,v不翻转。保持vid_datavalid始终为高电平。

 经过验证,可能不行。

原文地址:https://www.cnblogs.com/zhongguo135/p/7804432.html