DE2_70上实现NIOSII读写SSRAM
实验目的:
掌握在SOPC定制SSRAM控制核及通过Nios II对SSRAM访问的方法
实验环境:
Quartus II 9.0 / Nios II IDE 9.0 /DE2_70
参考资料:
真 OO无双
http://www.cnblogs.com/oomusou/archive/2009/02/14/de2_70_ssram.html
SOPC-IIINIOSII实验指导书正文(第三版)--实验九SDRAM
新建Quartus II工程后,单击SOPC,开始定制Nios系统
为Nios系统命名NIOS_CPU,单击OK
修改系统输入时钟,我们这里用100MHz时钟输入
然后依次添加cpu(/s),on-chip memory(40KB),jtag uart,这里不赘述这些IP的设置了
下面要加入ssram的IP啦,再加入ssram之前要先加入三态桥(在NIOS系统中,要实现与FPGA片外存储器通信,就必须在Avalon总线和连接外部总线之间添加Avalon三态桥)
再加入ssram,DE2_70上的SSRAM(IS61LPS51236A)和这里的IP(CY7C1380C)容量相同,都是512K*36
重命名ssram和三态桥,并将ssram与三态桥连接
进行复位和异常地址设置
自动分配基地址后,我们这里No errors or warning,可以Generate啦
Generate成功之后,回到Quartus II新建顶层Verilog,来例化NIOS_CPU,因为CPU系统的时钟设为100MHz,所以我们还需要定制一个PLL来产生一个100MHz的时钟
PLL_c0作为系统时钟,PLL_c1作为SSRAM芯片的工作时钟,需要与系统时钟偏移一定角度(这里借鉴无双的设置)
Top module Verilog code:
module NIOS_SSRAM( input iCLK_50, // 50 MHz input iKEY0, // Pushbutton0 //--------------------------- // SRAM Interface ------------------ inout [31:0] SRAM_DQ, // SRAM Data Bus 32 Bits inout [3:0] SRAM_DPA, // SRAM Parity Data Bus output [20:0] oSRAM_A, // SRAM Address bus 22 Bits output oSRAM_ADSC_N, // SRAM Controller Address Status output oSRAM_ADSP_N, // SRAM Processor Address Status output oSRAM_ADV_N, // SRAM Burst Address Advance output [3:0] oSRAM_BE_N, // SRAM Byte Write Enable output oSRAM_CE1_N, // SRAM Chip Enable output oSRAM_CE2, // SRAM Chip Enable output oSRAM_CE3_N, // SRAM Chip Enable output oSRAM_CLK, // SRAM Clock output oSRAM_GW_N, // SRAM Global Write Enable output oSRAM_OE_N, // SRAM Output Enable output oSRAM_WE_N // SRAM Write Enable ); // ssram wire SRAM_CLK; // sram clock wire [1:0] sram_dummy_addr; // used to ignore the a0/a1 pin from cypress ssram ip core assign oSRAM_ADSP_N = 1'b1; // SRAM Processor Address Status assign oSRAM_ADV_N = 1'b1; // SRAM Burst Address Advance assign oSRAM_CE2 = ~oSRAM_CE1_N; // SRAM Chip Enable assign oSRAM_CE3_N = oSRAM_CE1_N; // SRAM Chip Enable assign oSRAM_GW_N = 1'b1; // SRAM Global Write Enable assign oSRAM_CLK = SRAM_CLK; wire CPU_RESET_N; Reset_Delay u0_rst_dly( .iCLK(iCLK_50), .iRST(iKEY0), .oRESET(CPU_RESET_N) ); wire SYS_CLK_100; SYS_PLL u1_pll( .inclk0(iCLK_50), .c0(SYS_CLK_100), .c1(SRAM_CLK) ); NIOS_CPU NIOS_CPU_inst ( .CPU_CLK_100 (SYS_CLK_100), .reset_n (CPU_RESET_N), .address_to_the_ssram ({oSRAM_A[18:0],sram_dummy_addr}), .adsc_n_to_the_ssram (oSRAM_ADSC_N), .bw_n_to_the_ssram (oSRAM_BE_N), .bwe_n_to_the_ssram (oSRAM_WE_N), .chipenable1_n_to_the_ssram (oSRAM_CE1_N), .data_to_and_from_the_ssram (SRAM_DQ), .outputenable_n_to_the_ssram (oSRAM_OE_N) ); endmodule
RTL:
硬体部分设置完成,然后启动Nios IDE,进行软体设计,首先新建NIOS工程:
工程新建好后,先对工程属性进行设置:
预先将工程编译一遍(第一次编译会有点慢),然后打开system.h这个头文件(如下图),它包含了SOPC中IP对应硬件配置信息,下面的C程序设计中我们将用到其中的SSRAM_BASE(SSRAM的基地址)
Nios II C code:
#include <stdio.h> #include <sys/unistd.h> #include <string.h> #include "system.h" #include "alt_types.h" alt_u32 *ssram; int main() { alt_u32 i, len, error; printf("Nios II SSRAM Test!\n"); error = 0; printf("SSRAM Test Begin!\n"); ssram = (alt_u32 *)SSRAM_BASE; len = SSRAM_SPAN / 4; *ssram++ = 0x55555555; *ssram++ = 0xaaaaaaaa; ssram = (alt_u32 *)SSRAM_BASE; printf("SSRAM Data Bus Check\n"); if(*ssram++ != 0x55555555) error ++; if(*ssram != 0xaaaaaaaa) error ++; if(error) printf("Fail\n"); else { printf("OK!\n"); printf("Whole Chip Writing Data Now\n"); ssram = (alt_u32 *)SSRAM_BASE; for(i=0; i<len; i++) { *ssram++ = i; if(i % 50000 == 0) printf("."); } ssram = (alt_u32 *)SSRAM_BASE; printf("Verifing Now\n"); for(i=0; i<len; i++) { if(*ssram++ != i) break; if(i % 50000 == 0) printf("."); } if(i == len) printf("\nSSRAM is OK!\n"); else printf("\nSSRAM Test Fail!\n"); } usleep(10000); return 0; }
从Console中可以看出先写后读的数据都是对的,为进一步验证读写是否正确,使用DE2_70_Control_Panel_V1.3.0(其他Control_Panel的版本V1.2和V1.4都不能下载使用,后来在网上找到V1.3的,发现可以下载,但有时候V1.3也不能下载到板子中去,我就把Control_Panel删掉,再重新解压Control_Panel,再下载就可以啦,不知道这个问题的原因是什么,你若知道要告诉我哈!)。读出SSRAM中的数据,如下图示:
将读写长度改为640*480,写入数据都为0x20120801程序如下:
ssram = (alt_u32 *)SSRAM_BASE; for(i=0; i<640*480; i++) { *ssram++ = 0x20120801; if(i % 50000 == 0) printf("."); } ssram = (alt_u32 *)SSRAM_BASE; printf("Verifing Now\n"); for(i=0; i<640*480; i++) { if(*ssram++ != 0x20120801) break; if(i % 50000 == 0) printf("."); } if(i == 640*480) printf("\nSSRAM is OK!\n"); else printf("\nSSRAM Test Fail!\n");
运行结果如下:
Control_Panel读出结果如下:
其实这里还有一个问题就是我明明只写入了640*480=307200个32-bit的数据,共是307200*4=1228800个字节,但UE显示整个芯片(每次用Control_Panel读出Entire memory)都被写入了数据0x20120801,不知原因何在?求高手指点!
640*480=307200 (32-bit)
2097152/4=524288(32-bit)
307200*4=1228800
1228800-1=1228799=12BFFF
https://files.cnblogs.com/hubu9527/NIOS_SSRAM.7z