🍒 Cherry Syn チュートリアル 第7章

ジェネレート構文とコンパイル時最適化

🔁 ジェネレート構文 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 の場合に消えます。

📦 変数をRAMにマッピングする

通常、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 をマッピングしています。

それでは皆さん、ごきげんよう!