• 重温FPGA开发34


    RAM的应用介绍

    Random Access Memory

    ROM 只读不写
    RAM 即可读 又可写

    使用RAM存储一张图片的数据,并在TFT显示屏上显示出来。
    可以使用串口传输数据到RAM中,更改RAM的内容,以修改显示的内容。

    single port ram: 只有一个地址端口,同一时刻只能读或者写
    simple dual port ram:有两个地址端口,一个地址对应读,一个对应写
    true dual port ram:有两个地址端口,每个端口都能读或者写

    RAM容量的计算
    7A35T:由50个block RAM,每个RAM可以配置为2k18位的模式,250=100k个16/18 位的存储器单元

    每个像素有16位
    800x480 = 384000个16位数据

    RAM是一种可以写的ROM

    在这里插入图片描述

    RAM_tb.v

    `timescale 1ns/1ps
    
    module RAM_tb();
    	reg clka;
    	reg ena;
    	reg wea;
    	reg [15:0]addra;
    	reg [15:0]dina;
    	reg clkb;
    	reg enb;
    	reg [15:0]addrb;
    	wire [15:0]doutb;
    
    RAM RAM(
    	.clka(clka),
    	.ena(ena),
    	.wea(wea),
    	.addra(addra),
    	.dina(dina),
    	.clkb(clkb),
    	.enb(enb),
    	.addrb(addrb),
    	.doutb(doutb)    // output wire[15:0] doutb
    	);
    	
    	// 先写满 再读出来
    	initial clka = 1;
    	always #10 clka = ~clka;
    
    	intital clkb = 1;
    	always #15 clkb = ~clkb;
    
    	initial begin
    		ena = 0;
    		wea = 0;
    		addra = 0;
    		addrb = 0;
    		dina = 0;
    		enb = 0;
    		#201;
    		repeat(65536) begin
    			ena = 1;
    			wea = 1;
    			#20;
    			dina = dina + 1;
    			addra = addra + 1;
    		end
    		ena = 0;
    		wea = 0;
    		#20000;
    		addrb = 65535;
    		#200;
    		repeat(65536) begin
    			enb = 1;
    			#20;
    			addrb = addrb - 1;
    		end
    		#2000;
    		$stop
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    存储器的使用,在开始读写或者结束读写的位置非常容易出现数据错误或者遗失

    串口接收的数据一次接收一个字节 8位
    所以串口每接收2个字节的数据组成一个像素的值
    ram 的位宽是16位

    img_rx_wr.v

    module img_rx_wr(
    	Clk,
    	Reset,
    	rx_data,
    	rx_done,
    	ram_wren,
    	ram_wraddr,
    	ram_wrdata
    	);
    
    	input Clk;
    	input Reset;
    	input [7:0]rx_data;
    	input rx_done;
    	output ram_wren;
    	output [15:0]ram_wraddr;
    	output [15:0]ram_wrdata;
    
    	reg [16:0] data_cnt;  // 统计串口接受的数据个数计数器
    	
    	always@(posedge Clk or negedge Reset)
    	if(!Reset)
    		data_cnt <= 0;
    	else if(rx_done)
    		data_cnt <= data_cnt + 1'd1;
    
    	// 两个8位数据 进行拼接
    	reg [15:0] rx_data_tmp;
    	
    
    	always@(posedge Clk or negedge Reset)
    	if(!Reset)
    		rx_data_tmp <= 0;
    	else if(rx_done)
    		rx_data_tmp <= {rx_data_tmp[7:0], rx_data};
    
    	always@(posedge Clk or negedge Reset)
    	if(!Reset)
    		ram_wren <= 0;
    	else if(rx_done && data_cnt[0])
    		ram_wren <= 1'd1;
    	else
    		ram_wren <= 0;
    	
    	always@(posedge Clk or negedge Reset)
    	if(!Reset)
    		ram_wraddr <= 0;
    	else if(rx_done && data_cnt[0])
    		ram_wraddr <= data_cnt[16:1];
    		
    	// 写入的数据 	// 这里最好改成组合逻辑,因为寄存器会有延迟
    	always@(posedge Clk or negedge Reset)
    	if(!Reset)
    		ram_wraddr <= 0;
    	else if(rx_done && data_cnt[0])
    		ram_wrdata <= rx_data_tmp;
    			
    	
    	
    
    endmodule
    	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    testbench.v

    `timescale 1ns/1ps
    
    module img_rx_wr_tb();
    
    	reg Clk;
    	reg Reset;
    	reg [7:0]rx_data;
    	reg rx_done;
    	wire ram_wren;
    	wire [15:0]ram_wraddr;
    	wire [15:0]ram_wrdata;
    
    	img_rx_wr img_rx_wr(
    	Clk,
    	Reset,
    	rx_data,
    	rx_done,
    	ram_wren,
    	ram_wraddr,
    	ram_wrdata,
    	);
    
    	initial Clk = 1;
    	always#10 Clk = ~Clk;
    
    	initial begin
    		Reset = 0;
    		rx_data = 0;
    		rx_done = 0;
    		#201;
    		Reset = 1;
    		#2000;
    		rx_data = 255;
    		repeat(131072)	begin
    			rx_done = 1;
    			#20;
    			rx_done = 0;
    			#200;
    			rx_data = rx_data - 1;
    		end
    		#20000;
    		
    		repeat(131072)	begin
    			rx_done = 1;
    			#20;
    			rx_done = 0;
    			#200;
    			rx_data = rx_data - 1;
    		end
    		#20000;	
    	
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
  • 相关阅读:
    固定资产台账怎么管理
    Chrome vs Firefox 性能之争,到底哪家强?
    Pandas+Pyecharts | 40000+条考研信息数据可视化
    《动手学深度学习 Pytorch版》 8.6 循环神经网络的简洁实现
    CS配合frp上线
    Opencv_13_随机数与随机颜色
    NumPy(1)
    window升级版本
    jvm-sandbox-repeater时间mock插件设计与实现
    ThreadLocal真会内存泄漏?
  • 原文地址:https://blog.csdn.net/qq_30093417/article/details/125406481