ULX3SでブロックRAMを推論させたい
Yosys を使って、Verilog で定義したメモリを ULX3S 上のブロック RAM として推論させてみる。 推論される条件
Verilogで書いた配列のうち、条件に当てはまるものがブロックRAMとして推論されるらしい
クロックに同期して値が書き込まれる
クロックに同期して値が読み出される
配列のサイズがある程度の大きさ以上(厳密な条件は不明)
(例)1ワード8ビットの場合
要素数が256個 → ブロックRAMとして推論されない
要素数が280個 → ブロックRAMとして推論される
サンプルコード
以下のようなコードを作成。以下の pattern の部分がブロックRAMとして推論される
code:test.sv
module test(
input clk,
);
initial begin
for (integer i = 0; i < 512; i = i + 1) begin
// i の値を8ビットのパターンに変換
end
end
// 1秒ごとにLEDのパターンを変更
wire count_next = (count < 25000000)
? count + 1
: 0;
wire index_next = (count == 0)
? index + 1
: index;
wire led_next = patternindex; always @(posedge clk) begin
count <= count_next;
index <= index_next;
led <= led_next;
end
endmodule
以下のコマンドでビルド
code:sh
yosys -p "read_verilog -sv test.sv" -p "synth_ecp5"
出力される Printing statistics で、ブロックRAMのプリミティブである DP16KD が表示されればOK
code:sh
2.47. Printing statistics.
=== test ===
Number of wires: 10
Number of wire bits: 97
Number of public wires: 10
Number of public wire bits: 97
Number of ports: 2
Number of port bits: 9
Number of memories: 0
Number of memory bits: 0
Number of processes: 0
Number of cells: 5
DP16KD 1 <== これが表示されればOK!!
LUT4 2
TRELLIS_FF 2
配列のサイズが小さいとブロックRAMにならない
パターン配列のサイズを 512→256 にしたところ、ブロックRAMが推論されなかった
code:test.sv
以下のように、DP16KD が出てこない...
code:sh
2.47. Printing statistics.
=== test ===
Number of wires: 7
Number of wire bits: 52
Number of public wires: 7
Number of public wire bits: 52
Number of ports: 2
Number of port bits: 9
Number of memories: 0
Number of memory bits: 0
Number of processes: 0
Number of cells: 5 <== DP16KDがいない!!!
LUT4 2
TRELLIS_FF 3
(メモ)ECP5のメモリプリミティブ
EBR で始まるのがブロックRAMで、PFU で始まるのが分散RAM
ブロックRAM系
シングルポートRAM (RAM_DQ)
EBR SP16KD
デュアルポートRAM (RAM_DP_TRUE)
EBR DP16KD
擬似デュアルポートRAM (RAM_DP)
EBR PDPW16KD
分散RAM
分散シングルポートRAM (Distributed_SPRAM)
PFU SPR16X4C
分散デュアルポートRAM (Distributed_DPRAM)
PFU SPR16X4C
分散ROM (Distributed_ROM)
PFU ROMnx1a
ROM
FIFO
デュアルクロックFIFO (FIFO_DC)
参考
ECP5 and ECP5-5G Memory User Guide
ecp5: LiteX dual clock memory may fail to map to DP16KD
分散RAMとブロックRAM