目次

Go/Stop装置エミュレータ

 Go/Stop装置は、タイムトライアル競技の
 スタートの合図を送ります。



 写真のGo/Stop装置は、ミニ四駆のコース横に
 おいて使っていました。

 持っているGo/Stop装置は、内部の電球が切れて
 ランプの中の1個が点灯しなくなったのでLEDで
 代用してみます。

 Go/Stop装置の動作は、次の状態遷移図で表現可能。



 状態遷移図では、5状態がなので、ジョンソンカウンタ
 を利用してシーケンサを構成します。
 状態割当ては以下。
  1. 000(IDLE) 待機
  2. 001(LED_3) 最下段のLED点灯
  3. 011(LED_2) 下から2段目のLED点灯
  4. 111(LED_1) 上から2段目のLED点灯
  5. 110(LED_0) 最上段のLED点灯
  6. 100 最初にもどる
 状態割当てを決めたので、シーケンサのVHDLコードを定義。 process (nRESET,iCLK) begin if ( nRESET = '0' ) then iSTATE <= "000" ; elsif rising_edge(iCLK) then case conv_integer(iSTATE) is -- IDLE when 0 => if ( iTRG = '1' ) then iSTATE <= "001" ; else iSTATE <= "000" ; end if ; -- LED_3 when 1 => iSTATE <= "011" ; -- LED_2 when 3 => iSTATE <= "111" ; -- LED_1 when 7 => iSTATE <= "110" ; -- LED_0 when 6 => iSTATE <= "100" ; -- return first state when 4 => iSTATE <= "000" ; -- default when others => iSTATE <= "000" ; end case ; end if ; end process ;  状態遷移の周期は、1秒としておけば充分でしょう。  LEDの点灯は、状態値で制御します。 iLED_0 <= '1' when ( iSTATE = "110" ) else '0' ; iLED_1 <= '1' when ( iSTATE = "111" ) else '0' ; iLED_2 <= '1' when ( iSTATE = "011" ) else '0' ; iLED_3 <= '1' when ( iSTATE = "001" ) else '0' ;  シーケンサにトリガーを与えなければならないので  シフトレジスタを使ったシンクロナイザを用意。 process ( nRESET , iSCLK ) begin if ( nRESET = '0' ) then iSFT <= "000" ; elsif rising_edge( iSCLK ) then iSFT <= iSFT(1 downto 0) & TRGBTN ; end if ; end process ; iTRG <= '1' when ( iSFT = "011" ) else '0' ;  シンクロナイザーは、ボタンのチャタリング除去も  兼用したいので、iSCLKを2Hz以上とします。  回路は簡単でレジスタを3個、デコーダを1個使います。  光だけでなく、音もあった方がよいのでシステム  クロックを分周して生成しましょう。  Goのときは、880Hzを使い、他はLEDの点灯に  合わせて440Hzとします。また待機では無音に  するので、次のブロック図で制御を定義して  おけばよいでしょう。  1段目の分周器で、システムクロックから880Hz  を生成し、2段目の2分周器で半分にします。  システムクロックを4MHzとすると、880Hzに近い  周波数を生成するため、4545分周します。 process ( nRESET , CLOCK ) begin if ( nRESET = '0' ) then iSCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iSCNT = 9090 ) then iSCNT <= 0 ; else iSCNT <= iSCNT + 1 ; end if ; end if ; end process ; iSOUT0 <= '1' when ( iSCNT < 2272 ) else '1' when ( iSCNT > 4545 and iSCNT < 6817) else '0' ; iSOUT1 <= '1' when ( iSCNT > 4545 ) else '0' ;  音を出すためには、セレクタを使います。  シーケンサの状態値を利用して選択。 iSOUT <= iSOUT0 when ( iSTATE = "110" ) else iSOUT1 when ( iSTATE(0) = '1' ) else '0' ;  ジョンソンカウンタは、ベースとなるシフトレジスタの  レジスタ値が1クロックで1ビットしか変化しないこと  を利用して、デコードを単純にしています。  シンクロナイザとシーケンサで利用するクロックも定義。 process ( nRESET , CLOCK ) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iCNT = 3_999_999 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iCNT < 2_000_000 ) else '0' ; iSCLK <= '1' when ( iCNT < 1_000_000 ) else '1' when ( iCNT > 2_000_000 and iCNT < 3_000_000 ) else '0' ;  次のCPLD基板を利用して、エミュレートします。  XC9572を利用した場合のVHDLコードは、以下。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity gostopx is port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- 4MHz -- trigger TRGBTN : in std_logic ; -- LED out LOUT : out std_logic_vector(3 downto 0) ; -- sound out SOUT : out std_logic --; ) ; end gostopx; architecture Behavioral of gostopx is -- clock generator signal iCNT : integer range 0 to 3_999_999 ; -- synchronizer signal iSCLK : std_logic ; signal iTRG : std_logic ; signal iSFT : std_logic_vector(2 downto 0) ; -- LED signal iLED_0 : std_logic ; signal iLED_1 : std_logic ; signal iLED_2 : std_logic ; signal iLED_3 : std_logic ; -- sequencer signal iCLK : std_logic ; signal iSTATE : std_logic_vector(2 downto 0) ; -- sound selector signal iSOUT : std_logic ; -- sound generator signal iSCNT : integer range 0 to 9090 ; signal iSOUT0 : std_logic ; signal iSOUT1 : std_logic ; begin -- output LOUT <= iLED_0 & iLED_1 & iLED_2 & iLED_3; SOUT <= iSOUT ; -- clock generator process ( nRESET , CLOCK ) begin if ( nRESET = '0' ) then iCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iCNT = 3_999_999 ) then iCNT <= 0 ; else iCNT <= iCNT + 1 ; end if ; end if ; end process ; iCLK <= '1' when ( iCNT < 2_000_000 ) else '0' ; iSCLK <= '1' when ( iCNT < 1_000_000 ) else '1' when ( iCNT > 2_000_000 and iCNT < 3_000_000 ) else '0' ; -- decoder iLED_0 <= '1' when ( iSTATE = "110" ) else '0' ; iLED_1 <= '1' when ( iSTATE = "111" ) else '0' ; iLED_2 <= '1' when ( iSTATE = "011" ) else '0' ; iLED_3 <= '1' when ( iSTATE = "001" ) else '0' ; -- sequencer process (nRESET,iCLK) begin if ( nRESET = '0' ) then iSTATE <= "000" ; elsif rising_edge(iCLK) then case conv_integer(iSTATE) is -- IDLE when 0 => if ( iTRG = '1' ) then iSTATE <= "001" ; else iSTATE <= "000" ; end if ; -- LED_3 when 1 => iSTATE <= "011" ; -- LED_2 when 3 => iSTATE <= "111" ; -- LED_1 when 7 => iSTATE <= "110" ; -- LED_0 when 6 => iSTATE <= "100" ; -- return first state when 4 => iSTATE <= "000" ; -- default when others => iSTATE <= "000" ; end case ; end if ; end process ; -- synchronizer process ( nRESET , iSCLK ) begin if ( nRESET = '0' ) then iSFT <= "000" ; elsif rising_edge( iSCLK ) then iSFT <= iSFT(1 downto 0) & TRGBTN ; end if ; end process ; iTRG <= '1' when ( iSFT = "011" ) else '0' ; -- sound selector iSOUT <= iSOUT0 when ( iSTATE = "110" ) else iSOUT1 when ( iSTATE(0) = '1' ) else '0' ; -- sound generator process ( nRESET , CLOCK ) begin if ( nRESET = '0' ) then iSCNT <= 0 ; elsif rising_edge( CLOCK ) then if ( iSCNT = 9090 ) then iSCNT <= 0 ; else iSCNT <= iSCNT + 1 ; end if ; end if ; end process ; iSOUT0 <= '1' when ( iSCNT < 2272 ) else '1' when ( iSCNT > 4545 and iSCNT < 6817) else '0' ; iSOUT1 <= '1' when ( iSCNT > 4545 ) else '0' ; end Behavioral;  XC9572に入れるために、ピンアサインを決定します。 # system NET "CLOCK" LOC = "P5" ; NET "nRESET" LOC = "P39" ; # button NET "TRGBTN" LOC = "P1" ; # sound output NET "SOUT" LOC = "P9" ; # LED output NET "LOUT<0>" LOC = "P11" ; NET "LOUT<0>" LOC = "P12" ; NET "LOUT<0>" LOC = "P13" ; NET "LOUT<1>" LOC = "P14" ;  利用するスイッチは、以下。  スピーカは¥100ショップで入手できるものを利用。  スイッチ、スピーカは、クリップワイヤーを使って  CPLD基板上のピンに接続します。
目次

inserted by FC2 system