... | ... | @@ -84,7 +84,7 @@ Vivadoは、このレプリケーションを自動で適用することで、re |
|
|
「`w_addr1`でしか書き込めないメモリ領域」と「`w_addr2`でしか書き込めないメモリ領域」のように分割することを考えます。
|
|
|
このようにすることで、write port数が1のメモリしか使えない場合でも1 cycleに二か所書き込むことは可能になります。
|
|
|
|
|
|
このような、特定のアドレス範囲しか使えないメモリを複数用意する方法を**バンク化**と言います。
|
|
|
このような、特定のアドレス範囲しか使えないメモリ(バンク)を複数用意する方法を**バンク化**と言います。
|
|
|
もしかしたら、データメモリを構成するために、アドレスの下位2ビットが`2'b00`であるデータを保存するメモリ、`2'b01`用のメモリ、`2'b10`用のメモリ、`2'b11`用のメモリ、のようにメモリアドレス全体を4分割するような方法を使った人がいるかもしれません。
|
|
|
このようなものもバンク化の一種です。
|
|
|
|
... | ... | @@ -108,7 +108,7 @@ Vivadoは、このレプリケーションを自動で適用することで、re |
|
|
「どのバンクに最新のデータが入っているか」を管理する表(“生きている”値がどれかを記録する表、Live Value Table (LVT))を作る必要があるということです。
|
|
|
|
|
|
残念ながら、このLVTもまた、元のメモリと同じwrite port 数を要求するので、LVTを使う方法は本質的に問題を解決したことにはなりません。
|
|
|
ただし、LVTは非常に幅が狭い(レジスタファイルは32bit×31エントリ、LVTは1bit×31エントリ(write port数が2の時))なので、これをフリップフロップで作ることを妥協してしまえば、のこりは分散RAMで作ることができます。
|
|
|
ただし、LVTは非常に幅が狭い(レジスタファイルは32bit×31エントリ、LVTは1bit×31エントリ(write port数が2の時))ので、これをフリップフロップで作ることに妥協してしまえば、残りのデータ本体保存部分は分散RAMで効率的に作成できます。
|
|
|
|
|
|
LVTを使った場合、write port数をw、read port数をrとして、wr倍のメモリ容量が必要になります。
|
|
|
なぜなら、本体のデータを保存するためには、(write port数個だけバンクを用意)×(read port数個だけレプリケーション)が必要だからです。
|
... | ... | @@ -119,7 +119,7 @@ XOR-based multiport memoryは、Live Value Table の時と同様、メモリ領 |
|
|
|
|
|
XOR-based multiport memoryの核となるアイデアは、『`wdata`をそのまま担当メモリバンクに書き込むのではなく、「すべてのメモリバンクの値のビット毎排他的論理和を取った値が最新の値」になるように、**適切な値**を担当メモリバンクに書き込む』というものです。
|
|
|
このようになっていれば自明に、「どれが最新データであるか」みたいな面倒な問題はないことが分かります。
|
|
|
そのような書き込みがいつでも可能か(担当メモリバンクに書き込むだけで「最新の値」を任意の値に書き換えられるか)という点が気になりますが、これは排他的論理和の性質から、そのような条件を満たす値が常にちょうど一つ存在することが分かります。
|
|
|
そのような書き込みがいつでも可能か(担当メモリバンクに書き込むだけで「最新の値」を任意の値に書き換えられるか)という点が気になりますが、これは排他的論理和の性質から、そのような条件を満たす値が常にちょうど一つ存在することが分かります(考えてみてください)。
|
|
|
|
|
|
具体的な実装(4 read + 2 writeをサポートするレジスタファイル)は以下のようになります。
|
|
|
この実装(というか一般にマルチポートメモリのほとんど)は、論理的に同じインデックスの位置に同時に書き込むと値が壊れてしまいます。必要であれば「`waddr1 == waddr2`であるかを確認して、そうであれば`we1`を落とす」のようなロジックを追加してください。
|
... | ... | @@ -184,7 +184,7 @@ True dual port memoryはsimple dual port memoryの上位互換です。 |
|
|
True dual port memoryの機能を制限すればsimple dual port memoryを作れますが、その逆はできません。
|
|
|
FPGAに存在するBlockRAMは、true dual port memoryですが、[FPGA 内蔵 RAM の使用方法](FPGARAM#ブロックram)で紹介した方法で記述してしまうとsimple dual port memoryになってしまいます。
|
|
|
BlockRAMの機能をフルに使うには、以下のように記述します。
|
|
|
なお、当たり前ですが、同じアドレスに二つのポートから同一サイクルに書き込んだ場合、どんな値が書き込まれるかは保証されないので注意してください(同じ値を書き込むのもダメです)。
|
|
|
なお、当たり前ですが、同じアドレスに二つのポートから同一サイクルに書き込んだ場合、どんな値が書き込まれるかは保証されないので注意してください(同じ値を書き込むのもダメです。適切にweを落とすなどしてください)。
|
|
|
|
|
|
```verilog
|
|
|
module databram(addr1, rdata1, we1, wdata1, addr2, rdata2, we2, wdata2, clk);
|
... | ... | |