前面学习的改参数的方法回顾:
1.使用变量(数组边界:array[ ( 变量名 ) + : x 位 ] )
2.参数化设计(例化时修改参数)(如:①defparameter xx = m ; ②#(.参数名(新值)))
上节我们写的程序适用于分辨率为 640 * 480 的显示器,而实际应用中,我们有时候需要使用不同分辨率的显示屏,我们可以通过在上节的程序中修改具体参数来适配,生成多个文件来对应多种分辨率的显示器,这种方法虽然可行,但是生成的文件较多,不便于管理而且不高级。这里引入一种新的方法:
3.条件编译语法:写一个新的文件来存储参数,然后在主文件中include该参数文件(`incluede"xxx.v"),便可以实现不同分辨率的整套参数切换。
用到的语法:`define xxxn m...
`ifdef xxx1
`define a1 m1 ;
`define a2 m2 ;
`elsif xxxx
`define a1 n1 ;
`define a2 n2 ;
......
`endif
实现代码:
//`define Resolution_480x272 1 //刷新率为60Hz其时钟频率为 9MHz
//`define Resolution_640x480 1 //刷新率为60Hz其时钟频率为 25.2MHz
//`define Resolution_800x480 1 //刷新率为60Hz其时钟频率为 33.264MHz
//`define Resolution_800x600 1 //刷新率为60Hz其时钟频率为 40MHz
//`define Resolution_1024x600 1 //刷新率为60Hz其时钟频率为 50.64MHz
//`define Resolution_1024x768 1 //刷新率为60Hz其时钟频率为 65MHz
`define Resolution_1280x720 1 //刷新率为60Hz其时钟频率为 74.25MHz
//`define Resolution_1920x1080 1 //(1080p)刷新率为60Hz其时钟频率为 148.5MHz
//时钟频率计算公式:f = 1 / (( 1 / 60 ) / ( H_Total_Time * V_Total_Time ) )
`ifdef Resolution_480x272
`define H_Right_Border 0
`define H_Front_Porch 2
`define H_Sync_Time 41
`define H_Back_Porch 2
`define H_Left_Border 0
`define H_Data_Time 480
`define H_Total_Time 525
`define V_Bottom_Border 0
`define V_Front_Porch 2
`define V_Sync_Time 10
`define V_Back_Porch 2
`define V_Top_Border 0
`define V_Data_Time 272
`define V_Total_Time 286
`elsif Resolution_640x480
`define H_Right_Border 8
`define H_Front_Porch 8
`define H_Sync_Time 96
`define H_Back_Porch 40
`define H_Left_Border 8
`define H_Data_Time 640
`define H_Total_Time 800
`define V_Bottom_Border 8
`define V_Front_Porch 2
`define V_Sync_Time 2
`define V_Back_Porch 25
`define V_Top_Border 8
`define V_Data_Time 480
`define V_Total_Time 525
`elsif Resolution_800x480
`define H_Right_Border 0
`define H_Front_Porch 40
`define H_Sync_Time 128
`define H_Back_Porch 88
`define H_Left_Border 0
`define H_Data_Time 800
`define H_Total_Time 1056
`define V_Bottom_Border 8
`define V_Front_Porch 2
`define V_Sync_Time 2
`define V_Back_Porch 25
`define V_Top_Border 8
`define V_Data_Time 480
`define V_Total_Time 525
`elsif Resolution_800x600
`define H_Right_Border 0
`define H_Front_Porch 40
`define H_Sync_Time 128
`define H_Back_Porch 88
`define H_Left_Border 0
`define H_Data_Time 800
`define H_Total_Time 1056
`define V_Bottom_Border 0
`define V_Front_Porch 1
`define V_Sync_Time 4
`define V_Back_Porch 23
`define V_Top_Border 0
`define V_Data_Time 600
`define V_Total_Time 628
`elsif Resolution_1024x600
`define H_Right_Border 0
`define H_Front_Porch 24
`define H_Sync_Time 136
`define H_Back_Porch 160
`define H_Left_Border 0
`define H_Data_Time 1024
`define H_Total_Time 1344
`define V_Bottom_Border 0
`define V_Front_Porch 1
`define V_Sync_Time 4
`define V_Back_Porch 23
`define V_Top_Border 0
`define V_Data_Time 600
`define V_Total_Time 628
`elsif Resolution_1024x768
`define H_Right_Border 0
`define H_Front_Porch 24
`define H_Sync_Time 136
`define H_Back_Porch 160
`define H_Left_Border 0
`define H_Data_Time 1024
`define H_Total_Time 1344
`define V_Bottom_Border 0
`define V_Front_Porch 3
`define V_Sync_Time 6
`define V_Back_Porch 29
`define V_Top_Border 0
`define V_Data_Time 768
`define V_Total_Time 806
`elsif Resolution_1280x720
`define H_Right_Border 0
`define H_Front_Porch 110
`define H_Sync_Time 40
`define H_Back_Porch 220
`define H_Left_Border 0
`define H_Data_Time 1280
`define H_Total_Time 1650
`define V_Bottom_Border 0
`define V_Front_Porch 5
`define V_Sync_Time 5
`define V_Back_Porch 20
`define V_Top_Border 0
`define V_Data_Time 720
`define V_Total_Time 750
`elsif Resolution_1960x1080
`define H_Right_Border 0
`define H_Front_Porch 88
`define H_Sync_Time 44
`define H_Back_Porch 148
`define H_Left_Border 0
`define H_Data_Time 1920
`define H_Total_Time 2200
`define V_Bottom_Border 0
`define V_Front_Porch 4
`define V_Sync_Time 5
`define V_Back_Porch 36
`define V_Top_Border 0
`define V_Data_Time 1080
`define V_Total_Time 1125
`endif
module VGA(
clk,
reset,
content_data_request,//数据请求信号
horizontal_sig,//horizontal 水平的
vertical_sig, //vertical 垂直的
content_data,//要显示的内容数据
RGB_data,//输出的内容数据
vis_sig//内容显示同步信号(高电平时显示)
);
input clk ;
input reset ;
output reg content_data_request ;//数据请求信号
output reg horizontal_sig ;
output reg vertical_sig ;
input [23:0]content_data ;
output reg [23:0]RGB_data ;
output reg vis_sig ;//内容显示同步信号
reg h_vis_sig ;//行内容显示同步信号
reg v_vis_sig ;//列内容显示同步信号
`include "VGA_resolution_parameter.v"
//定义时间节点参数
//行参数
parameter h_pulse_start = 0 ; //行起始脉冲开始信号
parameter h_pulse_end = `H_Sync_Time ;// 行起始脉冲结束信号
parameter h_content_start = `H_Sync_Time + `H_Back_Porch + `H_Left_Border ;//行内容开始信号
parameter h_content_end = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time ;//行内容结束信号
parameter h_end = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time + `H_Right_Border + `H_Front_Porch;//行结束信号
//列参数
parameter v_pulse_start = 0 ; //列起始脉冲开始信号
parameter v_pulse_end = `V_Sync_Time ;//列起始脉冲结束信号
parameter content_start = `V_Sync_Time + `V_Back_Porch + `V_Top_Border ;//列内容开始信号
parameter content_end = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time ;//列内容结束信号
parameter v_end = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time + `V_Bottom_Border + `V_Front_Porch;//列结束信号
// //行参数 640*480
// parameter h_pulse_start = 0 ; //行起始脉冲开始信号
// parameter h_pulse_end = 96 ;// 行起始脉冲结束信号 96
// parameter h_content_start = 96 + 40 + 8 ;//行内容开始信号 144
// parameter h_content_end = 96 + 40 + 8 + 640 ;//行内容结束信号 784
// parameter h_end = 96 + 40 + 8 + 640 + 8 + 8;//行结束信号 800
// //列参数
// parameter v_pulse_start = 0 ; //列起始脉冲开始信号
// parameter v_pulse_end = 2 ;//列起始脉冲结束信号 2
// parameter content_start = 2 + 25 + 8 ;//列内容开始信号 35
// parameter content_end = 2 + 25 + 8 + 480 ;//列内容结束信号 515
// parameter v_end = 2 + 25 + 8 + 480 + 2 + 8;//列结束信号 525
//行与列 计数器
reg [11:0]h_cnt ;
reg [11:0]v_cnt ;
always@(posedge clk or negedge reset)//行计数
if(!reset)
h_cnt <= 0 ;
else if ( h_end - 1 <= h_cnt )//0-799
h_cnt <= 0 ;
else
h_cnt <= h_cnt + 1 ;
always@(posedge clk or negedge reset)//列计数
if(!reset)
v_cnt <= 0 ;
else if (( v_end - 1 <= v_cnt ) && ( h_end - 1 <= h_cnt ))//0-524
v_cnt <= 0 ;
else if (( h_end - 1 <= h_cnt ) && ( v_end - 1 > v_cnt ))
v_cnt <= v_cnt + 1 ;
//产生行起始脉冲
always@(posedge clk or negedge reset)//
if(!reset)
horizontal_sig <= 1 ;
else if( h_cnt == 0 )
horizontal_sig <= 0 ;//1-96 共96
else if ( h_cnt == h_pulse_end )
horizontal_sig <= 1 ;
//产生列起始脉冲
always@(posedge clk or negedge reset)//
if(!reset)
vertical_sig <= 1 ;
else if(( v_cnt == 0 )&& ( h_end - 1 <= h_cnt ) )
vertical_sig <= 0 ;//1-2 共2
else if (( v_cnt == v_pulse_end )&& ( h_end - 1 <= h_cnt ) )
vertical_sig <= 1 ;
//产生行显示同步信号
always@(posedge clk or negedge reset)//
if(!reset)
h_vis_sig <= 0 ;
else if (( h_content_start - 2 <= h_cnt ) && ( h_content_end - 1 - 2 >= h_cnt )) //提前两拍保证输出在第145拍开始
h_vis_sig <= 1 ;//146 - 785共
else
h_vis_sig <= 0 ;
//产生列显示同步信号
always@(posedge clk or negedge reset)//
if(!reset)
v_vis_sig <= 0 ;
else if (( content_start <= v_cnt ) && ( content_end >= v_cnt ) && ( ( h_end - 1 <= h_cnt ) ) )
v_vis_sig <= 1 ;
else if (( content_start > v_cnt ) || ( content_end < v_cnt ) )
v_vis_sig <= 0 ;
//请求信号
always@(posedge clk or negedge reset)
if(!reset)
content_data_request <= 0 ;//
else if ( ( v_vis_sig ) && ( h_vis_sig ) )
content_data_request <= 1 ;
else
content_data_request <= 0 ;
//显示同步信号
always@(posedge clk or negedge reset)//
if(!reset)
vis_sig <= 0 ;
else if ( content_data_request )
vis_sig <= 1 ;
else
vis_sig <= 0 ;
//显示
always@(posedge clk or negedge reset)//
if(!reset)
RGB_data <= 0 ;
else if ( content_data_request )
RGB_data <= content_data ;
else
RGB_data <= 0 ;
endmodule