ジェネレート機能

殆ど同じ記述をいくつも並べて書くのは面倒だ。それを解決するために for_gen という構文を追加した。


toplevel top(out uint#6 outp, in uint#3 a, in uint#3 b)
{
	const uint i;
	for_gen(i; 0; 2) {
  		outp#((i*2+1)..(i*2))=a#(i)@ b#(i);
	}
}

この例では、iに0, 1, 2という値を順番に代入しながら{}内の文を展開する。その結果、以下のように展開される。


toplevel top(out uint#6 outp, in uint#3 a, in uint#3 b)
{
	outp#(1..0)=a#(0)@ b#(0);
	outp#(3..2)=a#(1)@ b#(1);
	outp#(5..4)=a#(2)@ b#(2);
}

この例では左辺式のビットスライスを使っているので、トップレベルでの例題だが、もちろん for_gen 自体はプロセスにおいても使うことができる。for_genはコンパイル時に展開される。記述を楽にするための構文だ。

コンパイル時における最適化


const uint COND = 1;

process proc(clkin uint#1 clk, rstin uint#1 rst, out uint#1 outp)
{
	while (1) {
		if (COND) outp = 1;
		else outp = 2;	
	}
}

この例では、if文の条件は定数なのでコンパイル時に最適化され、


process proc(clkin uint#1 clk, rstin uint#1 rst, out uint#1 outp)
{
	while (1) {
		outp = 1;	
	}
}

と同じになる。

変数の宣言やプロセスの引数などのあるなしを、コンパイル時に決定している条件によって制御したい場合は、opt を使う。


const uint COND = 1;

process proc(clkin uint#1 clk, rstin uint#1 rst, opt COND out uint#8 outp)
{
    	opt COND uint#8 x = 1;
    
	if (COND) outp = x;	
}

この例で、COND = 0 にすると、outp, x, outp = x のすべてが最適化で消える。

opt の代わりに optn と書くと論理が反転になり、先の例では COND != 1 の場合に、outp, x, outp = x のすべてが最適化で消える。