第三週

メモリの設計

サンプルプロジェクトでは、前回の資料で説明した外部RAMの他に、Block RAMというFPGAの内部に自由に構成することができるメモリを使用しています。本章ではFPGA内部に構成可能なメモリの種類と作成法、初期化、使用法を順に説明します。

1.1 メモリの種類

Xilinx社のFPGA上には、Block RAMとDistributed RAMの2種類のメモリを構築することができます。Block RAMはFPGA内のメモリ領域を利用して構成される大規模なメモリです。Distributed RAMはロジック領域に構築される小規模なメモリです。使用する用途にあわせて使い分けます。

1.2.1 Block RAMによるメモリの作成

  1. ISEのソースウィンドウ上で右クリック > New Sourceをクリック
  2. 一覧の中からIP(CoreGen & Architecture wizard) を選択する
  3. ファイル名を入力し、次へをクリック
  4. Memories & Storage Elements > RAMs & ROMs > Single port Block Memory > Next > Finish の順にクリック

CORE Generatorが起動し、図のような設定画面が表示されます。データ幅、深さを設定し、Generateをクリックすればメモリの作成は完了です。

一度作成したメモリに変更を加えるには、ISE のソースウィンドウ内に表示されるメモリのソースをダブルクリックし、設定画面を立ち上げます。

1.2.2 Distributed RAMによるメモリの作成

  1. ISEのソースウィンドウ上で右クリック > New Source
  2. 一覧の中からIP(CoreGen & Architecture wizard) を選択する。
  3. ファイル名を入力し、次へをクリック
  4. Memories & Storage Elements > RAMs & ROMs > Distributed Memory > Next > Finish の順にクリック
後はBlock RAM同様に設定してください。

1.3 メモリの初期化

メモリに初期値を設定するためにCoefficientsファイル(.coe)を作成します。coeファイルの作成法として、以下の方法を説明します。
  1. エディタを利用する
  2. 直接記述する
最後に、どちらかの方法で作成されたCoefficientsファイルを読み込み、メモリの初期化を行います。

1.3.1 メモリエディタの利用

  1. ソースウィンドウ内で目的のメモリモジュールをクリック→プロセスウィンドウのManage Coresをダブルクリックします。
  2. Core Generatorが立ち上がります。Tools > Meomory Editorの順にクリックします。
  3. Block DepthとData Widthを入力します。
  4. Memory Contentsウィンドウに初期値を書き込みます。
  5. Memory EditorウィンドウのAdd Blockをクリックし、メモリブロック名を入力します。
  6. File > Save Memory Definition As... をクリックし、ファイル名をつけて保存します。
  7. Memory EditorウィンドウのFile > Generateをクリックすると、.coeファイルが生成されます。ファイル名は ”definitionファイル名”_”ブロック名”.coeとなります。

1.3.2 Coefficientsファイルの直接記述

テキストエディタ等で.coeファイルを直接記述することで作成することができます。具体的には次のような形式で記述します。

; Sample Initialization file for a 32x16bit RAM
memory_initialization_radix = 16 ;
memory_initialization_vector =

2018, 002c, 0018, 001b, 001f, 0021, 001f, 2017,
2017, 2017, 0029, 1fff, 2018, 0027, 0018, 001b,

2012, 0014, 0017, 2018, 001b, 001f, e01f, 0025,
2021, 401f, 0000, 0000, 0000, 0000, 0000, 0000;

この例では幅が16ビット、深さが32のメモリの初期値を16進数で記述しています。memory_initialization_radixでは初期値の基数を2、10、16の3つから指定することができます。memory_initialization_vectorから指定した基数で初期値を記述してください。このとき、以下の2つを必ず守って記述するようにしてください。

  • 初期値の個数をメモリの深さと一致させる
  • 初期値のビット数をメモリのビット幅と一致させる
最後にプロジェクトと同じディレクトリに拡張子を.coeとして保存し、完了します。

1.3.3 Coefficientsファイルの読み込み

作成した.coeファイルを読み込みメモリの初期化を行います。
  1. Core Generatorを立ち上げている場合にはそれを閉じ、ISEのソースウィンドウ上でメモリモジュールをダブルクリックします。
  2. NextをクリックしLoad init Fileが含まれるタブまで進めます。
  3. Load init Fileにチェックを入れ、Load File…をクリックします。
  4. 作成した.coeファイルを選択します。
  5. Generateをクリックします。

1.4.1 メモリの呼び出し

モジュール呼び出しを行うことで、メモリモジュールを組み込むことができます。

プロジェクトと同じディレクトリに ”メモリのファイル名”.veo というファイルがあるので、テキストエディタなどで開いてください。モジュール呼び出しのためのテンプレートが記述されているので、コピー&ペーストで自分のソースに追加し、インスタンス名、各入出力ポートへの結線を適宜変更してください。

各ポートがなにを入出力するのかわからない場合はメモリの設定画面内のポート図を参照してください。

1.4.2 データの読み出しと書き込み

メモリに格納されているデータにはアドレスが割当てられており、メモリのデータを読み書きするにはアドレスを指定する必要があります。
  • アドレスをメモリに与えると、そのアドレスに書き込まれているデータがメモリから1クロックサイクル後に出力されます。
  • 書き込みたいデータをアドレスとともにメモリに与えることで1クロックサイクル後に書き込まれます。この時、WE(Write Enable)信号をアクティヴ(デフォルトでは1)にする必要があります。
ram_timing_chart

回路の制御

2.1 レジスタによる遅延

順序回路の制御ではレジスタによる処理の遅延クロックサイクル数を考えることが重要です。

例として、課題1.3のQueueを上げます。Queueは4つのレジスタを使用しています。レジスタはクロックの立ち上がりに同期して値を更新するため、Queueに入力されたデータが全てのレジスタを通過し出力されるまで、4クロックサイクルかかります。すなわち、この回路の処理には4クロックサイクルの遅延が発生します。つまり、ある時刻tクロック目の入力値の処理結果はt+4クロック目に出力されることを表します。

queue_delay

以上の例のように、制御はクロックサイクル数を基準にしてデータの処理過程を判断し実行するため、レジスタによる遅延への考慮が不可欠になります。

2.2 パイプライン処理

FPGAにおいて、全てのレジスタは同時に動作します。以下に、各クロックにおけるQueue内レジスタの状態推移を示します。
pipeline

ソフトウェアのように1つづつデータに処理を適用していくのではなく、ハードウェアでは各データに対し各フェーズを順次適用することができます。これをパイプライン処理と言います。Queueの場合、処理するデータの数をNとした場合全体の処理時間はN+4となります。

Queueを使用する場合、最初の4クロックは無効な値が出力されるため、それらの値を無視する必要があります。さらに、処理を終了させるタイミングは処理するデータの数をNとした場合、N+4としなければなりません。

以上の例のように、モジュールの制御はデータの処理過程における遅延やパイプラインの深さを考慮しなければなりません、

2.3 フィルタ処理回路(filter_unit.v)の制御

前回の資料で取り扱わなかったフィルタ処理回路の制御について説明します。まず、制御回路を含めた回路図を図8に示します。以下、各々の制御回路の機能について説明します。

interface

Control

この回路は、10ビットのカウンタによってBlock RAMの読み出しと書き込みのためのアドレスを生成しています。(画像の幅が640とした場合)カウンタは0~639までの値をカウントし、その値を読み出しのアドレスとして、さらにレジスタにより1クロックシフトさせたものを書き込みのアドレスとして使用しています。したがって2つのアドレスの関係は

write_address = read_address – 1

となります。

課題

課題3