はじめに
FPGA開発では基板上で信号がPullup/Pulldownされている信号があります。
基板上でPullup/Pulldownされているということは、DUTには表現されません。
シミュレーションでは注意が必要で、テストベンチ側でPullup/Pulldownを表現する必要があります。
Pullup/Pulldown
wireに対して、以下の記述でPullup/Pulldownすることができます。
wire sig1, sig2;
pullup(sig1);
pulldown(sig2);
動作確認
tb.sv
sig0,1, 2はclkがHighのときにZ,LowのときはLowになります。
また、sig1はPullup、sig2はPulldownしています。
module tb;
initial #200 $finish;
bit clk = 0;
always #5 clk = !clk;
wire sig0, sig1, sig2;
assign sig0 = clk ? 'z : '0;
assign sig1 = clk ? 'z : '0;
assign sig2 = clk ? 'z : '0;
pullup(sig1);
pulldown(sig2);
endmodule
波形
clkがLowのときはsig0,1,2ともにLow、
clkがHighのときはsig0がz, sig1がPullupされていてHigh、sig2がPulldownされていてLowになっています。
Pullup/Pulldownで動作が変わる例
DUTの出力信号をDUT内部で使用しているときや、inoutポートにしているときなどはRTLの書き方によってはpullup/pulldownが必須になる場合もあります。
if文を使って、sig0,1,2からdin0,1,2を生成してみます。
tb.sv
sig0,1,2がHighのときにdin0,1,2はHighとなります。
module tb;
initial #200 $finish;
bit clk = 0;
always #5 clk = !clk;
wire sig0, sig1, sig2;
assign sig0 = clk ? 'z : '0;
assign sig1 = clk ? 'z : '0;
assign sig2 = clk ? 'z : '0;
pullup(sig1);
pulldown(sig2);
logic din0, din1, din2;
always_comb begin
if(sig0 === '1) // sig0が1のときのみヒットする
din0 = '1;
else
din0 = '0;
end
always_comb begin
if(sig1 === '1) // Pullupされているのでsig1がzのときもヒットする
din1 = '1;
else
din1 = '0;
end
always_comb begin
if(sig2 === '1) // Pulldownされているのでsig2がzでもヒットしない
din2 = '1;
else
din2 = '0;
end
endmodule
波形
clkがHighのときはsig0,1,2はzになります。しかし、sig1はpullupしているためHighになります。
なので、clkがHighのとき、din1のみHighになります。
まとめ
pullup/pulldownを使ってみました。
コメント