---
title: "高位合成（HLS）とは：C++からRTLを作る仕組みとpragmaの効き方・手書きHDLとの使い分け"
url: "https://www.issoh.co.jp/tech/details/18907/"
published: 2026-10-26
updated: 2026-10-26
categories: ["インフラ・クラウド"]
publisher: "株式会社一創"
---

# 高位合成（HLS）とは：C++からRTLを作る仕組みとpragmaの効き方・手書きHDLとの使い分け

高位合成（HLS：High-Level Synthesis）は、C/C++やSystemCで書いたアルゴリズムから、FPGAやASICに載せるRTL（レジスタ転送レベルの回路記述）を自動で生成する設計手法です。VerilogやVHDLでクロックごとの動きを書く代わりに、「何を計算するか」をソフトウェアの関数として書き、「どの演算を何クロック目に、どの回路で実行するか」をツールに決めさせます。この記事では、合成の仕組みを押さえたうえで、AMDのVitis HLS 2026.1系で16タップのFIRフィルタを合成する設定ファイルとコマンド、パイプライン化・アンロール・配列分割のpragmaが回路をどう変えるかを示す内容です。後半では、手書きHDLとの品質差を調査論文の数字で確かめ、採用する条件と見送る場面、ソフトウェア技術者をFPGA案件に加える体制まで判断します。FPGAそのものの仕組みは[FPGAがLUTと配線で回路を組む仕組みを解説した記事](https://www.issoh.co.jp/tech/details/9296/)に譲りました。

## まとめ｜アルゴリズム探索と短納期で選び極限のタイミングでは手書きHDLに戻す

先に示すのは、採用する案件の条件です。高位合成は、アルゴリズムの試行錯誤が多い案件と、納期が短い案件で選びます。C++のままテストベンチを回せるため、仕様を変えるたびにHDLを書き直す手間が消え、調査論文では開発時間がRTL設計の3分の1という平均値が出ています。

一方で、生成される回路の品質は平均すると手書きRTLに届きません。動作周波数を限界まで上げたい回路、数十本程度の制御ロジック、外部I/Oのタイミングを1クロック単位で詰める回路は、手書きHDLのほうが早く確実です。

実務での落としどころは、データ処理の中核をHLSで書き、周辺の制御とI/OはHDLで書く混在構成です。そのうえで、生成されたRTLとレポートを読めるハードウェア担当を最低1人置きます。pragmaの選び方はハードウェアの構造を知らないと決められないため、C++が書けるだけの体制では性能が出ません。

## 高位合成の仕組み｜C++の関数がスケジューリングとバインディングでRTLになるまで

高位合成ツールは、ソフトウェアのコンパイラに似た構造をしていますが、出力は機械語ではなく回路です。[IEEEの技術解説](https://technav.ieee.org/topic/high-level-synthesis)も、振る舞いの記述を実装可能なRTLへ変換する設計自動化の手法として位置づけています。

### 合成の3段階｜スケジューリング・バインディング・制御回路の生成

ツールの内部では、おおむね次の3つの処理が走ります。最初のスケジューリングでは、C++の演算をデータの依存関係で並べ、どの演算を何クロック目に実行するかを決める処理です。指定したクロック周期に収まらない演算は、複数のクロックに分割されます。

次のバインディングで、スケジュールした演算を実際の回路資源へ割り当てます。乗算をDSPブロックで作るか、配列をブロックRAMにするかレジスタにするかを決めるのが、この段階です。最後に、各演算の開始と終了を管理する状態機械（FSM）と、外部とのインタフェース回路が生成されます。設計者がpragmaで指示するのは、主にこのスケジューリングとバインディングの方針です。

### 略語HLSの取り違えに注意｜動画配信のHTTP Live Streamingとは別物

「HLS」で検索すると、動画配信の規格であるHTTP Live Streamingの解説が多く出てきます。こちらは映像を細切れのファイルに分けて配信する仕組みで、回路設計とは無関係です。FPGAや半導体の文脈で「HLS」と書かれていれば高位合成を指します。社内の資料では「高位合成（HLS）」と併記しておくと、配信系のチームとの会話で混乱しません。

### 主な高位合成ツール｜Vitis HLS・Catapult・Bambuの入力と対象

| ツール       | 提供元         | 入力言語        | 主な対象      |
| --------- | ----------- | ----------- | --------- |
| Vitis HLS | AMD         | C・C++       | AMDのFPGA  |
| Catapult  | Siemens EDA | C++・SystemC | ASIC・FPGA |
| Bambu     | ミラノ工科大学     | C・C++       | 研究・複数ベンダー |

FPGAの案件では、使うデバイスのベンダーが出すツールを選ぶのが基本です。AMDのFPGAならVitis HLSで、ツール本体は無償で入手できます。[SiemensのCatapult](https://www.siemens.com/en-us/products/ic/catapult-high-level-synthesis/)はC++またはSystemCを入力とし、ASIC・eFPGA・FPGAのいずれにも向けられる商用ツールで、ASICとFPGAで同じソースを使い回したい場合の候補になります。[Bambu](https://github.com/ferrandi/PandA-bambu)はミラノ工科大学のPandAプロジェクトが公開するオープンソースのフレームワークで、研究用途が中心です。ベンダーごとのツールの違いは[FPGAメーカー4社の開発ツールを比べた記事](https://www.issoh.co.jp/column/details/17707/)にまとめています。

## Vitis HLSで合成を動かす手順｜設定ファイル1枚でCシミュレーションから合成まで

ここからは、AMDのVitis HLSで16タップのFIRフィルタを合成する例を示します。Vitis HLSは2023.2系以降、統合IDEのVitis Unified IDEに組み込まれ、コマンドラインでは設定ファイル（`hls_config.cfg`）を渡して動かす方式が標準になりました。コマンドは[UG1399（2026.1版・2026年9月11日）のコマンドラインの節](https://docs.amd.com/r/en-US/ug1399-vitis-hls/Creating-HLS-Components-from-the-Command-Line)に沿っています。

### 合成対象のC++関数を書く｜任意ビット幅のap\_int型とループのラベル

```
// fir.h
#include <ap_int.h>
#define LEN  1024
#define TAPS 16
typedef ap_int<16> data_t;   // 入力・出力のサンプル
typedef ap_int<16> coef_t;   // 係数（Q15の固定小数点）
typedef ap_int<40> acc_t;    // 積和の途中結果
void fir(const data_t in[LEN], data_t out[LEN], const coef_t c[TAPS]);

// fir.cpp
#include "fir.h"
void fir(const data_t in[LEN], data_t out[LEN], const coef_t c[TAPS]) {
  data_t shift[TAPS];
  coef_t cl[TAPS];
#pragma HLS array_partition variable=shift type=complete
#pragma HLS array_partition variable=cl type=complete
INIT:
  for (int t = 0; t < TAPS; t++) { shift[t] = 0; cl[t] = c[t]; }
SAMPLE:
  for (int n = 0; n < LEN; n++) {
#pragma HLS pipeline II=1
    acc_t acc = 0;
  TAP:
    for (int t = TAPS - 1; t > 0; t--) {
      shift[t] = shift[t - 1];
      acc += shift[t] * cl[t];
    }
    shift[0] = in[n];
    acc += in[n] * cl[0];
    out[n] = acc >> 15;
  }
}
```

ソフトウェアのC++と違うのは型です。`ap_int<16>`は16ビットの符号付き整数で、ビット幅がそのまま回路の配線本数になります。`int`で書けば32ビットの演算器が作られるため、必要な幅だけを宣言するのが面積を抑える第一歩です。ヘッダは[AMDがGitHubで公開するシミュレーション用のap\_int.h](https://github.com/Xilinx/HLS%5Farbitrary%5FPrecision%5FTypes)でも中身を読めますが、合成にはツール同梱のものを使います。`SAMPLE:`のようなラベルは、レポートや設定ファイルでループを名指しするために付けます。

### テストベンチと設定ファイルを用意し3つのコマンドで検証と合成を回す

```
// fir_tb.cpp：C++の参照モデルと突き合わせる
#include <cstdio>
#include "fir.h"
int main() {
  static data_t in[LEN], out[LEN];
  coef_t c[TAPS];
  for (int t = 0; t < TAPS; t++) c[t] = 2048;              // 各タップ1/16
  for (int n = 0; n < LEN; n++) in[n] = (n % 64 < 32) ? 1000 : -1000;
  fir(in, out, c);
  int err = 0;
  for (int n = 0; n < LEN; n++) {
    long long acc = 0;
    for (int t = 0; t < TAPS && t <= n; t++)
      acc += (long long)in[n - t].to_int() * c[t].to_int();
    if (out[n].to_int() != (int)(acc >> 15)) err++;
  }
  printf("errors=%d\n", err);
  return err ? 1 : 0;   // 0以外を返すとシミュレーション失敗
}
```

```
# hls_config.cfg
part=xc7z020clg400-1

[hls]
syn.file=fir.cpp
syn.top=fir
tb.file=fir_tb.cpp
clock=10ns
syn.output.format=rtl
```

```
# 1. Cシミュレーション：C++として実行し、アルゴリズムの正しさを確かめる
vitis-run --mode hls --csim --config ./hls_config.cfg --work_dir fir_prj

# 2. C合成：RTLを生成し、レイテンシとリソースのレポートを出す
v++ -c --mode hls --config ./hls_config.cfg --work_dir fir_prj

# 3. C/RTL協調シミュレーション：同じテストベンチで生成RTLを検証する
vitis-run --mode hls --cosim --config ./hls_config.cfg --work_dir fir_prj
```

設定ファイルの`part`はデバイスの型番で、`[hls]`の外に書きます。`syn.top`が合成の最上位関数、`tb.file`がテストベンチで、複数あれば1ファイルずつ行を重ねます（[UG1399の設定ファイルコマンドの節](https://docs.amd.com/r/en-US/ug1399-vitis-hls/HLS-Config-File-Commands)）。HLSの強みが表れるのは、手順1と3の検証工程です。C++の参照モデルと同じテストベンチを、合成前のC++にも生成後のRTLにも流せるため、HDLでテストベンチを一から書く工程が減ります。IPとして出力する場合は`--package`を付けた`vitis-run`を追加します。

### 合成レポートで見る3つの数値｜レイテンシ・II・リソース使用量

C合成が終わったら、レポートで次の3つを見ます。1つ目はレイテンシで、関数の開始から結果が出るまでのクロック数です。2つ目はII（Initiation Interval）で、ループの次の反復を何クロック後に始められるかを示します。今回の`SAMPLE`ループで狙うのはII=1、つまり毎クロック1サンプルを処理する状態です。3つ目はLUT・フリップフロップ・DSP・ブロックRAMの使用数で、デバイスの容量に対する割合を確かめます。要求したIIに届かなかった場合、ツールは警告を出したうえで達成できた最小のIIで回路を作るため、警告を読み飛ばさないことが肝心です。

## pragmaの効き方を確かめる｜パイプライン化・アンロール・配列分割の3点

HLSの性能は、C++の書き方とpragmaの組み合わせで決まります。先のFIRで使った3種類のpragmaが、それぞれ回路をどう変えるかを見ていきます。

### PIPELINEで反復を重ねる｜II=1を阻むループ間の依存関係

パイプライン化は、ループの前の反復が終わる前に次の反復を始める指示です。[UG1399のループのパイプライン化の節](https://docs.amd.com/r/en-US/ug1399-vitis-hls/Pipelining-Loops)では、1反復3クロックのループを20回回すと順番どおりなら60クロックかかる例を挙げ、II=1を理想としています。構文は[PIPELINEプラグマの節](https://docs.amd.com/r/en-US/ug1399-vitis-hls/Pipeline)にあるとおり`#pragma HLS pipeline II=<int>`です。同じ節によると、パイプライン化したループの内側にあるループは自動でアンロールされます。FIRの`TAP`ループにpragmaを書かずに済んだのはこのためです。また、反復回数が64を超えるループは、pragmaが無くても自動でパイプライン化されます。

```
// II=1に届かない典型：前の反復が書いた値を次の反復が読む
void hist(const ap_uint<8> in[LEN], int bins[256]) {
HIST:
  for (int i = 0; i < LEN; i++) {
#pragma HLS pipeline II=1
    bins[in[i]]++;   // 同じビンが続くと、読み出し前に書き込みが終わっていない
  }
}
```

ヒストグラムのように、メモリへの読み書きが反復をまたいで依存するループは、II=1を指定しても届かないことがあります。UG1399も、データの依存関係がIIを押し上げると説明しています。対処は、依存する演算を反復の早い段階に寄せる、直前の値をレジスタに保持して同じビンへの連続加算をまとめる、といったC++側の書き換えです。pragmaを足しても依存関係は消えません。

### UNROLLで回路を複製する｜factor指定とリソースの増え方

アンロールは、ループ本体の回路を複製して複数の反復を同時に実行させる指示です。[UG1399（2025.2版）のUNROLLプラグマの節](https://docs.amd.com/r/2025.2-English/ug1399-vitis-hls/pragma-HLS-unroll)によると、`#pragma HLS unroll factor=4`のようにfactorを指定すると本体が4つに複製され、反復回数が4分の1になります。factorを省くと完全に展開されます。反復回数がfactorで割り切れなくても、ツールが出口の判定を追加するため結果は変わりません。

代償はリソースです。FIRの`TAP`ループが完全に展開されると、乗算器が16個並びます。タップ数を64に増やせば乗算器も64個近くになり、DSPブロックの不足につながる構成です。性能が足りないときに真っ先にアンロールを足す、という進め方は回路の面積を急に膨らませるため、レポートのリソース欄と並べて判断します。

### ARRAY\_PARTITIONでメモリのポート不足を解消する

アンロールしても速くならない原因の多くは、配列のポート不足です。C++の配列はブロックRAMとして作られることが多く、1つのメモリに同時にアクセスできる数には上限があります。16個の乗算器が同じクロックで係数を読みに行っても、メモリの出口が足りなければ順番待ちになります。

[UG1399の配列分割の節](https://docs.amd.com/r/en-US/ug1399-vitis-hls/Array%5Fpartition)によると、ARRAY\_PARTITIONは1つの配列を小さな複数の配列や個々の要素に分け、読み書きのポートを増やします。分け方は3種類で、要素を交互に振り分けるcyclic、連続した塊で分けるblock、1要素ずつレジスタにするcompleteがあります。FIRでは`shift`と`cl`をcompleteで分割し、16要素すべてを同時に読めるようにしました。大きな配列をcompleteで分けるとレジスタが膨らむため、アンロールのfactorとcyclicのfactorを揃える分け方が基本です。

```
// アンロールの並列度とメモリの分割数を揃える例
int buf[1024];
#pragma HLS array_partition variable=buf type=cyclic factor=4
SUM:
for (int i = 0; i < 1024; i++) {
#pragma HLS unroll factor=4
  acc += buf[i];   // 4つのメモリから1要素ずつ同時に読む
}
```

このほかの書き方の型は、[AMDのVitis HLS入門サンプル集](https://github.com/Xilinx/Vitis-HLS-Introductory-Examples)にまとまっています。配列分割・インタフェース・パイプライン化などの分類ごとに、ソースとテストベンチ、設定ファイルが揃っており、手元で合成して効果を確かめられます。

## 手書きHDLとの品質差と生産性｜面積・周波数・開発期間のトレードオフ

HLSを採用するかどうかは、生産性と回路の品質のどちらを取るかの判断です。感覚論で決めないために、まとまった調査の数字を見ます。

### 調査論文が示す数字｜開発時間は3分の1・品質はRTLが上回る

タンペレ大学のLahtiらが2019年にIEEE TCADへ発表した[高位合成の現状調査](https://researchportal.tuni.fi/en/publications/are-we-there-yet-a-study-on-the-state-of-high-level-synthesis/)は、2010年以降の46本の論文と118件の設計事例を集計しています。結果は、HLSの平均開発時間がRTL設計の3分の1で、生産性は4倍を超えるというものでした。一方、回路の品質（QoR：面積・性能など）は、平均するとRTL設計のほうが上だと結論づけています。論文の結論も、HLSは試作の高速化と短納期の設計で有力な選択肢だというものです。

| 比較の軸      | 高位合成       | 手書きHDL   |
| --------- | ---------- | -------- |
| 開発時間      | RTLの約3分の1  | 基準       |
| 回路の品質     | 平均でRTLに劣る  | 上回る      |
| 仕様変更の追従   | C++を直して再合成 | RTLを書き直す |
| サイクル単位の制御 | ツールに委ねる    | 設計者が決める  |

ただし、論文に集まる事例は「HLSで成果が出た」報告に偏りやすい点は割り引いて読むべきです。開発時間の短縮は、Cシミュレーションで検証を回せるアルゴリズム中心の回路で出やすく、I/O制御が中心の回路では縮みません。

### 生成されたRTLを読む力は必要｜II未達とタイミング違反の原因を追う

HLSを使えばHDLを書かずに済む、という期待は半分だけ当たります。C++を書く量は減りますが、レポートでIIが届かない原因を探る、生成されたRTLのタイミング違反を配置配線の結果から追う、といった作業にはHDLと回路の知識が要ります。言語ごとの読み方は[FPGA開発言語の選び方を扱った記事](https://www.issoh.co.jp/tech/details/18905/)で整理しました。HLSで作った回路も、論理合成・配置配線・タイミング検証の工程は手書きHDLと同じで、ここは[FPGA設計の7工程と期間の見積り方を扱った記事](https://www.issoh.co.jp/tech/details/16844/)の流れに乗ります。

## 高位合成を採用する条件と見送る場面｜体制づくりまで含めた判断

ここからは判断です。HLSの向き不向きは、回路の種類と組織の体制の両方で決まります。

### 採用する条件｜アルゴリズム探索が多い・短納期・ソフト技術者が主力

次の条件のうち2つ以上に当てはまれば、HLSを第一候補にします。1つ目は、画像処理・信号処理・推論の前処理など、アルゴリズムのパラメータを何度も変えて性能と精度を比べる案件です。C++のまま比べられるため、試行1回あたりの手間が小さく済みます。2つ目は、試作を数か月で出す必要がある短納期の案件です。3つ目は、チームの主力がC++のソフトウェア技術者で、HDLを書ける人が少ない組織です。ニューラルネットワークの推論を載せる場合は、HLSで一から書くより、ベンダーの推論IPを使う方式が先に検討に上がります。その比較は[FPGAで推論を回す実装を扱った記事](https://www.issoh.co.jp/tech/details/16846/)にあります。

### 見送る場面｜極限のタイミング要求・小規模な制御回路・I/O直結

反対に、次の場面ではHLSを見送り、手書きHDLで書きます。デバイスの上限近い周波数で動かす回路、面積を1割でも削りたい量産品の回路は、HLSの品質差がそのまま損失になります。数十行のHDLで書ける状態機械や、外部の通信プロトコルの信号を1クロック単位で合わせる回路も、HLSを使うとかえって遠回りです。ツールのライセンスと学習の費用を含めた総額の見方は[FPGAの総コストの内訳を扱った記事](https://www.issoh.co.jp/column/details/16900/)を参照してください。

### ソフト技術者をFPGA案件に載せる体制｜ハード担当1人とレビューの置き方

HLSでソフトウェア技術者がFPGA開発に加わるとき、体制の要はハードウェア担当を1人置くことです。役割は3つあります。データの流れからメモリの分け方とインタフェースを決めること、pragmaの指定と合成レポートをレビューすること、HLSで書く部分とHDLで書く部分の境界を引くことです。ソフトウェア技術者は、C++のアルゴリズムとテストベンチ、参照モデルとの突き合わせを担当します。テストベンチをC++で書けるのはHLSの大きな利点で、検証の工数を最も削れる部分です。

最初の1か月は、Vitis HLSのサンプル集を題材に「pragmaを外すとIIとリソースがどう変わるか」をレポートで確かめる練習に充てると、チームの共通言語ができます。センサーや機器の制御を含めた組み込み・IoTの開発としてFPGAの導入を相談したい場合は、[一創のAI・IoTソリューションの開発支援](https://www.issoh.co.jp/service/ai/iot/)で、HLSとHDLの切り分けから一緒に整理できます。

## 高位合成でよくある質問｜ツールの費用・使える言語・学習の順序

高位合成について、検索されることの多い質問に答えます。

### 高位合成ツールは有償ですか？

AMDのVitis HLSは、Vitisの開発環境に含まれて無償で入手できます。ただし、合成した回路を載せる大規模なデバイスの中には、配置配線に有償のライセンスが必要な品種があります。SiemensのCatapultのようにASICとFPGAの両方を対象にする商用ツールは、個別の見積りが必要です。ツールの費用は、デバイスと開発規模を決めてから確かめます。

### C++の機能はどこまで高位合成で使えますか？

ループ、配列、構造体、テンプレート、固定長の型は使えます。一方、実行時に大きさが決まる動的メモリ確保、再帰、OSの機能を呼ぶ標準ライブラリは、回路にできないため合成の対象外です。配列の大きさとループの回数は、コンパイル時に決まる形で書くのが原則です。テストベンチ側は通常のC++なので、ファイル入出力や標準ライブラリを自由に使えます。

### 高位合成とHDLはどちらから学ぶべきですか？

ソフトウェア技術者であれば、HLSから入って構いません。ただし、合成レポートを読み始めた段階で、クロック・レジスタ・メモリのポートといった回路の基本が必要になります。HLSで簡単な回路を作り、生成されたRTLの一部を読み、同じ回路をHDLで書き直してみる順序なら、両方の感覚を同時に身に付けられます。

### 高位合成で作った回路はASICにも使えますか？

ツールによります。Vitis HLSはAMDのFPGA向けで、ASICの設計には使えません。CatapultのようにASICとFPGAの両方を対象にするツールなら、同じC++のソースから両方のRTLを生成できます。FPGAで試作してからASICにする計画がある場合は、最初からASICに対応するツールを選ぶと、ソースを書き直さずに済みます。

### HLSで生成したRTLの品質はどうやって確かめますか？

3段階で確かめます。まずC合成のレポートで、IIとレイテンシが狙いどおりか、リソースがデバイスの容量に収まるかを見ます。次のC/RTL協調シミュレーションで検証するのは、C++のテストベンチと同じ結果が生成RTLでも得られるかどうかです。最後に、論理合成と配置配線を通した後のタイミングレポートで、目標の周波数を満たしているかを確かめます。HLSのレポート上の見積りと配置配線後の実際の値はずれることがあるため、最後の確認は省けません。

## 関連記事

- [FPGAとは？LUTと配線で回路を組む仕組みとCPU・ASIC・CPLDとの違い](https://www.issoh.co.jp/tech/details/9296/)：高位合成で生成した回路が、FPGAの中でどう実現されるかを扱う親記事です。
- [FPGA開発言語の選び方｜Verilog・VHDL・SystemVerilogの違いと判断表](https://www.issoh.co.jp/tech/details/18905/)：HLSと組み合わせるHDL三言語の選び方です。
- [FPGA設計の流れ｜7工程の進め方とソフト開発との違い・期間と体制の見積り方](https://www.issoh.co.jp/tech/details/16844/)：HLSの後に続く論理合成・配置配線・検証の工程と工数です。
- [FPGAとマイコンの違い｜同じ処理をCとVerilogで書き比べて分かる選定の5軸](https://www.issoh.co.jp/tech/details/18903/)：CとVerilogの書き比べで、ソフトと回路の考え方の違いを示した記事です。
- [FPGAによるAI推論とは？量子化・推論IP実装とGPUとの使い分けを実装視点で解説【2026年版】](https://www.issoh.co.jp/tech/details/16846/)：推論処理をHLSで書くか推論IPを使うかの判断を扱っています。

---

出典: [高位合成（HLS）とは：C++からRTLを作る仕組みとpragmaの効き方・手書きHDLとの使い分け](<https://www.issoh.co.jp/tech/details/18907/>)（株式会社一創）
