基于DE0的VGA显示驱动

显示标准:800*600@72HZ,50M时钟频率。

器件:cyclone3EP3C16484

软件版本:quatus ii9.0

代码:

顶层模块:

module pika(
 CLOCK_50,
 VGA_HS,
 VGA_VS,
 BUTTON,
 VGA_G,
 VGA_R,
 VGA_B
);

input CLOCK_50;
input [2:0]BUTTON;
output VGA_HS;
output VGA_VS;
output [3:0]VGA_G;
output [3:0]VGA_R;
output [3:0]VGA_B;

wire [10:0]x_addr;
wire [10:0]y_addr;
wire VGA_HS;
wire VGA_VS;
wire ready;
 sync_module u1 (
 .clk(CLOCK_50),
 .reset(BUTTON[2]),
 .x_addr(x_addr),
 .y_addr(y_addr),
 .hsync(VGA_HS),
 .vsync(VGA_VS),
 .ready(ready)
);

wire [63:0]rom_data;
wire [5:0]rom_addr;
 vga_ctrl_module u2 (
 .clk(CLOCK_50),
 .reset(BUTTON[2]),
 .ready(ready),
 .x_addr(x_addr),
 .y_addr(y_addr),
 .red(VGA_R[3]),
 .green(VGA_G[3]),
 .blue(VGA_B[3]),
 .rom_data(rom_data),
 .rom_addr(rom_addr)
);

 rom u3 (
 .address(rom_addr),
 .clock(CLOCK_50),
 .q(rom_data));
 
endmodule

 

同步模块:

module sync_module(
 clk,
 reset,
 x_addr,
 y_addr,
 hsync,
 vsync,
 ready
);

input clk;
input reset;
output [5:0]x_addr;
output [5:0]y_addr;
output hsync;
output vsync;
output ready;

reg [10:0]x_count;
always@(posedge clk or negedge reset)
 begin
  if(!reset)
   x_count<=11'd0;
  else if(x_count==11'd1040)
   x_count<=11'd0;
  else
   x_count<=x_count+1'd1;
 end
 
reg [10:0]y_count;
always@(posedge clk or negedge reset)
 begin
  if(!reset)
   y_count<=11'd0;
  else if(y_count==11'd666)
   y_count<=11'd0;
  else if(x_count==1040)
   y_count<=y_count+1'd1;
 end
 
assign ready=((x_count>183 && x_count<983)&&(y_count>28 && y_count<628))?1'd1:1'd0;
assign x_addr=(ready)?x_count-183:6'd0;
assign y_addr=(ready)?y_count-28:6'd0;
assign hsync=(x_count>119)?1'd1:1'd0;
assign vsync=(y_count>5)?1'd1:1'd0;

endmodule

 

VGA控制模块:

module vga_ctrl_module(
 clk,
 reset,
 ready,
 x_addr,
 y_addr,
 red,
 green,
 blue,
 rom_data,
 rom_addr
);

input clk;
input reset;
input ready;
input [10:0]x_addr;
input [10:0]y_addr;
input [63:0]rom_data;
output [5:0]rom_addr;
output red;
output green;
output blue;

reg [5:0]rom_adr;
always@(posedge clk or negedge reset)
 begin
  if(!reset)
   rom_adr<=6'd0;
  else if(ready && y_addr>300 && y_addr<364)
   rom_adr<=y_addr[10:0]-300;
  else rom_adr<=6'd0;
 end
 
reg [5:0]rom_data_bit;
always@(posedge clk or negedge reset)
 begin
  if(!reset)
   rom_data_bit<=6'd0;
  else if(ready && x_addr>200 && x_addr<264)
   rom_data_bit<=263-x_addr[10:0];
  else rom_data_bit<=6'd0;
 end

assign rom_addr=rom_adr;
assign red=(ready)?rom_data[rom_data_bit]:1'd0;
assign green=(ready)?rom_data[rom_data_bit]:1'd0;
assign blue=(ready)?rom_data[rom_data_bit]:1'd0;

endmodule

 ROM模块:

module rom (
 address,
 clock,
 q);

 input [5:0]  address;
 input   clock;
 output [63:0]  q;

 wire [63:0] sub_wire0;
 wire [63:0] q = sub_wire0[63:0];

 altsyncram altsyncram_component (
    .clock0 (clock),
    .address_a (address),
    .q_a (sub_wire0),
    .aclr0 (1'b0),
    .aclr1 (1'b0),
    .address_b (1'b1),
    .addressstall_a (1'b0),
    .addressstall_b (1'b0),
    .byteena_a (1'b1),
    .byteena_b (1'b1),
    .clock1 (1'b1),
    .clocken0 (1'b1),
    .clocken1 (1'b1),
    .clocken2 (1'b1),
    .clocken3 (1'b1),
    .data_a ({64{1'b1}}),
    .data_b (1'b1),
    .eccstatus (),
    .q_b (),
    .rden_a (1'b1),
    .rden_b (1'b1),
    .wren_a (1'b0),
    .wren_b (1'b0));
 defparam
  altsyncram_component.address_aclr_a = "NONE",
  altsyncram_component.clock_enable_input_a = "BYPASS",
  altsyncram_component.clock_enable_output_a = "BYPASS",
  altsyncram_component.init_file = "rom_pic_mif.mif",
  altsyncram_component.intended_device_family = "Cyclone III",
  altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
  altsyncram_component.lpm_type = "altsyncram",
  altsyncram_component.numwords_a = 64,
  altsyncram_component.operation_mode = "ROM",
  altsyncram_component.outdata_aclr_a = "NONE",
  altsyncram_component.outdata_reg_a = "CLOCK0",
  altsyncram_component.ram_block_type = "M9K",
  altsyncram_component.widthad_a = 6,
  altsyncram_component.width_a = 64,
  altsyncram_component.width_byteena_a = 1;


endmodule

 

初始化ROM的MIF表的内容(比卡丘):

0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000180000000000
0000380000000000
00003C0000000000
00007C0000000000
0000FC0000070000
0000FE00003F0000
0000E60001FF0000
0001860007FF0000
0001C6000C3E0000
000101F8701C0000
00018FFFE0380000
0001840780300000
0001600000607800
0001000000C0C800
0003000001C0CF00
0003003803010780
000F004C160300C0
000D807C1C0300E0
000F007C0C060060
001720380C060060
001A6001060600C0
00180003820C0180
001CFFC7C30C0300
001C7707C1B80E00
001C3F07C1181800
00BC1E01F1B01800
00EC0003B1D83000
018200071BCC3C00
0181000219C61600
00C1000031660E00
0060000020371C00
0028000000AC3000
003C0001E1F0E000
0006001B5BFCC000
0003001F03FCE000
0003803581FC6000
00010031807FC000
00038030E07F8000
0001000840F80000
0001C008C0F00000
0000C018C3C00000
0000C01D83000000
0000600E8C000000
000034066C000000
00001E03F0000000
0000070380000000
000001CF00000000
000000E700000000
0000006300000000
0000007E00000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000

 

引脚分配的TCL文件:

set_location_assignment PIN_J21 -to VGA_G[3]
set_location_assignment PIN_K17 -to VGA_G[2]
set_location_assignment PIN_J17 -to VGA_G[1]
set_location_assignment PIN_H22 -to VGA_G[0]
set_location_assignment PIN_L21 -to VGA_HS
set_location_assignment PIN_L22 -to VGA_VS
set_location_assignment PIN_H21 -to VGA_R[3]
set_location_assignment PIN_H20 -to VGA_R[2]
set_location_assignment PIN_H17 -to VGA_R[1]
set_location_assignment PIN_H19 -to VGA_R[0]
set_location_assignment PIN_K18 -to VGA_B[3]
set_location_assignment PIN_J22 -to VGA_B[2]
set_location_assignment PIN_K21 -to VGA_B[1]


set_location_assignment PIN_G21 -to CLOCK_50

set_location_assignment PIN_F1 -to BUTTON[2]

 

挺好玩的,呵呵,比卡丘很可爱!!!

posted @ 2010-12-25 21:40  lamapig  阅读(1520)  评论(2编辑  收藏  举报