Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Aldec :bind


SystemVerilogでは、デザインに手を加えること無しにモジュール内に他のモジュールのインスタンスを置くことができます。
これを行うのが、bindです。

Riviera-PROのアサーションの例題でもbindをやっています。
例えば、examples/assertions/sva/verilog/bufferディレクトリのbind1.svとbind2.svファイル。
  << bind1.sv >>

    module binding;

    BufferChecker BufferCheckerInst
			(
				.Clk($root.tb.UUT.Clk),
				.Rst($root.tb.UUT.Rst),
				.DataIn($root.tb.UUT.DataIn),
				.WR($root.tb.UUT.WR),
				.Ack($root.tb.UUT.Ack),
				.Busy($root.tb.UUT.Busy),
				.Full($root.tb.UUT.Full),
				.Strobe($root.tb.UUT.Strobe),
				.Empty($root.tb.UUT.Empty),
				.CurrentState($root.tb.UUT.CurrentState),
				.NextState($root.tb.UUT.NextState),
				.RD($root.tb.UUT.FifoBuffer.RD)
			);

    PrinterChecker PrinterCheckerInst (
					.Clk($root.tb.Clk),
					.Rst($root.tb.Rst),
					.Ack($root.tb.Ack),
					.Busy($root.tb.Busy),
					.Strobe($root.tb.Strobe)
					);
    endmodule

  << bind2.sv >>

    module binding_cov;

    TestBenchChecker TestBenchcheckerInst
			(
				.Clk($root.tb.Clk),
				.Rst($root.tb.Rst),
				.DataIn($root.tb.DataIn),
				.WR($root.tb.WR),
				.Busy($root.tb.Busy),
				.Ack($root.tb.Ack),
				.Full($root.tb.Full),
				.DataOut($root.tb.DataOut),
				.Strobe($root.tb.Strobe),
				.CurrentState($root.tb.UUT.CurrentState),
				.Empty($root.tb.UUT.FifoBuffer.Empty),
				.RD($root.tb.UUT.FifoBuffer.RD)
			);

    endmodule
でも、この方法は新しいモジュールの中にチェッカーのインスタンスを置き、
インスタンスのポートに階層を跨いだアクセスにて各信号を接続しています。

この方法、SystemVerilogではなくてもできます。ただし、$root.という記述はできませんが、
SystemVerilogでは、bindを使うことで行います。
  << bind1.sv >>

    bind tb.UUT BufferChecker BufferCheckerInst
			(
				.Clk(Clk),
				.Rst(Rst),
				.DataIn(DataIn),
				.WR(WR),
				.Ack(Ack),
				.Busy(Busy),
				.Full(Full),
				.Strobe(Strobe),
				.Empty(Empty),
				.CurrentState(CurrentState),
				.NextState(NextState),
				.RD(FifoBuffer.RD)
			);


    bind tb PrinterChecker PrinterCheckerInst (
					.Clk(Clk),
					.Rst(Rst),
					.Ack(Ack),
					.Busy(Busy),
					.Strobe(Strobe)
					);

  << bind2.sv >>

    bind tb TestBenchChecker TestBenchcheckerInst
			(
				.Clk(Clk),
				.Rst(Rst),
				.DataIn(DataIn),
				.WR(WR),
				.Busy(Busy),
				.Ack(Ack),
				.Full(Full),
				.DataOut(DataOut),
				.Strobe(Strobe),
				.CurrentState(UUT.CurrentState),
				.Empty(UUT.FifoBuffer.Empty),
				.RD(UUT.FifoBuffer.RD)
			);
オリジナルの記述との違いは、
    1). 新しいモジュール(binding, binding_cov)が必要ない
  2). ポートに接続する信号名が相対名になる
です。

bindは、インスタンスを挿入したいパス(この場合は、tb.UUTやtb)内の信号名にアクセスできますので、
$root.tb.UUT.や$root.tb.が無くなります。

見た目もすっきり、bindするインスタンスを1つのファイルにまとめておけば管理も簡単ね!

検証、Verification、Aldec、SystemVerilog