tiny - riscv - 双口RAM -访存指令

160 阅读1分钟

image.png

双口RAM

module dual_ram #( 
	parameter DW = 32,
	parameter AW = 12,
	parameter MEM_NUM = 4096
)
(
	input wire 			clk			,
	input wire 			rst			,
	input wire 			wen			,
	input wire[AW-1:0]	w_addr_i	,
	input wire[DW-1:0]  w_data_i	,
	input wire 			ren			,
	input wire[AW-1:0]	r_addr_i	,
	output wire[DW-1:0]  r_data_o	
);	
	
	
	wire[DW-1:0] r_data_wire	;	
	reg 		 rd_equ_wr_flag	;
	reg[DW-1:0]	 w_data_reg		;
	// 当标志位为1,读数据从写的数据读取。
	assign r_data_o = (rd_equ_wr_flag) ? w_data_reg : r_data_wire;
	
	always @(posedge clk)begin
		if(!rst)
			w_data_reg <= 'b0;
		else
			w_data_reg <= w_data_i;
	end
	
	//切换
	always @(posedge clk)begin
                // 读和写  同一地址。
		if(rst && wen && ren && w_addr_i == r_addr_i )
                
                        // 标志位置为1
			rd_equ_wr_flag <= 1'b1;
		else if(rst && ren)
			rd_equ_wr_flag <= 1'b0;
	end
		

	dual_ram_template #(
		.DW (DW),
		.AW (AW),
		.MEM_NUM (MEM_NUM)
	)dual_ram_template_isnt
	(
		.clk			(clk		),
		.rst			(rst		),
		.wen			(wen		),
		.w_addr_i		(w_addr_i	),
		.w_data_i		(w_data_i	),
		.ren			(ren		),
		.r_addr_i		(r_addr_i	),
		.r_data_o       (r_data_wire)
	);

endmodule




module dual_ram_template #(
	parameter DW = 32, //数据位宽
	parameter AW = 12, // 地址位宽
	parameter MEM_NUM = 4096
)
(
	input wire 			clk			,
	input wire 			rst			,
	input wire 			wen			,
	input wire[AW-1:0]	w_addr_i	,
	input wire[DW-1:0]  w_data_i	,
	input wire 			ren			,
	input wire[AW-1:0]	r_addr_i	,
	output reg[DW-1:0]  r_data_o
);
	reg[DW-1:0] memory[0:MEM_NUM-1];
	
	// 读时序
	
	always @(posedge clk)begin
		if(rst && ren)
			r_data_o <= memory[r_addr_i];
	end
        
        //写时序
	
	always @(posedge clk)begin
		if(rst && wen)
			memory[w_addr_i] <= w_data_i;
	end

endmodule


image.png

译码阶段发起访存读

在执行阶段可以对数据操作

访存指令

load: 一个字节 半个字,一个字32位,4个字节。

store: byte word half

ROM通过双口RAM实现。 写端口通过uart进来。读端口就是读指令、

自动化测试

安装python

安装iverilog 编译器