LUT-RAMを使ったシフトレジスタのRTL記述
Xilinx社のFPGAではLUT-RAMがシフトレジスタとして使えるようになっている。4入力LUTは16ビットRAMだからFF 16個分に相当してかなりお得である。このLUT-RAMを使ったシフトレジスタを合成させるには、シフトレジスタをリセットなしで書けばよいだけである。なお、リセットを書くと普通にFFのシフトレジスタが合成される。(RAMはリセットできないから)
例) 可変長シフトレジスタ 32段x8ビット、リセットなし
/* sreg.sv */ module sreg #(parameter WD=8, DEPTH=32, WA=$clog2(DEPTH)) (input clk ,input clken // clock enable ,input[WA-1:0] adr // address of output FF (0 to DEPTH-1) ,input [WD-1:0] din ,output[WD-1:0] dout ); reg[WD-1:0] d_reg[0:DEPTH-1]; always @(posedge clk) begin if(clken) begin d_reg[0] <= din; for(int i=1; i<DEPTH; i++) d_reg[i] <= d_reg[i-1]; end end assign dout = d_reg[adr]; endmodule |
◇
リセットなしだとRTLシミュレーションで初期値が不定(x)になるので不都合な場合がある。そのときは
initial for(int i=0; i<DEPTH; i++) d_reg[i] <= {WD{1'b0}}; |
を追加すればよい。合成では、この記述はコンフィギュレーション後の初期値と解釈されるので問題ない。
◇◇
上記の例は可変長で書いたが、
assign dout = d_reg[DEPTH-3]; |
と固定長で書いてもよいが、合成するとなぜか入力段と出力段にFFが付き、何か得するわけではない。