コンパイラ編 - SystemVerilogバックエンド
難易度: 🟡 中級
所要時間: 30分
CmからSystemVerilog (SV) を生成し、FPGA上でハードウェアとして動作させることができます。Tang Console(Gowin)、Xilinx、Intel等のFPGAに対応しています。
基本的な使い方
# SV生成
cm compile --target=sv program.cm -o output.sv
# テストベンチも自動生成される
# output_tb.sv が同時に生成
ポート宣言
#[input] / #[output] アトリビュートで入出力ポートを宣言します。
//! platform: sv
#[input] int a = 0;
#[input] int b = 0;
#[output] int sum = 0;
void adder() {
sum = a + b;
}
生成されるSV:
module adder (
input logic signed [31:0] a,
input logic signed [31:0] b,
output logic signed [31:0] sum
);
// adder
always_comb begin
sum = a + b;
end
endmodule
組み合わせ回路と順序回路
組み合わせ回路(always_comb)
通常の関数は組み合わせ回路(always_comb)として生成されます。
//! platform: sv
#[input] int a = 0;
#[input] int b = 0;
#[input] int c = 0;
#[output] int out = 0;
void max3() {
if (a > b) {
if (a > c) { out = a; } else { out = c; }
} else {
if (b > c) { out = b; } else { out = c; }
}
}
順序回路(always_ff)
posedge / negedge 型パラメータを使うと always_ff ブロックが生成されます。
//! platform: sv
#[output] uint counter = 0;
#[output] bool led = false;
void blink(posedge clk, bool rst) {
if (rst) {
counter = 0;
led = false;
} else {
if (counter == 49999999) {
counter = 0;
led = !led;
} else {
counter = counter + 1;
}
}
}
生成されるSV:
always_ff @(posedge clk) begin
if (rst) begin
counter <= 32'd0;
led <= 1'b0;
end else begin
if (counter == 32'd49999999) begin
counter <= 32'd0;
led <= !led;
end else begin
counter <= counter + 32'd1;
end
end
end
SV固有型
| Cm型 | 説明 | 生成されるSV |
|---|---|---|
posedge |
立ち上がりエッジ | always_ff @(posedge ...) |
negedge |
立ち下がりエッジ | always_ff @(negedge ...) |
wire |
ワイヤ | wire |
reg |
レジスタ | reg |
SV幅付きリテラル
SystemVerilog形式の幅付きリテラルを直接記述でき、SV出力でもそのまま保持されます。
//! platform: sv
#[input] utiny sel = 0;
#[output] utiny out = 0;
void literal_test() {
if (sel == 0) {
out = 3'b101; // 2進数: 3ビット幅
} else if (sel == 1) {
out = 8'hFF; // 16進数: 8ビット幅
} else {
out = 8'd170; // 10進数: 8ビット幅
}
}
| Cm記述 | SV出力 |
|---|---|
3'b101 |
3'b101 |
8'hFF |
8'hFF |
8'd170 |
8'd170 |
Cm型とSV型の対応
| Cm型 | SVビット幅 | SV型 |
|---|---|---|
bool |
1 | logic |
utiny |
8 | logic [7:0] |
tiny |
8 | logic signed [7:0] |
ushort |
16 | logic [15:0] |
short |
16 | logic signed [15:0] |
uint |
32 | logic [31:0] |
int |
32 | logic signed [31:0] |
BRAM推論
配列はBlock RAM(BRAM)として推論されます。
//! platform: sv
int memory[256];
#[input] utiny addr = 0;
#[input] int wdata = 0;
#[input] bool we = false;
#[output] int rdata = 0;
void bram_access(posedge clk) {
if (we) {
memory[addr] = wdata;
}
rdata = memory[addr];
}
テストベンチ自動生成
cm compile --target=sv を実行すると _tb.sv テストベンチも自動生成されます。iverilogで検証可能:
# コンパイルとテストベンチ生成
cm compile --target=sv program.cm -o output.sv
# シミュレーション実行
iverilog -g2012 -o sim output.sv output_tb.sv
vvp sim
ターゲットFPGA
| ボード | チップ | ツール |
|---|---|---|
| Tang Console | Gowin | Gowin EDA |
| Tang Nano 9K | Gowin GW1NR-9 | Gowin EDA |
| Arty A7 | Xilinx Artix-7 | Vivado |
| DE10-Lite | Intel MAX 10 | Quartus |
Note: Gowin EDAでは Project → Configuration → Synthesis → Verilog Language でSystemVerilogを有効にしてください。
前の章: WASMバックエンド
次の章: フォーマッタ
最終更新: 2026-03-09