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系统

clip_image002

为Nios系统命名NIOS_CPU,单击OK

clip_image004

修改系统输入时钟,我们这里用100MHz时钟输入

clip_image006

然后依次添加cpu(/s),on-chip memory(40KB),jtag uart,这里不赘述这些IP的设置了

clip_image008

下面要加入ssram的IP啦,再加入ssram之前要先加入三态桥(在NIOS系统中,要实现与FPGA片外存储器通信,就必须在Avalon总线和连接外部总线之间添加Avalon三态桥)

clip_image010

再加入ssram,DE2_70上的SSRAM(IS61LPS51236A)和这里的IP(CY7C1380C)容量相同,都是512K*36

clip_image012

重命名ssram和三态桥,并将ssram与三态桥连接

clip_image014

进行复位和异常地址设置

clip_image016

自动分配基地址后,我们这里No errors or warning,可以Generate啦

clip_image018

Generate成功之后,回到Quartus II新建顶层Verilog,来例化NIOS_CPU,因为CPU系统的时钟设为100MHz,所以我们还需要定制一个PLL来产生一个100MHz的时钟

PLL_c0作为系统时钟,PLL_c1作为SSRAM芯片的工作时钟,需要与系统时钟偏移一定角度(这里借鉴无双的设置)

clip_image020

clip_image022

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:

clip_image024

硬体部分设置完成,然后启动Nios IDE,进行软体设计,首先新建NIOS工程:

clip_image026

工程新建好后,先对工程属性进行设置:

clip_image028

预先将工程编译一遍(第一次编译会有点慢),然后打开system.h这个头文件(如下图),它包含了SOPC中IP对应硬件配置信息,下面的C程序设计中我们将用到其中的SSRAM_BASE(SSRAM的基地址)

clip_image030

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;

}

clip_image032

从Console中可以看出先写后读的数据都是对的,为进一步验证读写是否正确,使用DE2_70_Control_Panel_V1.3.0(其他Control_Panel的版本V1.2和V1.4都不能下载使用,后来在网上找到V1.3的,发现可以下载,但有时候V1.3也不能下载到板子中去,我就把Control_Panel删掉,再重新解压Control_Panel,再下载就可以啦,不知道这个问题的原因是什么,你若知道要告诉我哈!)。读出SSRAM中的数据,如下图示:

clip_image034

clip_image036

将读写长度改为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");

运行结果如下:

clip_image038

Control_Panel读出结果如下:

clip_image040

其实这里还有一个问题就是我明明只写入了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

 

posted @ 2012-08-01 20:36  hubu9527  Views(888)  Comments(0Edit  收藏  举报