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
原文地址:https://www.cnblogs.com/loadomain/p/3271867.html