EP4CE115F29C7的VGA显示

一.VGA

VGA的全称是Video Graphics Array,即视频图形阵列,是一个使用模拟信号进行视频传
输的标准。早期的CRT显示器由于设计制造上的原因,只能接收模拟信号输入,因此计算机内
部的显卡负责进行数模转换,而VGA接口就是显卡上输出模拟信号的接口。如今液晶显示器虽
然可以直接接收数字信号,但是为了兼容显卡上的VGA接口,也大都支持VGA标准。

二、VGA显示彩色条纹

1.IP核时钟分频
在这里插入图片描述
因为时钟频率 = 行帧长 × 列帧长 * 刷新率
所以640 ×480 60HZ对应时钟频率= 800 ×525 × 60 = 25.2M
用25MHZ时钟
在这里插入图片描述
2.顶层代码:

module vga_top(
 input wire    clk,
 input wire    rst_n,
 
 output wire       hsync,
 output wire       vsync,
 output wire [7:0] vga_r,
 output wire [7:0] vga_g,
 output wire [7:0] vga_b,
 output wire       vga_blk,
 output wire       vga_clk

);

wire [23:0] data_dis;

wire [10:0] h_addr;
wire [10:0] v_addr;

data_gen data_gen(
.vga_clk        (vga_clk),
.rst_n      (rst_n),
.h_addr     (h_addr),
.v_addr     (v_addr),

.data_dis   (data_dis)
);

vga_ctrl vga_ctrl(
.clk        (clk),
.rst_n      (rst_n),
.data_dis   (data_dis),

.h_addr     (h_addr),//数据有效显示区域行地址
.v_addr     (v_addr),//数据有效显示区域场地址

.hsync      (hsync),
.vsync      (vsync),

.vga_r      (vga_r),
.vga_g      (vga_g),
.vga_b      (vga_b),
.vga_blk    (vga_blk),
.vga_clk    (vga_clk)
);

endmodule

2.vga_ctrl

`define vga_640_480
`include "vga_param.v"
module vga_ctrl(
 input  wire        clk      ,
 input  wire        rst_n    ,
 input  wire [23:0] data_dis ,
 
 output reg  [10:0] h_addr   ,//数据有效显示区域行地址
 output reg  [10:0] v_addr   ,//数据有效显示区域场地址
 
 output reg         hsync    ,
 output reg         vsync    ,
 
 output reg  [7:0]  vga_r    ,
 output reg  [7:0]  vga_g    ,
 output reg  [7:0]  vga_b    ,
 output reg         vga_blk  ,
 output wire        vga_clk
);

parameter  H_SYNC_STA = 1,
           H_SYNC_STO = `H_Sync_Time,
           H_DATA_STA = `H_Sync_Time + `H_Back_Porch + `H_Left_Border,
			  H_DATA_STO = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time;
			  
parameter  V_SYNC_STA = 1,
           V_SYNC_STO = `V_Sync_Time,
           V_DATA_STA = `V_Sync_Time + `V_Back_Porch + `V_Top_Border,
			  V_DATA_STO = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time;

 reg   [11:0]   cnt_h_addr;//行地址计数器
 wire           add_h_addr ;
 wire           end_h_addr ;
 
 reg   [11:0]   cnt_v_addr;//列地址计数器
 wire           add_v_addr ;
 wire           end_v_addr ;
wire							clk_25			;
clk_25	clk_25_inst (
	.areset ( ~rst_n ),
	.inclk0 ( clk ),
	.c0 ( clk_25 )
	);
	assign vga_clk = ~clk_25;
always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_h_addr <= 12'd0;
	 end
	 else if(add_h_addr)begin
	      if(end_h_addr)begin
			   cnt_h_addr <= 12'd0;
			end
			else begin
			   cnt_h_addr <= cnt_h_addr + 12'd1;
			end
	 end
    else begin
	     cnt_h_addr <= 12'd0;
	 end
end

assign add_h_addr = 1'b1;
assign end_h_addr = add_h_addr && cnt_h_addr >= `H_Total_Time - 1;

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_v_addr <= 12'd0;
	 end
	 else if(add_v_addr)begin
	      if(end_v_addr)begin
			   cnt_v_addr <= 12'd0;
			end
			else begin
			   cnt_v_addr <= cnt_v_addr + 12'd1;
			end
	 end
    else begin
	     cnt_v_addr <= cnt_v_addr;
	 end
end

assign add_v_addr = end_h_addr;
assign end_v_addr = add_v_addr && cnt_v_addr >= `V_Total_Time - 1;

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
       hsync <= 1'b1;
	 end
	 else if(cnt_h_addr == H_SYNC_STA- 1)begin
	    hsync <= 1'b0;
	 end
	 else if(cnt_h_addr == H_SYNC_STO - 1)begin
	    hsync <= 1'b1;
	 end
    else begin
	    hsync <= hsync;
	 end
end

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
       vsync <= 1'b1;
	 end
	 else if(cnt_v_addr == V_SYNC_STA - 1)begin
	    vsync <= 1'b0;
	 end
	 else if(cnt_v_addr == V_SYNC_STO - 1)begin
	    vsync <= 1'b1;
	 end
    else begin
	    vsync <= vsync;
	 end
end


always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
       h_addr <= 11'd0;
	 end
	 else if((cnt_h_addr >= H_DATA_STA - 1) && (cnt_h_addr <= H_DATA_STO -1) )begin
	    h_addr <= cnt_h_addr - H_DATA_STA + 1;
	 end
    else begin
	    h_addr <= 11'd0;
	 end
end

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
       v_addr <= 11'd0;
	 end
	 else if((cnt_v_addr >= V_DATA_STA - 1) && (cnt_v_addr <= V_DATA_STO -1)  )begin
	    v_addr <= cnt_v_addr - V_DATA_STA + 1;
	 end
    else begin
	    v_addr <= 11'd0;
	 end
end

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
       vga_r <= 8'b0;
		 vga_g <= 8'b0;
		 vga_b <= 8'b0;
		 vga_blk <= 1'b0;	 
		 end
	 else if((cnt_h_addr >= H_DATA_STA - 1) && (cnt_h_addr <= H_DATA_STO -1) &&
	         (cnt_v_addr >= V_DATA_STA - 1) && (cnt_v_addr <= V_DATA_STO -1) )begin
	    vga_r <= data_dis[23:16];
		 vga_g <= data_dis[15:8];
		 vga_b <= data_dis[7:0];
		 vga_blk <= 1'b1;
	 end
    else begin
	    vga_r <= 8'b0;
		 vga_g <= 8'b0;
		 vga_b <= 8'b0;
		 vga_blk <= 1'b0;
	 end
end

endmodule

3.data_gen

module data_gen(
 input wire    vga_clk,
 input wire    rst_n,
 input wire [10:0] h_addr,
 input wire [10:0] v_addr,
 
 output reg [23:0] data_dis
);
 parameter BLACK    = 24'h000000,
           RED      = 24'hFF0000,
			  GREEN    = 24'h00FF00,
			  BLUE     = 24'h0000FF,
			  YELLOW   = 24'hFFFF00,
			  SKY_BULE = 24'h00FFFF,
			  PURPLE   = 24'hFF00FF,
			  GRAY     = 24'hC0C0C0,
			  WHITE    = 24'hFFFFFF;
//色条	 

always@(posedge vga_clk or negedge rst_n)begin
    if(!rst_n)begin
	    data_dis <= WHITE;
	 end
	 else begin
	    case(h_addr)
		 0  : data_dis <=  BLACK    ;
		 80 : data_dis <=  RED      ;
		 160: data_dis <=  GREEN    ;
		 240: data_dis <=  BLUE     ;
		 320: data_dis <=  YELLOW   ;
		 400: data_dis <=  SKY_BULE ;
		 480: data_dis <=  PURPLE   ;
		 560: data_dis <=  GRAY;
		 default: data_dis <= data_dis;
		 endcase
	 end
end
endmodule

结果:

在这里插入图片描述

三、VGA显示文字

1.在这里插入图片描述
2.导出位图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.打开刚才保存的
0fd302e7.png)

在这里插入图片描述

4.导出生成字模
在这里插入图片描述
在这里插入图片描述
5.只需要更改data_gen的代码

module data_gen(
 input wire    vga_clk,
 input wire    rst_n,
 input wire [10:0] h_addr,
 input wire [10:0] v_addr,
 
 output reg [23:0] data_dis
);
 parameter BLACK    = 24'h000000,
           RED      = 24'hFF0000,
			  GREEN    = 24'h00FF00,
			  BLUE     = 24'h0000FF,
			  YELLOW   = 24'hFFFF00,
			  SKY_BULE = 24'h00FFFF,
			  PURPLE   = 24'hFF00FF,
			  GRAY     = 24'hC0C0C0,
			  WHITE    = 24'hFFFFFF;
//文字	
		  
parameter  //点阵字模:每一行char_lineXX是显示的一行,共272列
   char_line00= 302'h000000001C00000000000000000000000000000000000000000000000000000000000000, //第1行
    char_line01=302'h0001FFF01F0077001C1FFFC0000000000000000000000000000000000000000000000000, //第2行
    char_line02=302'h0001FFF0070077001C1FFFC0000000000000000000000000000000000000000000000000, //第3行
    char_line03=302'h7FF1FFF0070077C01F1FFFC0000000000000000000000000000000000000000000000000, //第4行
    char_line04=302'h7FF1C070000071C007000700000000000000000000000000000000000000000000000000, //第5行
    char_line05=302'h7FF1C071FFF1F1F007001F0007C01FF001C01FC007C07FFC07C007C007C0007001C07FFC, //第6行
    char_line06=302'h7071C071FFF1C07007001C0007C01FF001C01FC007C07FFC07C007C007C0007001C07FFC, //第7行
    char_line07=302'h7071C071FFF7DC71C7707C701FF07FFC1FC07FF01FF07FFC1FF01FF01FF001F01FC07FFC, //第8行
    char_line08=302'h7071C07001C71C71C07070701C70701C1FC070701C70701C1C701C701C7001F01FC0701C, //第9行
    char_line09=302'h7071FFF007C71C71F07777707C70701C1FC0707C7C7C707C7C7C7C707C7C01F01FC0707C, //第10行
    char_line0a=302'h7071FFF007001C00707777707000701C01C0701C701C0070701C7000701C01F001C00070, //第11行
    char_line0b=302'h7FF1FFF007007F007077FF707000701C01C0701C701C0070701C7000701C07F001C00070, //第12行
    char_line0c=302'h7FF1C070070077007071FC707000001C01C0701C701C0070701C7000701C077001C00070, //第13行
    char_line0d=302'h7FF1C0701F71F7C07771FC7077F0007C01C0701C701C01F0701C77F0701C1F7001C001F0, //第14行
    char_line0e=302'h7071C0701F71C1C00770707077F0007001C0701C701C01C0701C77F0701C1C7001C001C0, //第15行
    char_line0f=302'h7071C0707FF7C1FC0771FC707FFC07F001C0707C701C01C0701C7FFC701C1C7001C001C0, //第16行
    char_line10=302'h7071C07077C7007C0771FC707C1C07C001C0707C701C01C0701C7C1C701C1C7001C001C0, //第17行
    char_line11=302'h7071FFF1F7F7FFFC1F77FF707C1C07F001C07FFC701C07C0701C7C1C701C7C7001C007C0, //第18行
    char_line12=302'h7071FFF1C771FFC01C777770701C007001C01FDC701C0700701C701C701C707001C00700, //第19行
    char_line13=302'h7FF1FFF1C771FFC1FC7F77F0701C007C01C01FDC701C0700701C701C701C7FFF01C00700, //第20行
    char_line14=302'h7FF1C0700771C1C1FC7C71F0701C001C01C0001C701C0700701C701C701C7FFF01C00700, //第21行
    char_line15=302'h7FF1C0700771C1C1FC7F71F0701C701C01C0001C701C0700701C701C701C7FFF01C00700, //第22行
    char_line16=302'h7071C0700701C1C01C777070701C701C01C0001C701C0700701C701C701C007001C00700, //第23行
    char_line17=302'h7077C0700701C1C01C77F0707C1C701C01C01C7C7C7C07007C7C7C1C7C7C007001C00700, //第24行
    char_line18=302'h000700700701C1C01C71C0701C1C701C01C01C701C7007001C701C1C1C70007001C00700, //第25行
    char_line19=302'h000700700701C1C01C71C0701FFC7FFC1FFC1FF01FF007001FF01FFC1FF007FF1FFC0700, //第26行
    char_line1a=302'h000700700701C1C01C70007007F01FF01FFC07C007C0070007C007F007C007FF1FFC0700, //第27行
    char_line1b=302'h001F07700701FFC01C7FFFF007F01FF01FFC07C007C0070007C007F007C007FF1FFC0700, //第28行
    char_line1c=302'h001C07700701FFC01C7FFFF0000000000000000000000000000000000000000000000000, //第29行
    char_line1d=302'h007C07F00701FFC01C7FFFF0000000000000000000000000000000000000000000000000, //第30行
    char_line1e=302'h007001C00701C1C000000070000000000000000000000000000000000000000000000000, //第31行
    char_line1f=302'h007001C00701C1C000000070000000000000000000000000000000000000000000000000; //第32行

	reg[8:0] char_bit;
    always@(posedge vga_clk)
        if(h_addr==10'd144)
		     char_bit<=9'd302;   //当显示到144像素时准备开始输出图像数据
        else if(h_addr>10'd144&&h_addr<10'd446)     //左边距屏幕144像素到416像素时    416=144+272(图像宽度)
           char_bit<=char_bit-1'b1;       //倒着输出图像信息 
    always@(posedge vga_clk) 
        if(h_addr>10'd144&&h_addr<10'd446)    //X控制图像的横向显示边界:左边距屏幕左边144像素  右边界距屏幕左边界416像素
            begin case(v_addr)            //Y控制图像的纵向显示边界:从距离屏幕顶部160像素开始显示第一行数据
                10'd160:
                if(char_line00[char_bit])
					    data_dis<=RED;  //如果该行有数据 则颜色为红色
                else 
					    data_dis<=BLACK;                      //否则为黑色
                10'd162:
                if(char_line01[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd163:
                if(char_line02[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd164:
                if(char_line03[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd165:
                if(char_line04[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK; 
                10'd166:
                if(char_line05[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd167:
                if(char_line06[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK; 
                10'd168:
                if(char_line07[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd169:
                if(char_line08[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK; 
                10'd170:
                if(char_line09[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd171:
                if(char_line0a[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd172:
                if(char_line0b[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd173:
                if(char_line0c[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd174:
                if(char_line0d[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd175:
                if(char_line0e[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd176:
                if(char_line0f[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd177:
                if(char_line10[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd178:
                if(char_line11[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd179:
                if(char_line12[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd180:
                if(char_line13[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd181:
                if(char_line14[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd182:
                if(char_line15[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd183:
                if(char_line16[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd184:
                if(char_line17[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd185:
                if(char_line18[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd186:
                if(char_line19[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd187:
                if(char_line1a[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd188:
                if(char_line1b[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd189:
                if(char_line1c[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd190:
                if(char_line1d[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd191:
                if(char_line1e[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                10'd192:
                if(char_line1f[char_bit])
					    data_dis<=RED;
                else 
					    data_dis<=BLACK;
                default:data_dis<=BLACK;   //默认颜色黑色
            endcase 
        end
    else data_dis<=BLACK;             //否则黑色 
endmodule

结果:
在这里插入图片描述

四、VGA显示图片

1.转换图片为mif格式,因为用的EP4CE115F29C7的板子VGA_R、VGA_G、VGA_B用的[7:0]所以选择格式888
在这里插入图片描述
2.导入ROM核
在这里插入图片描述
设置位宽度为24位,大小为图片大小128×78 = 9984
在这里插入图片描述
在这里插入图片描述
3.导入刚才的mif文件
在这里插入图片描述
4.修改data_gen代码

module data_gen(
 input wire    vga_clk,
 input wire    rst_n,
 input wire [10:0] h_addr,
 input wire [10:0] v_addr,
 
 output reg [23:0] data_dis
);
 parameter BLACK    = 24'h000000,
           RED      = 24'hFF0000,
			  GREEN    = 24'h00FF00,
			  BLUE     = 24'h0000FF,
			  YELLOW   = 24'hFFFF00,
			  SKY_BULE = 24'h00FFFF,
			  PURPLE   = 24'hFF00FF,
			  GRAY     = 24'hC0C0C0,
			  WHITE    = 24'hFFFFFF;
wire							flag_begin_h			    ; // 图片显示行
wire							flag_begin_v			    ; // 图片显示列
parameter	height = 78; // 图片高度
parameter	width  = 128; // 图片宽度
reg			[ 13:0 ]		rom_address				; // ROM地址
wire			[ 23:0 ]		rom_data				;

//ROM地址计数器

always@(posedge vga_clk or negedge rst_n)begin
  if(!rst_n )begin
     data_dis = WHITE;
  end
  else if(flag_enable_out2)begin
     data_dis = rom_data;
  end
  else begin
     data_dis = WHITE;
  end

end

always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rom_address <= 0;
    end
    else if ( rom_address == 9983 ) begin //计数满清零
        rom_address <= 0;
    end
        else if ( flag_enable_out2 ) begin  //在有效区域内+1
        rom_address <= rom_address + 1;
        end
    else begin  //无效区域保持
        rom_address <= rom_address;
    end
end
assign flag_begin_h     = h_addr > ( ( 640 - width ) / 2 ) && h_addr < ( ( 640 - width ) / 2 ) + width + 1;
assign flag_begin_v     = v_addr > ( ( 480 - height )/2 ) && v_addr <( ( 480 - height )/2 ) + height + 1;
assign flag_enable_out2 = flag_begin_h && flag_begin_v;
rom3	rom3_inst (
	.address ( rom_address ),
	.clock ( vga_clk ),
	.q ( rom_data )
	); 
endmodule 

结果:
在这里插入图片描述

参考:
https://blog.csdn.net/qq_47281915/article/details/125134764?spm=1001.2014.3001.5502

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EP4CE115F29C7是一款Cyclone IV系列的FPGA芯片,它可以用于数字电路设计和开发。要设计一个数字秒表,您需要使用Verilog语言编写代码,实现秒表的计数和显示功能。 以下是一种可能的Verilog代码实现: ```verilog module stopwatch( input clk, // 时钟信号 input rst, // 复位信号 input start, // 启动/停止信号 output reg [23:0] time // 秒表计时值,用24位二进制表示 ); reg [23:0] count; // 计数器值,用24位二进制表示 reg running; // 秒表是否在计时状态的标志 always @(posedge clk or posedge rst) begin if (rst) begin count <= 0; running <= 0; end else if (start) begin running <= ~running; // 切换计时状态 end if (running) begin count <= count + 1; // 计数器加1 end time <= count; // 将计数器值输出到时间寄存器中 end endmodule ``` 这个Verilog模块包含一个时钟输入信号、一个复位信号、一个启动/停止信号和一个24位输出端口。当启动/停止信号为高电平时,秒表开始计时,再次触发该信号则停止计时。计数器值通过时钟信号不断增加,并将其输出到时间寄存器中。当复位信号为高电平时,计数器和时间寄存器都被清零。 要将此代码烧录到EP4CE115F29C7芯片中,您需要使用专用的FPGA开发工具,如Quartus II。在该工具中,您可以将Verilog代码编译成适合芯片的二进制文件,并将其通过JTAG或其他接口上传到芯片中。接下来,您需要设计一个数字显示器电路,将时间寄存器的值转换为可读的数字格式,并将其显示在七段LED显示器或其他显示屏上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值