目次

スロットマシン

 スイッチと7セグメントLEDが載ったボードで、電子サイコロを  作ったので、これを3つ並べると、スロットマシンができると  思いつきました。  4つあるプッシュボタンを、左からBegin、stopA、stopB、stopCと使います。  Beginボタンを押して、3つの7セグメントLEDが  勝手に賽の目を表示します。  stopAボタンを押して、左の7セグメントLEDの  賽の目を止めます。  stopBボタンを押して、中央の7セグメントLEDの  賽の目を止めます。  stopCボタンを押して、右の7セグメントLEDの  賽の目を止めます。  この動作を実現するためのブロック図で動作を考えます。  3個の10進カウンタを用意し、シンクロナイザからの  信号で、カウンタを一斉に動かします。個々のカウンタ  を、STOP信号で止めらると、スロットマシンになります。  3個の10進カウンタは、0〜9の賽の目を出すので、  7セグメントLEDの出力ビットパターンへの変換用  デコーダを用意します。  利用ボードには、7セグメントLEDが6個あるので  ダイナミック点灯で、3個を点灯するセレクタを  設けます。  ボードでは50MHzクロックがあるので、1kHz程度まで  周波数を下げて利用します。そのために、クロック  ジェネレータを使います。  各処理ブロックを定義していきます。

10進カウンタ

 開始、停止ができる10進カウンタは、電子サイコロで  利用したコードを、呼び出して使います。  component指定で、dcntx.vhdの内容を指定します。 component dcntx is port( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger BTRG : in std_logic ; -- begin trigger STRG : in std_logic ; -- stop trigger -- output COUT : out std_logic_vector(3 downto 0) --; ); end component ;  内部で利用する信号を定義し、呼び出します。 -- counter signal iCOUNTX : std_logic_vector(3 downto 0) ; signal iCOUNTY : std_logic_vector(3 downto 0) ; signal iCOUNTZ : std_logic_vector(3 downto 0) ; -- internal digit counter XCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(0),iCOUNTX); YCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(1),iCOUNTY); ZCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(2),iCOUNTZ);  componentで指定するVHDLコードの内部に、シンクロナイザを  定義してあるので、トリガー信号を渡してカウンタを動かします。 iBTRG <= not BTRG ; iSTRG <= not STRG ;  10進カウンタを、目で追える程度のスピードで動かすため  50MHzを分周し、iCLOCK2とします。

デコーダ

 デコーダは、電子サイコロで定義したコードを、呼び出し使います。  component指定で、ledx.vhdの内容を指定します。 component ledx is port ( -- input DIN : in std_logic_vector(3 downto 0); -- output DOUT : out std_logic_vector(6 downto 0) --; ); end component ;  内部で利用する信号を定義し、呼び出します。 -- 7 segment LED signal iLOUTX : std_logic_vector(6 downto 0) ; signal iLOUTY : std_logic_vector(6 downto 0) ; signal iLOUTZ : std_logic_vector(6 downto 0) ; -- internal decoder XSLED : ledx port map (iCOUNTX,iLOUTX); YSLED : ledx port map (iCOUNTY,iLOUTY); ZSLED : ledx port map (iCOUNTZ,iLOUTZ);

セレクタ

 6けた分の7セグメントLEDがあるので、ダイナミック点灯する  ために、6進カウンタを用意します。  カウンタで0、1、2のとき、イネーブル信号を出します。  同時に、デコーダの出力を端子に印加します。 -- output SEGOUT <= iLOUTX when ( iLCNT = 0 ) else iLOUTY when ( iLCNT = 1 ) else iLOUTZ when ( iLCNT = 2 ) else "1111111" ; SEGSEL <= "111011" when ( iLCNT = 0 ) else "111101" when ( iLCNT = 1 ) else "111110" when ( iLCNT = 2 ) else "111111" ;  6進カウンタは、バイナリカウンタで構成します。 process (nRESET,iCLOCK) begin if ( nRESET = '0' ) then iLCNT <= 0 ; elsif rising_edge( iCLOCK ) then if ( iLCNT = 6 ) then iLCNT <= 0 ; else iLCNT <= iLCNT + 1 ; end if ; end if ; end process ;

クロックジェネレータ

 自作IPで説明した内容を利用します。

全体

 各コンポーネントを活用し、スロットマシンにまとめます。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity slot is generic ( TOPX : integer := 15 ; RMAX : integer := 25000 ; TOPY : integer := 5 ; CMAX : integer := 27 --; ); port( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger BTRG : in std_logic ; STRG : in std_logic_vector(2 downto 0) ; -- output DP : out std_logic ; SEGSEL : out std_logic_vector(5 downto 0) ; SEGOUT : out std_logic_vector(6 downto 0) --; ); end slot; architecture Behavioral of slot is -- clock generate component component clkgenx is generic ( TOPX : integer ; RMAX : integer --; ); port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- output CLKOUT : out std_logic -- ; ); end component; -- digit counter component component dcntx is port( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger BTRG : in std_logic ; -- begin trigger STRG : in std_logic ; -- stop trigger -- output COUT : out std_logic_vector(3 downto 0) --; ); end component ; -- 7 segment LED component component ledx is port ( -- input DIN : in std_logic_vector(3 downto 0); -- output DOUT : out std_logic_vector(6 downto 0) --; ); end component ; -- internal clock signal iCLOCK : std_logic ; signal iCLOCK2 : std_logic ; -- trigger signal iBTRG : std_logic ; signal iSTRG : std_logic_vector(2 downto 0) ; -- counter signal iCOUNTX : std_logic_vector(3 downto 0) ; signal iCOUNTY : std_logic_vector(3 downto 0) ; signal iCOUNTZ : std_logic_vector(3 downto 0) ; -- 7 segment LED signal iLOUTX : std_logic_vector(6 downto 0) ; signal iLOUTY : std_logic_vector(6 downto 0) ; signal iLOUTZ : std_logic_vector(6 downto 0) ; signal iLCNT : integer range 0 to 6 ; begin -- internal clock (1kHz) XCLK : clkgenx generic map (TOPX,RMAX) port map (nRESET,CLOCK,iCLOCK); YCLK : clkgenx generic map (TOPY,CMAX) port map (nRESET,iCLOCK,iCLOCK2); -- internal digit counter XCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(0),iCOUNTX); YCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(1),iCOUNTY); ZCOUNTER : dcntx port map (nRESET,iCLOCK2,iBTRG,iSTRG(2),iCOUNTZ); -- internal decoder XSLED : ledx port map (iCOUNTX,iLOUTX); YSLED : ledx port map (iCOUNTY,iLOUTY); ZSLED : ledx port map (iCOUNTZ,iLOUTZ); -- input iBTRG <= not BTRG ; iSTRG <= not STRG ; -- output SEGOUT <= iLOUTX when ( iLCNT = 0 ) else iLOUTY when ( iLCNT = 1 ) else iLOUTZ when ( iLCNT = 2 ) else "1111111" ; SEGSEL <= "111011" when ( iLCNT = 0 ) else "111101" when ( iLCNT = 1 ) else "111110" when ( iLCNT = 2 ) else "111111" ; DP <= '1' ; -- LED selector process (nRESET,iCLOCK) begin if ( nRESET = '0' ) then iLCNT <= 0 ; elsif rising_edge( iCLOCK ) then if ( iLCNT = 6 ) then iLCNT <= 0 ; else iLCNT <= iLCNT + 1 ; end if ; end if ; end process ; end Behavioral;

ピン割当て

 ボードで動かすためには、FPGAのI/Oボードと接続している  信号のピンをUCFファイルの中に記述します。 # system NET "CLOCK" LOC = "P56" ; NET "nRESET" LOC = "P107" ; # trigger NET "STRG<2>" LOC = "P6" ; NET "STRG<1>" LOC = "P10" ; NET "STRG<0>" LOC = "P18" ; NET "BTRG" LOC = "P24" ; # 7 segment LED charactor NET "DP" LOC = "P91" ; NET "SEGOUT<0>" LOC = "P92" ; NET "SEGOUT<1>" LOC = "P87" ; NET "SEGOUT<2>" LOC = "P88" ; NET "SEGOUT<3>" LOC = "P85" ; NET "SEGOUT<4>" LOC = "P86" ; NET "SEGOUT<5>" LOC = "P81" ; NET "SEGOUT<6>" LOC = "P82" ; # 7 segment LED selector NET "SEGSEL<0>" LOC = "P98" ; NET "SEGSEL<1>" LOC = "P83" ; NET "SEGSEL<2>" LOC = "P75" ; NET "SEGSEL<3>" LOC = "P74" ; NET "SEGSEL<4>" LOC = "P77" ; NET "SEGSEL<5>" LOC = "P76" ;


目次 inserted by FC2 system