XC6SLX9にはブロックRAMが18kb×32個あります.これらをHDLで使用するときにはISEが持つCORE Generatorを使うと便利です.この文書では,i4002を念頭においたRAMをISE CORE Generatorで作成する方法を説明しています.


i4002の仕様

1個のi4002には4ビット幅のメモリが80個ありますので合計で320ビットの記憶容量があります.このため,作成するBlockRAMは,アドレス幅が7(80<128=27),データ幅が4となります.また,i4002にはリセット端子が備わっているのでこれもBlockRAMの機能に盛り込みます.このようなBlockRAMをCORE Generatorで作成します.


CORE Generator

ISEの一機能であるCORE Generatorを使ってBlockRAMを作成します.そのためにまずは新たなプロジェクトを作成します.i4002の作成を目指すため,プロジェクト名を「i4002」とします.下のようにISEのメニューにあるFileからNew Project...を選択してください.

i4002 01

 

次にプロジェクト名と保存先を指定します.

i4002 02

 

ターゲットデバイスとしてXC6SLX9TQG144-3,使用する言語をVerilogとなっていることを確認してください.

i4002 03

 

プロジェクトを作成する準備が整いましたらFinishボタンを押してください.

i4002 04

 

次にBlockRAMを作成するために新しいソースを作成していきます.下図のようにProjectメニューの中のNew Souce...を選択してください.

i4002 05

 

新しいソースとしてIPを選択します.IPとはIntellectual Propertyのことで,FPGAやASICに含まれる部分的な回路情報のことを指します.単にIP以外に,IPコアという言い方をする場合もあります.下のようにIPを選択し,ファイル名をBlockRAMFori4002とします.

i4002 06

 

次に,数あるIPの中からBlock Memory Generatorを選択します.Memories & Storage Elementsの中のRAMs & ROMsの中にあるものを選んでください.

i4002 07

 

新たなソースが完成しました.引き続き,BlockRAMの仕様を設定していきます.

i4002 08

 

Block Memory Generatorではメモリの種類,バス幅,アドレス幅,リセットの有無などの設定を行えます.まずはInterface TypeをデフォルトのNativeにして次に進みます.

i4002 09

 

次にメモリの種類としてSingle Port RAMを選択し,合わせてRAMのアルゴリズムを最小エリアになるようにします.

i4002 10

 

次にデータの幅とアドレスの幅を指定します.以前書いたように,今回はデータ幅4,個数を80としますので下図のようになります.

 i4002 11 2

次のダイアログでは特に行うことはありませんので次へ進んでください.

i4002 12

 

次にリセット端子に関する設定を行えるダイアログになります.しかし,ここでいうリセットとは,BlockRAMから出力されるデータが0になるというだけでメモリが本当にリセットされるわけではありません.従いましてここでは下図のようになにもチェックマークをつけずに次へ進みます.

i4002 13

 

最後に,FPGAに備わるBlockRAMの使用状況を確認します.XC6SLX9には18kbのBlockRAMが32個あり,1個のBlockRAMは9kbのBlockRAMが2個あります.今回作成したi4002のためのBlockRAMはたったの320bですので,9kb(=9000b)に余裕で収まります.従いまして,下図のようにBlockRAM resouces(s)(9K BRAMs)が1となっていることが確認できるかと思います.以上でBlockRAMの作成は終了です.

i4002 14

 


IPの使用方法

作成されたIP(BlockRAM)をVerilogから呼び出す方法について説明します.まずは下図のようにBlockRAMFori4002というIPがISE上で認識されていることを確認したうえで,ファイルを開くためのアイコンを押してください.

i4002 15

 

次に,プロジェクト内に作成されているはずのipcore_dirフォルダを開き,その中にあるBlockRamFori4002.vを選択します.このように,作成されたIPはipcore_dirフォルダにでき,加えてインタフェースとして.vファイルが同フォルダにあります.

i4002 16

 

 

.vファイルを開きますと,下図のようにBlockRamFori4002のモジュールが現れます.あとはこのモジュールにあるポート宣言にもとづき,階層設計をしていけばよいわけです.

i4002 17

 


BlockRAMのインタフェース

作成されたBlockRAMには下表の端子が備わっています.特徴的なのはデータバスの取り扱いです.SRAMのICの場合,データバスの端子はinoutになっており,入力と出力を共用にしてあります.しかしこのBlockRAMでは入力端子と出力端子を別に持っています.

信号名 通称 用途
clka 1 クロック 立ち上がりエッジで動作する.
wea 1 ライトイネーブル Lowのときには読み込み,Highのときには書き込む
addra 7 アドレス BlockRAMのアドレス
dina 4 データイン BlockRAMにデータが入力するときに使う
douta 4 データアウト BlockRAMからデータを出力するときに使う

 


動作の確認

作成したBlockRAMの動作を確認するためにテストベンチを作成するとともに,作成したIPを使用する方法を示すため,トップモジュールを作成します.まずはトップモジュールです.下図のようにISEのProjectメニューにあるNew Source...を選択します.

i4002 18

 

次にトップモジュールTopModuleを追加します.今回作成するトップモジュールは,先ほど作成したBlockRAMの動作を確認するためだけのものです.i4002の中に含まれるRAMのようにするには別のトップモジュールを作成してください.

i4002 19

 

ポート宣言は下記のとおりです.名称は異なるもののBlockRAMと同じになっています.

i4002 20

 

最後に確認するためのダイアログが現れます.

i4002 21

 

作成されたモジュールにBlockRamFori4002を接続するため,下記のように追記します.以上でトップモジュールができました.

i4002 22

 

次にテストベンチを作成します.今回は次のような動作をするテストベンチにします.

  • 番地1に数値3を記憶する
  • 番地5に数値2を記憶する
  • 番地0に数値10を記憶する
  • 番地1の値をoDoutから出力する
  • 番地0の値をoDoutから出力する
  • 番地5の値をoDoutから出力する

 以上の条件に合致するテストベンチ(t_TopModule.v)を追加・作成します.

module t_TopModule;

	// Inputs
	reg iClk;
	reg iWe;
	reg [6:0] iAddr;
	reg [3:0] iDin;

	// Outputs
	wire [3:0] oDout;

	// Instantiate the Unit Under Test (UUT)
	TopModule uut (
		.iClk(iClk), 
		.iWe(iWe), 
		.iAddr(iAddr), 
		.iDin(iDin), 
		.oDout(oDout)
	);

	initial begin

		// Initialize Inputs
		iClk = 0;
		iWe = 0;
		iAddr = 0;
		iDin = 0;

		// Wait 100 ns for global reset to finish
		#100;

		// Add stimulus here
		iWe = 1;

		iDin = 3;
		#5
		iAddr = 1;

		#25
		iDin = 2;
		#5
		iAddr = 5;

		#25
		iDin = 10;
		#5
		iAddr = 0;

		#50
		iWe = 0;
		iAddr = 1;
		#30
		iAddr = 0;
		#30
		iAddr = 5;
	end

	initial begin
		forever
			#10 iClk = ~iClk;
	end
      
endmodule

 

テストベンチができましたらISimによるシミュレーションをしましょう.下の図のようにt_TopModuleを選択し,Simulate Behavioral Modelをダブルクリックします.

i4002 23

 

ISimが起動されると最初に0~1000[ns]までシミュレーションしてくれます.今回作成したテストベンチですと,主に見たいところは0~300[ns]あたりなのでそのあたりを拡大してください.下図だけでも動作の様子を確認できますが,これだけではBlockRAMの中身が本当に確かに変わっているのか分かりません.

i4002 24

 

そこで次のようにBlockRAMの中身をみえるようにしましょう.まず,左側にあるInstance and Process Nameにあるツリーをたどっていき,native_mem_...というものを選択してください.次にObject Nameにあるmemory[0:79,3...]というものを選択し,タイミングチャートへドラッグ&ドロップしましょう.

i4002 25

 

memoryという信号を追加しましたらもう一度シミュレーションします.下図のようにRestartボタンをまず押し,次に時間限定実行をしてください.その後,0~300[ns]付近を中心に見てください.iWeがHighになっている100~215[ns]までの間でCLKが立ち上がったとき,iAddrにiDinの値がmemoryへ記憶されていることが確認できます.また,215[ns]以降ではiAddrにある値がoDoutに出力されているのも確認できます.なお,oDoutはiWeがHigh,つまり書き込み時にも値を出力しています.従って,oDoutはiAddrに位置づけられた値を常に出力しているといえます.

i4002 26

 

以上でBlockRAMの使い方の説明を終わります.Spartan6にあるBlockRAMを使えば,分散RAMを消費することなしに開発できますのでぜひとも活用してください.