殆ど同じ記述をいくつも並べて書くのは面倒だ。それを解決するために 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 のすべてが最適化で消える。