2.4.2.1. 高速クロック・ドメイン
2.4.2.2. ループの再構築
2.4.2.3. コントロール信号のバックプレッシャー
2.4.2.4. FIFOステータス信号によるフロー・コントロール
2.4.2.5. スキッドバッファーを使用したフロー制御
スキッドバッファーの例(シングルクロック)
スキッドバッファーの例(デュアルクロック)
2.4.2.6. リードモディファイライトメモリー
2.4.2.7. カウンターとアキュムレーター
2.4.2.8. ステートマシン
2.4.2.9. メモリー
2.4.2.10. DSPブロック
2.4.2.11. 一般ロジック
2.4.2.12. モジュラスと除算
2.4.2.13. リセット
2.4.2.14. ハードウェアの再利用
2.4.2.15. アルゴリズム要件
2.4.2.16. FIFO
2.4.2.17. 三進加算器
2.4.2.5. スキッドバッファーを使用したフロー制御
スキッドバッファーを使用してFIFOをパイプライン化することができます。必要に応じて、スキッドバッファーをカスケードできます。スキッドバッファを挿入すると、FIFOコントロール信号を含むループが展開されます。スキッドバッファーはフローコントロール・ロジックのループを除去しませんが、ループは一連の短いループに変換されます。一般に、スキッドバッファーを使用する代わりに、ほとんど空でほぼ完全な信号に切り替えます。
図 66. リード・コントロール・ループ内の2つのスキッドバッファーを有するFIFOフロー・コントロール・ループ
FIFOコントロール信号を含むループがあり、フロー制御用の多数の宛先にブロードキャストされている場合、ブロードキャスト信号を除去できるかどうかを検討してください。パイプラインのブロードキャスト・コントロール信号を使用し、FIFOからほぼ完全に空の状態ビットを使用します。
スキッドバッファーの例(シングルクロック)
/ synopsys translate_off
//`timescale 1 ps / 1 ps
// synopsys translate_on
module singleclock_fifo_lowell
#(
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 16,
parameter SHOWAHEAD = "ON", // "ON" = showahead mode ('pop' is an acknowledgement); /
"OFF" = normal mode ('pop' is a request).
parameter RAM_TYPE = "AUTO", // "AUTO" or "MLAB" or "M20K".
// Derived
parameter ADDR_WIDTH = $clog2(FIFO_DEPTH) + 1 // e.g. clog2(64) = 6, but 7 bits /
needed to store 64 value
)
(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] in_data, // write data
input wire pop, // rd request
input wire push, // wr request
output wire out_valid, // not empty
output wire in_ready, // not full
output wire [DATA_WIDTH-1:0] out_data, // rd data
output wire [ADDR_WIDTH-1:0] fill_level
);
wire scfifo_empty;
wire scfifo_full;
wire [DATA_WIDTH-1:0] scfifo_data_out;
wire [ADDR_WIDTH-1:0] scfifo_usedw;
logic [DATA_WIDTH-1:0] out_data_1q;
logic [DATA_WIDTH-1:0] out_data_2q;
logic out_empty_1q;
logic out_empty_2q;
logic e_pop_1;
logic e_pop_2;
logic e_pop_qual;
assign out_valid = ~out_empty_2q;
assign in_ready = ~scfifo_full;
assign out_data = out_data_2q;
assign fill_level = scfifo_usedw + !out_empty_1q + !out_empty_2q;
// add output pipe
assign e_pop_1 = out_empty_1q || e_pop_2;
assign e_pop_2 = out_empty_2q || pop;
assign e_pop_qual = !scfifo_empty && e_pop_1;
always_ff@(posedge clk)
begin
if(rst == 1'b1)
begin
out_empty_1q <= 1'b1; // empty is 1 by default
out_empty_2q <= 1'b1; // empty is 1 by default
end
else begin
if(e_pop_1)
begin
out_empty_1q <= scfifo_empty;
end
if(e_pop_2)
begin
out_empty_2q <= out_empty_1q;
end
end
end
always_ff@(posedge clk)
begin
if(e_pop_1)
out_data_1q <= scfifo_data_out;
if(e_pop_2)
out_data_2q <= out_data_1q;
end
scfifo scfifo_component
(
.clock (clk),
.data (in_data),
.rdreq (e_pop_qual),
.wrreq (push),
.empty (scfifo_empty),
.full (scfifo_full),
.q (scfifo_data_out),
.usedw (scfifo_usedw),
// .aclr (rst),
.aclr (1'b0),
.almost_empty (),
.almost_full (),
.eccstatus (),
//.sclr (1'b0)
.sclr (rst) // switch to sync reset
);
defparam
scfifo_component.add_ram_output_register = "ON",
scfifo_component.enable_ecc = "FALSE",
scfifo_component.intended_device_family = "Stratix",
scfifo_component.lpm_hint = (RAM_TYPE == "MLAB") ? "RAM_BLOCK_TYPE=MLAB" : /
((RAM_TYPE == "M20K") ? "RAM_BLOCK_TYPE=M20K" : ""),
scfifo_component.lpm_numwords = FIFO_DEPTH,
scfifo_component.lpm_showahead = SHOWAHEAD,
scfifo_component.lpm_type = "scfifo",
scfifo_component.lpm_width = DATA_WIDTH,
scfifo_component.lpm_widthu = ADDR_WIDTH,
scfifo_component.overflow_checking = "ON",
scfifo_component.underflow_checking = "ON",
scfifo_component.use_eab = "ON";
endmodule
スキッドバッファーの例(デュアルクロック)
// synopsys translate_off
//`timescale 1 ps / 1 ps
// synopsys translate_on
module skid_dualclock_fifo
#(
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 16,
parameter SHOWAHEAD = "ON",
parameter RAM_TYPE = "AUTO", // "AUTO" or "MLAB" or "M20K".
// Derived
parameter ADDR_WIDTH = $clog2(FIFO_DEPTH) + 1
)
(
input wire rd_clk,
input wire wr_clk,
input wire rst,
input wire [DATA_WIDTH-1:0] in_data, // write data
input wire pop, // rd request
input wire push, // wr request
output wire out_valid, // not empty
output wire in_ready, // not full
output wire [DATA_WIDTH-1:0] out_data, // rd data
output wire [ADDR_WIDTH-1:0] fill_level
);
wire scfifo_empty;
wire scfifo_full;
wire [DATA_WIDTH-1:0] scfifo_data_out;
wire [ADDR_WIDTH-1:0] scfifo_usedw;
logic [DATA_WIDTH-1:0] out_data_1q;
logic [DATA_WIDTH-1:0] out_data_2q;
logic out_empty_1q;
logic out_empty_2q;
logic e_pop_1;
logic e_pop_2;
logic e_pop_qual;
assign out_valid = ~out_empty_2q;
assign in_ready = ~scfifo_full;
assign out_data = out_data_2q;
assign fill_level = scfifo_usedw + !out_empty_1q + !out_empty_2q;
// add output pipe
assign e_pop_1 = out_empty_1q || e_pop_2;
assign e_pop_2 = out_empty_2q || pop;
assign e_pop_qual = !scfifo_empty && e_pop_1;
always_ff@(posedge rd_clk)
begin
if(rst == 1'b1)
begin
out_empty_1q <= 1'b1; // empty is 1 by default
out_empty_2q <= 1'b1; // empty is 1 by default
end
else begin
if(e_pop_1)
begin
out_empty_1q <= scfifo_empty;
end
if(e_pop_2)
begin
out_empty_2q <= out_empty_1q;
end
end
end
always_ff@(posedge rd_clk)
begin
if(e_pop_1)
out_data_1q <= scfifo_data_out;
if(e_pop_2)
out_data_2q <= out_data_1q;
end
dcfifo dcfifo_component
(
.data (in_data),
.rdclk (rd_clk),
.rdreq (e_pop_qual),
.wrclk (wr_clk),
.wrreq (push),
.q (scfifo_data_out),
.rdempty (scfifo_empty),
.rdusedw (scfifo_usedw),
.wrfull (scfifo_full),
.wrusedw (),
.aclr (1'b0),
.eccstatus (),
.rdfull (),
.wrempty ()
);
defparam
dcfifo_component.add_usedw_msb_bit = "ON",
dcfifo_component.enable_ecc = "FALSE",
dcfifo_component.intended_device_family = "Stratix 10",
dcfifo_component.lpm_hint = (RAM_TYPE == "MLAB") \
? "RAM_BLOCK_TYPE=MLAB" : ((RAM_TYPE == "M20K") \
? "RAM_BLOCK_TYPE=M20K" : ""),
dcfifo_component.lpm_numwords = FIFO_DEPTH,
dcfifo_component.lpm_showahead = SHOWAHEAD,
dcfifo_component.lpm_type = "dcfifo",
dcfifo_component.lpm_width = DATA_WIDTH,
dcfifo_component.lpm_widthu = ADDR_WIDTH+1,
dcfifo_component.overflow_checking = "ON",
dcfifo_component.read_aclr_synch = "ON",
dcfifo_component.rdsync_delaypipe = 5,
dcfifo_component.underflow_checking = "ON",
dcfifo_component.write_aclr_synch = "ON",
dcfifo_component.use_eab = "ON",
dcfifo_component.wrsync_delaypipe = 5;
endmodule