
FPGAボードであるTerasic社のDE0-Nanoを使っていろいろ遊んでいますが、今回はNiosからSDRAMへのリードとライトに挑戦してみました。
DE0-Nanoには、ISSI社の256-MBIT SYNCHRONOUS DRAMであるIS42S16160Bが実装されています。
SDRAMコントローラのIPを使って、NiosからこのSDRAMにリードとライトをしてみたいと思います。
今回はハードウェア編で、QuartusのPlatform Designerを使ったIPの実装から、FPGAへの書き込みまでを記事にしておきます。
なお、SDRAMコントローラの設定は、Terasic社のサンプルプロジェクト(DE0_NANO_SDRAM_Nios_Test)をコピーしています。
【改訂2版】FPGAボードで学ぶ 組込みシステム開発入門[Intel FPGA編] 新品価格 | ![]() |

Platform Designerを使ってIPを追加
IPの追加
Quartusでプロジェクトを作成したら、Platform Designerを起動します。
起動したら、まずは下記のIPを追加します。
- Nios II Processor
- On-Chip Memory (RAM or ROM) Intel FPGA IP
- JTAG UART Intel FPGA IP
Platform Designerの起動からIPの追加までは、下記の記事を参考にしてください。
上の3つのIPは基本的な機能です。
次にSDRAMを制御するIPを追加します。
追加するIPは以下の2つです。
- ALTPLL Intel FPGA IP
- SDRAM Controller Intel FPGA IP
ALTPLL Intel FPGA IPは、PLLです。DE0-Nanoに実装されたFPGAには4つのPLLが内蔵されています。
そのPLLを使って、FPGAからSDRAMに供給するクロックを生成します。
SDRAM Controller Intel FPGA IPは、SDRAMをコントロールするためのIPです。

すべてのIPの追加が終わると、上の図のようになると思います。(IPの名前はわかりやすい名前に変更しています)
追加が終わったら、IPの設定をしていきます。
IPの設定
clk_0の設定
clk_0は最初から追加されていたと思います。
意味はよく理解できていませんが、下図のように赤枠内が太字になっているか確認しておきます。

DE0-Nanoに実装されている発振器の周波数は50MHzなので、Clock frequencyには”50000000″と入力しておきます。

nios2_cpuの設定
nios2_cpuの設定は、”Vectors”タブを選択し、”Reset vector memory”と”Exception vector memory”をFPGA内蔵メモリである”onchip_memory.s1″を選択しました。
ここでSDRAMを設定することもできますが、今回はFPGA内蔵メモリを選択しました。

onchip_memoryの設定
FPGA内蔵のonchip_memoryのサイズは、40960bytesにしました。
これはソフトウェア作成中にメモリ不足のエラーが出たので、メモリサイズを増やしていった結果、この値になりました。

jtag_uartの設定
ここの設定は何も変更しなかったと思います。デフォルト値のままで、以下の設定です。

SDRAMコントローラの設定
ここはTerasic社のサンプルプロジェクトをコピーして、以下の設定にしました。

altpllの設定
ここもTerasic社のサンプルプロジェクトをコピーです。
なぜ?という設定が多々ありましたが、とりあえずコピーしました。
1 of 11
“What is the frequency of the inclk0 input?”を50MHzに設定します。
その他の設定も確認し、”Next”をクリックします。

2 of 11
設定を確認し”Next”をクリックします。
Create ‘locked’ outputにチェックが入っていますが、ここはチェック無しで大丈夫かも???PLLがロックしたときに出力される信号だと思うのですが、この信号は使わなかったので。

3 of 11
設定を確認し”Next”をクリックします。

4 of 11
設定を確認し”Next”をクリックします。

5 of 11
設定を確認し”Next”をクリックします。

6 of 11
赤枠内を設定します。

赤枠内を設定後、青枠内の数値は、以下のValue(before)ようになっているかもしれません。
なぜかはわかりませんが、、、次の”7 of 11″の設定後には、Value(after)に変わっていました。
Description | Value(before) | Value(after) |
Primary clock VCO frequency (MHz) | 600.000 | 600.000 |
Modulus for M counter | 12 | 12 |
Modulus for N counter | 1 | 1 |
Initial VCO phase cycles for M counter | 1 | 2 |
VCO phase tap for M counter | 0 | 0 |
VCO post scale K counter | 2 | 2 |
c0 settings: | ||
Post-scale counter | 6 | 6 |
Initial VCO phase cycles | 1 | 2 |
VCO phase tap | 0 | 0 |
High period count | 3 | 3 |
Low period count | 3 | 3 |
Mode | Even | Even |
7 of 11
赤枠内を設定します。
緑枠内のClock phase shiftを-60に設定することを忘れずに。Terasic社のサンプルプロジェクトをコピーしているので-60とわかりましたが、サンプルプロジェクトがなかったら私には絶対にわからない設定でした。

青枠内の数値は以下のようになっていると思います。
Description | Value(before) |
Primary clock VCO frequency (MHz) | 600.000 |
Modulus for M counter | 12 |
Modulus for N counter | 1 |
Initial VCO phase cycles for M counter | 2 |
VCO phase tap for M counter | 0 |
VCO post scale K counter | 2 |
c1 settings: | |
Post-scale counter | 6 |
Initial VCO phase cycles | 1 |
VCO phase tap | 0 |
High period count | 3 |
Low period count | 3 |
Mode | Even |
8 of 11
未使用なので設定項目はありません。

9 of 11
未使用なので設定項目はありません。

10 of 11
未使用なので設定項目はありません。

11 of 11
“Finish”をクリックして終了です。

PLLの数の謎
DE0-NanoにはCyclone IV E EP4CE22というFPGAが実装されていて、内蔵されているPLLの数は4つです。
しかし、altpllの設定ではc0からc4までの5つ(6 of 11から10 of 11まで)の設定をしました。
なぜ、c0からc4までの5つだったのでしょうか???謎です。
ConnectionsとExportの設定
ちょっと複雑な結線ですが、頑張って以下の画像のように結線します。
Exportの設定も忘れずに。

Terasic社のサンプルプロジェクトを参考にして上記の結線にしました。Terasic社のサンプルプロジェクトとは追加しているIPが異なるので、ここの結線もTerasic社のサンプルプロジェクトとは異なっています。
参考記事 第2回 Nios IIで遊ぼう Quartus Platform Designer編
HDLの生成
Platform Designerの設定が終わったら保存します。拡張子が.qsysで保存されると思います。
次にメニュー System -> Assign Base Addressesを選択します。
メッセージウインドウにエラーがなければ、Generate HDLをクリックします。

そして、ここで気になるメッセージが。(点線の赤枠)
SDRAM Controller will only be supported in Quartus Prime Standard Edition in the future release.
将来的に、SDRAM Controllerは有償のStandard Editionのみサポートで、無償のLite Editionでは使えなくなってしまうかもしれませんね。
話は元に戻って、”Generate HDL”をクリックすると、xxx_inst.vhdというファイルが生成されます(Generate HDLでVHDLを選択した場合)
xxxはPlatform Designerの保存時の名前です。
生成されたVHDLのファイルの中身です。
component sdram_qsys is port ( altpll_areset_conduit_export : in std_logic := 'X'; -- export altpll_locked_conduit_export : out std_logic; -- export altpll_sdram_clk : out std_logic; -- clk clk_clk : in std_logic := 'X'; -- clk reset_reset_n : in std_logic := 'X'; -- reset_n sdram_wire_addr : out std_logic_vector(12 downto 0); -- addr sdram_wire_ba : out std_logic_vector(1 downto 0); -- ba sdram_wire_cas_n : out std_logic; -- cas_n sdram_wire_cke : out std_logic; -- cke sdram_wire_cs_n : out std_logic; -- cs_n sdram_wire_dq : inout std_logic_vector(15 downto 0) := (others => 'X'); -- dq sdram_wire_dqm : out std_logic_vector(1 downto 0); -- dqm sdram_wire_ras_n : out std_logic; -- ras_n sdram_wire_we_n : out std_logic -- we_n ); end component sdram_qsys; u0 : component sdram_qsys port map ( altpll_areset_conduit_export => CONNECTED_TO_altpll_areset_conduit_export, -- altpll_areset_conduit.export altpll_locked_conduit_export => CONNECTED_TO_altpll_locked_conduit_export, -- altpll_locked_conduit.export altpll_sdram_clk => CONNECTED_TO_altpll_sdram_clk, -- altpll_sdram.clk clk_clk => CONNECTED_TO_clk_clk, -- clk.clk reset_reset_n => CONNECTED_TO_reset_reset_n, -- reset.reset_n sdram_wire_addr => CONNECTED_TO_sdram_wire_addr, -- sdram_wire.addr sdram_wire_ba => CONNECTED_TO_sdram_wire_ba, -- .ba sdram_wire_cas_n => CONNECTED_TO_sdram_wire_cas_n, -- .cas_n sdram_wire_cke => CONNECTED_TO_sdram_wire_cke, -- .cke sdram_wire_cs_n => CONNECTED_TO_sdram_wire_cs_n, -- .cs_n sdram_wire_dq => CONNECTED_TO_sdram_wire_dq, -- .dq sdram_wire_dqm => CONNECTED_TO_sdram_wire_dqm, -- .dqm sdram_wire_ras_n => CONNECTED_TO_sdram_wire_ras_n, -- .ras_n sdram_wire_we_n => CONNECTED_TO_sdram_wire_we_n -- .we_n );
参考記事 第2回 Nios IIで遊ぼう Quartus Platform Designer編
QuartusでSDRAMコントローラを作成
まずは生成したxxx_inst.vhdを使って、SDRAMコントローラをVHDLで作成します。
作成したVHDLがこちら。
library ieee; use ieee.std_logic_1164.all; entity nios_sdram is port( CLK50M : in std_logic; A_RST : in std_logic; CLK_RST : in std_logic; PLL_LOCK : out std_logic; DRAM_CLK : OUT STD_LOGIC; DRAM_CKE : OUT STD_LOGIC; DRAM_ADDR : OUT STD_LOGIC_VECTOR(12 DOWNTO 0); DRAM_BA : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); DRAM_CS_N : OUT STD_LOGIC; DRAM_CAS_N : OUT STD_LOGIC; DRAM_RAS_N : OUT STD_LOGIC; DRAM_WE_N : OUT STD_LOGIC; DRAM_DQ : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0); DRAM_DQM : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ); end nios_sdram; architecture rtl of nios_sdram is component sdram_qsys is port ( altpll_areset_conduit_export : in std_logic := 'X'; -- export altpll_locked_conduit_export : out std_logic; -- export altpll_sdram_clk : out std_logic; -- clk clk_clk : in std_logic := 'X'; -- clk reset_reset_n : in std_logic := 'X'; -- reset_n sdram_wire_addr : out std_logic_vector(12 downto 0); -- addr sdram_wire_ba : out std_logic_vector(1 downto 0); -- ba sdram_wire_cas_n : out std_logic; -- cas_n sdram_wire_cke : out std_logic; -- cke sdram_wire_cs_n : out std_logic; -- cs_n sdram_wire_dq : inout std_logic_vector(15 downto 0) := (others => 'X'); -- dq sdram_wire_dqm : out std_logic_vector(1 downto 0); -- dqm sdram_wire_ras_n : out std_logic; -- ras_n sdram_wire_we_n : out std_logic -- we_n ); end component sdram_qsys; begin u0 : component sdram_qsys port map ( altpll_areset_conduit_export => A_RST, -- altpll_areset_conduit.export altpll_locked_conduit_export => PLL_LOCK, -- altpll_locked_conduit.export altpll_sdram_clk => DRAM_CLK, -- altpll_sdram.clk clk_clk => CLK50M, -- clk.clk reset_reset_n => CLK_RST, -- reset.reset_n sdram_wire_addr => DRAM_ADDR, -- sdram_wire.addr sdram_wire_ba => DRAM_BA, -- .ba sdram_wire_cas_n => DRAM_CAS_N, -- .cas_n sdram_wire_cke => DRAM_CKE, -- .cke sdram_wire_cs_n => DRAM_CS_N, -- .cs_n sdram_wire_dq => DRAM_DQ, -- .dq sdram_wire_dqm => DRAM_DQM, -- .dqm sdram_wire_ras_n => DRAM_RAS_N, -- .ras_n sdram_wire_we_n => DRAM_WE_N -- .we_n ); end rtl;
VHDLの作成が終わったら、メニュー File -> Create / Update -> Create Symbol Files for Current Fileを選択して、回路図で使えるようにシンボルを作成します。
別にシンボルは作成しなくても良いのですが、プロジェクトのトップは回路図にするのが好きなので、私はシンボル化しておきました。
作成したプロジェクト階層トップの回路図です。ピン番号も割付け済です。

参考記事 第2回 Nios IIで遊ぼう Quartus Platform Designer編
参考記事 FPGAボードDE0-Nanoを使ってみる:ピン割付けからRAMへの書き込みまで
参考記事 Quartusを使って、回路図とHDLの混在でFPGAを設計する
FPGAチャレンジャー入門編:ALTERA-Cyclone-IV版 キット CD (キットで学ぶ! シリーズ) 新品価格 | ![]() |

FPGAスタータ・キットで初体験!オリジナル・マイコン作り?フリーのCPUコアNios 2/eと高速ロジックで七変化 (トライアルシリーズ) 新品価格 | ![]() |

コンパイル
ここまできたらコンパイルしますが、Platform Designerで作成したqsysをプロジェクトに追加することを忘れずに。
プロジェクトへの追加は、メニューProject -> Add/Remove Files in Projectを選択します。
すると、以下のウインドウが開きます。

Platform Designerで作成したqsysファイル、プロジェクト階層トップの回路図ファイル、SDRAMコントローラのVHDLファイルの3つが入っています。
これでコンパイル実行です。
エラーがでなければ、FPGAに書き込みを行います。
参考記事 Quartus入門
参考記事 FPGAボードDE0-Nanoを使ってみる:ピン割付けからRAMへの書き込みまで
まとめ
Terasic社のサンプルプロジェクトをコピーさせていただきましたが、けっこうな作業量でした。
EclipseでSDRAMにリード・ライトするniosのプログラムは以下の記事をご参照ください。Terasic社のツールを使った検証もしています。
