黑金社区 FPGA 那些事儿--Verilog 建模设计 学习 试验九 VGA显示 试验
最近这段时间忙着搬家,然后准备生产相关事情,各种杂事~
然后光棍节来,给自己和老爸老妈买点东西。。。
效率好低。。要检讨啊~ 不能找借口!
黑金的试验九 --VGA的用法
VGA 液晶显示
主要由5个信号控制
HSYNC : 列同步信号
VSYNC : 行同步信号
RED : 红分量
GREEN : 绿分量
BLUE : 蓝分量
VGA 的扫描是固定的。一帧的屏幕是由“m 行扫描”和“n 列填充”组成。假设以800
x 600 x 60Hz 为例的显示标准( 800 宽x 600 高x 60Hz ), 那么宏观上它有600 行
和800 列为一行。
VGA 如上图 从左到右,逐行显示。
作为新手,一开始不大明白。其实这个就是相当于HSYNC 一次通信需要1056位数据,然后前128是低电平做同步,然后后面一段一段的。真正有效地就是C Q 段 就是我们说的800X600
实现的时候,就只要找到最基本的单元,一个一个累加就好了。
如上面显示的,最基本单元是HSYNC,列信号。列信号记满,然后行信号加一个。
剩下的就是用系统的CLK 构造一个满足我们要求的 VGA CLK ,即下面表中的时钟那栏。
如果正好,就可以直接用,系统clk 太低,就PLL倍频下,如果clk,通过计数,产生一个VGA_clk
通过本次学习,了解了一个模块的基本构造,菜鸟理解如下,还请大师们多多指点:
<1> 需要搭建一个最基本的时钟模块,用以产生整个系统所需要的主时钟,本次采用的是ISE自带的IP核 clk_wizard 生成的
<2> 需要构建一个最基本的动作实现模块,用以实现最基本的动作。本例中即VGA_SYNC模块。告诉我们how to do 怎么做这个显示这个动作,应该就是常见的 时序
<3> 需要构建一个控制模块,用以实现最表象的东西,本例中即VGA_display_control模块,告诉我们 最终的表像,无论你的内容是什么,最终表现在外面的就只是GRB 3个东西
你要控制的就是什么时候显示怎么样子的GRB分量,其他的模块都是补充说明你要控制的时间、控制的内容
上面的三个是大树的主干,其他再怎么弄,都是一些枝枝叶叶罢了,你可以没有部分枝叶,但是不能没有大树
感觉还是有点怪异,不知道是不是这样说对不对,大致是这样的意思,目前的理解是这样的
在本次试验中需要学习的地方如下:
1> 构造基本时钟的手法
2> 在同步和控制2个模块之间,他通过一个使能信号,我用了 vga_vlddata_flag 来连接,只有控制模块时序基本目标,就给一个标志信号,告诉控制模块可以开始干嘛干嘛了
3> 眼花缭乱的 X ? y : z 语句 ,灵活运用, 比如vga_red_sig = ( vga_vlddata_flag && (你要显示的内容 ) ) ? 1'b1 : 1'b0 ;
通过简简单单的一个?语句就实现了在特定条件下 输出1或者0
4> 各种位操作,有待熟悉和提高,出现的最多的警告就是位操作引起的
5> 到目前为止,个人理解wire 和reg 声明如下:
一般在开头赋值 assign 内部wire变量声明 = 外部的input 脚 ,然后在always里面直接引用,初始化的时候不能对这个input 变量赋值
一般在结尾赋值 assign 最终输出的output = 内部reg 变量声明,在always里面使用内部变量,需要在初始化的时候赋值,不然会报错
不过不知道这么转一下有什么好处不,更加清楚么,请大神们指点下
6> 引用子模块的时候 用后面这个方式: vga_clk_module U91_vga_clk_generator();
子模块的文件名都加上_module 然后U91 9 表示顶层名字 1 表示9模块的1小模块 后面名字表示功能
然后后面计划准备用下面这个命名方式,待完善:
1. 最顶层连接外部器件的端口名字都加上 模块名_xxx_sig_o/模块名_xxx _sig_i 比如 vga_hsync_sig_o
2. 然后将他按照上面那个5> 条 赋给中间声明,w_模块名_xxx_sig 比如w_vga_hsync_sig // input from / output to 要注释上从哪里来 到哪里去
3. 然后子模块里面 端口用 模块名_xxx_sig 不带o i 比如vga_hsync_sig
4. 然后子模块如果需要,再赋给中间变量 r_xxx_sig 或者w_xxx_sig 比如 r_hsync_sig
暂时是这么想的,后面再看看,再改吧
然后还碰到个很奇怪的问题,有没有大神 帮忙看看啊,百度了下 还是不是很清楚,个人感觉应该还是位的问题
WARNING:Xst:2677 - Node <column_n_4> of sequential type is unconnected in block <vga_display_control_module>.
这个每个单个文件综合的时候都完美无缺,没有任何错误,然后用顶层文件综合就出现这个Warning了
好像是说我中间变量没有连接上,好奇怪 不知道怎么搞,为什么一样声明的,就这三个报错,其他的不报错呢。。。求大神们指点~~
然后代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module exam9_VGA_display_module( 2 3 // System input 4 clk , 5 rst_n , 6 7 // input 8 9 // output 10 vga_vsync_display_o , // Row sync sig output 11 vga_hsync_display_o , // Column sync sig output 12 13 vga_red_sig_o , 14 vga_green_sig_o , 15 vga_blue_sig_o 16 17 ); 18 19 20 /*************** Port Declaration ******************/ 21 22 // System input 23 input clk ; 24 input rst_n ; 25 26 // input 27 28 // output 29 30 output vga_hsync_display_o ; 31 output vga_vsync_display_o ; 32 33 output vga_red_sig_o ; 34 output vga_green_sig_o ; 35 output vga_blue_sig_o ; 36 37 /************ Port data type declaration *************/ 38 /**************** Define Parameter *****************/ 39 /*************** Internal Registers *****************/ 40 /****************** Internal Wire ******************/ 41 wire w_vga_clk_40MHz ; 42 43 wire w_vga_hsync_sig ; 44 wire w_vga_vsync_sig ; 45 46 wire w_vga_vlddata_flag ; 47 wire [10:0] w_vga_column_addr ; 48 wire [9:0] w_vga_row_addr ; 49 50 wire [5:0] w_vga_rom_addr ; 51 wire [63:0] w_vga_rom_data ; 52 53 wire w_vga_red_sig ; 54 wire w_vga_green_sig ; 55 wire w_vga_blue_sig ; 56 57 /**************** Code Starts Here *****************/ 58 // module IP core for generating the vga work clk 59 vga_clk_module U91_vga_clk_generator( 60 .CLK_IN1(clk) , 61 .RESET(rst_n), 62 .CLK_OUT1(w_vga_clk_40MHz) 63 ); 64 65 66 // module for how vga display 67 vga_sync_module U92_vga_sync( 68 69 // System input 70 .vga_clk(w_vga_clk_40MHz), 71 .rst_n(rst_n), 72 73 // input 74 75 // output 76 .vga_hsync_sig(w_vga_hsync_sig), 77 .vga_vsync_sig(w_vga_vsync_sig), 78 79 .vga_vlddata_flag(w_vga_vlddata_flag), 80 .vga_column_addr(w_vga_column_addr), 81 .vga_row_addr(w_vga_row_addr) 82 83 ); 84 85 vga_rom_data_module U93_vga_rom_data ( 86 87 // System input 88 .vga_clk(w_vga_clk_40MHz), 89 .rst_n(rst_n), 90 91 // input 92 .vga_rom_addr(w_vga_rom_addr), 93 94 // output 95 .vga_rom_data(w_vga_rom_data) 96 97 ); 98 99 // module for what vga to display 100 vga_display_control_module U94_vga_display( 101 102 // System input 103 .vga_clk(w_vga_clk_40MHz), 104 .rst_n(rst_n), 105 106 // input 107 .vga_vlddata_flag(w_vga_vlddata_flag), 108 109 .vga_column_addr(w_vga_column_addr), 110 .vga_row_addr(w_vga_row_addr), 111 112 .vga_rom_data(w_vga_rom_data), // input from U93 vga_rom 113 114 // output 115 .vga_rom_addr(w_vga_rom_addr), // output to U93 vga_rom 116 117 .vga_red_sig(w_vga_red_sig), 118 .vga_green_sig(w_vga_green_sig), 119 .vga_blue_sig(w_vga_blue_sig) 120 121 ); 122 123 /*****************************************************/ 124 assign vga_hsync_display_o = w_vga_hsync_sig ; 125 assign vga_vsync_display_o = w_vga_vsync_sig ; 126 127 assign vga_red_sig_o = w_vga_red_sig ; 128 assign vga_green_sig_o = w_vga_green_sig ; 129 assign vga_blue_sig_o = w_vga_blue_sig ; 130 /*****************************************************/ 131 132 133 endmodule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module vga_sync_module( 2 3 // System input 4 vga_clk, 5 rst_n, 6 7 // input 8 9 // output 10 vga_hsync_sig , 11 vga_vsync_sig , 12 13 vga_vlddata_flag , 14 vga_column_addr , 15 vga_row_addr 16 17 ); 18 19 /*************** Port Declaration ******************/ 20 21 // System input 22 input vga_clk ; // clk input 40MHz 23 input rst_n ; 24 25 // input 26 27 // output 28 output vga_hsync_sig ; 29 output vga_vsync_sig ; 30 31 output vga_vlddata_flag ; 32 output [10:0] vga_column_addr ; 33 output [9:0] vga_row_addr ; 34 35 36 /************ Port data type declaration *************/ 37 wire vga_hsync_sig ; 38 wire vga_vsync_sig ; 39 40 wire vga_vlddata_flag ; 41 wire [10:0] vga_column_addr ; 42 wire [9:0] vga_row_addr ; 43 44 /**************** Define Parameter *****************/ 45 46 /*************** Internal Registers *****************/ 47 reg vga_count ; // the basic count to get 800X600 clk 48 reg clk_800x600x60 ; 49 50 reg [10:0] h_count ; // the hsync count for column 51 reg [9:0] v_count ; // the vsync count for row 52 reg r_vlddata_flag ; // the flag for VGA display valid data ,like 800X600X60 53 54 /****************** Internal Wire ******************/ 55 56 /**************** Code Starts Here *****************/ 57 // to get the CLK 800X600X60 = 40MHz 58 // if the input clk is not 40MHz , you need to change the MAX vga_count to get it 59 always @ ( posedge vga_clk or negedge rst_n) 60 if ( !rst_n ) 61 begin 62 vga_count <= 1'b0 ; 63 clk_800x600x60 <= 1'b0 ; 64 end 65 else if ( vga_count == 1'b1 ) 66 begin 67 vga_count <= 1'b0 ; 68 clk_800x600x60 <= ~clk_800x600x60 ; 69 end 70 else 71 begin 72 vga_count <= vga_count + 1'b1 ; 73 clk_800x600x60 <= 1'b0 ; 74 end 75 76 // vga HSYCN count 128_88_800_40 =1056 for 800X600X60 77 always @ ( posedge clk_800x600x60 or negedge rst_n ) 78 if ( !rst_n ) 79 begin 80 h_count <= 11'd0 ; 81 end 82 else if ( h_count == 11'd1056 ) 83 begin 84 h_count <= 11'd0 ; 85 end 86 else 87 begin 88 h_count <= h_count + 1'b1 ; 89 end 90 91 // vga VSYNC count 4_23_600_1 = 628 for 800X600X60 92 always @ ( posedge clk_800x600x60 or negedge rst_n ) 93 if ( !rst_n ) 94 begin 95 v_count <= 10'd0; 96 end 97 else if ( v_count == 10'd628 ) 98 begin 99 v_count <= 10'd0 ; 100 end 101 else if ( h_count == 11'd1056 ) 102 begin 103 v_count <= v_count + 1'b1 ; 104 end 105 106 // vga valid data flag 107 // flag = 1 when [h_count between 216~1041 (800)] && [v_count between 27 ~ 627 (600)] 108 always @ ( posedge clk_800x600x60 or negedge rst_n ) 109 if ( !rst_n ) 110 begin 111 r_vlddata_flag <= 1'b0 ; 112 end 113 else if ( ( h_count > 11'd216 && h_count < 11'd1041 ) && ( v_count > 11'd27 && v_count < 11'd627 ) ) 114 begin 115 r_vlddata_flag <= 1'b1 ; 116 end 117 else 118 begin 119 r_vlddata_flag <= 1'b0 ; 120 end 121 122 /*****************************************************/ 123 assign vga_hsync_sig = ( h_count < 11'd128 ) ? 1'b0 : 1'b1 ; 124 assign vga_vsync_sig = ( v_count < 10'd4 ) ? 1'b0 : 1'b1 ; 125 126 assign vga_vlddata_flag = r_vlddata_flag ; 127 128 assign vga_column_addr = r_vlddata_flag ? ( h_count - 11'd216 ) : 11'd0 ; 129 assign vga_row_addr = r_vlddata_flag ? ( v_count - 10'd27 ) : 10'd0 ; 130 131 /*****************************************************/ 132 133 endmodule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module vga_rom_data_module( 2 3 // System input 4 vga_clk , 5 rst_n , 6 // input 7 vga_rom_addr , 8 9 // output 10 vga_rom_data 11 12 ); 13 14 /*************** Port Declaration ******************/ 15 16 // System input 17 input vga_clk ; 18 input rst_n ; 19 20 // input 21 input vga_rom_addr ; 22 23 // output 24 output vga_rom_data ; 25 26 /************ Port data type declaration *************/ 27 wire [5:0] vga_rom_addr ; 28 wire [63:0] vga_rom_data ; 29 30 /**************** Define Parameter *****************/ 31 32 /*************** Internal Registers *****************/ 33 reg [63:0] r_rom_data ; 34 /****************** Internal Wire ******************/ 35 wire [5:0] w_rom_addr = vga_rom_addr ; 36 37 /**************** Code Starts Here *****************/ 38 // The ROM DATA LUT 39 40 always @ ( posedge vga_clk or negedge rst_n ) 41 if( !rst_n ) 42 begin 43 //w_rom_addr <= 6'd0 ; 不能给wire 赋值 44 r_rom_data <= 64'd0 ; 45 end 46 else 47 case ( w_rom_addr ) 48 6'd0 : 49 r_rom_data <= 64'h0000_0000_0000_0000 ; 50 6'd1 : 51 r_rom_data <= 64'h0000_0000_0000_0000 ; 52 // add the other data 53 54 endcase 55 56 /*****************************************************/ 57 assign vga_rom_data = r_rom_data ; 58 59 /*****************************************************/ 60 61 endmodule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module vga_display_control_module( 2 3 // System input 4 vga_clk , 5 rst_n , 6 7 // input 8 vga_vlddata_flag , 9 vga_column_addr , 10 vga_row_addr , 11 12 vga_rom_data , 13 14 // output 15 vga_rom_addr , 16 17 vga_red_sig , 18 vga_green_sig , 19 vga_blue_sig 20 21 ); 22 23 /*************** Port Declaration ******************/ 24 25 // System input 26 input vga_clk ; // vga_clk = 40MHz 27 input rst_n ; 28 29 // input 30 input vga_vlddata_flag ; 31 input [10:0] vga_column_addr ; 32 input [9:0] vga_row_addr ; 33 34 input [63:0] vga_rom_data ; 35 36 // output 37 output [5:0] vga_rom_addr ; 38 39 output vga_red_sig ; 40 output vga_green_sig ; 41 output vga_blue_sig ; 42 43 /************ Port data type declaration *************/ 44 45 /**************** Define Parameter *****************/ 46 47 48 49 /*************** Internal Registers *****************/ 50 // reg r_display_flag ; // for exam 9-2 51 reg [5:0] row_n ; 52 reg [5:0] column_n ; 53 54 /****************** Internal Wire ******************/ 55 56 /**************** Code Starts Here *****************/ 57 58 // code for exam 9-3 59 // to get row number 60 always @ ( posedge vga_clk or negedge rst_n) 61 if( ! rst_n ) 62 begin 63 //r_display_flag <= 1'b0 ; 64 row_n <= 6'd0 ; 65 end 66 else if ( vga_vlddata_flag && ( vga_row_addr < 10'd64) ) 67 begin 68 row_n <= vga_row_addr[5:0] ; 69 end 70 71 // to get column number 72 always @ ( posedge vga_clk or negedge rst_n) 73 if( ! rst_n ) 74 begin 75 //r_display_flag <= 1'b0 ; 76 column_n <= 6'd0 ; 77 end 78 else if ( vga_vlddata_flag && ( vga_column_addr < 11'd64) ) 79 begin 80 column_n <= vga_column_addr[5:0] ; 81 end 82 /*****************************************************/ 83 assign vga_rom_addr = row_n ; 84 85 assign vga_red_sig = ( vga_vlddata_flag && ( vga_rom_data [63-column_n] )) ? 1'b1 : 1'b0 ; 86 assign vga_green_sig = ( vga_vlddata_flag && ( vga_rom_data [63-column_n] )) ? 1'b1 : 1'b0 ; 87 assign vga_blue_sig = ( vga_vlddata_flag && ( vga_rom_data [63-column_n] )) ? 1'b1 : 1'b0 ; 88 89 /*****************************************************/ 90 91 92 endmodule
小弟万分感谢~
蹒跚在信号处理的道路上~
张小朋友要加油啊~