目次CPLD入門デジタル時計周辺回路


デジタル時計用 周辺回路
ソースコード/解説



001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
--**********************************************************************************
--*                                                                                *
--*                           Digital Clock peripheral logic                       *
--*                                                         Device : XC9536-PC44   *
--*                                                         Author : Seiichi Inoue *
--**********************************************************************************
library IEEE;                                         -- Library declaration
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity clock2 is
    Port ( S,R : in std_logic_vector(1 downto 0);     -- SR-FF INPUT
           Q : out std_logic_vector(1 downto 0);      -- SR-FF OUTPUT
           CLK_10M : in std_logic;                    -- 1/200000 counter INPUT
           CLK_50 : out std_logic;                    -- 1/200000 counter OUTPUT
           A,B,C : in std_logic;                      -- 3-8 Decoder INPUT
           DEC : out std_logic_vector(7 downto 0));   -- 3-8 Decoder OUTPUT
  attribute pin_assign : string;                      -- Pin assign
  attribute pin_assign of S : signal is "6,2";
  attribute pin_assign of R : signal is "4,44";
  attribute pin_assign of Q : signal is "42,40";
  attribute pin_assign of CLK_10M : signal is "7";
  attribute pin_assign of CLK_50 : signal is "39";
  attribute pin_assign of A : signal is "37";
  attribute pin_assign of B : signal is "35";
  attribute pin_assign of C : signal is "33";
  attribute pin_assign of DEC : signal is "27,25,28,26,22,20,18,24";
end clock2;

architecture clock2_arch of clock2 is
  signal SI,RI,QI,QRI : std_logic_vector(1 downto 0); -- SR-FF signals
  signal Q100K : std_logic_vector(16 downto 0);       -- 1/100000 counter
  signal QCLK : std_logic_vector(0 downto 0);         -- 1/2 counter
  signal IN_DATA : std_logic_vector(2 downto 0);      -- 3-8 Decoder signals

begin
-- ** SR-FF **
  Q <= QI;                                            -- Set OUTPUT
  QI <= S nand SI;                                    -- Make NAND
  QRI <= R nand RI;                                   -- Make NAND
  SI <= QRI;                                          -- Connect QRI and SI
  RI <= QI;                                           -- Connect QI and RI

-- ** 1/200000 counter **
  CLK_50 <= QCLK(0);                                  -- Set OUTPUT
  process( CLK_10M ) begin
    if CLK_10M='1' and CLK_10M'event then             -- Clock rising edge ?
      if Q100K=99999 then                             -- Count = 100000 ?
         Q100K <= "00000000000000000";                -- YES. Clear counter
         QCLK <= QCLK + '1';                          -- Set 1/200000 counter
      else                                            -- No.
         Q100K <= Q100K + '1';                        -- Count-up
      end if;
    end if;
  end process;

-- ** 3-8 Decoder **
  IN_DATA <= C & B & A;                               -- Binding vector
  process( IN_DATA ) begin
    case IN_DATA is                                   -- Decode with input data
      when "000" => DEC <= "11111110";
      when "001" => DEC <= "11111101";
      when "010" => DEC <= "11111011";
      when "011" => DEC <= "11110111";
      when "100" => DEC <= "11101111";
      when "101" => DEC <= "11011111";
      when "110" => DEC <= "10111111";
      when "111" => DEC <= "01111111";
      when others => DEC <= "XXXXXXXX";               -- Illegal condition
    end case;
  end process;

end clock2_arch;

--**********************************************************************************
--*                       end of Digital Clock peripheral logic                    *
--**********************************************************************************

解説
行番号コメント
007
-010
std_logicライブラリを指定します。
WebPACK 3.1WP1.x ではこれらのライブラリーが標準で組み込まれます。
013
-018
入力/出力のポートを指定します。
SR-FFは2組作るのでベクターで指定します。
3-8デコーダの出力は8ビットの組にするためにベクター指定します。
019
-028
入力/出力のピンを指定します。
ベクター指定してる信号は指定した数のピンを設定します。
ピンはCPLDを実装するパターンを描いて決めました。
032
-035
内部ロジックで使用する信号を定義します。
100000のカウントをするためには17ビット必要です。
1/2のカウンターは1ビットなのでベクターにする必要はないのですが、算術演算をするためにベクター指定しています。
IN_DATAは3-8デコーダの入力を束ねるための内部信号定義です。
039内部ロジックのレジスタを出力レジスタに結びつけます。
040セット(S)側のNAND回路を作ります。
041リセット(R)側のNAND回路を作ります。
042リセット側の出力をセット側の入力に結びつけます。
043セット側の出力をリセット側の入力に結びつけます。
0461/2カウンターのレジスタを出力レジスタに結びつけます。
047入力信号をCLK_10Mにしてプロセスを開始します。
048 CLK_10Mの0から1への変化を検出します。
「CLK_10M='1' and CLK_10M'event」はCLK_10Mが'0'から'1'に変化したことを検出する記述です。
049
-051
Q100Kが99999になったらカウンターをクリアします。0からスタートするので99999で100000カウントです。同時に1/2カウンター(QCLK)を加算します。QCLKは1ビットしかないので、100000カウントする都度"0"と"1"を交互に繰り返すことになります。ですから、1/2の出力は1/200000になります。
053Q100Kが100000でない場合、カウンターを加算します。
0593-8デコーダの入力(A,B,C)をベクターに束ねます。
060IN_DATAを入力信号としてプロセスを開始します。
061
-069
IN_DATAの内容によりCASE文で分岐します。
入力データに該当するデータをDECに出力します。
070 CASE文の場合、全ての入力パターンが指定されていても、when othersが必要です。
今回の指定ではDon't care(出力は不定という意味のX(0でも1でも良い))を記載しています。