verilog書く人

自称ASIC設計者です。どなたかkaggle一緒に出ましょう。

コードクローンファインダー for verilog

コードクローン(Code Clone)

(上記サイトより引用)

コードクローンとは

コードクローンとはソースコード中での類似または一致した部分を表します. コードクローンは,「コピーとペースト」によるプログラミングや,意図的に同一処理を繰り返して書くことにより,プログラムテキスト中に作りこまれます.

コードクローンの弊害

一般的に,コードクローンはソフトウェアの保守を困難にする要因の一つである,といわれています. 例えば,あるコードクローン上にフォールトが発見された場合に,開発者はそれと対応する全てのコードクローンを確認して,必要があれば全てのコードクローンに同様の修正を行う必要があるからです. 特に大規模システムでは,チームによる開発が通常行われており,上述したように一人の開発者がサブシステムを確認し,全てのコードクローンに対して一貫した修正を行うことはきわめて困難な作業であるといえます.


そのような事態を例えばCなどの言語ではコードクローンファインダーとして、
CCFinderのようなソフトが発表されている。

verilogでもこういうのあったら便利だけどニッチな言語だから見当たらないので、
Pyverilogを利用して作ってみました。実はPyverilog作者のshtaxxx氏が発案者だったりします。感謝。

 

開発指針

私が感じているCなどのソフトウェア言語とverilogの違い。

C
・ほとんどのコードはメソッド(関数orプロシージャ)の中に存在する。

Verilog
・ほとんどのコードはalways文(そしてそのほとんどはFFに代表されるレジスタ)の中に存在
verilogにもfunction文はあるが、使用頻度は多くない。
また参照はmoduleの中でのみ行われるため、クローンを探す需要はあまりない。


というわけでalways文で記述されるレジスタのクローンを探すことにしました。
verilogにおいてクローンを減らすということは回路面積を減らすことにもつながります。

 

機能説明

現在codeclone_finderで発見することができるクローンは以下の二つ。

・論理的に全く同一なレジスタ

例えばこのようなこーど。

always @(posedge CLK or negedge RST) begin
    if(RST) begin
        reg1 <= 1'b0;
    end else begin
        reg1 <= IN;
    end
end

assign in1 = IN;

always @(posedge CLK or negedge RST) begin
    if(RST) begin
        reg2 <= 1'b0;
    end else begin
        reg2 <= in1;
    end
end

in1とIN1の実体は同じであるためreg1とreg2は毎クロック必ず同じ値を保持します。
reg2の記述を消し、reg1を使いまわすべきです。

・論理的に全く反転しているレジスタ

always @(posedge CLK or negedge RST) begin
    if(RST) begin
        reg2 <= 1'b0;
    end else begin
        reg2 <= in1;
    end
end

always @(posedge CLK or negedge RST) begin
    if(RST) begin
        reg3 <= 1'b1;
    end else begin
        reg3 <= !in1;
    end
end

上記のコードでは、reg2とreg3は毎クロック必ず同じ値を保持します。

遅延のために後ろにインバータを使いたくないというような非常に稀な状況を除いて、このようなリファクタリングが有効です。

always @(posedge CLK or negedge RST) begin
    if(RST) begin
        reg2 <= 1'b0;
    end else begin
        reg2 <= in1;
    end
end

assign reg3 = !reg2;

これで保守性が上がるとともにレジスタが1個減ります。

codeclone_finderの使い方

まずは

 

を参考に、Pyverilog_toolboxをインストールしてください。

そして
コマンドプロンプト上で
(Pyverilog_toolboxをインストールしたディレクトリ)/verify_tool
に移動し、

$ Python codeclone_finder xxxx.v

と入力します。(xxxx.vは自分で用意したverilogコード)
試しにPyverilog_toolboxに梱包されているテストコードで動かすと

$ Python codeclone_finder ../testcode/reg_clone.v

Invert reg pairs: *1, *2, *3
Clone reg pairs: *4, *5

のようにコードクローンを指摘してくれます。

 

最後に

将来的には類似していてリファクタリングが可能なレジスタを見つけたり、
リファクタリングまで児童でしてくれるブラウザが作れればいいかなーと思いつつ。

*1:TOP.sub.reg1, 0), (TOP.reg4, 0

*2:TOP.reg1, 0), (TOP.reg4, 0

*3:TOP.reg3, 0), (TOP.reg4, 0

*4:TOP.reg3, 0), (TOP.sub.reg1, 0

*5:TOP.sub.reg1, 0), (TOP.reg1, 0