目次

Altera FPGA

 知り合いが、AlteraのFPGAを利用したトレーニング基板
 を設計、開発したので、使わせて貰いました。



 この基板には、ダウンロード用回路ByteBlaster互換品が
 実装されており、USBで回路情報をアップロードできます。

 CQ出版の雑誌付録であった基板では、ByteBlasterMV相当の
 回路を作成し、利用しました。



 Altera社が公開している回路では、74HC244を利用していますが
 手持ちがなかったので、74HC04、74HC125を使いました。



 ByteBlasterMV相当の回路を接続したFPGA基板は、以下です。



 トレーニング基板の写真を見ると、周辺は
 次のデバイスになっています。

 これらのデバイスを利用し、このFPGA(CycloneIV)を
 動かしてみます。

 漠然と考えても、動作は完成しないので、次の処理を
 考えました。

 A/D、D/Aコンバータは、上の3動作が完成して
 テーマを考え、動かします。

 各デバイスとFPGAピンの接続を回路図から確認しました。

 プッシュスイッチ
  2つあり、信号名はSW3、SW4とされています。
   SW3   66
   SW4   67

 DIPスイッチ
  2つあり、信号名はSW1、SW2とされています。
   SW1_1 53
   SW1_2 54
   SW1_3 55
   SW1_4 58

   SW2_1 59
   SW2_2 60
   SW2_3 64
   SW2_4 65

 LED
  8つのLEDがあり、信号名はLED1〜LED8とされています。
   LED1  3
   LED2  2
   LED3  1
   LED4  144
   LED5  143
   LED6  142
   LED7  141
   LED8  138

 7セグメントLED
  2つあり、信号名は7SEG1、7SEG2とされています。
   7SEG1_A  33
   7SEG1_B  34
   7SEG1_C  38
   7SEG1_D  28
   7SEG1_E  30
   7SEG1_F  31
   7SEG1_G  32
   7SEG1_DP 39

   7SEG2_A  49
   7SEG2_B  50
   7SEG2_C  51
   7SEG2_D  42
   7SEG2_E  43
   7SEG2_F  44
   7SEG2_G  46
   7SEG2_DP 52

 圧電ブザー
  音出力になっているので、SOUNDとしてあります。
   SOUND 7

 モータドライバ
  2つあり、信号名はMT1、MT2とされています。
   MT1_RIN  68
   MT1_VREF 69
   MT1_FIN  70
   MT1_CLK  74

   MT2_RIN  71
   MT2_VREF 72
   MT2_FIN  73
   MT2_CLK  75

 A/Dコンバータ
  1チャネル8ビットの入力で、信号名はADCVです。
   ADCV_D0     121
   ADCV_D1     124
   ADCV_D2     125
   ADCV_D3     126
   ADCV_D4     127
   ADCV_D5     128
   ADCV_D6     129
   ADCV_D7     132
   ADCV_ENCODE 133
   ADCV_PWRDWN 135

  10ピンコネクタに、AINが接続されています。

 D/Aコンバータ
  1チャネル12ビットになっています。信号名はDACV_DB。
   DACV_DB0  76
   DACV_DB1  77
   DACV_DB2  82
   DACV_DB3  83
   DACV_DB4  84
   DACV_DB5  85
   DACV_DB6  100
   DACV_DB7  100
   DACV_DB8  100
   DACV_DB9  100
   DACV_DB10 100
   DACV_DB11 110
   DACV_RW   111
   DACV_CSn  112
   DACV_STBn 113

  20ピンコネクタには、DACV_DBが出力されています。
  10ピンコネクタに、2チャネルのD/A出力を接続して
  あります。

 拡張ピン
  自由に利用できる拡張ピンが用意されています。
  信号名はEXPです。
   EXP_0 114
   EXP_1 115
   EXP_2 119
   EXP_3 120
   EXP_4 136
   EXP_5 137

  20ピンコネクタには、EXP_0〜EXP_3が抵抗を
  挟んで接続されています。出力で利用します。
  10ピンコネクタに、EXP_4、EXP_5が接続されて
  います。入力で利用します。

 クロック入力
  クロック入力は7本あります。
  20MHzか1Hzが入力されています。
   CLK1 23 (20MHz)
   CLK2 24 (20MHz)
   CLK3 25 (1Hz)
   CLK4 91 (1Hz)
   CLK5 90 (1Hz)
   CLK6 89 (1Hz)
   CLK7 88 (1Hz)


 開発環境はAlteraの場合、QuartusIIなので
 ライセンス不要のWebエディションをダウン
 ロードして、インストールします。



 Alteraのページでユーザー登録してから、開発ソフトウエア
 のページに移ってから、ダウンロードします。
 ユーザー登録は無料ですが、ダウンロードには時間が
 かかります。気長に待つことができる時にダウンロード
 するとよいでしょう。

 実際の動作時に使い方をマスターしていきます。


プッシュスイッチの状態をLEDに反映

 FPGA基板には、2つのプッシュスイッチと8個のLEDが  あります。プッシュスイッチの状態を2個のLEDに反映  させるVHDLコードを考えます。  図で動作を考えます。  entityでスイッチとLEDを指定します。 entity swtst1 is port ( -- input PS : in std_logic_vector(1 downto 0) ; -- output LEDX : out std_logic_vector(1 downto 0) ; LEDY : out std_logic_vector(1 downto 0) -- ; ); end swtst1 ;  スイッチが正論理、負論理があるので、2ビット  ずつ出力してみます。 -- pin LEDX <= iLEDX ; LEDY <= iLEDY ; -- output iLEDX <= iPS ; iLEDY <= not iPS ; -- input iPS <= PS ;  RTLあるいはBehavioralでまとめます。 architecture Behavioral of swtst1 is -- internal registers signal iLEDX : std_logic_vector(1 downto 0) ; signal iLEDY : std_logic_vector(1 downto 0) ; -- input buffer signal iPS : std_logic_vector(1 downto 0) ; begin -- pin LEDX <= iLEDX ; LEDY <= iLEDY ; -- output iLEDX <= iPS ; iLEDY <= not iPS ; -- input iPS <= PS ; end Behavioral;  LEDとスイッチのピンアサインを決めます。  Alteraの開発環境では、拡張子が「qsf」のファイル中に  ピンアサインを格納します。  スイッチとLEDの対応は、次のように定義すれば充分。 set_location_assignment PIN_67 -to PS[0] set_location_assignment PIN_66 -to PS[1] set_location_assignment PIN_3  -to LEDX[1] set_location_assignment PIN_138 -to LEDX[0] set_location_assignment PIN_2 -to LEDY[1] set_location_assignment PIN_141 -to LEDY[0]  拡張子が「qsf」のファイルの中には、次の  情報も入れます。 Family:Cyclone IV E Package:TQFP 144 Device:EP4CE6E22I7  これらは、開発環境がプロジェクトを作成するとき  情報として含まれています。ファイルの中には、次  のように定義されていました。 set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22I7 set_global_assignment -name TOP_LEVEL_ENTITY swtst1 set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:06:50 NOVEMBER 08, 2013" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name VHDL_FILE swtst1.vhd set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V"  デバイスの種別、パッケージ、ピン数、グレード等は  プロジェクトを作成するときに、決めておけば充分と  考えられますが、最近のICでは、3.3V、2.5V等の信号  電圧や差動信号の指定が必要になります。  信号に関係する情報は、次のように指定しておかないと  実用に耐えるデバイスにはならないでしょう。 set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDX set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDY  これらをQuartusIIのPin Planner(ピンプランナー)で  チマチマ指定するのは、面倒です。  CUIで使えるスクリプトを作り対応します。  テキストファイルに入れたピン番号と信号名から  QSFファイルに格納する定義を生成するスクリプト  をAWKで記述しました。  非常に単純で、10行に満たないコードです。 # mkpin.awk { printf("set_location_assignment PIN_"); printf("%d -to %s\n",$1,$2); }  テキストファイルは、次のように単純に記述します。 67 PS[0] 66 PS[1] 3 LEDX[1] 138 LEDX[0] 2 LEDY[1] 141 LEDY[0]  AWKが動作する環境で、次のようにタイプすると  画面に結果を表示します。I/Oリダイレクトでの  テキストファイルへ保存で簡単にピンアサインを  QSFファイル中に入れる定義として取得できます。 gawk -f mkpin.awk tt.dat{enter}  作成した回路情報を、ByteBlasterMVもどきで  アップロードして、動作確認すると設計通りに  動きました。  スイッチを押していない状態。  左スイッチを押した状態。  (赤LEDの点灯位置が変わってます)  左スイッチを押した状態。  (緑LEDの点灯位置が変わってます)

LEDで方向指示器実現

 20MHzのクロックが入力されているので  DIPスイッチの状態を見て、左か右への  方向指示をしてみます。  仕様は、次のようにします。  左のスイッチを上げたとき   右から左に向けて、順次LEDを点灯します。   10セット分点灯したなら、全LEDを消灯します。  右のスイッチを上げたとき   左から右に向けて、順次LEDを点灯します。   10セット分点灯したなら、全LEDを消灯します。  入力と出力を決めておきます。  仕様を決めたので、カウンタ値で、出力パターンを  定義します。 iLEFT <= X"01" when ( iCNT = 1 ) else X"03" when ( iCNT = 2 ) else X"07" when ( iCNT = 3 ) else X"0f" when ( iCNT = 4 ) else X"1f" when ( iCNT = 5 ) else X"3f" when ( iCNT = 6 ) else X"7f" when ( iCNT = 7 ) else X"ff" when ( iCNT = 8 ) else X"00" ; iRIGHT <= X"80" when ( iCNT = 1 ) else X"c0" when ( iCNT = 2 ) else X"e0" when ( iCNT = 3 ) else X"f0" when ( iCNT = 4 ) else X"f8" when ( iCNT = 5 ) else X"fc" when ( iCNT = 6 ) else X"fe" when ( iCNT = 7 ) else X"ff" when ( iCNT = 8 ) else X"00" ;  DIPスイッチの状態で、どちらのパターンを  出力するかを選びます。 LEDX <= not iLEDX ; iLEDX <= iLEFT when ( iSWD = "01" ) else iRIGHT when ( iSWD = "10" ) else X"00" ;  '0'出力で点灯する負論理で動かすため、iLEDXを  バッファで利用します。  出力パターンは、カウント値で決めているので  カウンタを作成します。 process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iSTATE <= 0 ; iCNT <= CNTLAST ; elsif rising_edge( iCLKX ) then case iSTATE is -- wait trigger when 0 => if ( iCTRG = '1' ) then iSTATE <= 1 ; else iSTATE <= 0 ; end if ; -- initialize counter when 1 => iCNT <= 0 ; iSTATE <= 2 ; -- judge when 2 => if ( iCNT = CNTLAST ) then iSTATE <= 4 ; else iSTATE <= 3 ; end if ; -- counter increment when 3 => iCNT <= iCNT + 1 ; iSTATE <= 2 ; -- return first state when 4 => iSTATE <= 0 ; -- default when others => iSTATE <= 0 ; end case ; end if ; end process ; iCBUSY <= '1' when ( iSTATE = 2 ) else '1' when ( iSTATE = 3 ) else '0' ;  トリガーを与えると、最大値までカウントアップし自動停止  させます。カウンタが動作中か否かを示すために、フラグの  iCBUSYを使います。  カウンタを複数回にわたって動かすための  ステートマシンを用意しておきます。 process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iBSTATE <= 0 ; iBCNT <= 0 ; elsif rising_edge( iCLKX ) then case iBSTATE is -- wait trigger when 0 => if ( iTRG = '1' ) then iBSTATE <= 1 ; else iBSTATE <= 0 ; end if ; -- initialize counter when 1 => iBCNT <= BCNTLAST ; iBSTATE <= 2 ; -- judge when 2 => if ( iBCNT = 0 ) then iBSTATE <= 8 ; else iBSTATE <= 3 ; end if ; -- send trigger when 3 => iBSTATE <= 4 ; -- synchronize wait when 4 => iBSTATE <= 5 ; -- wait complete when 5 => if ( iCBUSY = '0' ) then iBSTATE <= 7 ; else iBSTATE <= 6 ; end if ; -- loop when 6 => iBSTATE <= 5 ; -- update counter when 7 => iBCNT <= iBCNT - 1 ; iBSTATE <= 2 ; -- return first state when 8 => iBSTATE <= 0 ; -- default when others => iBSTATE <= 0 ; end case ; end if ; end process ; iCTRG <= '1' when ( iBSTATE = 3 ) else '0' ;  トリガーを与えると、カウンタに動作を開始させ  自動停止を確認します。動作か停止かは、フラグ  iCBUSYで判断。開始トリガーは、iCTRGと使います。  ステートマシンを動かすのは、TRGを利用し  外部から通知します。  TRGは、スイッチに接続しているので、チャタリング  除去が必要になります。シフトレジスタを使い、処理  します。 process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge( iCLKX ) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ;  ステートマシンやカウンタを動かすため  20MHzのクロックを分周して使います。 -- divider 20MHz -> 1kHz (generate 1kHz) process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iDCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iDCNT = DCNTMAX ) then iDCNT <= 0 ; else iDCNT <= iDCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iDCNT = 0 ) else '0' ; -- divider 1kHz -> 50Hz (generate 50Hz) process (nRESET,iCLK) begin if ( nRESET = '0' ) then iDCNTX <= 0 ; elsif rising_edge( iCLK ) then if ( iDCNTX = DCNTXMAX ) then iDCNTX <= 0 ; else iDCNTX <= iDCNTX + 1 ; end if ; end if ; end process ; iCLKX <= '1' when ( iDCNTX = 0 ) else '0' ;  VHDLコードにまとめると、次のようになります。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ltstx is port ( -- system nRESET : in std_logic; CLOCK : in std_logic; -- trigger input TRG : in std_logic; -- DIP switch input SWD : in std_logic_vector(1 downto 0) ; -- LED output LEDX : out std_logic_vector(7 downto 0) -- ; ); end ltstx; architecture Behavioral of ltstx is -- constant values constant DCNTMAX : integer := 19999 ; constant DCNTXMAX : integer := 99 ; constant STATEMAX : integer := 4 ; constant CNTLAST : integer := 12 ; constant BSTATEMAX : integer := 8 ; constant BCNTLAST : integer := 5 ; -- output signal iLEDX : std_logic_vector(7 downto 0) ; -- input signal iSWD : std_logic_vector(1 downto 0) ; -- trigger signal iTRG_SFT : std_logic_vector(2 downto 0) ; signal iTRG : std_logic ; -- internal output signal iLEFT : std_logic_vector(7 downto 0) ; signal iRIGHT : std_logic_vector(7 downto 0) ; -- divider 0 (generate 1kHz) signal iDCNT : integer range 0 to DCNTMAX ; signal iCLK : std_logic ; -- divider 1 (generate 10Hz) signal iDCNTX : integer range 0 to DCNTXMAX ; signal iCLKX : std_logic ; -- blink counter signal iSTATE : integer range 0 to STATEMAX ; signal iCNT : integer range 0 to CNTLAST ; signal iCBUSY : std_logic ; -- blink manager signal iBSTATE : integer range 0 to BSTATEMAX ; signal iBCNT : integer range 0 to BCNTLAST ; signal iCTRG : std_logic ; begin -- output LEDX <= not iLEDX ; -- input iSWD <= not SWD ; -- internal output iLEDX <= iLEFT when ( iSWD = "01" ) else iRIGHT when ( iSWD = "10" ) else X"00" ; -- decoder iLEFT <= X"01" when ( iCNT = 1 ) else X"03" when ( iCNT = 2 ) else X"07" when ( iCNT = 3 ) else X"0f" when ( iCNT = 4 ) else X"1f" when ( iCNT = 5 ) else X"3f" when ( iCNT = 6 ) else X"7f" when ( iCNT = 7 ) else X"ff" when ( iCNT = 8 ) else X"00" ; iRIGHT <= X"80" when ( iCNT = 1 ) else X"c0" when ( iCNT = 2 ) else X"e0" when ( iCNT = 3 ) else X"f0" when ( iCNT = 4 ) else X"f8" when ( iCNT = 5 ) else X"fc" when ( iCNT = 6 ) else X"fe" when ( iCNT = 7 ) else X"ff" when ( iCNT = 8 ) else X"00" ; -- divider 20MHz -> 1kHz (generate 1kHz) process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iDCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iDCNT = DCNTMAX ) then iDCNT <= 0 ; else iDCNT <= iDCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iDCNT = 0 ) else '0' ; -- divider 1kHz -> 50Hz (generate 50Hz) process (nRESET,iCLK) begin if ( nRESET = '0' ) then iDCNTX <= 0 ; elsif rising_edge( iCLK ) then if ( iDCNTX = DCNTXMAX ) then iDCNTX <= 0 ; else iDCNTX <= iDCNTX + 1 ; end if ; end if ; end process ; iCLKX <= '1' when ( iDCNTX = 0 ) else '0' ; -- trigger input process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge( iCLKX ) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ; -- blink counter process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iSTATE <= 0 ; iCNT <= CNTLAST ; elsif rising_edge( iCLKX ) then case iSTATE is -- wait trigger when 0 => if ( iCTRG = '1' ) then iSTATE <= 1 ; else iSTATE <= 0 ; end if ; -- initialize counter when 1 => iCNT <= 0 ; iSTATE <= 2 ; -- judge when 2 => if ( iCNT = CNTLAST ) then iSTATE <= 4 ; else iSTATE <= 3 ; end if ; -- counter increment when 3 => iCNT <= iCNT + 1 ; iSTATE <= 2 ; -- return first state when 4 => iSTATE <= 0 ; -- default when others => iSTATE <= 0 ; end case ; end if ; end process ; iCBUSY <= '1' when ( iSTATE = 2 ) else '1' when ( iSTATE = 3 ) else '0' ; -- blink manager process (nRESET,iCLKX) begin if ( nRESET = '0' ) then iBSTATE <= 0 ; iBCNT <= 0 ; elsif rising_edge( iCLKX ) then case iBSTATE is -- wait trigger when 0 => if ( iTRG = '1' ) then iBSTATE <= 1 ; else iBSTATE <= 0 ; end if ; -- initialize counter when 1 => iBCNT <= BCNTLAST ; iBSTATE <= 2 ; -- judge when 2 => if ( iBCNT = 0 ) then iBSTATE <= 8 ; else iBSTATE <= 3 ; end if ; -- send trigger when 3 => iBSTATE <= 4 ; -- synchronize wait when 4 => iBSTATE <= 5 ; -- wait complete when 5 => if ( iCBUSY = '0' ) then iBSTATE <= 7 ; else iBSTATE <= 6 ; end if ; -- loop when 6 => iBSTATE <= 5 ; -- update counter when 7 => iBCNT <= iBCNT - 1 ; iBSTATE <= 2 ; -- return first state when 8 => iBSTATE <= 0 ; -- default when others => iBSTATE <= 0 ; end case ; end if ; end process ; iCTRG <= '1' when ( iBSTATE = 3 ) else '0' ; end Behavioral;  ピンアサインは、以下としました。  (これらは、QSFファイルをコピーしてテキストエディタで   必要な部分だけを変更しています。) set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22I7 set_global_assignment -name TOP_LEVEL_ENTITY ltstx set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "14:00:22 NOVEMBER 11, 2013" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name VHDL_FILE ltstx.vhd set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_location_assignment PIN_67 -to nRESET set_location_assignment PIN_23 -to CLOCK set_location_assignment PIN_66 -to TRG set_location_assignment PIN_55 -to SWD[0] set_location_assignment PIN_58 -to SWD[1] set_location_assignment PIN_3 -to LEDX[7] set_location_assignment PIN_2 -to LEDX[6] set_location_assignment PIN_1 -to LEDX[5] set_location_assignment PIN_144 -to LEDX[4] set_location_assignment PIN_143 -to LEDX[3] set_location_assignment PIN_142 -to LEDX[2] set_location_assignment PIN_141 -to LEDX[1] set_location_assignment PIN_138 -to LEDX[0] set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDX set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to nRESET set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TRG set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWD set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

DIPスイッチの設定で7セグメントLEDに16進表示

 1Hzのクロックが入力されているので  DIPスイッチの状態を利用して、2個  の7セグメントLEDに16進表示させて  みます。  1秒ごとに2個のDIPスイッチの状態を入力し  デコード後、2個の7セグメントLEDに、各々  16進表示する仕様にします。  入力と出力を決めておきます。  図からentityを記述できます。 entity adecx is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- DIP switch inputs SWDX : in std_logic_vector(3 downto 0) ; SWDY : in std_logic_vector(3 downto 0) ; -- LED output LEDX : out std_logic_vector(7 downto 0) ; LEDY : out std_logic_vector(7 downto 0) -- ; ); end adecx;  1秒ごとにDIPスイッチの状態を入力します。 process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "0000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then iREGX <= iSWDX ; iREGY <= iSWDY ; end if ; end process ;  内部レジスタの値をデコードし、7セグメントLEDの  ビットパターンを生成します。 iLEDX <= "01100000" when ( conv_integer(iREGX) = 1 ) else "11011010" when ( conv_integer(iREGX) = 2 ) else "11110010" when ( conv_integer(iREGX) = 3 ) else "01100110" when ( conv_integer(iREGX) = 4 ) else "10110110" when ( conv_integer(iREGX) = 5 ) else "10111110" when ( conv_integer(iREGX) = 6 ) else "11100100" when ( conv_integer(iREGX) = 7 ) else "11111110" when ( conv_integer(iREGX) = 8 ) else "11110110" when ( conv_integer(iREGX) = 9 ) else "11101110" when ( conv_integer(iREGX) = 10 ) else "00111110" when ( conv_integer(iREGX) = 11 ) else "10011100" when ( conv_integer(iREGX) = 12 ) else "01111010" when ( conv_integer(iREGX) = 13 ) else "10011110" when ( conv_integer(iREGX) = 14 ) else "10001110" when ( conv_integer(iREGX) = 15 ) else "11111100" ; iLEDY <= "01100000" when ( conv_integer(iREGY) = 1 ) else "11011010" when ( conv_integer(iREGY) = 2 ) else "11110010" when ( conv_integer(iREGY) = 3 ) else "01100110" when ( conv_integer(iREGY) = 4 ) else "10110110" when ( conv_integer(iREGY) = 5 ) else "10111110" when ( conv_integer(iREGY) = 6 ) else "11100100" when ( conv_integer(iREGY) = 7 ) else "11111110" when ( conv_integer(iREGY) = 8 ) else "11110110" when ( conv_integer(iREGY) = 9 ) else "11101110" when ( conv_integer(iREGY) = 10 ) else "00111110" when ( conv_integer(iREGY) = 11 ) else "10011100" when ( conv_integer(iREGY) = 12 ) else "01111010" when ( conv_integer(iREGY) = 13 ) else "10011110" when ( conv_integer(iREGY) = 14 ) else "10001110" when ( conv_integer(iREGY) = 15 ) else "11111100" ;  主要な部分を定義したので、ソースコードにまとめます。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity adecx is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- DIP switch inputs SWDX : in std_logic_vector(3 downto 0) ; SWDY : in std_logic_vector(3 downto 0) ; -- LED output LEDX : out std_logic_vector(7 downto 0) ; LEDY : out std_logic_vector(7 downto 0) -- ; ); end adecx; architecture Behavioral of adecx is -- outputs signal iLEDX : std_logic_vector(7 downto 0) ; signal iLEDY : std_logic_vector(7 downto 0) ; -- inputs signal iSWDX : std_logic_vector(3 downto 0) ; signal iSWDY : std_logic_vector(3 downto 0) ; -- registers signal iREGX : std_logic_vector(3 downto 0) ; signal iREGY : std_logic_vector(3 downto 0) ; begin -- output LEDX <= iLEDX ; LEDY <= iLEDY ; -- input iSWDX <= not SWDX ; iSWDY <= not SWDY ; -- latch process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "0000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then iREGX <= iSWDX ; iREGY <= iSWDY ; end if ; end process ; -- decoder abcdefgDp iLEDX <= "01100000" when ( conv_integer(iREGX) = 1 ) else "11011010" when ( conv_integer(iREGX) = 2 ) else "11110010" when ( conv_integer(iREGX) = 3 ) else "01100110" when ( conv_integer(iREGX) = 4 ) else "10110110" when ( conv_integer(iREGX) = 5 ) else "10111110" when ( conv_integer(iREGX) = 6 ) else "11100100" when ( conv_integer(iREGX) = 7 ) else "11111110" when ( conv_integer(iREGX) = 8 ) else "11110110" when ( conv_integer(iREGX) = 9 ) else "11101110" when ( conv_integer(iREGX) = 10 ) else "00111110" when ( conv_integer(iREGX) = 11 ) else "10011100" when ( conv_integer(iREGX) = 12 ) else "01111010" when ( conv_integer(iREGX) = 13 ) else "10011110" when ( conv_integer(iREGX) = 14 ) else "10001110" when ( conv_integer(iREGX) = 15 ) else "11111100" ; iLEDY <= "01100000" when ( conv_integer(iREGY) = 1 ) else "11011010" when ( conv_integer(iREGY) = 2 ) else "11110010" when ( conv_integer(iREGY) = 3 ) else "01100110" when ( conv_integer(iREGY) = 4 ) else "10110110" when ( conv_integer(iREGY) = 5 ) else "10111110" when ( conv_integer(iREGY) = 6 ) else "11100100" when ( conv_integer(iREGY) = 7 ) else "11111110" when ( conv_integer(iREGY) = 8 ) else "11110110" when ( conv_integer(iREGY) = 9 ) else "11101110" when ( conv_integer(iREGY) = 10 ) else "00111110" when ( conv_integer(iREGY) = 11 ) else "10011100" when ( conv_integer(iREGY) = 12 ) else "01111010" when ( conv_integer(iREGY) = 13 ) else "10011110" when ( conv_integer(iREGY) = 14 ) else "10001110" when ( conv_integer(iREGY) = 15 ) else "11111100" ; end Behavioral;  VHDLコードに続き、ピンアサインを定義します。 set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22I7 set_global_assignment -name TOP_LEVEL_ENTITY adecx set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:07:49 NOVEMBER 11, 2013" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name VHDL_FILE adecx.vhd set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_location_assignment PIN_67 -to nRESET set_location_assignment PIN_88 -to CLOCK set_location_assignment PIN_58 -to SWDX[0] set_location_assignment PIN_55 -to SWDX[1] set_location_assignment PIN_54 -to SWDX[2] set_location_assignment PIN_53 -to SWDX[3] set_location_assignment PIN_65 -to SWDY[0] set_location_assignment PIN_64 -to SWDY[1] set_location_assignment PIN_60 -to SWDY[2] set_location_assignment PIN_59 -to SWDY[3] set_location_assignment PIN_39 -to LEDX[0] set_location_assignment PIN_32 -to LEDX[1] set_location_assignment PIN_31 -to LEDX[2] set_location_assignment PIN_30 -to LEDX[3] set_location_assignment PIN_28 -to LEDX[4] set_location_assignment PIN_38 -to LEDX[5] set_location_assignment PIN_34 -to LEDX[6] set_location_assignment PIN_33 -to LEDX[7] set_location_assignment PIN_52 -to LEDY[0] set_location_assignment PIN_46 -to LEDY[1] set_location_assignment PIN_44 -to LEDY[2] set_location_assignment PIN_43 -to LEDY[3] set_location_assignment PIN_42 -to LEDY[4] set_location_assignment PIN_51 -to LEDY[5] set_location_assignment PIN_50 -to LEDY[6] set_location_assignment PIN_49 -to LEDY[7] set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to nRESET set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDX set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDY set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top  この動作を基板に転送して、動作確認すると  DIPスイッチの1ビットの半田付け不良を発見  できました。  2つのDIPスイッチの設定で、7セグメントLEDに  16進が表示されているのがわかります。

ブザーで音出し

 基板上にブザーがあるので、可聴帯域の周波数を  切り替えて、音を出してみます。  入出力を図示して考えます。  人間の可聴帯域は、20Hz〜20kHzとなっていますが  ブザーにトランジスタが接続されているため、高い  周波数は使わないようにします。  50Hz、100Hz、200Hz、400Hz、800Hz、1.6kHz、3.2kHz  6.4kHzの8種の周波数を選べるようにします。  7セグメントLEDのテストで作ったコードを流用し  DIPスイッチのビットをONすると、その周波数が  出力される仕様に。  20MHzから12.8kHzを生成して、バイナリーカウンタを  動かします。バイナリーカウンタの各ビットを出力し  必要な周波数にします。 -- iSCLK = 12.8kHz process (nRESET,iSCLK) begin if ( nRESET = '0' ) then iSCNT <= (others => '0') ; elsif rising_edge( iSCLK ) then iSCNT <= iSCNT + '1' ; end if ; end process ;  8種の周波数を出力するためには、セレクタを使います。 iBEEPX <= iSCNT(0) when ( conv_integer(iREGX) = 8 ) else iSCNT(1) when ( conv_integer(iREGX) = 4 ) else iSCNT(2) when ( conv_integer(iREGX) = 2 ) else iSCNT(3) when ( conv_integer(iREGX) = 1 ) else iSCNT(4) when ( conv_integer(iREGY) = 8 ) else iSCNT(5) when ( conv_integer(iREGY) = 4 ) else iSCNT(6) when ( conv_integer(iREGY) = 2 ) else iSCNT(7) when ( conv_integer(iREGY) = 1 ) else '0' ;  セレクタにはレジスタを利用しているので、DIPスイッチから  情報を入力します。 process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "0000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then iREGX <= iSWDX ; iREGY <= iSWDY ; end if ; end process ;  DIPスイッチの状態を、8個の個別LEDに反映させて  わかりやすくしておきます。 GLED <= not iREGX ; RLED <= not iREGY ;  12.8kHzを生成するには、次の分周回路を利用します。 process (nRESET,CLOCK7) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK7 ) then if ( iCNT = 1562 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iCNT = 0 ) else '0' ;  ソースコードにまとめると、次のようになります。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity abeep is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; CLOCK7 : in std_logic ; -- DIP switch inputs SWDX : in std_logic_vector(3 downto 0) ; SWDY : in std_logic_vector(3 downto 0) ; -- BEEP BEEPX : out std_logic ; -- green and red LEDs output GLED : out std_logic_vector(3 downto 0) ; RLED : out std_logic_vector(3 downto 0) -- ; ); end abeep; architecture Behavioral of abeep is -- outputs signal iLEDX : std_logic_vector(7 downto 0) ; signal iLEDY : std_logic_vector(7 downto 0) ; -- inputs signal iSWDX : std_logic_vector(3 downto 0) ; signal iSWDY : std_logic_vector(3 downto 0) ; -- registers signal iREGX : std_logic_vector(3 downto 0) ; signal iREGY : std_logic_vector(3 downto 0) ; -- divider signal iCNT : integer range 0 to 1562 ; signal iSCLK : std_logic; signal iSCNT : std_logic_vector(7 downto 0) ; signal iBEEPX : std_logic ; begin -- output GLED <= not iREGX ; RLED <= not iREGY ; BEEPX <= iBEEPX ; -- input iSWDX <= not SWDX ; iSWDY <= not SWDY ; -- latch process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "0000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then iREGX <= iSWDX ; iREGY <= iSWDY ; end if ; end process ; -- divider process (nRESET,CLOCK7) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK7 ) then if ( iCNT = 1562 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iCNT = 0 ) else '0' ; process (nRESET,iSCLK) begin if ( nRESET = '0' ) then iSCNT <= (others => '0') ; elsif rising_edge( iSCLK ) then iSCNT <= iSCNT + '1' ; end if ; end process ; -- select iBEEPX <= iSCNT(0) when ( conv_integer(iREGX) = 8 ) else iSCNT(1) when ( conv_integer(iREGX) = 4 ) else iSCNT(2) when ( conv_integer(iREGX) = 2 ) else iSCNT(3) when ( conv_integer(iREGX) = 1 ) else iSCNT(4) when ( conv_integer(iREGY) = 8 ) else iSCNT(5) when ( conv_integer(iREGY) = 4 ) else iSCNT(6) when ( conv_integer(iREGY) = 2 ) else iSCNT(7) when ( conv_integer(iREGY) = 1 ) else '0' ; end Behavioral;  ピンアサインを決めます。 set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22I7 set_global_assignment -name TOP_LEVEL_ENTITY abeep set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:07:49 NOVEMBER 11, 2013" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_location_assignment PIN_67 -to nRESET set_location_assignment PIN_88 -to CLOCK set_location_assignment PIN_23 -to CLOCK7 set_location_assignment PIN_7 -to BEEPX set_location_assignment PIN_58 -to SWDX[0] set_location_assignment PIN_55 -to SWDX[1] set_location_assignment PIN_54 -to SWDX[2] set_location_assignment PIN_53 -to SWDX[3] set_location_assignment PIN_65 -to SWDY[0] set_location_assignment PIN_64 -to SWDY[1] set_location_assignment PIN_60 -to SWDY[2] set_location_assignment PIN_59 -to SWDY[3] set_location_assignment PIN_3 -to GLED[3] set_location_assignment PIN_2 -to GLED[2] set_location_assignment PIN_1 -to GLED[1] set_location_assignment PIN_144 -to GLED[0] set_location_assignment PIN_143 -to RLED[3] set_location_assignment PIN_142 -to RLED[2] set_location_assignment PIN_141 -to RLED[1] set_location_assignment PIN_138 -to RLED[0] set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to nRESET set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK7 set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDX set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDY set_global_assignment -name VHDL_FILE abeep.vhd set_global_assignment -name USE_CONFIGURATION_DEVICE OFF set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS OUTPUT DRIVING GROUND" set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

モータ制御チップ処理

 基板上に、DCモータ制御チップが用意されています。  データシートで必要情報を見て、動作を考えます。  方向制御は、正転、逆転を、Fin、Rinで制御できる  ようです。また、回転制御は、Fin、RinにPWM波形  を入れると読めます。  ドライブICの電源入力が、別にあるので、マブチ  モータRE140、RE160等は、接続してPWM波形を与え  簡単に動かせそうです。  正転、逆転は、Fin、RinのどちらにPWM波形を与えるか  切り替えるように、プッシュスイッチで制御します。  FPGA内部に状態変数を2つもてば回転方向の設定と  PWM波形を出力するか停止するかを制御できます。  大まかなVHDLコードを考えると以下です。 iOUTX <= '1' when ( iPCNT < iDUTY ) else '1' when ( iDUTY = 100 ) else '0' ; iFinRin <= ('0' & iOUTX) when ( iREGX(2 downto 1) = "01" ) else (iOUTX & '0') when ( iREGX(2 downto 1) = "10" ) else "00" ;  方向設定とPWM波形出力制御は、4ビットのDIP  スイッチ中の2ビットで設定します。  DUTY比は、4ビットのDIPスイッチで設定します。  次のように、DUTY比を固定としておきます。 0001 -> 5% 0011 -> 25% 0111 -> 50% 1111 -> 100%  DIPスイッチは次のように設定します。  左のDIPスイッチの3ビットは、プッシュスイッチを  押し、トリガーを入れたときだけ内部に記憶します。  次のように、トリガーを捕らえてレジスタに値を格納します。 -- trigger input process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge( CLOCK ) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ; -- latch process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then if ( iTRG = '1' ) then iREGX <= iSWDX(2 downto 0) ; end if ; iREGY <= iSWDY ; end if ; end process ;  DUTY比は、常に更新します。 iDUTY <= 5 when ( iREGY = "0001" ) else 25 when ( iREGY = "0011" ) else 50 when ( iREGY = "0111" ) else 100 when ( iREGY = "1111" ) else 0 ;  PWMの元周波数は、100kHzにします。 process (nRESET,CLOCK7) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK7 ) then if ( iCNT = 199 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iCNT = 0 ) else '0' ;  0〜99までカウントしPWMの1周期を10kHzにします。 process (nRESET,iSCLK) begin if ( nRESET = '0' ) then iPCNT <= 0 ; elsif rising_edge( iSCLK ) then if ( iPCNT = 99 ) then iPCNT <= 0 ; else iPCNT <= iPCNT + 1 ; end if ; end if ; end process ;  DUTY比によるパルス幅は、カウンタとレジスタ値を  比較して確定します。 iOUTX <= '1' when ( iPCNT < iDUTY ) else '1' when ( iDUTY = 100 ) else '0' ;  ソースコードにまとめると、以下。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity amotor is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; CLOCK7 : in std_logic ; -- trigger inputs TRG : in std_logic ; -- DIP switch inputs SWDX : in std_logic_vector(3 downto 0) ; SWDY : in std_logic_vector(3 downto 0) ; -- PWM FinRin : out std_logic_vector(1 downto 0) ; OUTX : out std_logic ; -- green and red LEDs output GLED : out std_logic_vector(3 downto 0) ; RLED : out std_logic_vector(3 downto 0) -- ; ); end amotor; architecture Behavioral of amotor is -- outputs signal iRLED : std_logic_vector(1 downto 0) ; signal iOUTX : std_logic ; -- trigger input signal iTRG_SFT : std_logic_vector(2 downto 0) ; signal iTRG : std_logic ; -- inputs signal iSWDX : std_logic_vector(3 downto 0) ; signal iSWDY : std_logic_vector(3 downto 0) ; -- registers signal iREGX : std_logic_vector(2 downto 0) ; signal iREGY : std_logic_vector(3 downto 0) ; -- divider (100kHz) signal iCNT : integer range 0 to 199 ; signal iSCLK : std_logic ; -- PWM signal iDUTY : integer range 0 to 100 ; signal iPCNT : integer range 0 to 99 ; signal iFinRin : std_logic_vector(1 downto 0) ; begin -- output RLED <= not ('0' & iREGX) ; GLED <= not iREGY ; FinRin <= iFinRin ; OUTX <= iREGX(0) ; -- input iSWDX <= not SWDX ; iSWDY <= not SWDY ; -- trigger input process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iTRG_SFT <= "000" ; elsif rising_edge( CLOCK ) then iTRG_SFT <= iTRG_SFT(1 downto 0) & (not TRG) ; end if ; end process ; iTRG <= '1' when ( iTRG_SFT = "011" or iTRG_SFT = "001" ) else '0' ; -- latch process (nRESET,CLOCK) begin if ( nRESET = '0' ) then iREGX <= "000" ; iREGY <= "0000" ; elsif rising_edge( CLOCK ) then if ( iTRG = '1' ) then iREGX <= iSWDX(2 downto 0) ; end if ; iREGY <= iSWDY ; end if ; end process ; -- divider process (nRESET,CLOCK7) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK7 ) then if ( iCNT = 199 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iSCLK <= '1' when ( iCNT = 0 ) else '0' ; -- PWM counter process (nRESET,iSCLK) begin if ( nRESET = '0' ) then iPCNT <= 0 ; elsif rising_edge( iSCLK ) then if ( iPCNT = 99 ) then iPCNT <= 0 ; else iPCNT <= iPCNT + 1 ; end if ; end if ; end process ; -- select iDUTY <= 5 when ( iREGY = "0001" ) else 25 when ( iREGY = "0011" ) else 50 when ( iREGY = "0111" ) else 100 when ( iREGY = "1111" ) else 0 ; iOUTX <= '1' when ( iPCNT < iDUTY ) else '1' when ( iDUTY = 100 ) else '0' ; iFinRin <= ('0' & iOUTX) when ( iREGX(2 downto 1) = "01" ) else (iOUTX & '0') when ( iREGX(2 downto 1) = "10" ) else "00" ; end Behavioral;  ピンアサインをQSFファイルに書き出します。 set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22I7 set_global_assignment -name TOP_LEVEL_ENTITY amotor set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:07:49 NOVEMBER 11, 2013" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_location_assignment PIN_67 -to nRESET set_location_assignment PIN_88 -to CLOCK set_location_assignment PIN_23 -to CLOCK7 set_location_assignment PIN_66 -to TRG set_location_assignment PIN_69 -to OUTX set_location_assignment PIN_68 -to FinRin[0] set_location_assignment PIN_70 -to FinRin[1] set_location_assignment PIN_58 -to SWDX[0] set_location_assignment PIN_55 -to SWDX[1] set_location_assignment PIN_54 -to SWDX[2] set_location_assignment PIN_53 -to SWDX[3] set_location_assignment PIN_65 -to SWDY[0] set_location_assignment PIN_64 -to SWDY[1] set_location_assignment PIN_60 -to SWDY[2] set_location_assignment PIN_59 -to SWDY[3] set_location_assignment PIN_3 -to RLED[3] set_location_assignment PIN_2 -to RLED[2] set_location_assignment PIN_1 -to RLED[1] set_location_assignment PIN_144 -to RLED[0] set_location_assignment PIN_143 -to GLED[3] set_location_assignment PIN_142 -to GLED[2] set_location_assignment PIN_141 -to GLED[1] set_location_assignment PIN_138 -to GLED[0] set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to nRESET set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLOCK7 set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDX set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SWDY set_global_assignment -name VHDL_FILE amotor.vhd set_global_assignment -name USE_CONFIGURATION_DEVICE OFF set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS OUTPUT DRIVING GROUND" set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall set_global_assignment -name SOURCE_FILE amotor.qsf set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top  動作は、2つのLEDのアノードとカソードを交互に  接続した回路でテストしました。  方向を正転とし、DUTY比を5%にし、LEDの点灯を  テストすると、次のようになります。  方向を逆転とし、DUTY比を100%とすると、以下の  ようになりました。  接続は、次のようにしてあります。
目次

inserted by FC2 system