for_gen
ほぼ同じ記述を何度も書くのは面倒。そこで 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);
}
}
この記述は、以下のように展開されます:
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
はコンパイル時に展開される構文で、プロセス内でも使用可能です。
定数条件による最適化の例:
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;
}
}
この記述は、以下のように最適化されます:
process proc(clkin uint#1 clk, rstin uint#1 rst, out uint#1 outp)
{
while (1) {
outp = 1;
}
}
opt
/ optn
変数や引数の有無を条件で制御したい場合は 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
のすべてが消えます。
optn
を使うと論理が反転し、COND != 1
の場合に消えます。
通常、Cherry Syn で生成される回路では、変数はレジスタにマッピングされます。
しかし、RAM にマッピングできると便利な場面もあるため、対応しました。
process process1(clkin uint#1 clk, rstin uint#1 rst, ram uint#9 r0[2048])
{
uint#8 onram<r0> a; // address 0
uint#8 onram<r0> b; // address 1
uint#16 onram<r0> c; // address 1–2
uint#8 onram<r0> d[16]; // address 0x3–0x12
uint#8 i;
a = 1;
b = a;
c = 300;
for (i = 0; i != 16; i++) d[i] = i;
while (1);
}
この例では、RAM r0
に変数 a
, b
, c
, 配列 d
をマッピングしています。
それでは皆さん、ごきげんよう!