VHDLデュアル7セグメントディスプレイコントローラ:Pmod SSD対応で簡単FPGA統合
7セグメントディスプレイの仕組み
Digilent製Pmod SSD:Seven-segment Displayに2桁の数字を表示するVHDLモジュールを紹介します。このデュアル7セグメントディスプレイはPmodインターフェース対応で、はんだ付け不要で使用可能。多くのFPGA開発ボードに標準搭載のPmodコネクタに直接挿せます。動作確認にはLattice iCEstick(低コストFPGAボード、Pmodコネクタ搭載)を使用。iCEstickの並列Pmodコネクタをディスプレイ期待の直列プラグに変換する2×6ピン→デュアル6ピンPmodスプリッタケーブルと、USB Type-A延長ケーブル(iCEstickを直接挿すと不便なため)を推奨します。
Digilent Pmodモジュールのデータシートによると、7つのピンが各セグメントを制御し、ロジックHighで対応セグメントが点灯。2桁ありますが同時に制御できるのは1桁のみ。J2コネクタのP4/Cピンで左右を切り替え:'0'で右桁、'1'で左桁がアクティブ。「DP」小数点は未接続でアクセス不可です。
エンティティ定義
entity seg7 is
generic (
-- refresh_hz = (2 ** clk_cnt_bits) / clk_hz
clk_cnt_bits : integer
);
port (
clk : in std_logic;
rst : in std_logic;
value : in integer range 0 to 99;
segments : out std_logic_vector(6 downto 0);
digit_sel : out std_logic
);
end seg7;
ジェネリックclk_cnt_bitsは、ディスプレイリフレッシュレート(左右桁切り替え周波数)を制御する内部カウンタのビット幅を定義。目安は50〜数百Hz。式:refresh_hz = 2clk_cnt_bits / clk_hz。入力valueは0〜99の整数(2桁表示可能な範囲)。出力は7セグメントベクトルと桁選択信号。
BCD(2進化十進数)表現
表示桁の表現にBCDを使用。バイナリ表現では桁分離が困難なためです。
subtype digit_type is integer range 0 to 9; type digits_type is array (1 downto 0) of digit_type; signal digit : digit_type; signal digits : digits_type;
digit_typeは1桁分の値(0〜9)。digits_typeは2桁分の配列。digitは現在表示中の桁の値、digitsは左右両桁の値を保持。
10進数からBCDへの変換
入力value(0〜99のバイナリ)を2つのBCD(0〜9)に分離。標準的な「Double Dabble(シフト・アド3)」アルゴリズムも使えるが、2桁のみなので整数除算で簡潔に実装:
digits(1) <= value / 10; -- 十の位 digits(0) <= value - ((value / 10) * 10); -- 一の位
クロックサイクルカウントでリフレッシュ制御
FPGAでの時間遅延はクロックサイクルカウントで実現。clk_cnt_bitsジェネリックでビット幅を決めた無符号カウンタclk_cntを用意し、クロック立ち上がり毎にインクリメント。無符号型の自動ラップアラウンドを利用します。
signal clk_cnt : unsigned(clk_cnt_bits - 1 downto 0);
COUNT_PROC : process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
clk_cnt <= (others => '0');
else
clk_cnt <= clk_cnt + 1;
end if;
end if;
end process;
MSBで左右桁を交互切り替え
カウンタの最上位ビット(MSB)は50%デューティで'0'/'1'を交互に取るため、これを桁選択と多重化に利用:
digit_sel <= clk_cnt(clk_cnt'high); digit <= digits(0) when clk_cnt(clk_cnt'high) = '0' else digits(1);
BCD→7セグメントエンコーダ
digit信号のBCD値を7セグメント表示パターンに変換。ベクトルインデックス0=Aセグメント、1=B、…、6=Gに対応(データシート準拠)。
ENCODER_PROC : process(digit)
begin
case digit is
when 0 => segments <= "0111111";
when 1 => segments <= "0000110";
when 2 => segments <= "1011011";
when 3 => segments <= "1001111";
when 4 => segments <= "1100110";
when 5 => segments <= "1101101";
when 6 => segments <= "1111101";
when 7 => segments <= "0000111";
when 8 => segments <= "1111111";
when 9 => segments <= "1101111";
end case;
end process;
動作確認と実装
テストベンチではvalueを1秒ごとにインクリメントし、100秒超をシミュレートして桁上がりを確認。ModelSim波形でdigits配列のカウント動作を検証可能。FPGA実装時、value未初期化時は'0'になるため「00」表示からスタート。ラッパーモジュールでvalueを10Hzでインクリメントし、iCEstick上で全数字循環表示を確認しました(ループGIF動画参照)。
Pmod SSD購入先
- Digilent(公式)
- Digi-Key
- Mouser
- RS Electronics(英国)
- Farnell(英国)
※ Lattice iCEstick等の6×2ピンPmodコネクタ搭載ボードで使用する場合、スプリッタケーブルも必要(Digilent、Digi-Key、Mouser、RS Electronicsで入手可)。Amazon、eBayでも各種販売あり。
VHDL初心者向けコースのご案内
Digilent 7セグメントディスプレイとLattice iCEstickを用いたVHDL・FPGA初心者向けコース「FPGA and VHDL Fast-Track: Hands-On for Absolute Beginners」を開講しました。プログラミング経験はあるがVHDLは初めて、短期間で基礎を習得したいITプロフェッショナル・学生向け。低コストボードで数時間以内に実ハードウェア開発が可能です。詳細はリンク先でご確認ください。
VHDL
- VHDLのCase-When文マスター:効率的なマルチプレクサ設計
- VHDLジェネレート文をマスターする: 再利用可能なデバウンサーを簡単に構築
- VHDLポートマップインスタンス化マスター:実践ガイド
- VHDLにおける信号と変数の違いを理解する
- VHDLで有限ステートマシンを設計:信号機の実践例
- VHDL並行文マスター:実践ガイド
- Ready/Validハンドシェイクを使用したブロックRAMベースのAXI FIFO実装
- 上級VHDLクイズ パート2:HDL専門知識をテスト
- ブロックRAMからの正弦波でブリージングLED効果を実現する
- ブロックRAMにおける堅牢なVHDLリングバッファFIFOの設計
- VHDLの条件分岐をマスター:If-Then-Elsif-Else の完全解説