• VGA逐行扫描控制器的Verilog建模


    前言:因为VGA是一种模拟图像传输数据接口,所要将数字信号用DAC转换成模拟量。本文用的一款ADI公司高精度的视频IC,实则一款高带宽的视频DAC。因为VGA时序较为简单,并且网上的VGA驱动基本大同小异。本文也没有什么特别创新之处。

    注意点:(a)行扫描计数器和场扫描计数器需要与每个像素点、消隐数目想对应,这样才能得到正确的行列地址坐标。

    参考资料:《VESA_VGA时序标准》、《ADV7123a》

    源码1:逐行扫描的VGA控制器

      1 `timescale 1 ns / 100 ps
      2 `define RedWidth    10
      3 `define GreenWidth    10
      4 `define BlueWidth    10
      5 `define VGA640x480x60Hz
      6 module vga_pscan_ctrl(
      7                         sys_clk,
      8                         sys_rst_n,
      9                         vga_red_i,
     10                         vga_green_i,
     11                         vga_blue_i,
     12                         column_addr_o,
     13                         row_addr_o,
     14                         frame_flag_o,
     15                         video_valid_o,
     16                         //vga port
     17                         vga_red,
     18                         vga_green,
     19                         vga_blue,
     20                         vga_v_sync,
     21                         vga_h_sync,
     22                         //special port
     23                         vga_sync,
     24                         vga_blank,
     25                         vga_clk
     26                         );
     27 //macro
     28 `ifdef    VGA640x480x60Hz
     29     `define ColumnWidth    10
     30     `define RowWidth    9
     31     `define H_SYNC 96
     32     `define H_BACK_PORCH 48
     33     `define H_VIDEO 640
     34     `define H_FRONT_PORCH 16
     35     `define H_TOTAL 800
     36     `define H_BIAS 144            //`H_SYNC+`H_BACK_PORCH
     37     `define V_SYNC 2
     38     `define V_BACK_PORCH 33
     39     `define V_VIDEO 480
     40     `define V_FRONT_PORCH 10
     41     `define V_TOTAL 525
     42     `define V_BIAS 35                //V_SYNC+V_BACK_PORCH
     43 `endif
     44 input sys_clk;
     45 input sys_rst_n;
     46 input [`RedWidth-1:0] vga_red_i;
     47 input [`GreenWidth-1:0] vga_green_i;
     48 input [`BlueWidth-1:0] vga_blue_i;
     49 output [`ColumnWidth-1:0] column_addr_o;    //像素当前列地址
     50 output [`RowWidth-1:0] row_addr_o;                //像素当前行地址
     51 output frame_flag_o;        //帧结束
     52 output video_valid_o;        //数据有效
     53 //vga port
     54 output [`RedWidth-1:0] vga_red;
     55 output [`GreenWidth-1:0] vga_green;
     56 output [`BlueWidth-1:0] vga_blue;
     57 output vga_v_sync;
     58 output vga_h_sync;
     59 //special port
     60 output vga_blank;
     61 output vga_sync;
     62 output vga_clk;
     63 //pix clk divider
     64 reg pix_clk=1;
     65 always @ (posedge sys_clk) begin
     66     pix_clk <= ~pix_clk;
     67 end
     68 
     69 //horizion counter
     70 reg [`ColumnWidth-1:0] h_cnt = 0;
     71 always @ (posedge sys_clk) begin
     72 if(sys_rst_n == 1'b0) h_cnt <= 0;
     73 else if((pix_clk == 1'b1)&&(h_cnt < `H_TOTAL-1))    h_cnt <= h_cnt + 1'd1;
     74 else if((pix_clk == 1'b1)&&(h_cnt == `H_TOTAL-1))    h_cnt <= 0;
     75 else h_cnt <= h_cnt;    
     76 end
     77 
     78 //vertical counter
     79 reg [`RedWidth-1:0] v_cnt = 0;
     80 always @ (posedge sys_clk) begin
     81 if(1'b0 == sys_rst_n) v_cnt <= 0;
     82 else if((pix_clk)&&(h_cnt == `H_TOTAL-1)&&(v_cnt < `V_TOTAL-1))    v_cnt <= v_cnt + 1'd1;
     83 else if((pix_clk)&&(h_cnt == `H_TOTAL-1)&&(v_cnt == `V_TOTAL-1))    v_cnt <= 0;
     84 else v_cnt <= v_cnt;
     85 end
     86 
     87 //generate the sync
     88 assign vga_h_sync = (h_cnt > `H_SYNC-1)?1'b1:1'b0;
     89 assign vga_v_sync = (v_cnt > `V_SYNC-1)?1'b1:1'b0;
     90 
     91 //generate data valid
     92 wire h_video_valid = ((h_cnt > `H_SYNC+`H_BACK_PORCH-1)&&(h_cnt < `H_TOTAL-`H_FRONT_PORCH))?1'b1:1'b0;
     93 wire v_video_valid = ((v_cnt > `V_SYNC+`V_BACK_PORCH-1)&&(v_cnt < `V_TOTAL-`V_FRONT_PORCH))?1'b1:1'b0;
     94 assign video_valid_o = (h_video_valid && v_video_valid)?1'b1:1'b0;
     95 //generate frame_flag_o
     96 assign frame_flag_o = ((v_cnt == `V_TOTAL-1)&&(h_cnt == `H_TOTAL-1))?1'b1:1'b0;
     97 
     98 //generate vga_blank and vga_sync and vga_clk
     99 assign vga_clk = pix_clk;
    100 assign vga_sync = 1'b0;
    101 assign vga_blank = vga_h_sync & vga_v_sync;
    102 
    103 //generate column_addr_o and row_addr_o
    104 reg [`ColumnWidth-1:0] column_addr_o=0;
    105 reg [`RowWidth-1:0] row_addr_o=0;
    106 always @ (posedge sys_clk) begin
    107 if(sys_rst_n == 1'b0)    begin
    108                                 column_addr_o <= 0;
    109                                 row_addr_o <= 0;end
    110 else if(video_valid_o) begin
    111                                 column_addr_o <= h_cnt - `H_BIAS;
    112                                 row_addr_o <= v_cnt - `V_BIAS;end
    113 else begin    
    114         column_addr_o <= column_addr_o;
    115         row_addr_o <= row_addr_o;end
    116 end
    117 //generate RGB
    118 assign vga_red = (video_valid_o)?vga_red_i:`RedWidth'd0;
    119 assign vga_green = (video_valid_o)?vga_green_i:`GreenWidth'd0;
    120 assign vga_blue = (video_valid_o)?vga_blue_i:`BlueWidth'd0;
    121 
    122 endmodule

    源码2:简单驱动

     1 `timescale 1 ns / 100 ps
     2 `define RedWidth    10
     3 `define GreenWidth    10
     4 `define BlueWidth    10
     5 `define Offset1    0
     6 `define Offset2    0
     7 module vga_driver(
     8                             sys_clk,
     9                             sys_rst_n,
    10                             sys_en,
    11                             vga_red_o,
    12                             vga_green_o,
    13                             vga_blue_o
    14                             );
    15 input sys_clk;
    16 input sys_rst_n;
    17 input sys_en;
    18 output [`RedWidth-1:0] vga_red_o;
    19 output [`GreenWidth-1:0] vga_green_o;
    20 output [`BlueWidth-1:0] vga_blue_o;
    21 reg [`RedWidth-1:0] vga_red_o=0;
    22 reg [`GreenWidth-1:0] vga_green_o=0;
    23 reg [`BlueWidth-1:0] vga_blue_o=0;
    24 
    25 //generate red vector
    26 always @ (posedge sys_clk) begin
    27 if(sys_rst_n == 1'b0)    vga_red_o <= 0;
    28 else if(sys_en) vga_red_o <= vga_red_o + 1'd1;
    29 else vga_red_o <= vga_red_o;
    30 end
    31 
    32 //generate green vector
    33 always @ (posedge sys_clk) begin
    34 if(sys_rst_n == 1'b0)    vga_green_o <= `Offset1;
    35 else if(sys_en) vga_green_o <= vga_green_o + 1'd1;
    36 else vga_green_o <= vga_green_o;
    37 end
    38 
    39 //generate blue vector
    40 always @ (posedge sys_clk) begin
    41 if(sys_rst_n == 1'b0) vga_blue_o <= `Offset2;
    42 else if (sys_en)    vga_blue_o <= vga_blue_o + 1'd1;
    43 else vga_blue_o <= vga_blue_o;
    44 end
    45 
    46 endmodule

    源码3:VGA相关模块的顶层例化

     1 `timescale 1 ns / 100 ps
     2 `define RedWidth    10
     3 `define GreenWidth    10
     4 `define BlueWidth    10
     5 `define VGA640x480x60Hz
     6 module vga(
     7                     sys_clk,
     8                     sys_rst_n,
     9                     //vga port
    10                     vga_red,
    11                     vga_blue,
    12                     vga_green,
    13                     vga_h_sync,
    14                     vga_v_sync,
    15                     //special port
    16                     vga_blank,
    17                     vga_sync,
    18                     vga_clk
    19                     );
    20 `ifdef    VGA640x480x60Hz
    21     `define ColumnWidth    10
    22     `define RowWidth    9
    23 `endif
    24 input sys_clk;
    25 input sys_rst_n;
    26 //vga port
    27 output [`RedWidth-1:0] vga_red;
    28 output [`GreenWidth-1:0] vga_green;
    29 output [`BlueWidth-1:0] vga_blue;
    30 output vga_v_sync;
    31 output vga_h_sync;
    32 //special io
    33 output vga_blank;
    34 output vga_sync;
    35 output vga_clk;
    36 //wires
    37 wire [`RedWidth-1:0] vga_red_w;
    38 wire [`GreenWidth-1:0] vga_green_w;
    39 wire [`BlueWidth-1:0] vga_blue_w;
    40 wire [`ColumnWidth-1:0] column_addr_w;
    41 wire [`RowWidth-1:0] row_addr_w;
    42 wire frame_flag_w;
    43 wire video_valid_w;
    44 vga_driver                inst_vga_driver(
    45                             .sys_clk(sys_clk),
    46                             .sys_rst_n(sys_rst_n),
    47                             .sys_en(video_valid_w),
    48                             .vga_red_o(vga_red_w),
    49                             .vga_green_o(vga_green_w),
    50                             .vga_blue_o(vga_blue_w)
    51                             );
    52 
    53 vga_pscan_ctrl        inst_vga_pscan_ctrl(
    54                         .sys_clk(sys_clk),
    55                         .sys_rst_n(sys_rst_n),
    56                         .vga_red_i(vga_red_w),
    57                         .vga_green_i(vga_green_w),
    58                         .vga_blue_i(vga_blue_w),
    59                         .column_addr_o(column_addr_w),
    60                         .row_addr_o(row_addr_w),
    61                         .frame_flag_o(frame_flag_w),
    62                         .video_valid_o(video_valid_w),
    63                         //vga port
    64                         .vga_red(vga_red),
    65                         .vga_green(vga_green),
    66                         .vga_blue(vga_blue),
    67                         .vga_v_sync(vga_v_sync),
    68                         .vga_h_sync(vga_h_sync),
    69                         //special port
    70                         .vga_sync(vga_sync),
    71                         .vga_blank(vga_blank),
    72                         .vga_clk(vga_clk)
    73                         );
    74 
    75 endmodule

    仿真文件:

     1 `timescale 1 ns / 100 ps
     2 `define RedWidth    10
     3 `define GreenWidth    10
     4 `define BlueWidth    10
     5 module vga_tsb;
     6 reg sys_clk;
     7 reg sys_rst_n;
     8 initial begin
     9 sys_clk=1;
    10 sys_rst_n=0;
    11 #100 sys_rst_n=1;
    12 end
    13 always begin
    14 #10 sys_clk=~sys_clk;
    15 end
    16 
    17 wire [`RedWidth-1:0] vga_red;
    18 wire [`GreenWidth-1:0] vga_green;
    19 wire [`BlueWidth-1:0] vga_blue;
    20 wire vga_h_sync;
    21 wire vga_v_sync;
    22 vga                inst_vga(
    23                     .sys_clk(sys_clk),
    24                     .sys_rst_n(sys_rst_n),
    25                     //vga port
    26                     .vga_red(vga_red),
    27                     .vga_blue(vga_blue),
    28                     .vga_green(vga_green),
    29                     .vga_h_sync(vga_h_sync),
    30                     .vga_v_sync(vga_v_sync),
    31                     .vga_blank(vga_blank),
    32                     .vga_sync(vga_sync)
    33                     );
    34 
    35 
    36 
    37 endmodule

    仿真脚本文件:

     1 vlib work
     2 vmap work work
     3 
     4 vlog -work work vga_pscan_ctrl.v
     5 vlog -work work vga_driver.v
     6 vlog -work work vga.v
     7 vlog -work work vga_tsb.v
     8 
     9 vsim -novopt -lib work vga_tsb
    10 
    11 view wave
    12 # signals in vga_driver
    13 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_driver/vga_red_o
    14 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_driver/vga_green_o
    15 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_driver/vga_blue_o
    16 add wave sim:/vga_tsb/inst_vga/inst_vga_driver/sys_en
    17 
    18 # signals in vga_pscan_ctrl
    19 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_red_i
    20 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_green_i
    21 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_blue_i
    22 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/column_addr_o
    23 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/row_addr_o
    24 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/frame_flag_o
    25 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/video_valid_o
    26 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_sync
    27 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_blank
    28 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/pix_clk
    29 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/v_video_valid
    30 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_v_sync
    31 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/v_cnt
    32 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_h_sync
    33 add wave sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/h_video_valid
    34 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/h_cnt
    35 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_red
    36 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_green
    37 add wave -radix unsigned sim:/vga_tsb/inst_vga/inst_vga_pscan_ctrl/vga_blue
    38 
    39 run 50ms
  • 相关阅读:
    面试基础知识文档
    敏捷式开发
    redis总结
    自我介绍的问题
    面试2
    唐巧的iOS技术博客选摘
    IOS开发中滑动页面时NSTimer停止的问题
    iOS多线程GCD(转)
    iOS 用instancetype代替id作返回类型有什么好处?
    C语言中全局变量、局部变量、静态全局变量、静态局部变量的区别 (转)
  • 原文地址:https://www.cnblogs.com/loadomain/p/3271867.html
Copyright © 2020-2023  润新知