アサーションを試してみる(OVL編)

回路の設計規模が巨大化してくると、従来のテストベンチによるブラックボックステストのみではバグの見落とし等、不十分だったり効率が悪いです。そこで、最近は(というより結構前から)アサーション検証も合わせて、テストを行うことが多いようです。

んで、そもそもアサーションベース検証ってなんだ。って話ですが、要するに、設計した回路が要求通りに記述されているかをRTLレベルで監視するやつです。たとえば、バスでReqを送った1~10Cycle以内に必ずACKが帰ってくるとか、このFIFOは絶対にFullにならないとか、連続してReqを出していないかだとか。こういった、要件が満足されないときにErrorを吐いてくれます。こういうのって設計が大規模になるほど普通のテストベンチ書いてシミュレーションして原因を救命するのは結構大変です。

アサーションにはスタティック検証と、ダイナミック検証があるみたいです。ここではダイナミック検証について触れ、いくつかあるアサーション用言語でもフリーで公開されているOVL(Open Verification Library)を触ってみようと思います。

OVL以外にもPSLとかSVAとかがありますが、いずれもシミュレータ側での対応が必要です。OVLは通常のVerilog HDLで書かれているようなので、多分フリーのシミュレータとかでも動くかと思います(確証なし)。ここではVerilogを使ってますが、VHDLなどでもほぼ同じようにできるんだと思います。私は試したわけではないから知りませんけど…

Riviera-PROでOVLを使ってみる

以下に記載したことはRiviera-PRO Version 2013.02.81.4877で検証した情報です。ツールについてまだ熟知しているわけではないので、もし間違った所があればtwitter等で指摘してください。

ワークスペース・デザインのの生成と、OVLのライブラリ化

とりあえず適当なWorkspaceとDesignを作って、テストターゲットのRTLファイルと、テストベンチのファイルを作っておいてください。そして、

Riviera-proインストールディレクトリ/vlib/ovl/compile_ovl_vl.do

(VHDLだとcompile_ovl_vhd.do)をRiviera-PROのさっき作ったDesignの中に放り込んで、そいつを右クリックでExecute

Riviera-proインストールディレクトリ/vlib/ovl/ovl_vl

にフォルダが生成され、その中にRiviera-PRO用のOVL library(ovl_vl.lib)が生成されます。一度、このlibraryが生成されたら、Designのcompile_ovl_vl.doはデザインから消しても問題ありません。

あとから分かりましたが、Tools → Execute Macro…からcompile_ovl_vl.doを指定してもライブラリ化できる。そして、コンソールでcompile_ovl_vl.doを実行してもok

OVLライブラリをデザインに登録する

Librariesタブの中の、libruary.cfgを右クリックして、Attachで、先ほど生成されたovl_vl.libを選択します。

でも、これだけではまだカレントデザインにOVL ライブラリがインクルードされていません。Design Managerで対象のデザインを右クリックしてpropertiesを選択。CategoryからCompilation → SystemVerilog → Entries → Librariesで、フォルダマークを押して、ovl_vlを選択。

次に、OVLのヘッダファイルをincludeするために、 Compilation → SystemVerilog → Entries → Include Directoriesで、

Riviera-proインストールディレクトリ/vlib/ovl/std_ovl

フォルダを選択。このディレクトリにはstd_ovl_defines.hが含まれています。

検証ターゲットとテストベンチ

今回はどうでも良い検証ターゲットと、テストベンチを用意しました。あまり例として良くないと思うのですが… どういうところにアサーションを導入するかっていうのは私もまだ勉強中です。

今回の例は、あるカウンタ(b_counter)を用意して、そいつがparameterで与えられるSTOPの値を超えていて、なおかつiCORECTがEnableの時にErrorとするようにしています。

テストベンチ

 
`define CYCLE 20		//50MHz
`default_nettype none
 
module ovl_ecample_test;
	parameter N = 8;
	parameter STOP = 8'hf0;
 
	reg iCLOCK;
	reg inRESET;
	reg iCORECT;
	wire [N-1:0] oCOUNT;
 
	ovl_example #(
		N,
		STOP
	)TARGET(
		.iCLOCK(iCLOCK),
		.inRESET(inRESET),
		.iCORECT(iCORECT),
		.oCOUNT(oCOUNT)
	);
 
	initial begin
		#0 begin
			iCLOCK = 1'b0;
			iCORECT = 1'b0;
			inRESET = 1'b0;
		end
		#1 begin
			inRESET = 1'b1;
		end
		#(`CYCLE * 2000000)begin	
			$finish;
		end
	end //initial
 
	always#(`CYCLE /2)begin
		iCLOCK = !iCLOCK;
	end
 
endmodule //test bench
 
`default_nettype wire

ターゲットRTL

`include "std_ovl_defines.h"
`default_nettype none
 
module ovl_example #(
		parameter N = 8,
		parameter STOP = 8'hf0
	)(
		input iCLOCK,
		input inRESET,
		input iCORECT,
		output [N-1:0] oCOUNT
	);
 
	//Counter
	reg [N-1:0] b_counter;
	always@(posedge iCLOCK or negedge inRESET)begin
		if(!inRESET)begin
			b_counter <= {N{1'b0}};
		end
		else begin
			if(iCORECT)begin
				if(b_counter < STOP)begin
					b_counter <= b_counter + {{N-1{1'b0}}, 1'b1};
				end
				else begin
					b_counter <= b_counter + {N{1'b0}};
				end
			end
			else begin
				b_counter <= b_counter + {{N-1{1'b0}}, 1'b1};
			end
		end
	end //end always : counter
 
	//Assertion(OVL)
	ovl_range #(
		`OVL_ERROR,										//Severity
		N,												//Width
		0,												//MIN
		STOP,											//MAX
		`OVL_ASSERT,
		"[Error][OVL][ovl_example] : range over error",
		`OVL_COVER_NONE, 	
		`OVL_POSEDGE,									//Clock Edge
		`OVL_ACTIVE_LOW,								//Reset Condition
		`OVL_GATE_CLOCK				
	)ovl_counter_range_check(
		.clock(iCLOCK),
		.reset(inRESET),
		.enable(1'b1),
		.test_expr(b_counter),							//Target
		.fire()
	);
 
	assign oCOUNT = b_counter;
 
endmodule
 
`default_nettype wire

今回使用したものはovl_rangeというもので、test_exprで与えられる値が、parameterで与えるmin, maxの間に収まっていないときにErrorと出してくれます。これ以外のもたくさんの検証が可能ですが、FPGAの部屋などに詳しく乗っているため(とても参考になりました!)ここでは詳しく書きません。

FPGAの部屋 OVL(Open Verification Library)を試してみる7(OVLチェッカの概要)

あとはpdfのマニュアルがRiviera-PROと一緒にインストールされているのでそこら辺を参考にする。

ということで、コンパイルして実行してみました。しっかり、Consoleにエラーが出ていますね。

今回のようにインラインアサーションにする場合はどのファイルからメッセージが出ているか不明になるため、parameterで与えるエラーメッセージにモジュール名を含めると良いかと思います。