NIOS II- Dual_Port RAM IP的应用

NIOS II- Dual_Port RAM IP

在NIOS II 的学习中用到FPGA—NIOS II的信息交互,最常用的方式:FIFO/RAM/Avalon-MM Pipeline Bridge。根据项目需求决定采用Dual_Port RAM进行数据交互。
由于查阅资料并没有发现有Dual_Port RAM数据交互的详细步骤,故将自己的步骤记录下来,供后续研究者参考。
本设计所用芯片为ALTERA系列中Cyclone IV E:EP4CE10F17C8

1、建立工程,写入硬件代码、引脚绑定并编译。最终的硬件Verilog代码如下(部分代码需要在生成Qsys文件之后才能编译通过):

module SOPC_GHRD_RAM(
	input 					sys_clk, 	//晶振时钟,50Mhz
	input 					sys_rst_n, 	//按键复位,低电平有效
	input  					rs232_rx, 	//RS232数据输入
	output 					rs232_tx  	//RS232数据输出
);

//wire define
wire 	clk_50m; 
wire 	clk_100m; 				//Qsys系统时钟,100Mhz
wire 	clk_100m_shift;
wire 	pll_locked;
wire 	rst_n;

assign rst_n = sys_rst_n & pll_locked ;

//例化pll IP核
pll_clk u_pll(
	.inclk0 					(sys_clk		),
	.areset 					(~sys_rst_n		),
	.c0 						(clk_50m		),
	.c1 						(clk_100m		), //SDRAM 时钟
	.c2 						(clk_100m_shift ), 
	.locked 					(pll_locked		)
);

reg	  [ 4 : 0] address;
reg   [ 31: 0] writedata;
wire           write_read;
wire  [ 3 : 0] byteenable;
wire  [ 31: 0] readdata;

//例化Qsys系统
system_qsys u_ram(
	.clk_clk 								(clk_100m		),
	.reset_reset_n 							(rst_n			),
	.dual_port_ram_clk_clk        	 		(clk_100m		),      // dual_port_ram_clk.clk
	.dual_port_ram_reset_reset     			(rst_n			),     	// dual_port_ram_reset.reset
	.dual_port_ram_reset_reset_req 			(1'b0			), 		// dual_port_ram_s.reset_req
	.dual_port_ram_s_address    			(address		),   	// dual_port_ram_s.address
	.dual_port_ram_s_chipselect 			(1'b1			), 		// dual_port_ram_s.chipselect
	.dual_port_ram_s_clken      			(1'b1			),      // dual_port_ram_s.clken
	.dual_port_ram_s_write      			(write_read		),     	// 1 write  0 read
	.dual_port_ram_s_readdata   			(readdata		),   	// dual_port_ram_s.readdata
	.dual_port_ram_s_writedata  			(writedata		),		// dual_port_ram_s.writedata
	.dual_port_ram_s_byteenable    			(4'b1111		)     	// dual_port_ram_s.byteenable
);
/*---------------------Dual_Port RAM测试代码---------------------------------*/
wire [7:0]	tx_byte; //连线的wire声明不能缺少 
uart_byte_tx uart_byte_tx
(
	.clk						( clk_100m 		), 
	.rst_n						( rst_n 		),
	.rs232_tx					( rs232_tx 		),    
	.tx_en						( 1 			),    
	.tx_done					( tx_done 		),  		
	.tx_byte					( read_data[7:0])   		
 );
/********************************************************************/
wire [ 4:0] read_addr;
reg  [31:0] read_data;
always @(posedge clk_100m or negedge rst_n) 
begin
	if (!rst_n)
	begin	// reset
		writedata <= 32'h256;
		address	 <= 5'h0;
	end
	else if (writedata == 32'hffff_ffff)
	begin
		writedata <= 32'h0;
		address	 <= 5'h0;
	end
	else if (write_read)	 //write_read写使能信号有效时数据跳变
	begin
		writedata <= writedata + 1'b1;
		address	 <= address + 5'h1;
	end
	else if (!write_read) 
	begin
		case(read_addr)
			5'h03: begin address <= read_addr; read_data <= readdata;end
		endcase	
	end
end
assign read_addr = 5'h03;
assign write_read = (writedata < (32'h256+32'h20 ));//存满32个32bit的数据后write_read拉低

endmodule 

NOTE:
有关dual_port_ram_s_byteenable 的参数配置在avalon总线相关手册中找到:
NIOS II- Dual_Port RAM IP的应用_第1张图片
在这里插入图片描述

2、创建Qsys工程,完成连接

Tools —> Qsys,分别添加
NiOS II Processor: Nios II/f
On-Chip Memory(rom): width=32 size=10240bytes
On-Chip Memory(ram): width=32 size=10240bytes
On-Chip Memory(dual_port ram)如下图所示:
NIOS II- Dual_Port RAM IP的应用_第2张图片
Jtag_uart: 默认
Sysid: 默认
连线,分配地址
NIOS II- Dual_Port RAM IP的应用_第3张图片
双击CPU,修改Reset vector和Exception vctor
NIOS II- Dual_Port RAM IP的应用_第4张图片
Generation -> Generate生成工程,保存为system.qsys

3、完成硬件工程

Hierarchy -> work上右键settings,添加NiOS_ii.qsys文件,完成代码并编译。之后烧录板子中。
NIOS II- Dual_Port RAM IP的应用_第5张图片

4、建立软件工程

Tools -> Nios II Software Build Tools for Eclipse,选择软件工作环境为工程,进入Eclipse工作界面。
File -> New,选第一个,正常建立工程nios_ram_demo。
将hello_world.c文件重命名为main.c,之后写入如下代码

#include 
#include 
#include 
#include "unistd.h" //延迟函数头文件
#include "system.h" //系统头文件
#include "alt_types.h" //数据类型头文件

int i=0,k=0;
long int data[32];
int main()
{
	printf("Hello-Nios-RAM!\n");
	for(i=0;i<32*4;i=i+4)
	{
		data[k] = IORD_32DIRECT(DUAL_PORT_RAM_BASE,i);//从地址位置为 DUAL_PORT_RAM_BASE+0 的寄存器中直接读取 32Bit的数据
		printf("data_%d=%x\t",k,data[k]);
		k = k+1;
	}
	IOWR_32DIRECT(DUAL_PORT_RAM_BASE, 12, 32); //往地址位置为 DUAL_PORT_RAM_BASE+8 的寄存器中直接写入 32Bit 的数据
  return 0;
}

5、编译软件

在编译工程之前可以通过配置来减少程序编译所生成的代码量:
我们在“Project Explorer”窗口中选中“nios_ram_demo_bsp”工程,然后点击鼠标右键,在弹出的菜单栏中依次选择【Nios II】→【BSP Editor…】,会出现“Nios II BSP Editor”界面,在界面中做如下改动即可:
NIOS II- Dual_Port RAM IP的应用_第6张图片
NIOS II- Dual_Port RAM IP的应用_第7张图片
最后生成bsp库—>nios_ram_demo主文档右键—>Bulid Project—>Run —>run as —> Nios II Hardware烧录。

6、功能验证

NIOS II- Dual_Port RAM IP的应用_第8张图片
NIOS II- Dual_Port RAM IP的应用_第9张图片
由第一幅图可知FPGA中写入的32个数据(0x00000256 ——0x00000275)已经成功传入NIOS中;第二幅图说明NIOS写入的1个数据0x00000020(低八位是0x20)同样成功传入。

你可能感兴趣的:(SOPC)