ページコンテンツ
ここまで、FPGAやHDLなどの解説記事を出してきました。
しかし、プログラミング関係の鉄則となるのは、実際に作ってみること。
どんなに論理で学んでも「何を作るのか?」「何をやるのか?」が最重要項目となります。
プログラミング学習に関しては一生懸命四則演算とか、文法を覚える必要は全くなく、まず間違いなく何を作るか?そして実際に作るが最短距離になります。
この記事では、実際に「弱・中・強」の3段階風量モードを備えた扇風機の制御基板を、HDLとFPGAを使って最初から設計・実装・動作確認まで行う手順をまとめます。
電気に詳しくなくても、手順通り進めれば必ず完成します。
目標仕様(仕様設計)
項目 | 内容 |
---|---|
モード数 | 3段階:弱 / 中 / 強 |
入力 | ボタン(1つ)を押すごとにモード切り替え |
出力 | モーター回転信号(PWM) |
状態表示 | LED 3個で現在の風量モードを表示 |
安定性 | グリッチ防止(チャタリング除去)付き |
開発言語 | Verilog HDL |
FPGAで回路を設計する際、「安定性」とは回路が想定どおりに動き続けることが保証されている状態を指します。
つまり、入力が揺らいだときでも出力に誤動作が生じないこと、電源投入後すぐに正しく初期化されること、クロックが乱れたときにバグを起こさないことなど、予測不能な挙動を排除する工夫が含まれます。
HDLの記述は一見するとシンプルでも、非同期入力や信号遷移のタイミング差があると、意図しないグリッチ(瞬間的な誤信号)が発生します。
このような問題はシミュレーションだけでは検出できないことも多く、物理的な実機環境でこそ発生する厄介な問題です。
そのため、安定した動作のためには、信号の同期化、チャタリング除去、初期化処理、遅延吸収といった「設計者による安全対策」が不可欠です。
「グリッチ(glitch)」とは、本来なら起きるはずのない一瞬だけの不正な信号変化のことです。たとえば、LEDをONにする信号が出ているはずなのに、ほんの1クロックだけOFFになってしまったり、逆に一瞬だけ間違ってONになるような現象です。
グリッチは、主に入力信号が複数の回路経路を経由する際、遅延時間が微妙にズレることによって発生します。
FPGAでは、こうしたズレが複雑な回路で蓄積しやすく、状態遷移が誤動作する要因になります。
グリッチを防ぐには、信号をフリップフロップで一度受けてクロックに同期させる「同期化」、あるいは信号を2段階のレジスタで受けるといった手法が効果的です。
これはFPGAの世界では「同期設計の基本」であり、安定した動作のためには欠かせない対策です。
「チャタリング(chattering)」とは、スイッチやボタンを押したときに、機械的なバウンドにより信号が細かくON/OFFを繰り返す現象のことです。
たとえば、人間が1回ボタンを押しただけでも、内部では10回以上のパルスが発生してしまうことがあります。
これは、Bluetoothキーボードなどを使ったことがある人はあるあるですよね。
スイッチ接点の物理的な性質によるもので、HDL設計上ではボタン1回に対して信号が複数回カウントされる不具合を引き起こします。
特に今回のようにボタンでモードを切り替える回路では、チャタリングがあると1回押すだけで3段階すべてスキップしてしまうといった誤動作が起こり得ます。
チャタリング除去には、一定時間(たとえば10ms)ボタンの状態が安定していないと変化を認めないような「デジタルフィルタ(遅延型デバウンス)」処理をHDLで組み込みます。
このように、機械の曖昧さをデジタル論理で明確に変換することが、HDL設計の重要なポイントとなります。
使用するソフトウェア・ハードウェア一覧と役割
名称 | 役割 | 備考 |
---|---|---|
Tang Nano 9K(GW1NR-9) | FPGA本体 | HDMI・多ピンIO・USB書き込み対応 |
Gowin IDE | HDL記述、合成、書き込み | Tang Nano 9K専用IDE(無料) |
Icarus Verilog | HDLシミュレーション | UNIX系CLIツール(Windowsでも動作可) |
GTKWave | 波形表示 | シミュレーション結果確認に必須 |
ブレッドボード・ジャンパーワイヤ | 実験用回路接続 | LEDやボタンを接続 |
トグルスイッチ or タクトスイッチ | モード切り替え入力 | 押すごとに風量切り替え |
LED×3 + 抵抗×3 | モード表示用 | 各モードで1つが点灯 |
ファンモーター + FET(IRF520等) | 実際の出力駆動用 | モーター制御 |
電源(5V or 12V) | ファン用電源 | FPGAとは別供給 |
シミュレーションって何?
◎ シミュレーションとは「回路をつくる前に頭の中で動かしてみること」
簡単に言うと、「作る前に動かしてみる練習」のことです。
例えば、こんな状況を想像してみてください。
ボタンを押すたびに風量が「弱 → 中 → 強」と変わる扇風機を作ったとします。
でも、いきなり本物の基板に書き込んで動かしてみたら……全然動かない!?
なぜ? どこが悪い? 何が起こってるのかも見えない!
これではとても困りますよね。
そこで出番なのが「シミュレーション」という便利な技術です。
これは、回路がどう動くかをパソコンの画面の中で“見える化”する作業のこと。
実際のファンやLEDは動かないけれど、「スイッチを押したら信号がどう変わったか?」という回路の中の動きがグラフや波の形で見えるようになります。
つまり、回路の練習試合のようなものだと考えてください。
シミュレーションってどうやってやるの?無料なの?
はい。
シミュレーションには無料のソフトを使います。
使う道具はこの2つ:
- Icarus Verilog(イカルス・ヴェリログ)
→ あなたが作った回路の「動きを計算してくれる」ソフト。
これは無料で使えるコマンド入力型のソフトです。 - GTKWave(ジーティーケーウェーブ)
→ Icarus Verilogで出てきたデータを「波のグラフ」で表示してくれるソフト。
これも無料で使えます。パソコンで波を眺める道具と思ってください。
Icarus VerilogとGTKWaveはどこで手に入るの?
▼ Macを使っている場合すごく簡単に入ります。ターミナルを開いて、こう入力するだけ:
brew install icarus-verilog gtkwave
設計の全体像
┌─────────────┐
│ タクトスイッチ │ ← ボタン1つ
└────┬────────┘
│
▼
┌──────────────┐
│ FPGA(Tang Nano 9K)│
│ ・モード制御 │
│ ・PWM生成 │
└────┬───────┘
│
▼
┌──────────┐ ┌─────┐
│ モード表示LED群 │ ← LED3つ(弱中強)
└──────────┘ └─────┘
│
▼
┌────────────┐
│ モータードライバ(FET)│ ← PWMで制御
└────────────┘
│
▼
┌────────┐
│ DCファンモーター │
└────────┘
Verilog HDLでの基本回路
ファイルの保存場所と拡張子は?
以下のように保存します:
- 回路本体 →
fan_controller.v
- テスト用コード →
testbench.v
.v
という拡張子が大事です。
これが「Verilogのファイルだよ」とパソコンに教えるマーク。
ここで前に出てきた「Icarus Verilog(シミュレーションの道具)」が登場します。
たとえば、デスクトップに以下のようなファイルを作ってあるとします:
~/Desktop/fan_project/
├── fan_controller.v ← 本体回路
├── pwm_generator.v ← PWM信号の出力回路
└── testbench.v ← 試運転用の指示書
このフォルダでターミナルを開いて、以下のコマンドを入力します。
つまり、コンパイル作業をコマンド上でやるということですね。
- テキストファイル(Verilogコード)を書く
- ターミナルでコンパイルコマンドを打つ
- その結果が機械語のファイルになる
- それを動かすと、仮想的な「回路の動き」が見られる
- その動きを波形で表示して確認する(GTKWave)
コンパイル
HDL(Verilogなど)で書いたコードをそのままでは使えません。
まずは「機械(シミュレータやFPGA)が理解できる形に変換する作業」が必要です。
それがいわゆるコンパイルです。
iverilog -o fan_tb testbench.v fan_controller.v pwm_generator.v
これで「fan_tb」という実行用ファイルができあがり、それをこうして動かします。
vvp fan_tb
その結果が .vcd
というファイルに出力され、これを GTKWave で開いて中身を見ることができます。
モードカウンタ(ボタンでモード切替)
module fan_controller (
input wire clk,
input wire reset,
input wire button,
output reg [1:0] mode // 00=弱, 01=中, 10=強
);
reg [1:0] state;
reg button_last;
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= 2'b00;
button_last <= 0;
end else begin
// ボタン立ち上がり検出
if (button && !button_last) begin
state <= state + 1;
if (state == 2'd2)
state <= 0;
end
button_last <= button;
end
end
assign mode = state;
endmodule
PWMモジュール(風量に応じたデューティ比)
module pwm_generator (
input wire clk,
input wire [1:0] mode,
output wire pwm_out
);
reg [7:0] counter = 0;
reg [7:0] duty = 0;
always @(mode) begin
case (mode)
2'b00: duty = 8'd64; // 弱(25%)
2'b01: duty = 8'd128; // 中(50%)
2'b10: duty = 8'd192; // 強(75%)
default: duty = 8'd0;
endcase
end
always @(posedge clk) begin
counter <= counter + 1;
end
assign pwm_out = (counter < duty) ? 1 : 0;
endmodule
シミュレーションを実行
testbench.v
を作成してボタン押下と出力変化を確認- コマンドラインで動作確認:
iverilog -o fan_tb testbench.v fan_controller.v pwm_generator.v
vvp fan_tb
gtkwave fan_tb.vcd
FPGA書き込み手順
- Gowin IDEでプロジェクト作成
- ソースコード読み込み
- ピン配置設定(例):
- clk → PIN38
- button → PIN40
- pwm_out → PIN35
- LED → PIN22, 23, 24
- Synthesize → P&R → Bitstream生成
- Tang Nano 9KにUSB接続 → 書き込み
モーター制御部の回路図(簡易)
FPGA(PWM信号)
│
├──→ Gate
┌───┴────┐
│ Nch MOSFET │
└──┬──────┘
│
DCファン+電源(12V)
│
GND
まとめと今後の展望
本記事では、HDLとFPGAを使って「三段階モードの扇風機制御回路」をゼロから設計・実装・動作確認するまでの手順を公開しました。
動作原理、PWM制御、LED表示、回路構成に至るまで再現可能な構成としています。
ここから例えば、温度センサーを導入して、自動風量の制御や、人感センサーを導入する、Bluetoothでスマホから操作したりと、改造はいくらでも展開できますよね。

音楽家:朝比奈幸太郎
神戸生まれ。2025 年、40 年近く住んだ神戸を離れ北海道・十勝へ移住。
録音エンジニア五島昭彦氏より金田式バランス電流伝送 DC 録音技術を承継し、
ヴィンテージ機材で高品位録音を実践。
ヒーリング音響ブランド「Curanz Sounds」でソルフェジオ周波数音源を配信。
“音の文化を未来へ”届ける活動を展開中。