基于basys2的VGA显示中ROM以及RAM的使用

1 篇文章 0 订阅
1 篇文章 0 订阅

基于basys2的VGA显示中ROM以及RAM的使用

          上篇文章讲述了关于vga字符显示以及打字机效果的实现,我们是利用寄存器制作的显示模块,但是如果我们扩大显示
      的字节数,就会发现,软件在布局布线的时候会报错,意思就是板子的资源不够用了,思来想去,也不是没道理,毕竟板
      子的资源是有限的。既然这样,我们就可以换一种思路。前面我们用到了ROM储存字模,显示存储使用起存其实现的。
      那么我们可以利用RAM的可读可写功能,制作一个显存,由于开发板上RAM是一块特定的资源,我们利用这块资源,
      及大大节省了板子的寄存器资源。就不会在报错了。
    		我这里采用的是单口的RAM,只能同时执行单一的读操作或者写操作。我们要根据开发板接收到的数据,从ROM中
    读取字模并按照一定的逻辑存储到RAM中,这一点是比较难的,但是相对的,在RAM输出的时候只需要利用计数器,
    就可以实现输出了。由于一个字符的宽的是8位,但是在事件过程中会发现,每个字符的第一列都会显示在下一个字
    符的第一列,也就是说,第一列字符有延时。造成这个的主要原因是RAM在写入的时候有一个周期的延迟,所以导
    致每次写入的时候最后一位数据会写入到下一个字符。由于这个问题暂时还没有更好的解决办法,所以我采用了一
    个方法,就是扩大了每个字符的位宽,就是每一个字符的显示由以前的8个像素点,变成了现在的呃9个。前面说到
    了因为每个字符的第一列会延迟到下一个字符。所以我们干脆直接将第一列像素全部置零,而后面的八位才是真正
    的字符。这样就解决了延迟问题。当然和不是根本的解决办法。我们只是利用了”障眼法“。



    下面是代码:【注意这只是VGA的display模块,其他模块请参考上篇文章】
module display_2(
		input  vga_clk,							//VGA驱动时钟
		input  sys_rst_n,                        //复位信号
		input [9:0] pixel_xpos,               //像素点横坐标
		input [9:0] pixel_ypos,               //像素点纵坐标
		output reg [7:0] pixel_data,//像素点数据
		input [7:0] led,
		input po_flag,
		input clk,
		input key_en
		
    );
		reg [6:0] begin_addra;
		reg [9:0] begin_x;
		reg [9:0] begin_y;



		parameter H_DISP = 10'd640;					  //分辨率一行
		parameter V_DISP = 10'd480;                    //分辨率一列
	
	
		localparam RED 	 = 8'b111_000_00;         //RGB332		红色
	
		localparam BLUE 	 = 8'b000_000_11;         //RGB332		蓝色
	
		reg [5:0] addra;
		wire  [127:0] douta;
		wire douta_ram;
		reg [11:0] addra_ram;
		reg [11:0] addra_ram_1;

		reg wea;
		reg dina;
	
	
IP_ROM_7 IP_ROM_7 (
  .clka(clk), // input clka
  .addra(addra), // input [5 : 0] addra
  .douta(douta) // output [127 : 0] douta
);
	

	//显存RAM
ram_2304  ram_2304(
  .clka(clk), // input clka
  .wea(wea), // input [0 : 0] wea
  .addra(addra_ram), // input [11 : 0] addra
  .dina(dina), // input [0 : 0] dina
  .douta(douta_ram) // output [0 : 0] douta
);
	reg [2:0]cnt_en;
	reg [7:0] cnt;
	reg [3:0] cnt_t;
	reg [11:0] cnt_data;
	always@(posedge clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
		wea <= 0;
		else if(cnt == 8 && cnt_t == 15)
		wea <= 0;
		else if(cnt_en == 3)
		wea <= 1;
		else
		wea <= wea;
	end
	reg [4:0] cnt_8;
	always@(posedge clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
		cnt_8 <= 0;
		else if(cnt_8 == 15 )
		cnt_8 <= 0;
		else if(cnt == 8 && cnt_t == 15)
		cnt_8 <= cnt_8 + 1'b1;
	
	end
	reg [8:0] dina_1;//RAM写入
	always@(posedge clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
		begin
		cnt_t <= 0;
		cnt <= 0;
		end
		else if(wea)
			begin
				case(cnt_t)
				0:begin 
				    dina_1 <= {1'b0,douta[127 :120]};//增加空像素,解决延时问题
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				1:begin 
					dina_1 <= {1'b0,douta[119 :112]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
				
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				2:begin 
					dina_1 <= {1'b0,douta[111 :104]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				3:begin
					dina_1 <= {1'b0,douta[103 :96]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				4:begin 
				dina_1 <= {1'b0,douta[95 :88]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				5:begin 
				dina_1 <= {1'b0,douta[87 :80]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				6:begin 
			dina_1 <= {1'b0,douta[79 :72]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				7:begin 
			dina_1 <= {1'b0,douta[71 :64]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				8:begin 
				dina_1 <= {1'b0,douta[63 :56]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				9:begin 
				dina_1 <= {1'b0,douta[55 :48]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				10:begin 
			dina_1 <= {1'b0,douta[47 :40]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				11:begin 
			dina_1 <= {1'b0,douta[39 :32]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					dina <= 0;
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					dina <= douta[39 - cnt];
					cnt <= cnt +1'b1;
					end
					end
				12:begin
				dina_1 <= {1'b0,douta[31 :24]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				13:begin 
			dina_1 <= {1'b0,douta[23 :16]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				14:begin
				dina_1 <= {1'b0,douta[15 :8]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= cnt_t + 1'b1;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
				15:begin 
		dina_1 <= {1'b0,douta[7 :0]};
					dina <= dina_1[8-cnt];
					addra_ram_1 <= cnt_t*144+cnt+9*cnt_8;
					if(cnt == 8)
					begin
					cnt <= 0;
					
					cnt_t <= 0;
					end
					else
					begin
					
					cnt <= cnt +1'b1;
					end
					end
					endcase
			end

	
end

always@(posedge clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	addra_ram <= 0;
	else if(wea)
	addra_ram <= addra_ram_1;
	else if(!wea && pixel_xpos>= begin_x&&pixel_xpos <144+begin_x &&pixel_ypos>= begin_y && pixel_ypos < begin_y +16)
	
		addra_ram <= cnt_data;
	
	
	

end
always@(posedge vga_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	pixel_data <= 0;
	else if(!wea && pixel_xpos>= begin_x&&pixel_xpos <144+begin_x &&pixel_ypos>= begin_y && pixel_ypos < begin_y +16)
	begin
		
		if(douta_ram != 0)
		pixel_data <= BLUE;
		else
		pixel_data <= RED;
	end
	else
	pixel_data <= RED;

end

always@(posedge vga_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	cnt_data <= 0;
	else if(!wea && pixel_xpos>= begin_x&&pixel_xpos <144+begin_x &&pixel_ypos>= begin_y && pixel_ypos < begin_y +16)
	begin
		if(cnt_data == 2303)
		cnt_data <= 0;
		else
		cnt_data <= cnt_data + 1'b1;
	end

end
always@(posedge clk or negedge sys_rst_n)
begin
		if(!sys_rst_n)
		addra <= 0;
		else 
		begin
				case(led)
				"A":	addra <= 6'd0;
				"B":	addra <= 6'd1;
				"C":	addra <= 6'd2;
				"D":	addra <= 6'd3;
				"E":	addra <= 6'd4;
				"F":	addra <= 6'd5;
				"G":	addra <= 6'd6;
				"H":	addra <= 6'd7;
				"I":	addra <= 6'd8;
				"J":	addra <= 6'd9;
				"K":	addra <= 6'd10;
				"L":	addra <= 6'd11;
				"M":	addra <= 6'd12;
				"N":	addra <= 6'd13;
				"O":	addra <= 6'd14;
				"P":	addra <= 6'd15;
				"Q":	addra <= 6'd16;
				"R":	addra <= 6'd17;
				"S":	addra <= 6'd18;
				"T":	addra <= 6'd19;
				"U":	addra <= 6'd20;
				"V":	addra <= 6'd21;
				"W":	addra <= 6'd22;
				"X":	addra <= 6'd23;
				"Y":	addra <= 6'd24;
				"Z":	addra <= 6'd25;
				"0":	addra <= 6'd26;
				"1":	addra <= 6'd27;
				"2":	addra <= 6'd28;
				"3":	addra <= 6'd29;
				"4":	addra <= 6'd30;
				"5":	addra <= 6'd31;
				"6":	addra <= 6'd32;
				"7":	addra <= 6'd33;
				"8":	addra <= 6'd34;
				"9":	addra <= 6'd35;
				" ":	addra <= 6'd36;
				8'hD0:	addra <= 6'd37;
				8'hC1:	addra <= 6'd38;
				8'hCF:	addra <= 6'd39;
				8'hE0:	addra <= 6'd40;
				8'hCE:	addra <= 6'd41;
				8'hC4:	addra <= 6'd42;
			

				default: begin_addra <= 0;
				endcase
		end
end
	reg en;
	
	always@(posedge clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
			en<=0;
			end
		else if(po_flag)
		en <= 1;
		else if(cnt_en == 3'd3)
		en <= 0;

	end
	
	always@(posedge clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
		cnt_en <= 0;
		else if(en)
		cnt_en <= cnt_en + 1'b1;
		else
		cnt_en <= 0;
	
	end
	
	

		

 always@(posedge clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
	begin
		begin_x <= 20;
		begin_y <= 20;
	
	end
	else
	begin
		begin_x <= 200;
		begin_y <= 200;
		
	end


end

 
	





endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蛋蛋壳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值