FPGA之VGA转HDMI之编码模块的编写

        VGA 图像信息到 HDMI 图像信息的转化需要对输入的 VGA 图像信息进行编码、并行串行转换、单端信号转差分信号、单沿采样转双沿采样。

        其中,编码模块就是为了完成 VGA 图像数据 8b 10b 的编码。其结构框图如下所示:

        

图1 编码模块框图

图2 编码模块输入输出信号功能框图

图3 编码模块参考流程图

图4 编码模块参考流程图参数说明

        下面我们依据HDMI官方手册中的流程图(图3)进行 HDMI 8bit 转 10bit 的代码编写:

module encode
(
    input  wire       vga_clk   ,   //时钟信号
    input  wire       sys_rst_n ,   //复位信号,低电平有效
    input  wire       hsync     ,   //行同步信号
    input  wire       vsync     ,   //场同步信号
    input  wire       rgb_vaild ,   //使能信号
    input  wire [7:0] data_in   ,   //输入8bit待编码数据
    
    output reg  [9:0] data_out      //输出编码后的10bit数据
);

//parameter define
parameter   DATA_OUT0   =   10'b1101010100 ,
            DATA_OUT1   =   10'b0010101011 ,
            DATA_OUT2   =   10'b0101010100 ,
            DATA_OUT3   =   10'b1010101011 ;

//wire define           
wire      ctrl_1  ;   //条件1
wire       ctrl_2 ;   //条件2
wire       ctrl_3 ;   //条件3
wire [8:0] q_m    ;   //转换后9bit数据

//reg define
reg [3:0] data_in_n1  ;  //待编码数据中1的个数
reg [7:0] data_in_reg ;  //待编码数据打一拍
reg [4:0] cnt         ;
reg [3:0] q_m_n1      ;  //转换后9bit数据1的个数
reg [3:0] q_m_n0      ;  //转换后9bit数据0的个数
reg [9:0] q_m_reg     ;  //q_m信号打一拍
reg       de_reg1     ;  //使能信号打一拍
reg       de_reg2     ;  //使能信号打两拍
reg       hsync_reg1  ;  //控制信号hsync打一拍
reg       hsync_reg2  ;  //控制信号hsync打两拍
reg       vsync_reg1  ;  //控制信号vsync打一拍
reg       vsync_reg2  ;  //控制信号vsync打两拍


//data_in_n1:待编码数据中1的个数
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in_n1 <= 4'd0 ;
    else 
        data_in_n1 <= data_in[0] + data_in[1] + data_in[2] + data_in[3] + 
                        data_in[4] + data_in[5] + data_in[6] + data_in[7] ;

//data_in_reg:待编码数据打一拍
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_in_reg <= 4'd0 ;
    else
        data_in_reg <= data_in ;

//ctrl_1:条件1
assign ctrl_1 = ((data_in_n1 > 4'd4) || ((data_in_n1 == 4'd4) && 
        (data_in_reg[0] == 1'b0))) ? 1'b1 : 1'b0 ;

//q_m:第一阶段转换后9bit数据     
assign q_m[0] = data_in_reg[0] ;
assign q_m[1] = (ctrl_1 == 1'b1) ? (q_m[0] ^~ data_in_reg[1]) : (q_m[0] ^ data_in_reg[1]) ;
assign q_m[2] = (ctrl_1 == 1'b1) ? (q_m[1] ^~ data_in_reg[2]) : (q_m[1] ^ data_in_reg[2]) ;
assign q_m[3] = (ctrl_1 == 1'b1) ? (q_m[2] ^~ data_in_reg[3]) : (q_m[2] ^ data_in_reg[3]) ;
assign q_m[4] = (ctrl_1 == 1'b1) ? (q_m[3] ^~ data_in_reg[4]) : (q_m[3] ^ data_in_reg[4]) ;
assign q_m[5] = (ctrl_1 == 1'b1) ? (q_m[4] ^~ data_in_reg[5]) : (q_m[4] ^ data_in_reg[5]) ;
assign q_m[6] = (ctrl_1 == 1'b1) ? (q_m[5] ^~ data_in_reg[6]) : (q_m[5] ^ data_in_reg[6]) ;
assign q_m[7] = (ctrl_1 == 1'b1) ? (q_m[6] ^~ data_in_reg[7]) : (q_m[6] ^ data_in_reg[7]) ;
assign q_m[8] = (ctrl_1 == 1'b1) ? 1'b0 : 1'b1 ;

//q_m_n1:转换后9bit数据中1的个数
//q_m_n0:转换后9bit数据中0的个数
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin 
            q_m_n0 <= 4'd0 ;
            q_m_n1 <= 4'd0 ;
        end
    else 
        begin
            q_m_n1 <= data_in[0] + data_in[1] + data_in[2] + data_in[3] + 
                data_in[4] + data_in[5] + data_in[6] + data_in[7] ;
            q_m_n1 <= data_in[0] - (data_in[1] + data_in[2] + data_in[3] + 
                data_in[4] + data_in[5] + data_in[6] + data_in[7]) ;
        end

//ctrl_2:条件2
assign ctrl_2 = (cnt == 5'd0) || (q_m_n0 == q_m_n1) ? 1'b1 : 1'b0 ;

//ctrl_3:条件3
assign  ctrl_3 = (((cnt >= 5'd0) && (q_m_n1 > q_m_n0))
            || ((cnt <= 5'd0) && (q_m_n0 > q_m_n1))) ? 1'b1 : 1'b0 ;

//数据打拍,为了个数据同步            
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            q_m_reg    <= 1'b0 ;
            de_reg1    <= 1'b0 ;
            de_reg2    <= 1'b0 ;
            hsync_reg1 <= 1'b0 ;
            hsync_reg2 <= 1'b0 ;
            vsync_reg1 <= 1'b0 ;
            vsync_reg2 <= 1'b0 ;
        end    
    else        
        begin
            q_m_reg    <= q_m_reg    ;
            de_reg1    <= rgb_vaild  ;
            de_reg2    <= de_reg1    ;
            hsync_reg1 <= hsync      ;
            hsync_reg2 <= hsync_reg1 ;
            vsync_reg1 <= vsync      ;
            vsync_reg2 <= vsync_reg2 ;
        end             

//data_out:输出编码后的10bit数据
//cnt:视差计数器,0-1个数差别,最高位为符号位
always@(posedge vga_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            data_out <= 10'b0 ;
            cnt      <= 5'd0  ;
        end
    else
        begin   
            if(de_reg2 == 1'b1)
                begin
                    if(ctrl_2 == 1'b1)
                        begin
                            data_out[9]   <= ~q_m_reg[8] ;
                            data_out[8]   <= q_m_reg[8]  ;
                            data_out[7:0] <= (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
                            cnt <= (q_m_reg[8] == 1'b0) ? (cnt + q_m_n0 - q_m_n1) : (cnt + q_m_n1 - q_m_n0);
                        end
                    else
                        begin
                            if(ctrl_3 == 1'b1)
                                begin
                                    data_out[9]     <= 1'b1;
                                    data_out[8]     <= q_m_reg[8];
                                    data_out[7:0]   <= ~q_m_reg[7:0];
                                    cnt <=  cnt + {q_m_reg[8], 1'b0} + (q_m_n0 - q_m_n1);
                                end
                            else
                                begin
                                    data_out[9]     <= 1'b0;
                                    data_out[8]     <= q_m_reg[8];
                                    data_out[7:0]   <= q_m_reg[7:0];
                                    cnt <=  cnt - {~q_m_reg[8], 1'b0} + (q_m_n1 - q_m_n0);
                                end
                            
                        end
                end
            else
                begin
                    case({vsync_reg2,hsync_reg2})
                        2'b00:  data_out <= DATA_OUT0;
                        2'b01:  data_out <= DATA_OUT1;
                        2'b10:  data_out <= DATA_OUT2;
                        default:data_out <= DATA_OUT3;
                    endcase
                    cnt <=  5'b0;                    
                end
        end    
endmodule

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值