CoreGeneratorでMCBラッパを作るとサンプルデザインがついてきます。
今回は、特電Spartan-6ボードを使ってこのサンプルデザインを動かしてみます。
まず、ISEでプロジェクトを作成したらCoreGeneratorを起動し、New Source Wizardを起動し、MIGを選択します。コンポーネントの名前は mymcb にしておきます。
MIGの設定の最初の画面です。

次のダイアログでは、Create Designを選びます。

次のダイアログでは、Bank1をDDR2 SDRAMに設定します。特電Spartan-6ボードではBank1にSDRAMが接続されています。これ以降、MIGでは"C1"という名前で呼ばれます。

次のダイアログではDDR2メモリの型番を選択しますが、HYB512800はないので、Create Custum Partを選択して作ります。

Create Custom Partのダイアログでは、元となる部品として「MT47H128M8XX-25」を選びます。それから、Row Address、Column Address、Bank Addressを14,10,2に変更します。
Saveを押すと元の画面に戻るので、Nextを押して次のダイアログへ行きます。
次のダイアログでは特に変更するところはないので、そのままNextを押します。

その次のダイアログでは、MCBの6つあるユーザ側ポートを入力にするか出力にするか、バンクアドレスの配置はどうするか、などを決定します。とりあえずはデフォルトでよいでしょう。

その次のダイアログでは、ポートのアービトレーション(調停)のアルゴリズムを決めます。デフォルトでよいでしょう。

その次のダイアログでは、物理層的な部分の設定を行います。System ClockをSingle-Endedに変更します。

次のダイアログは、できあがったデザインのパラメータの確認です。

次のダイアログでは、Acceptを押してNextを押します。

これでCoreGenでの設定は終わりです。
元のプロジェクトマネージャに戻ってみると、mymcbがプロジェクトに追加されています。
いきなりですが、mymcbをプロジェクトから外します。

そして、Add Sourceを行います。

そして、(プロジェクトのフォルダ)\ipcore_dir\mymcb\example_design\rtlにあるファイル一式をプロジェクトに追加します。traffic_genフォルダの中のファイル一式も追加します。

追加した中のpipeline_inserterを削除します。

次にexample_topを編集しますが、example_topをそのまま編集するのではなくプロジェクトのディレクトリのトップにコピーを作成して、そのコピーを編集します。新しい名前はmcbselftest.vhdにしておきます。
まず、entityの名前をMCBSelfTestに変更します。そして、ポートの定義を変更し、errorやcarib_doneなどの信号を削除し、xtalclk_ip、pushsw_ip、led_op、HDR_A_BPを追加します。
port
(
mcb1_dram_dq : inout std_logic_vector(C1_NUM_DQ_PINS-1 downto 0);
mcb1_dram_a : out std_logic_vector(C1_MEM_ADDR_WIDTH-1 downto 0);
mcb1_dram_ba : out std_logic_vector(C1_MEM_BANKADDR_WIDTH-1 downto 0);
mcb1_dram_ras_n : out std_logic;
mcb1_dram_cas_n : out std_logic;
mcb1_dram_we_n : out std_logic;
mcb1_dram_odt : out std_logic;
mcb1_dram_cke : out std_logic;
mcb1_dram_dm : out std_logic;
mcb1_rzq : inout std_logic;
mcb1_zio : inout std_logic;
mcb1_dram_dqs : inout std_logic;
mcb1_dram_dqs_n : inout std_logic;
mcb1_dram_ck : out std_logic;
mcb1_dram_ck_n : out std_logic;
xtalclk_ip : in std_logic;
pushsw_ip : in std_logic;
HDR_A_BP : out std_logic_vector(0 downto 0);
led_op : out std_logic_vector(7 downto 0)
);
end MCBSelfTest;
それから、PLLの逓倍率や分周比を設定します。以下の設定では50MHzのクロックを8倍して400MHzを作ってそれをデータ速度にします(DDR2のクロックは200MHzになる)。ユーザクロックにはそれを8分周した50MHzが使われます。
mcbselftest.vhdの中にある該当箇所を次のように変更します。
constant C1_CLKOUT0_DIVIDE : integer := 1;
constant C1_CLKOUT1_DIVIDE : integer := 1;
constant C1_CLKOUT2_DIVIDE : integer := 8;
constant C1_CLKOUT3_DIVIDE : integer := 8;
constant C1_CLKFBOUT_MULT : integer := 8;
constant C1_DIVCLK_DIVIDE : integer := 1;
それから、ArchitectureのBegin以降を次のように変更します。
c1_sys_clk_p <= '0';
c1_sys_clk_n <= '0';
led_op <= "00000" & c1_error & c1_calib_done & pushsw_ip;
inst_clkbuf : ODDR2 port map (
Q => HDR_A_BP(0),
C0 => c1_clk0,
C1 => not c1_clk0,
CE => '1',
D0 => '0',
D1 => '1',
R => '0',
S => '0'
);
memc1_infrastructure_inst : memc1_infrastructure
generic map
(
C_MEMCLK_PERIOD => 20000, -- 20ns
C_RST_ACT_LOW => C1_RST_ACT_LOW,
C_INPUT_CLK_TYPE => C1_INPUT_CLK_TYPE,
C_CLKOUT0_DIVIDE => C1_CLKOUT0_DIVIDE,
C_CLKOUT1_DIVIDE => C1_CLKOUT1_DIVIDE,
C_CLKOUT2_DIVIDE => C1_CLKOUT2_DIVIDE,
C_CLKOUT3_DIVIDE => C1_CLKOUT3_DIVIDE,
C_CLKFBOUT_MULT => C1_CLKFBOUT_MULT,
C_DIVCLK_DIVIDE => C1_DIVCLK_DIVIDE
)
port map
(
sys_clk_p => c1_sys_clk_p,
sys_clk_n => c1_sys_clk_n,
sys_clk => xtalclk_ip,
sys_rst_n => pushsw_ip,
clk0 => c1_clk0,
・・・
次に、UCFファイルを作成します。
オリジナルのUCFファイルは
(プロジェクトのフォルダ)\ipcore_dir\mymcb\example_design\par\example_top.ucf
にあるので、これをプロジェクトのトップにコピーして、mcbselftest.ucfに変更します。
まず、クロック速度を50MHzと宣言します。
##################################################
## Clock constraints
##################################################
NET "memc1_infrastructure_inst/sys_clk_ibufg" TNM_NET = "SYS_CLK1";
TIMESPEC "TS_SYS_CLK1" = PERIOD "SYS_CLK1" 20 ns HIGH 50 %;
##################################################
特電ボード用に追加したポートのピン配置を設定します。
NET "xtalclk_ip" LOC = "D11" | IOSTANDARD = LVCMOS33;
NET "pushsw_ip" LOC = "D6" | IOSTANDARD = LVCMOS33;
NET "led_op<0>" LOC = "F13" | IOSTANDARD = LVCMOS33;
NET "led_op<1>" LOC = "C11" | IOSTANDARD = LVCMOS33;
NET "led_op<2>" LOC = "C9" | IOSTANDARD = LVCMOS33;
NET "led_op<3>" LOC = "A9" | IOSTANDARD = LVCMOS33;
NET "led_op<4>" LOC = "B9" | IOSTANDARD = LVCMOS33;
NET "led_op<5>" LOC = "A8" | IOSTANDARD = LVCMOS33;
NET "led_op<6>" LOC = "B8" | IOSTANDARD = LVCMOS33;
NET "led_op<7>" LOC = "A7" | IOSTANDARD = LVCMOS33;
NET "HDR_A_BP<0>" LOC = "C6" | IOSTANDARD = LVCMOS33;
それから、キャリブレーション用のピン配置を変更します。
NET "mcb1_rzq" LOC = "U17" ;
NET "mcb1_zio" LOC = "U18" ;
UCFファイルができたら、プロジェクトに追加します。
こうしてできあがったプロジェクトは次のようになります。

論理合成する際に、Configuration Optionsで、Unused IOB PinsをPull Upに変更するのを忘れずに行います。これを忘れると、特電Spartan-6ボードのUSB-JTAGが認識されなくなってしまいます。

論理合成が通ったら、mcbselftest.bit を書き込みます。
書き込みと同時にセルフテストのデザインが走ります。静かに動いていますが、ずっとテストが行われています。
青いボタンを押すとMCBのコントローラにリセットがかかります。
LEDは
・D0 リセット中
・D1 キャリブレーション完了
・D2 エラーあり
で点灯します。正常時はD1のみ点灯です。
どういうテストが行われているのかはよくわかりませんが、終端抵抗をショートさせてみたりすると、エラーが発生し、D2が点灯するので、何かの読み書き比較を行っているのでしょう。
MITOUJTAGを使っている場合は、ピン配置定義ファイルとしてMCBSelfTest.padを読み込むと、

FPGAの各ピンの入出力状態が固定され、バウンダリスキャンで見えるようになります。

端子の状態をみてみると、MCBのセルフテストが動いている間は、忙しくDDR2 SDRAMへの端子が動いているのがわかります。

ロジアナモードで見てみると、MCBのリセット中は停止していて、ZIO、RZQともにL出力。リセット開放と同時にZIO、RZQは入力に変わり、DRAMの各端子が動き出すのが見えます。

I/O端子の波形を見る限り、A13~A10、A1、A0、BA1は動いていないようでした。

今回はCoreGeneratorに付いてくるサンプルデザインをコンパイルし、セルフテストを走らせてみました。
次はユーザ・デザインを作ってみようと思います。
最近のコメント