FC2カウンター FPGAの部屋 PS/2キーボードインターフェース用テストベンチ(task使用)のアサーション($timeformat)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

PS/2キーボードインターフェース用テストベンチ(task使用)のアサーション($timeformat)

たっくさんから $timeformat を教えてもらったので、もう一度、PS/2キーボードインターフェース用テストベンチを書き直した。
$timeformatの説明はこのページにあるので、詳しくはこのページを見てください。
PS/2インターフェースなので、単位はusec 、小数点以下は3桁、つまり nsec まで表示とした。

$timeformat(-6, 3, "usec", 4);


PS/2プロトコルで送ったコードとPS/2インターフェース回路で受けたコードが合わないときに表示するデータに時刻を追加した。

if (scandata != input_code) begin
    $display("Error!!!  %t, input_code = %h, scandata = %h"
        ,$time, input_code, scandata);
    $stop;
end


テストベンチの全コードを下に示す。

// ps2read_tb.v

`default_nettype none
`timescale 1ns / 100ps

module ps2read_tb;

    parameter CYCLE=20;

    reg clk, reset, ps2clk, ps2data;
    wire [7:0] scandata;
    reg [7:0] testcode;
    
    ps2read ps2read_inst (
        .clk(clk),
        .reset(reset),
        .ps2clk(ps2clk),
        .ps2data(ps2data),
        .scandata(scandata)
    );
    
    initial begin
        clk <= 1'b1;
    end
    always #(CYCLE/2)
        clk <= ~clk;
    
    initial begin
        $timeformat(-6, 3, "usec", 4);
        
        reset <= 1'b1;
        ps2clk <= 1'b1;
        ps2data <= 1'b1;
        
        #80; // リセット
        reset <= 1'b0; // リセット解除
        
        PS2_SigGen(8'h1C);
        PS2_SigGen(8'h32);
        
        #500;
        $stop;
    end
    
    task PS2_SigGen;
        input [7:0] input_code;
        integer i;
        begin
            ps2clk <= 1'b1;
            ps2data <= 1'b0; // Stop bit
            
            #40000;
            ps2clk <= 1'b0; // 立ち下がりエッジ
            #40000;
            
            for(i=0; i<=7; i=i+1) begin
                ps2clk <= 1'b1; // 立ち上がりエッジ
                ps2data <= input_code[i]; // シリアルデータ出力
                
                #40000;
                ps2clk <= 1'b0; // 立下りエッジ
                #40000;
            end
        
            ps2clk <= 1'b1;
            ps2data <= !(^input_code);
        
            #40000;
            ps2clk <= 1'b0; // 立ち下がりエッジ
            #40000;
        
            ps2clk <= 1'b1;
            ps2data <= 1'b1; // Stop bit
        
            #40000;
            ps2clk <= 1'b0; // 立ち下がりエッジ
            
            if (scandata != input_code) begin
                $display("Error!!!  %t, input_code = %h, scandata = %h"
                    ,$time, input_code, scandata);
                $stop;
            end
            
            #40000;
            ps2clk <= 1'b1; // 1に戻す
        end
    endtask
endmodule


更にわざとエラーが出るように、if 文の中を == に書き換えて Veritak でシミュレーションしてみた。
keyboard_verilog_5_071015.png

黄色の枠で囲んだところが、わざとエラーが出るようにしたところ。
ピンクの枠で囲んでいるのがエラーメッセージだ。840.080 usec でエラーが出ている。
今のところ、コードが合っているのは当たり前なのだが、PS/2インターフェース回路を後で修正したときに、意図せずに間違ったデータが出たときに教えてくれるというわけだ。
PS/2インターフェース回路などでは間違うことはないかもしれないが、たとえばPCI-Xインターフェース回路で、”Aという信号をアサートしたら、何クロック以内にBという信号をアサートする必要がある”というルールをVerilogコードまたはPSLなどで書いておく。そうすると、回路を修正していく過程で、修正する項目しかwave波形表示ウインドウで注目していなくても、それらのルールに合致しているということが自動的に証明されるはずである。
これは結構重要で、あっちを修正したはずが、こっちがだめになったということが良くある。これをwave画面上で気がつけばよいが、実際にやってみるまで気がつかないということが良くある。
もっと怖いのは、たまたまそのシステムでは大丈夫だが、ほかのシステムでテストしたときにだめということになり、あわててしまうこともある。なるべく、決まったルールはシミュレーション上で自動的に判別できたほうが良いと思う。そうでないとwave波形を見る目が血走ってぐったり疲れてしまう。心の健康のためにもアサーションを導入しようという気持ちだ。(半分冗談、こうゆう時にいまどきのブロガーは(笑)と入れるのだろうか?)
  1. 2007年10月15日 06:06 |
  2. アサーション事始め
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/623-2b5fefcf
この記事にトラックバックする(FC2ブログユーザー)