Update FPGARAM authored by Toru Koizumi's avatar Toru Koizumi
RAM の書き方 RAM の書き方
============ ============
Verilog HDL で順序回路を書いてシミュレーションが成功しても、必ずしもそれが FPGA で実現できるとは限りません。
FPGA で実現できる順序回路を書くためには、(Verilog HDLで許される文法より狭い範囲である)特定の書き方をする必要があります。
以下の書き方をするように心がけてください。
## RAM の種類 ## RAM の種類
FPGA 上で RAM を構成する方法には、フリップフロップ、分散RAM 、ブロックRAM の三種類があります。 FPGA 上で RAM を構成する方法には、フリップフロップ、分散RAM 、ブロックRAM の三種類があります。
...@@ -33,9 +38,6 @@ FPGA 上で RAM を構成する方法には、フリップフロップ、分散R ...@@ -33,9 +38,6 @@ FPGA 上で RAM を構成する方法には、フリップフロップ、分散R
``` ```
同時に読める数(read port 数)を増やすのも難しくはありません。単に入出力の信号線を増やし、`assign`文を複数にするだけです。 同時に読める数(read port 数)を増やすのも難しくはありません。単に入出力の信号線を増やし、`assign`文を複数にするだけです。
同時に書ける数(write port 数)を増やすのも同様であり、記述上は[^1]難しくありません。当たり前ですが、同じ場所に複数同時に書き込んだりするとおかしなことになります。
[^1]:実際にどういった回路が組みあがるか、という話になると難しいですが、その辺は論理合成ツールが頑張ってくれるので気にする必要はありません。
## ブロックRAM ## ブロックRAM
...@@ -59,7 +61,31 @@ FPGA 上で RAM を構成する方法には、フリップフロップ、分散R ...@@ -59,7 +61,31 @@ FPGA 上で RAM を構成する方法には、フリップフロップ、分散R
endmodule endmodule
``` ```
port 数の増やし方は、分散RAM の時と同様です。 port 数の増やし方は、分散RAM の時と同様ですが、2つまでしか増やせません。
### バイトマスク付きライト
ブロックRAMは、一部の要素のみ書き込むという使い方もできます。サブワード書き込み命令の実装に利用できます。
```verilog
module ram(clk, we, r_addr, r_data, w_addr, w_data);
input clk;
input [3:0] we; // 書き込むバイトは1, 書き込まないでそのままにするバイトは0を指定
input [4:0] r_addr, w_addr;
input [31:0] w_data;
output [31:0] r_data;
reg [4:0] addr_reg;
reg [31:0] mem [0:31];
always @(posedge clk) begin
if(we[0]) mem[w_addr][ 7: 0] <= w_data[ 7: 0];
if(we[1]) mem[w_addr][15: 8] <= w_data[15: 8];
if(we[2]) mem[w_addr][23:16] <= w_data[23:16];
if(we[3]) mem[w_addr][31:24] <= w_data[31:24];
addr_reg <= r_addr;
end
assign r_data = mem[addr_reg];
endmodule
```
## RAM の初期化 ## RAM の初期化
...@@ -126,5 +152,3 @@ ROM の場合も、write 線がないだけで RAM と同様です。すなわ ...@@ -126,5 +152,3 @@ ROM の場合も、write 線がないだけで RAM と同様です。すなわ
assign r_data = mem[addr_reg]; assign r_data = mem[addr_reg];
endmodule endmodule
``` ```
---