基于ise14.7平台,用Nexys3开发板弄了一个显示程序。程序包含六部分
首先是顶层模块:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:04:30 07/22/2015
// Design Name:
// Module Name: vga_initials
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module vga_initials(
input wire vidon,
input wire[9:0] hc,
input wire[9:0] vc,
input wire[0:31] M,
input wire[7:0] sw,
output wire[3:0] rom_addr4,
output reg[2:0] red,
output reg[2:0] green,
output reg[1:0] blue
);
parameter hbp=10'b0010010000;//行显示后沿=144(128+16)
parameter vbp=10'b0000011111;//场显示后沿=31(2+29)
parameter W=32;
parameter H=16;
wire[10:0]C1,R1,rom_addr,rom_pix;
reg spriteon,R,G,B;
assign C1={2'b00,sw[3:0],5'b0001};
assign R1={2'b00,sw[7:4],5'b0001};
assign rom_addr=vc-vbp-R1;
assign rom_pix =hc-hbp-C1;
assign rom_addr4=rom_addr[3:0];
//Enable sprite video out when within the sprite region
always@(*)
begin
if((hc>=C1+hbp)&&(hc<=C1+hbp+W)&&(vc>=R1+vbp)&&(vc<=R1+vbp+H))
spriteon=1;
else
spriteon=0;
end
//输出彩色信号
always@(*)
begin
red=0;
green=0;
blue=0;
if((spriteon==1)&&(vidon==1))
begin
R=M[rom_pix];
G=M[rom_pix];
B=M[rom_pix];
red={R,R,R};
green={G,G,G};
blue={B,B};
end
end
endmodule
然后是子模块1:
module clkdiv(
input wire mclk,
input wire clr,
output wire clk25
);
reg[1:0]q;
//2-bit counter
always@(posedge mclk or posedge clr)
begin
if(clr==1)
q<=0;
else
q<=q+1'b1;
end
assign clk25=q[1];//50MHz 时钟100MHz (100M/2的1次方)=50MHz
endmodule
子模块2:
module vga_640x480(
input wire clk,
input wire clr,
output reg hsync,
output reg vsync,
output reg[9:0] hc,
output reg[9:0] vc,
output reg vidon
);
parameter hpixels=10'b1100100000;//行像素点=800
parameter vlines=10'b1000001001;//行数=521
parameter hbp=10'b0010010000;//行显示后延=144(128+16)
parameter hfp=10'b1100010000;//行显示前沿=748(128+16+640)
parameter vbp=10'b0000011111;//场显示后沿=31(2+29)
parameter vfp=10'b0111111111;//场显示前延=511(2+29+480)
reg vsenable;//Enable for the vertical counter
//行同步信号计数器
always@(posedge clk or posedge clr)
begin
if(clr==1)
hc<=0;
else
begin
if(hc==hpixels-1)
begin
//The counter has reached the end of pixel count
hc<=0;//计数器复位
vsenable<=1;
//Enable the vertical counter to increment
end
else
begin
hc<=hc+1'b1;//Increment the horizontal counter
vsenable<=0;//Leave the vsenable off
end
end
end
//产生hsync脉冲
//当hc为0~127时,行同步脉冲为低电平
always@(*)
begin
if(hc<96)
hsync=0;
else
hsync=1;
end
//场同步信号计数器
always@(posedge clk or posedge clr)
begin
if(clr==1)
vc<=0;
else
if(vsenable==1)
begin
if(vc==vlines-1)
//Reset when the number of lines is reached
vc<=0;
else
vc<=vc+1'b1;//场计数器+1
end
end
//产生vsync脉冲
//当hc为0或1时,场同步脉冲为低电平
always@(*)
begin
if(vc<2)
vsync=0;
else
vsync=1;
end
//Enable video out when within the porches
always@(*)
begin
if((hc
vidon=1;
else
vidon=0;
end
endmodule
子模块3:
module vga_initials(
input wire vidon,
input wire[9:0] hc,
input wire[9:0] vc,
input wire[0:31] M,
input wire[7:0] sw,
output wire[3:0] rom_addr4,
output reg[2:0] red,
output reg[2:0] green,
output reg[1:0] blue
);
parameter hbp=10'b0010010000;//行显示后沿=144(128+16)
parameter vbp=10'b0000011111;//场显示后沿=31(2+29)
parameter W=32;
parameter H=16;
wire[10:0]C1,R1,rom_addr,rom_pix;
reg spriteon,R,G,B;
assign C1={2'b00,sw[3:0],5'b0001};
assign R1={2'b00,sw[7:4],5'b0001};
assign rom_addr=vc-vbp-R1;
assign rom_pix =hc-hbp-C1;
assign rom_addr4=rom_addr[3:0];
//Enable sprite video out when within the sprite region
always@(*)
begin
if((hc>=C1+hbp)&&(hc<=C1+hbp+W)&&(vc>=R1+vbp)&&(vc<=R1+vbp+H))
spriteon=1;
else
spriteon=0;
end
//输出彩色信号
always@(*)
begin
red=0;
green=0;
blue=0;
if((spriteon==1)&&(vidon==1))
begin
R=M[rom_pix];
G=M[rom_pix];
B=M[rom_pix];
red={R,R,R};
green={G,G,G};
blue={B,B};
end
end
endmodule
子模块四:
module prom_DMH(
input wire[3:0]addr,
output wire[0:31]M
);
reg[0:31]rom[0:15];//16个32位寄存器
parameter data={
32'b01111110000011000001101000000010,//0
32'b01000001000011000001101000000010,//1
32'b01000000100010100010101000000010,//2
32'b01000000010010100010101000000010,//3
32'b01000000001010100010101000000010,//4
32'b01000000001010010100101000000010,//5
32'b01000000001010010100101000000010,//6
32'b01000000001010010100101111111110,//7
32'b01000000001010001000101000000010,//8
32'b01000000001010001000101000000010,//9
32'b01000000001010001000101000000010,//10
32'b01000000001010001000101000000010,//11
32'b01000000010010000000101000000010,//12
32'b01000000100010000000101000000010,//13
32'b01000001000010000000101000000010,//14
32'b01111110000010000000101000000010//15
};
integer i;
initial
begin
for(i=0;i<16;i=i+1)
rom=data[(511-32*i)-:32];
end
assign M=rom[addr];
endmodule
约束文件: