帰らざるMOS回路(24)今時ゲートレベルでもあるまいに。ライブラリをVerilogしてみる

Joseph Halfmoon

前回は、論理圧縮ツール Espresso を使うことができる LogicFriday を試してみました。今回は再びLogicsimへ戻ります。しかし後々のこと(なんだそれ)を考えるとライブラリがVerilogでも書けた方が安心。ということでVerilog化始めました。まずは組み合わせ回路、コンパレータから。

※使用させていただいとります「フリー」ツールのホームページへのリンクは以下です。

    • 画面上でゲートレベルの論理回路動作が会話的に観察できるツール

Logisim

上記からダウンロードして実行可能ですが、開発は既に “suspended indefinitely” 状態です。

    • 「フリー」のVerilogといったらこれかと

Icarus Verilog

    • Verilog処理系などが出力する VCDフォーマットのファイルをタイミングチャートとしてみるためのビューワーです。

GTKWave

Verilog化してみるLogicSimのライブラリ

今回やってみるのはロジックの comparator です。2つの数値を比較して大小、イコールを判定するもの。大小の判定まで含めるよりもイコール判定のみの方が回路規模が小さいので実用的に応用が多いかと。

    1. 入力は左辺に、任意のビット数に指定可能
    2. 出力は右辺に、「大なり」、「イコール」、「小なり」 の3線
    3. タイミングを持たない組み合わせ回路である
    4. 入力の数値は符号無整数、符号付き(2の補数)整数を選択可能

今回は、とりあえず 8ビット入力、符号無にてVerilog化してみたいと思います。LogicSim上で「大なり」が出力されているところが以下に。caseGT

「イコール」は冒頭のアイキャッチ画像に。以下は「小なり」のときです。LogicSimは、画面の上でクリクリやっていけば論理が動くので、頭に靄のかかった年寄りにも動作が分かり易いです。しかし、如何せんシミュレータとしては使いずらいところがあります。

caseLT

なお、コンパレータブロックの属性を開くと以下のような感じです。Data Bitsでビット幅を指定し、Numeric Typeで、符号無か2の補数(符号付き)かを選びます。

Comparator

 

Verilogで書いてみた

組み合わせ回路を以下のように書いてみました。こんなんでいいのかな~?

/** @file
    8bit 2 input comparator, unsigend
*/

`ifndef COMPU8_V_
`define COMPU8_V_

/** The COMP module
    @param[in] A [7:0] input
    @param[in] B [7:0] input
    @param[out] GT A>B
    @param[out] EQ A==B
    @param[out] LT A<B
*/
module compU8(
    A, B, 
    GT, EQ, LT
);

input [7:0] A, B;
output GT, EQ, LT;

assign GT = (A > B) ? 1'b1: 1'b0;
assign LT = (A < B) ? 1'b1: 1'b0;
assign EQ = (A == B);

endmodule

`endif // COMPU8_V_

上記のコンパレータ回路のテストベンチが以下に。前回、テストベンチの遅延の付け方を間違っていたので(どうせ組み合わせ回路なので違っても問題ない、というお気楽さで前回分は直してないです。すみません。)直しました。もともとあやふやな記憶だし。。。

/** @file
    testBench.v, to test compU8.v (8 bit comparator, unsigned)
*/

`ifndef TESTBENCH_V_
`define TESTBENCH_V_

`timescale 1 us / 100 ns

/** The compU8 testbench */
module compU8_tb;

reg [7:0] A, B;
wire GT, EQ, LT;
parameter STEP = 10;

compU8 dut(
    A, B, GT, EQ, LT
);

initial begin
    $dumpfile("compU8.vcd");
    $dumpvars(-1, dut);
    $monitor("%d GT=%b, EQ=%b, LT=%b", $stime, GT, EQ, LT);
end

// testbench actions
initial begin
    #0		A = 8'b00000001; B = 8'b00001000;
    #STEP	A = 8'b00000010;
    #STEP	A = 8'b00000100;
    #STEP 	A = 8'b00001000;
    #STEP	A = 8'b00010000;
    #STEP	A = 8'b00100000;
    #STEP	A = 8'b01000000;
    #STEP	A = 8'b10000000;
    #STEP	A = 8'b00000000; B = 8'b00000000;
    $finish;

end

endmodule

`endif // TESTBENCH_V_
実行してみた

icarus verilogで「エラボレーション」して「シミュレーション」するには以下です。

$ iverilog -o tb.out testBench.v compU8.v
$ vvp tb.out

シミュレーション時に$monitorにより表示される実行結果は以下です。まず「小なり」LTで始まって、「イコール」EQになり、「大なり」GTになった後、EQに戻って停止します。一応、目論見通りかね。

vvpResultA

波形ビューワーで観察するためのコマンドラインは以下です。

$ gtkwave compU8.vcd

波形ビューワーの画面が以下に。

gtkResult

Verilogのリハビリのためにも、ライブラリを端からVerilog化してみますか。まずは符号付きの処理か、メンドイ感じがする。ホントか。

帰らざるMOS回路(23)今時ゲートレベルでもあるまいに。ミニマイゼーションして論理合成 に戻る

帰らざるMOS回路(25)今時ゲートレベルでもあるまいに。カウンタをVerilogしてみる へ進む