Pullup/Pulldown 実機とシミュレーションの違い

Systemverilog

はじめに

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を使ってみました。

コメント

タイトルとURLをコピーしました