##環境
- Terasic DE0-Nano
- Quartus Prime 18.1 Lite Edition
奮発して「FPGAボードで学ぶ組込みシステム開発入門[Intel FPGA編]」を購入した。
本書はDE1-SoCとDE10-Liteを対象にしており、DE0-Nanoは対象にしてないが、
そこは適当に読み解きながら試す。
第8章 1節 外部SDRAMの制御
表8-3
DE1-SoCのSDRAMは64M、当方のDE0-Nanoは32MBであるため、Address Width Columを10→9に変更する。
リスト8-1
最上位層のsdram.vを変更した。おそらく本書はリセットどこかのピンにつないでるらしいが、ピンアサインは記載が無いので、DE0-NanoのMy_First_NiosII_Qsys.pdfを参考にした。
.reset_reset_n (~RST),
.reset_reset_n (1'b1),
本書にある、SDRAMの全領域にBYTE,SHORT,INTを順次書き込むテストプログラムを走らせると、たまにNGになる。
調査のため、コードを変更して以下のとおりにする。
#include "sys/alt_stdio.h"
#include "sys/alt_cache.h"
#include "system.h"
#define SDRAM_C ((volatile unsigned char *) NEW_SDRAM_CONTROLLER_0_BASE)
#define SDRAM_S ((volatile unsigned short *) NEW_SDRAM_CONTROLLER_0_BASE)
#define SDRAM_I ((volatile unsigned int *) NEW_SDRAM_CONTROLLER_0_BASE)
#define MEMSIZE 0x02000000
int main()
{
int i, err=0;
unsigned int i1, i2, i3;
unsigned int ary[3];
// SDRAMに書き込む値
ary[0] = 0x47bd9f6a;
ary[1] = 0x1e806c95;
ary[2] = 0x2fdc3a5c;
for ( int j=0; j<16; j++ ) {
//BYTE書き込み
alt_printf("%x",j);
alt_printf(" BYTE Checking...");
for ( i=0; i<MEMSIZE-3; i=i+3 ){
SDRAM_C[i] = ary[0];
SDRAM_C[i+1] = ary[1];
SDRAM_C[i+2] = ary[2];
}
alt_dcache_flush_all();
//BYTE読み出し
for ( i=0; i<MEMSIZE-3; i=i+3 ){
i1 = SDRAM_C[i];
i2 = SDRAM_C[i+1];
i3 = SDRAM_C[i+2];
if( i1 != (ary[0] & 0xff ) ){
err=1;
alt_printf("\nExpected i1:");
alt_printf("%x",ary[0]& 0xff);
alt_printf(" Read Val:");
alt_printf("%x",i1);
alt_printf(" at ");
alt_printf("%x",i);
alt_printf("\n");
}
if( i2 != (ary[1] & 0xff ) ){
err=1;
alt_printf("\nExpected i2:");
alt_printf("%x",ary[1] & 0xff);
alt_printf(" Read Val:");
alt_printf("%x",i2);
alt_printf(" at ");
alt_printf("%x",i+1);
alt_printf("\n");
}
if( i3 != (ary[2] & 0xff ) ){
err=1;
alt_printf("\nExpected i3:");
alt_printf("%x",ary[2] & 0xff);
alt_printf(" Read Val:");
alt_printf("%x",i3);
alt_printf(" at ");
alt_printf("%x",i+2);
alt_printf("\n");
}
}
if ( err==1 )
alt_printf("NG!!!\n");
else
alt_printf("OK.\n");
err=0;
//SHORT書き込み
alt_printf("%x",j);
alt_printf(" SHORT Checking...");
for ( i=0; i<MEMSIZE/2-3; i=i+3 ){
SDRAM_S[i] = ary[0];
SDRAM_S[i+1] = ary[1];
SDRAM_S[i+2] = ary[2];
}
alt_dcache_flush_all();
//SHORT読み出し
for ( i=0; i<MEMSIZE/2-3; i=i+3 ){
i1 = SDRAM_S[i];
i2 = SDRAM_S[i+1];
i3 = SDRAM_S[i+2];
if( i1 != (ary[0] & 0xffff ) ) {
err=1;
alt_printf("\nExpected i1:");
alt_printf("%x",ary[0] & 0xffff);
alt_printf(" Read Val:");
alt_printf("%x",i1);
alt_printf(" at ");
alt_printf("%x",i);
alt_printf("\n");
}
if( i2 != (ary[1] & 0xffff ) ) {
err=1;
alt_printf("\nExpected i2:");
alt_printf("%x",ary[1] & 0xffff);
alt_printf(" Read Val:");
alt_printf("%x",i2);
alt_printf(" at ");
alt_printf("%x",i+1);
alt_printf("\n");
}
if( i3 != (ary[2] & 0xffff ) ) {
err=1;
alt_printf("\nExpected i3:");
alt_printf("%x",ary[2] & 0xffff);
alt_printf(" Read Val:");
alt_printf("%x",i3);
alt_printf(" at ");
alt_printf("%x",i+2);
alt_printf("\n");
}
}
if ( err==1 )
alt_printf("NG!!!\n");
else
alt_printf("OK.\n");
err=0;
//INT書き込み
alt_printf("%x",j);
alt_printf(" INT Checking...");
for ( i=0; i<MEMSIZE/4-3; i=i+3 ){
SDRAM_I[i] = ary[0];
SDRAM_I[i+1] = ary[1];
SDRAM_I[i+2] = ary[2];
}
alt_dcache_flush_all();
//INT読み出し
for ( i=0; i<MEMSIZE/4-3; i=i+3 ){
i1 = SDRAM_I[i];
i2 = SDRAM_I[i+1];
i3 = SDRAM_I[i+2];
if( i1 != ary[0] ) {
err=1;
alt_printf("Expected i1:");
alt_printf("%x",ary[0]);
alt_printf(" Read Val:");
alt_printf("%x",i1);
alt_printf(" at ");
alt_printf("%x",i);
alt_printf("\n");
}
if( i2 != ary[1] ) {
err=1;
alt_printf("Expected i2:");
alt_printf("%x",ary[1]);
alt_printf(" Read Val:");
alt_printf("%x",i2);
alt_printf(" at ");
alt_printf("%x",i+1);
alt_printf("\n");
}
if( i3 != ary[2] ) {
err=1;
alt_printf("Expected i3:");
alt_printf("%x",ary[2]);
alt_printf(" Read Val:");
alt_printf("%x",i3);
alt_printf(" at ");
alt_printf("%x",i+2);
alt_printf("\n");
}
}
if ( err==1 )
alt_printf("NG!!!\n");
else
alt_printf("OK.\n");
err=0;
}
return 0;
}
結果は以下の通り。
0 BYTE Checking...OK.
0 SHORT Checking...OK.
0 INT Checking...OK.
1 BYTE Checking...OK.
1 SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 2a35e5
Expected i3:3a5c Read Val:5c95 at 2a35e7
Expected i1:9f6a Read Val:3a5c at 34bc15
Expected i3:3a5c Read Val:5c95 at 34bc17
NG!!!
1 INT Checking...OK.
2 BYTE Checking...OK.
2 SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 159465
Expected i3:3a5c Read Val:5c95 at 159467
NG!!!
2 INT Checking...OK.
3 BYTE Checking...OK.
3 SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 6c7515
Expected i3:3a5c Read Val:5c95 at 6c7517
NG!!!
3 INT Checking...OK.
4 BYTE Checking...OK.
4 SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 4b5c25
Expected i3:3a5c Read Val:5c95 at 4b5c27
Expected i2:6c95 Read Val:3a5c at fffecb
Expected i3:3a5c Read Val:5c95 at fffecf
NG!!!
4 INT Checking...OK.
5 BYTE Checking...OK.
5 SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 31e885
Expected i3:3a5c Read Val:5c95 at 31e887
NG!!!
5 INT Checking...OK.
6 BYTE Checking...OK.
6 SHORT Checking...OK.
6 INT Checking...OK.
7 BYTE Checking...OK.
7 SHORT Checking...
Expected i2:6c95 Read Val:3a5c at fffdab
Expected i3:3a5c Read Val:5c95 at fffdaf
NG!!!
7 INT Checking...OK.
8 BYTE Checking...OK.
8 SHORT Checking...OK.
8 INT Checking...OK.
9 BYTE Checking...OK.
9 SHORT Checking...OK.
9 INT Checking...OK.
a BYTE Checking...OK.
a SHORT Checking...
Expected i2:6c95 Read Val:3a5c at fffecb
Expected i3:3a5c Read Val:5c95 at fffecf
NG!!!
a INT Checking...OK.
b BYTE Checking...OK.
b SHORT Checking...OK.
b INT Checking...OK.
c BYTE Checking...OK.
c SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 79f0f5
Expected i3:3a5c Read Val:5c95 at 79f0f7
Expected i2:6c95 Read Val:3a5c at fffdab
Expected i3:3a5c Read Val:5c95 at fffdaf
NG!!!
c INT Checking...OK.
d BYTE Checking...OK.
d SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 165
Expected i3:3a5c Read Val:5c95 at 167
Expected i1:9f6a Read Val:3a5c at 249465
Expected i3:3a5c Read Val:5c95 at 249467
NG!!!
d INT Checking...OK.
e BYTE Checking...OK.
e SHORT Checking...
Expected i1:9f6a Read Val:3a5c at 37425
Expected i3:3a5c Read Val:5c95 at 37427
NG!!!
e INT Checking...OK.
f BYTE Checking...OK.
f SHORT Checking...OK.
f INT Checking...OK.
SHORTのとき異常が出ている。なんでだろ~
(2019.6.26追記)
解決した。pll出力をSYSCLKとSDRAMクロックに与えているが、SDRAMクロックの位相差を付けてなかったため、
アドレスが変化する前に書き込み、またはDQが変化する前に読みこみしていたよう。
DE0-Nanoサンプルプログラムにある通り、SDRAMクロックを-60degとした。