同期リセット、非同期リセットについては太古の昔に次のように定義されていた。
とくにXilinxは同期リセットのほうが合成に都合がいいとされていた。
それで、今現状はどうなんだろう?と試してみることにした。
対象のコードは次のように7入力で6つのANDと1つのORを1出力する回路です。
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
このコードで試しているのはXilinxのUltraScale+で合成をかけているからです。
UltraScale+は6入力LUTなので6つのANDで1つのLUTが使われますが他の1つのORとリセットがどうなるか?というところが確認ポイントです。
次の5つのケースを試してみました。
このケースはリセットされない回路です。
I/Oは直接ピンに接続します。
`default_nettype none
`timescale 1ns/1ps
module fftest0
(
input wire RST_N,
input wire CLK,
input wire DIN0,
input wire DIN1,
input wire DIN2,
input wire DIN3,
input wire DIN4,
input wire DIN5,
input wire DIN6,
output reg DOUT
);
always @(posedge CLK) begin
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
end
endmodule
`default_nettype wire
このケースはリセットがないので単純にLUTが2つ使われて構成されるはずです。
![]()
ケース1は非同期リセットです。
`default_nettype none
`timescale 1ns/1ps
module fftest1
(
input wire RST_N,
input wire CLK,
input wire DIN0,
input wire DIN1,
input wire DIN2,
input wire DIN3,
input wire DIN4,
input wire DIN5,
input wire DIN6,
output reg DOUT
);
always @(posedge CLK or negedge RST_N) begin
if(!RST_N) begin
DOUT <= 0;
end else begin
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
end
end
endmodule
`default_nettype wire
記述上はCLK
とRST_N
の変化点で回路が動くように作ったものです。
![]()
ケース2は同期リセットです。
`default_nettype none
`timescale 1ns/1ps
module fftest2
(
input wire RST_N,
input wire CLK,
input wire DIN0,
input wire DIN1,
input wire DIN2,
input wire DIN3,
input wire DIN4,
input wire DIN5,
input wire DIN6,
output reg DOUT
);
reg CLK_RST_N;
always @(posedge CLK) begin
CLK_RST_N <= RST_N;
end
always @(posedge CLK) begin
if(!CLK_RST_N) begin
DOUT <= 0;
end else begin
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
end
end
endmodule
`default_nettype wire
入力したRST_N
を明示的にCLK
で叩き直して回路に適用しています。
![]()
ケース3も同期リセットです。
`default_nettype none
`timescale 1ns/1ps
module fftest3
(
input wire RST_N,
input wire CLK,
input wire DIN0,
input wire DIN1,
input wire DIN2,
input wire DIN3,
input wire DIN4,
input wire DIN5,
input wire DIN6,
output reg DOUT
);
always @(posedge CLK) begin
if(!RST_N) begin
DOUT <= 0;
end else begin
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
end
end
endmodule
`default_nettype wire
ケース2と違うところはRST_N
を明示的にCLK
で叩いていないところです。
しかし、回路はCLK
の変化点でのみ動作するので同期リセット回路を想定した記述です。
ケース4は非同期リセットです。
`default_nettype none
`timescale 1ns/1ps
module fftest4
(
input wire RST_N,
input wire CLK,
input wire DIN0,
input wire DIN1,
input wire DIN2,
input wire DIN3,
input wire DIN4,
input wire DIN5,
input wire DIN6,
output reg DOUT
);
reg CLK_RST_N;
always @(posedge CLK) begin
CLK_RST_N <= RST_N;
end
always @(posedge CLK or negedge CLK_RST_N) begin
if(!CLK_RST_N) begin
DOUT <= 0;
end else begin
DOUT <= DIN0 | (DIN1 & DIN2 & DIN3 & DIN4 & DIN5 & DIN6);
end
end
endmodule
`default_nettype wire
RST_N
をCLK
で叩き直しているので同期リセットのように見えますが回路はCLK_RST_N
の変化点でリセットされるように記述しているので同期リセットに見せかけた非同期リセットが想定です。
配置配線の結果は次のようになりました。
ケース0 | ケース1 | ケース2 | ケース3 | ケース4 | |
---|---|---|---|---|---|
同期/非同期 | なし | 非同期 | 同期 | 同期 | 非同期 |
LUT | 2 | 3 | 3 | 3 | 3 |
FF | 1 | 1 | 2 | 1 | 2 |
IO | 9 | 10 | 10 | 10 | 10 |
BUFG | 1 | 1 | 1 | 1 | 1 |
I/Oはリセットなし以外は10本なので間違いありません。
LUTはケース1〜ケース4で変わりません。
FFはケース1とケース3が1個でケース2とケース4が2個です。
FFが1個のときはDOUT
のFFのみ構成されています。
FFが2個のときはDOUT
とRST_N
のFFが構成されて2個になっています。