

楽器
このプロジェクトは、FPGA Spartan3Eを搭載したデバッグボードに実装されています。 さまざまなインターフェイス(VGA、PS / 2)による最も単純なバインディングが含まれ、LEDとLEDディスプレイ、トリガースイッチ、ボタン、サードパーティ製のものを接続するためのさまざまな出力を備えています。 料金は非常に安く、中国の店舗の1つでebayから注文しました。 価格-送料込みで135.00ドル (旧価格で〜4000r)。
メーカーの公式ウェブサイトは現在死んでいますが、驚くことではありません。
ボードの主な機能:
- FPGA Spartan3E( XC3S500E-4PQ208C ) -50万論理ゲート、
- クロックソースCLK = 50 MHz、
- 外部メモリ64M SDRAM、
- FPGAファームウェアを保存するためのSPIフラッシュ(M25P80)、
- LEDマトリックスLED 8x8、LEDライン8個、
- 8つのトリガースイッチと5つのボタン、
- 2つのLEDディスプレイ用のコネクタ、
- モニターを接続するためのVGAコネクタ、
- PS / 2コネクタなど
FPGA Spartan3E XC3S500Eのリソースを表に示します。

単純なプロジェクトとFPGAデザインの最初の導入では、これで十分です。
LEDマトリクス
LED8x8 LEDのマトリックスがFPGAに接続されています。 明らかに、各LEDは直接接続されていません。64個のFPGAコンタクトを使用する必要があるためです。これは非常に高価で不合理です。 以下は、デバッグボード上の中国語のデータシートの図です。 LEDは8個の列と行で接続されており、接続は直接ではなく、PNPトランジスタを介して接続されていることがわかります。 トランジスタのエミッタは供給電圧に、ベースはFPGAの接点に、コレクタはLEDのマトリックスに接続されています。 合計16の接点がFPGAに接続されています。 論理制御LEDマトリックス- 負 、つまり、LEDは低論理レベルで点灯します(log。0)。

つまり、特定の行と列に必要なロジックレベルを設定すると、特定のLEDが点灯します。
例:
A)ベクトルLEDY = "11111110"、およびベクトルLEDX = "11111110"の場合、右下隅の唯一のLEDが点灯します。
11111111
11111111
11111111
11111111
11111111
11111111
11111111
11111110
B)ベクトルLEDY = "11111110"、およびベクトルLEDX = "00000000"の場合、ボトムライン全体が点灯します。
11111111
11111111
11111111
11111111
11111111
11111111
11111111
00000000
C )ベクトルLEDY = "00000000"、およびベクトルLEDX = "11111110"の場合、右側の列全体が点灯します。
11111110
11111110
11111110
11111110
11111110
11111110
11111110
11111110
D)ベクトルLEDY = "00000000"、およびベクトルLEDX = "00000000"の場合、LEDのマトリックス全体が点灯します。
これに関して、特定の困難が生じる。 特定の文字が文字または数字の形で表示されるようにLEDのマトリックスを点灯する方法は? これは実際には難しくありません。
LEDへの文字出力
LEDのマトリックスに文字を出力するプロセスは非常に簡単です。 まず、特定のビット容量のカウンターを編成し、その上位3ビットを使用してLEDYベクトルを切り替える必要があります。 なぜ3桁ですか? 8ビットベクトルの切り替えは、3つの制御ビットを使用するステートマシンを使用して記述できます。 VHDLでは、これは次のように行われます。
カウンター
pr_cnt: process(clk, rst) is begin if (rst = '0') then cnt_led <= (others => '0'); elsif rising_edge(clk) then if (rst_reg = '0') then cnt_led <= (others => '0'); else cnt_led <= cnt_led + '1'; end if; end if; end process;
最初のリセット(最初)はグローバルです。 2番目のリセット(rst_reg)はソフトウェアであり、トリガーによって制御されます。
LEDYのステートマシン
pr_3x8: process(cnt_cmd) is begin case cnt_cmd is when "000" => en_xhdl <= "11111110"; when "001" => en_xhdl <= "11111101"; when "010" => en_xhdl <= "11111011"; when "011" => en_xhdl <= "11110111"; when "100" => en_xhdl <= "11101111"; when "101" => en_xhdl <= "11011111"; when "110" => en_xhdl <= "10111111"; when others => en_xhdl <= "01111111"; end case; end process;
カウンタのステータスを変更すると、LEDのLEDY列に1ビットが含まれます。 したがって、 移動ゼロスキームが編成されます。
次に、 LEDX行ベクトルを整理するためのロジックがまったく同じ2つのステートマシンが必要です。 原則として1つで十分ですが、列ベクトルと同じように視覚的です。
中間宇宙船
pr_8x4: process(en_xhdl) is begin case en_xhdl is when "11111110" => led_cmd <= "000"; when "11111101" => led_cmd <= "001"; when "11111011" => led_cmd <= "010"; when "11110111" => led_cmd <= "011"; when "11101111" => led_cmd <= "100"; when "11011111" => led_cmd <= "101"; when "10111111" => led_cmd <= "110"; when others => led_cmd <= "111"; end case; end process;
LEDXベクターのKA
pr_ledx: process(led_cmd) is begin case led_cmd is when "000" => ledx <= "01111110"; when "001" => ledx <= "10111101"; when "010" => ledx <= "11011011"; when "011" => ledx <= "11100111"; when "100" => ledx <= "11100111"; when "101" => ledx <= "11011011"; when "110" => ledx <= "10111101"; when others =>ledx <= "01111110"; end case; end process;
これらのアクションの結果として、 LEDXベクトルが形成されます。 LEDマトリックスにシンボルを描くのはこのベクトルであり、LEDYベクトルは不必要なLEDのタイムリーなシャットダウンを担当します。 この例では、十字または「X」記号がLEDマトリックスで点灯するはずです。これは、最後のステートマシンを注意深く見ると視覚的に確認できます。 したがって、列ベクトルは補助になり、行ベクトルは文字を描画し、その助けを借りて、LEDマトリックスに何かを「書き込む」ことができます。
このプロジェクトでは、同じタイプの2つのファイルを作成して、LEDマトリックス用のシンボルを生成しました。 最初のブロックにはハートが表示され、2番目のブロックにはROMメモリ設計の助けを借りて、「MARCH 8!」というテキストが表示されます。 テキスト文字はメモリ内にあり、正しくアドレス指定する必要があります。 表示プロセスは十分に速いので、文字が読めるように出力周波数を調整する必要があります。 これを行うには、27ビット用に追加のカウンターを作成する必要があります。これにより、50 MHzの入力周波数を2 ^ 27で除算し、LEDマトリックス上の文字の変化を観察できます。
文字コードは、2次元配列としてメモリに記録されます。 8ビットの数値は、ステートマシンのロジック(LEDにシンボルを出力するため)とアドレス(LEDのマトリックスのシンボルを変更するため)によって異なります。
type rom_type is array (7 downto 0) of std_logic_vector(7 downto 0); type rom_8x8 is array (0 to 7) of rom_type; constant ROM_TEXT: rom_8x8:=( ( "11000011", "10011001", "00111101", "00111111", "00111111", "00111101", "10011001", "11000011") ... /cut -- 2D-: pr_8x8: process(clk, rst) is begin if (rst = '0') then data_led <= (others => '0'); elsif rising_edge(clk) then data_led <= ROM_TEXT(CONV_INTEGER(addr_txt(Na-1 downto Na-3)))(CONV_INTEGER(led_cmd)); end if; end process;
特殊効果
マトリックス上のシンボルを照らすだけなら、それは少し退屈ですか? ライトを点滅させて実行するという形で、プロジェクトに特殊効果を追加する必要があります。 とても簡単です。 これには、よく知られたPWMアルゴリズム(パルス幅変調)が必要です。 その助けを借りて、負荷に供給される電力を制御できます(つまり、電流を調整します)。 これは、一定の信号周波数でパルスのデューティサイクルを変更することによって行われます。
FPGAでPWMがどのように作成されるかについては説明しません。これについて多くの記事が書かれています。 基本的な原理は、いくつかの制御されたカウンターで、ゼロと1のパルスの持続時間の変化が組織化されるということです。 私のプロジェクトでは、PWM自体(カウントを増やすことでカウンターの速度を変更することで)と、LEDマトリックスへのデータ出力の速度を変更すること、列ベクトルLEDYのカウンターのビット容量を変更すること(必要なビットフィールドを選択すること)の両方を制御できます。 これにより、フリッカー、減衰、ランニングライトのさまざまな効果を得ることができます。これは、最終ビデオで見ることができます。
FPGAプロジェクト
FPGAプロジェクトはいくつかの部分で構成されています:これらは、マイクロサーキットの動作を記述するVHDLソースコードファイル、およびFPGAコンタクトの接続、それらの標準、出力電流、速度、プロジェクトのクロック周波数制限などを定義するUCF制限ファイルです。
UCFのピン配置
## BUTTONS = ## K1-K5 NET "KB[5]" LOC = P54; NET "KB[4]" LOC = P58; NET "KB[3]" LOC = P57; NET "KB[2]" LOC = P159; NET "KB[1]" LOC = P154; ## LEDS = ## LED_MATRIX NET "LED_X<7>" LOC = "P49" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<6>" LOC = "P48" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<5>" LOC = "P40" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<4>" LOC = "P50" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<3>" LOC = "P62" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<2>" LOC = "P98" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<1>" LOC = "P64" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_X<0>" LOC = "P63" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<7>" LOC = "P75" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<6>" LOC = "P78" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<5>" LOC = "P76" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<4>" LOC = "P69" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<3>" LOC = "P74" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<2>" LOC = "P65" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<1>" LOC = "P68" | IOSTANDARD = LVTTL | DRIVE = 8; NET "LED_Y<0>" LOC = "P77" | IOSTANDARD = LVTTL | DRIVE = 8; NET "RESET" LOC = P148 | IOSTANDARD = LVTTL; NET "CLK" LOC = P183 | IOSTANDARD = LVCMOS33; NET "CLK_IN" TNM_NET = "CLK_TN"; TIMESPEC TS_CLK = PERIOD "CLK_TN" 20 ns HIGH 50 %;
VHDLトップレベルファイル
entity top_xc3s500e_heart is port( ---- SWITCHES ---- RESET : in std_logic; --! asycnchronous reset: SW(0) SW : in std_logic_vector(7 downto 1); --! other switches ---- CLOCK 50 MHz ---- CLK : in std_logic; --! main clock 50 MHz ---- LED DISPLAY ---- LED_X : out std_logic_vector(7 downto 0); --! LEDs Y LED_Y : out std_logic_vector(7 downto 0); --! LEDs X ---- BUTTONS ---- KB : in std_logic_vector(5 downto 1); --! Five Buttons ); end top_xc3s500e_heart;
ポートの説明:
- RESET-グローバルリセット(スイッチSW [0])、
- CLK -50 MHzクロック速度、
- SW <1> -PWM動作の解像度、
- SW <2> -制御モード「heart」、
- SW <3> -8x8マトリックスリセット、
- SW <4> -HEART / TEXTブロックの切り替え、
- KB <1> -メインPWMカウンターの速度制御(合計周期)、
- KB <2> -セカンダリPWMカウンターの速度制御(デューティサイクル)、
- KB <3> -制御マトリックスカウンター8x8の変更(ベクトルLEDYの場合)。
- LED_X -LEDマトリックスの行ベクトル、
- LED_Y -LEDマトリックスの列ベクトル、
合成プロセス後のプロジェクトの概略図を次の図に示します。 入力および出力バッファー、DCMノード、ボタンの接点バウンスを除去するための3つのノードと3つの機能ノード:PWM制御、LED8x8 LEDマトリックス上のシンボルジェネレーター、およびマトリックスへのハート出力が含まれます。

合成、配置、トレースの後、FPGAのプロジェクトは次のようになります。

ご覧のとおり、FPGAは通常空です。 使用されたリソースの結果は、上の図にも示されています。
結果
そのため、正しいファームウェアがFPGAにロードされ、必要なボタンが押され、スイッチが正しい位置に配置されると、LEDマトリックスが有効になり、次の機能が表示されます。
写真:心

ビデオ:ちらつきと走る心
ビデオ:テキスト「MARCH 8!」:
このプロジェクトは、CAD Xilinx ISEのVHDLで作成されました。 人件費:1夕方(プロジェクト作成)+午後2時(記事執筆)。 誰かがこのようなことをすることに興味があるなら、ソースコードはgithubに投稿されます。
もう一度、私はすべての女性をこれからの休日にお祝いしたいです。 みなさんの幸せ、暖かさ、愛を祈ります! 特に、私は愛する妻に挨拶します。
ご清聴ありがとうございました!