FPGA project : VGA

 

module vga_ctrl(
    input       wire                vga_clk     ,
    input       wire                vga_rst_n   ,
    input       wire    [15:00]     pix_data    ,

    output      wire                hsync       ,
    output      wire                vsync       ,
    output      wire    [ 9: 0]     pix_x       ,
    output      wire    [ 9: 0]     pix_y       ,
    output      wire    [15:00]     rgb         
);

    parameter   H_SYNC  = 10'd96    , 
                H_BACK  = 10'd40    , 
                H_LEFT  = 10'd8     , 
                H_VALID = 10'd640   , 
                H_RIGHT = 10'd8     , 
                H_FORNT = 10'd8     , 
                H_TOTAL = 10'd800   ; 

    parameter   V_SYNC  = 10'd2     ,
                V_BACK  = 10'd25    ,
                V_TOP   = 10'd8     ,
                V_VALID = 10'd480   ,
                V_BOTTOM= 10'd8     ,
                V_FRONT = 10'd2     ,
                V_TOTAL = 10'd525   ;
    // reg define signal
    reg     [9:0]       cnt_h ;
    reg     [9:0]       cnt_v ;
    wire                rgb_valid ;
    wire                rgb_valid_req ;

    //  [9:0] cnt_h : period counter for line signal ,0 ~ 799
    always @(posedge vga_clk or negedge vga_rst_n) begin
        if(~vga_rst_n) begin
            cnt_h <= 10'd0 ;
        end else begin
            if(cnt_h == H_TOTAL - 1'b1) begin
                cnt_h <= 10'd0 ;
            end else begin
                cnt_h <= cnt_h + 1'b1 ;
            end
        end
    end
    //  [9:0] cnt_v ; period counter field scan 0 ~ 524. “行”计数1次,“场”计数+1。
    always @(posedge vga_clk or negedge vga_rst_n) begin
        if(~vga_rst_n) begin
            cnt_v <= 10'd0 ;
        end else begin
            if((cnt_h == H_TOTAL - 1'b1) && (cnt_v == V_TOTAL - 1'b1)) begin
                cnt_v <= 10'd0 ;
            end else begin
                if(cnt_h == H_TOTAL - 1'b1) begin
                    cnt_v <= cnt_v + 1'b1 ;
                end else begin
                    cnt_v <= cnt_v ;
                end
            end
        end
    end
    // rgb_valid 两个周期计数器,都计数到“有效图像周期”内,rgb_valid 拉高。
    assign rgb_valid = (cnt_h <= H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1) 
                && (cnt_h >= H_SYNC + H_BACK + H_LEFT) 
                && (cnt_v >= V_SYNC + V_BACK + V_TOP) 
                && (cnt_v <= V_SYNC + V_BACK + V_TOP + V_VALID - 1'b1) ? 1'b1 : 1'b0 ;

    assign rgb_valid_req = (cnt_h <= H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1) 
                && (cnt_h >= H_SYNC + H_BACK + H_LEFT - 1'b1 ) 
                && (cnt_v >= V_SYNC + V_BACK + V_TOP) 
                && (cnt_v <= V_SYNC + V_BACK + V_TOP + V_VALID - 1'b1) ? 1'b1 : 1'b0 ;

    // out_signal_describe
    // hsync , 行同步信号,只有在“行同步周期”内才拉高
    assign hsync = ((cnt_h <= H_SYNC - 1'b1) && (cnt_h >= 10'd0)) ? 1'b1 : 1'b0 ;
    // vsync , 场同步信号, 只有在“场同步周期”内才拉高
    assign vsync = ((cnt_v <= V_SYNC - 1'b1) && (cnt_v >= 10'd0)) ? 1'b1 : 1'b0 ;
    // pix_x  , 像素横坐标, 只有在rgb_valid_req 拉高才进行扫描。0 ~ 639。 等于行计数器(144 ~ 783) - 前面三个阶段的计数 (144).
    assign pix_x = (rgb_valid_req == 1'b1) ? cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1) : 10'h3ff ; 
    // pix_y  , 像素纵坐标, 只有在rgb_valid_req 拉高才进行扫描。0 ~ 479。 等于场计数器(35 ~ 514 ) - 前面三个阶段的计数 (35) .
    assign pix_y = (rgb_valid_req == 1'b1) ? cnt_v - (V_SYNC + V_BACK + V_TOP)  : 10'h3ff ; 
    // [15:00]     rgb 只有在valid == 1 时,进行像素赋值
    assign rgb   = (rgb_valid_req == 1'b1) ? pix_data : 10'd0 ; 
endmodule
`timescale 1ns/1ns
module test_vga_ctrl ();
    reg                   sys_clk_50m ;
    reg                   sys_rst_n   ;
    reg     [15:00]       pix_data    ;

    wire                  vga_clk     ;
    wire                  locked      ;

    wire                  vga_rst_n   ;
    
    assign vga_rst_n = sys_rst_n && locked;

    wire                  hsync       ;
    wire                  vsync       ;
    wire    [ 9: 0]       pix_x       ;
    wire    [ 9: 0]       pix_y       ;
    wire    [15:00]       rgb         ;

pll_25m	pll_25m_inst (
	.areset             ( ~sys_rst_n   ),
	.inclk0             ( sys_clk_50m  ),
	.c0                 ( vga_clk      ),
	.locked             ( locked       )
);

vga_ctrl vga_ctrl_insert(
    .vga_clk            ( vga_clk  ) ,
    .vga_rst_n          ( vga_rst_n) ,
    .pix_data           ( pix_data ) ,

    .hsync              ( hsync    ) ,
    .vsync              ( vsync    ) ,
    .pix_x              ( pix_x    ) ,
    .pix_y              ( pix_y    ) ,
    .rgb                ( rgb      )      
); // 640X480@60

    parameter CYCLE = 20  ;
    initial begin
        sys_clk_50m    = 1'b1  ;
        sys_rst_n <= 1'b0  ;
        pix_data  <= 16'd0 ;
        #(CYCLE * 2)       ;
        sys_rst_n <= 1'b1  ;
        #(CYCLE * 10000)   ;
    end
    always #(CYCLE / 2) sys_clk_50m = ~sys_clk_50m ;
    // pix_data
    always @(posedge vga_clk or negedge vga_rst_n) begin
        if(~vga_rst_n) begin
            pix_data <= 16'd0 ;
        end else begin
            if(pix_x >= 10'd0 && pix_x <= 10'd639 && pix_y >= 10'd0 && pix_y <= 10'd479) begin
                pix_data <= 16'hffff ;
            end else begin
                pix_data <= 16'd0 ;
            end
        end
    end
    // assign pix_data = (pix_x >= 10'd0 && pix_x <= 10'd639 && pix_y >= 10'd0 && pix_y <= 10'd479) ? 16'hffff : 16'd0 ; 

endmodule

 

坐标不重要。要让vga_rgb 和vga_valid时序对齐。

虽然横坐标看上去多了一个,但是vga_valid 和cnt_h (144 ~ 783)对齐了,那就是对的。

还差一个模块,明天写。 

数据产生模块:

 

module vga_pix (
    input           wire            vga_clk   ,
    input           wire            vga_rst_n ,
    input           wire    [9:0]   pix_x     ,
    input           wire    [9:0]   pix_y     ,

    output          reg     [15:0]  pix_data  
);
    // parameter   H_VALID = 10'd640 ,
    //             V_VALID = 10'd480 ;

    parameter   RED     = 16'hF800 ,
                ORANGE  = 16'hFC00 ,
                YELLOW  = 16'hFFe0 ,
                GREEN   = 16'h07e0 ,
                QING    = 16'h07FF ,
                BLUE    = 16'h001F ,
                PURPLE  = 16'hF81F ,
                BLACK   = 16'h0000 ,
                WHITE   = 16'hFFFF ,
                GRAY    = 16'hD69A ;

    // output signal
    always @(posedge vga_clk or negedge vga_rst_n) begin
        if(~vga_rst_n) begin
            pix_data <= 10'h3ff ;
        end else begin // 有简便写法 ( H_VALID / 10 ) * n
            if((pix_x >= 10'd0) && (pix_x <= 10'd63))
                pix_data <= RED ;
            else 
            if((pix_x >= 10'd64) && (pix_x <= 10'd127))
                pix_data <= ORANGE ;
            else
            if((pix_x >= 10'd128) && (pix_x <= 10'd191))
                pix_data <= YELLOW ;
            else 
            if((pix_x >= 10'd192) && (pix_x <= 10'd255))
                pix_data <= GREEN ;
            else 
            if((pix_x >= 10'd256) && (pix_x <= 10'd319))
                pix_data <= QING ;
            else 
            if((pix_x >= 10'd320) && (pix_x <= 10'd383))
                pix_data <= BLUE ;
            else 
            if((pix_x >= 10'd384) && (pix_x <= 10'd447))
                pix_data <= PURPLE ;
            else 
            if((pix_x >= 10'd448) && (pix_x <= 10'd511))
                pix_data <= BLACK ;
            else 
            if((pix_x >= 10'd512) && (pix_x <= 10'd575))
                pix_data <= WHITE ;
            else 
            if((pix_x >= 10'd576) && (pix_x <= 10'd639))
                pix_data <= GRAY ;
            else 
                pix_data <= BLACK ;
        end
    end

endmodule 
`timescale 1ns/1ns
module test_top ();
    reg                 sys_clk   ;
    reg                 sys_rst_n ;

    wire    [15:00]     rgb   ;
    wire                hsync ;
    wire                vsync ;
top_vga top_vga_insert(
    .sys_clk                ( sys_clk    ) ,
    .sys_rst_n              ( sys_rst_n  ) ,

    .rgb                    ( rgb        ) ,
    .hsync                  ( hsync      ) ,
    .vsync                  ( vsync      ) 
);

    parameter CYCLE = 20  ;
    initial begin
        sys_clk    = 1'b1  ;
        sys_rst_n <= 1'b0  ;
        #(CYCLE * 2)       ;
        sys_rst_n <= 1'b1  ;
        #(CYCLE * 10000)   ;
    end
    always #(CYCLE / 2) sys_clk = ~sys_clk ;
endmodule

 

 

 修改一下,虽然从仿真结果上看,rgb赋值用这两个valid信号都是一样的。

但是从逻辑上看,确实要用 rgb_valid 赋值才是正确的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值