FC2カウンター FPGAの部屋 soc-lm32のその後3
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

soc-lm32のその後3

”soc-lm32のその後2”でLatticeMico32プロセッサのコンパイラの準備ができたので、DDRに4つWriteしてから、4つReadするようにCプログラムを書き換えて、シミュレーションしてみた。(元のブートローダ・プログラムはすべてのDDR SDRAMにWriteしてから、すべてReadしていた)
そうすると、自分で書いたWishBoneバスのインターフェースがおかしくて、wb_ack_oが出力されていなかった。これを修正して、WishBoneバスのプロトコルとしては正常になったが、今度はデータが1クロック遅れている。
何でと思ったら、非同期FIFOがFWFTモードでなかったのが原因だった。Coregenをあげて、もう一度見てみると、分散RAMの非同期FIFOはFWFTモードが選べなかった。
以前、”Virtex4のFIFO(FWFTモード)”でやってみた時は、Fifo Generator 2.3 のSpartan3で、BlockRAMと分散RAMのFWFTモードのFIFOをジェネレートできたようだ。しかし、ISE10.1iのFifo Generater 4.4 (Spartan3E) の分散RAMを使用した非同期FIFOでは、FWFTモードが選べない。
FWFTモードが選べないのはしょうがないので、データの出力イネーブルを1クロック遅らせた。
これでハード的には大丈夫なはず。。。
soc-lm32_10_081012.png

もう一度、ブートローダのmコマンド(memtest) をすべてのDDR SDRAMをテストするように戻してからインプリメントして、やってみたところ、まだMEMTEST ERROR が出てしまっている。どんな風に間違っているのかを調べるために v コマンドでDDR SDRAMのデータを見たら、0x40000000 であるはずのデータが 0x42000000 になっている。以下、同様になっていた。
soc-lm32_9_081012.png

これはおかしいと思った。もしやソフトウェアが間違っているのかも?どうも4回りしているような気がする。
soc-lm32/firmware/bootloader/spike_hw.h を見ると

#define RAM_SIZE 0x04000000


と書いてあったが、Spartan3E Starter Kit についてる DDR SDRAM (MT46V32M16P-6T) は512Mbit なので、バイトにすると 64Mbyte なので、0x04000000 であっているはず。
soc-lm32/firmware/bootloader/main.c の memtest.c 一部を下に引用する。

void memtest()
{
    volatile uint32_t *p;

    uart_putstr("\r\nMEMTEST...");

    for (p=(uint32_t *)RAM_START; p<(uint32_t *)(RAM_START+RAM_SIZE); p++) {
        *p = (uint32_t) p;  
    }



(uint32_t *)(RAM_START+RAM_SIZE)

のところで、RAM_SIZEを足した後に、uint32_t * でキャストをすると4倍になってしまうと思ったので、ここを、

(uint32_t *)(RAM_START+RAM_SIZE/(sizeof(uint32_t *)))

に変更した。

これでインプリメントして、m コマンドを入れてみたらOKとなった。v コマンドで内容を見ても、大丈夫そうだった。
soc-lm32_8_081012.png

これで、DDR SDRAMもOKとなった。。。自分で作ったDDR SDRAMコントローラIPの動作が確認できて、とてもうれしい。実際に、プロセッサのメモリとして動いているのを見ると、感慨もひとしおだ。
いよいよ、uCLinuxを勉強しながら、ダウンロードスピードを増すために、UARTのビットレートアップを図っていこうと思う。

2008/10/14:追加 くりさんのご指摘で考え直したところ、(uint32_t *)(RAM_START+RAM_SIZE) はそのままで良いという結論になりました。ということは私の作ったDDR SDRAMコントローラの最上位アドレス2ビットの扱いがおかしいということになります。もう一度、この近辺をデバックします。とりあえず、それ以外は動いているので、すぐデバックできると思います。
くりさん、ご指摘ありがとうございました。勘違いしていました。

2008/10/14:追加2 
DDR SDRAMコントローラの最上位アドレス2ビットの扱いがおかしい訳ではなく、バイトアドレスのWishBoneバスのアドレスを、RAMチップデータ幅単位(2バイト)のDDR SDRAMコントローラのアドレスにそのまま入れていたのが原因でした。
つまり、WishBoneバスのアドレスをDDR SDRAMコントローラに入れるところの非同期FIFOの入力を

async_fifo_addr async_fifo_addr_inst (
 .din({wb_r_w, wb_adr_i}),


から、これに

async_fifo_addr async_fifo_addr_inst (
 .din({wb_r_w, 1'b0, wb_adr_i[31:1]}),


に変更したところ、元のソフトウェアでOKとなりました。
お騒がせして申し訳ありません。。。
  1. 2008年10月13日 19:01 |
  2. Spartan3E Starter Kit でマイコンを作る
  3. | トラックバック:0
  4. | コメント:2

コメント

こんばんわ。
>RAM_SIZEを足した後に、uint32_t * でキャストをすると4倍になってしまうと思ったので
 うーんと、この場合、キャスト自体が4倍(=スケーリング)することはないというか、あるとすれば RAM_START+RAM_SIZE の加算時ですが、それには RAM_START が4バイトのポインタとして宣言されていることが必要です。もし、RAM_STARTも #define などで定義された単なる整数定数の場合は、計算は(RAM_START+RAM_SIZE)が整数加算として優先され、しかる後、加算値が整数型からポインタ型に変換されます。この場合、単にコンパイラが文句を言わないように、内部の宣言型が調整されるだけで、数値はそのままの値が使われることになるはずです。もしコンパイラ出力に疑問を感じた場合は、objdump等で逆アセンブルし、コードを直接確認するのが、もっとも確実な方法です。まあ、objdumpにもバグがあれば・・・ですが。
  1. 2008/10/13(月) 23:22:55 |
  2. URL |
  3. くり #mQop/nM.
  4. [ 編集 ]

くりさん、ご指摘ありがとうございました。
ブログ記事を修正しました。もう一度、DDR SDRAMコントローラをデバックします。
  1. 2008/10/14(火) 04:55:01 |
  2. URL |
  3. marsee #-
  4. [ 編集 ]

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/910-41ec7e17
この記事にトラックバックする(FC2ブログユーザー)