目次
前
次
PLDによるハードテスト
Z80ボードは、ROMの中にプログラムを焼きこむ時間が必要に
なり、効率が悪いとわかりました。
もう少し、単純かつ短時間でテストするために、PLD
(Programmable Logic Device)を使うことにします。
手元には複数のCPLD/FPGAボードがあるので、そのうち
現在出番の少なくなったXilinxの3.3V動作CPLDボードを
使います。
このボードには、XC9572XLとCoolRunnerIIが載っているので
それぞれに、以下の電子回路のテストをさせます。
- 密着センサー
- DCモータ
- BCS(Bar Code Scanner)
- ロータリーエンコーダ
- GBC(Game Boy Cammera)
ボードには、フリースペースがありますが、再利用したい
ので、中継コネクタ+コネクタ基板を作成しました。
40ピンコネクタから、10ピンコネクタx4に変換し
10ピンケーブルで、MCR-VCマシンを構成する基板に
接続できるようにします。
40ピンコネクタのピン配置は、以下です。
1 GND 2 VU
3 Vdd(3.3V) 4 P44 <LED>
5 P43 6 P42
7 P41 8 P40
9 P39 10 P38
11 P37 12 P36
13 P34 14 P33 <RESET>
15 P32 16 P31
17 P30 18 P29
19 P28 20 P27
21 P23 22 P22
23 P21 24 P20
25 P19 26 P7
27 --- 28 ---
29 --- 30 P3
31 P2 32 P1 <CLOCK>
33 P18 34 P16
35 P14 36 P13
37 P12 38 P8
39 P6 40 P5
40ピンコネクタを挿し込むと、次のようになります。
利用できるピンは全部で33ピンですが、一部は、リセット、
クロック、テスト用LEDに使われているので、10ピンコネクタを
A〜Dの4グループに分けて、接続を決めます。
GroupA
1 Vdd
2 P43
3 P42
4 P41
5 P40
6 P39
7 P38
8 P37
9 P36
10 GND
GroupB
1 Vdd
2 P34
3 P32
4 P31
5 P30
6 P29
7 P28
8 P27
9 P23
10 GND
GroupC
1 Vdd
2 ---
3 P22
4 P21
5 P20
6 P19
7 P7
8 P3
9 P2
10 GND
GroupD
1 Vdd
2 P18
3 P16
4 P14
5 P13
6 P12
7 P8
8 P6
9 P5
10 GND
密着センサーの動作テストを考えてみると、センサーから
データを入力し、LEDに表示することにします。
8ビットデータを、トリガークリックで、LEDに表示します。
VHDLコードで記述します。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mcrvc1 is
Generic (
BSIZE : integer := 8 ;
CSIZE : integer := 3 ;
BOTTOM : integer := 0 -- ;
);
Port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- input
SENSOR : in std_logic_vector(BSIZE-1 downto BOTTOM) ;
-- trigger
TRG : in std_logic ;
-- output
LED : out std_logic ;
LEDOUT : out std_logic_vector(BSIZE-1 downto BOTTOM)-- ;
);
end mcrvc1;
architecture behavioral of mcrvc1 is
signal iREG : std_logic_vector(BSIZE-1 downto BOTTOM) ;
signal iSTRG : std_logic_vector(CSIZE-1 downto BOTTOM) ;
signal iTRG : std_logic ;
begin
-- output
LEDOUT <= iREG ;
LED <= not iTRG ;
-- input
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSTRG <= "000" ;
elsif rising_edge( CLOCK ) then
iSTRG <= iSTRG(1 downto 0) & TRG ;
end if ;
end process ;
iTRG <= '1' when ( iSTRG = "011" or iSTRG = "001" ) else '0' ;
-- latch
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iREG <= (others => '0') ;
elsif rising_edge( CLOCK ) then
if ( iTRG = '1' ) then
iREG <= not SENSOR ;
end if ;
end if ;
end process ;
end behavioral;
ピン配置を定義します。
# system
NET "LED" LOC = "P44" ;
NET "nRESET" LOC = "P33" ;
NET "CLOCK" LOC = "P1" ;
# group A
NET "SENSOR<7>" LOC = "P43" ;
NET "SENSOR<6>" LOC = "P42" ;
NET "SENSOR<5>" LOC = "P41" ;
NET "SENSOR<4>" LOC = "P40" ;
NET "SENSOR<3>" LOC = "P39" ;
NET "SENSOR<2>" LOC = "P38" ;
NET "SENSOR<1>" LOC = "P37" ;
NET "SENSOR<0>" LOC = "P36" ;
# group B
NET "LEDOUT<7>" LOC = "P34" ;
NET "LEDOUT<6>" LOC = "P32" ;
NET "LEDOUT<5>" LOC = "P31" ;
NET "LEDOUT<4>" LOC = "P30" ;
NET "LEDOUT<3>" LOC = "P29" ;
NET "LEDOUT<2>" LOC = "P28" ;
NET "LEDOUT<1>" LOC = "P27" ;
NET "LEDOUT<0>" LOC = "P23" ;
# group C(7bits)
NET "TRG" LOC = "P22" ;
次にモータ制御ボードのテストをします。
写真の右側に見えるMOS-FET、ドライバには2つの
LEDを接続してあり、PWM波形が入ると、LEDが点灯
する仕掛けがあります。
左側には、赤8本、緑8本のLEDを実装しています。
赤LEDは、密着型センサーのモニタ用です。緑LEDは
内部状態を表示するインディケータにしてあります。
中央に、LEDとスイッチを配置しています。モード指定
とスタートトリガーを、トグルとプッシュスイッチに
割当てています。緑LEDで表示できない、緊急状態に
システムが陥ったときや、センターラインと交差する
白線を検出したことを示すLEDを用意しています。
赤LED、緑LEDの点灯表示テスト、中央2個のスイッチの
ON/OFFを2個のLEDでモニタします。
モータドライバへの出力は、カウンタを用意して、カウンタ
の出力を接続します。
3つの内容を含めたVHDLコードは、以下としました。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mcrvc7 is
generic (
PMAX : integer := 40000 ;
TOP : integer := 22 ;
BSIZE : integer := 2 ;
CSIZE : integer := 8 ;
BOTTOM : integer := 0 --;
) ;
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- input
SWX : in std_logic_vector(BSIZE-1 downto BOTTOM) ;
-- output
LED : out std_logic ;
LOUT : out std_logic_vector(BSIZE-1 downto BOTTOM) ;
RLOUT : out std_logic_vector(CSIZE-1 downto BOTTOM) ; -- red LED
GLOUT : out std_logic_vector(CSIZE-1 downto BOTTOM) ; -- green LED
PWMX : out std_logic_vector(BSIZE-1 downto BOTTOM) --;
) ;
end mcrvc7;
architecture Behavioral of mcrvc7 is
signal iSCNT : std_logic_vector(TOP-1 downto BOTTOM) ;
signal iLCNT : std_logic_vector(BSIZE downto BOTTOM) ;
signal iPWMX : std_logic_vector(BSIZE-1 downto BOTTOM) ;
signal iSWX : std_logic_vector(BSIZE-1 downto BOTTOM) ;
signal iGLOUT : std_logic_vector(CSIZE-1 downto BOTTOM) ;
begin
-- output
LOUT <= not iSWX ;
RLOUT <= not iGLOUT ;
GLOUT <= not iGLOUT ;
PWMX <= iPWMX ;
LED <= not iSCNT(TOP-1) ;
-- divider
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSCNT <= (others => '0') ;
elsif rising_edge( CLOCK ) then
-- increment
iSCNT <= iSCNT + '1' ;
end if ;
end process ;
-- local counter
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iLCNT <= "000" ;
iPWMX <= "00" ;
elsif rising_edge( CLOCK ) then
-- increment
iLCNT <= iSCNT(TOP-4 downto TOP-6) ;
iPWMX <= iSCNT(TOP-4 downto TOP-5) ;
end if ;
end process ;
-- latch
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSWX <= "00" ;
elsif falling_edge( CLOCK ) then
if ( iSCNT(TOP-8 downto TOP-9) = "11" ) then
iSWX <= not SWX ;
end if ;
end if ;
end process ;
-- decoder
iGLOUT <= "00000001" when ( iLCNT = "000" ) else
"00000010" when ( iLCNT = "001" ) else
"00000100" when ( iLCNT = "010" ) else
"00001000" when ( iLCNT = "011" ) else
"00010000" when ( iLCNT = "100" ) else
"00100000" when ( iLCNT = "101" ) else
"01000000" when ( iLCNT = "110" ) else
"10000000" when ( iLCNT = "111" ) else
"00000000" ;
end Behavioral;
ピン配置は、次のように定義しました。
# system
NET "LED" LOC = "P44" ;
NET "nRESET" LOC = "P33" ;
NET "CLOCK" LOC = "P1" ;
# group A
NET "RLOUT<7>" LOC = "P43" ;
NET "RLOUT<6>" LOC = "P42" ;
NET "RLOUT<5>" LOC = "P41" ;
NET "RLOUT<4>" LOC = "P40" ;
NET "RLOUT<3>" LOC = "P39" ;
NET "RLOUT<2>" LOC = "P38" ;
NET "RLOUT<1>" LOC = "P37" ;
NET "RLOUT<0>" LOC = "P36" ;
# group B
NET "PWMX<0>" LOC = "P34" ;
NET "PWMX<1>" LOC = "P31" ;
NET "SWX<0>" LOC = "P29" ;
NET "SWX<1>" LOC = "P28" ;
NET "LOUT<1>" LOC = "P27" ;
NET "LOUT<0>" LOC = "P23" ;
# group D
NET "GLOUT<7>" LOC = "P18" ;
NET "GLOUT<6>" LOC = "P16" ;
NET "GLOUT<5>" LOC = "P14" ;
NET "GLOUT<4>" LOC = "P13" ;
NET "GLOUT<3>" LOC = "P12" ;
NET "GLOUT<2>" LOC = "P8" ;
NET "GLOUT<1>" LOC = "P6" ;
NET "GLOUT<0>" LOC = "P5" ;
赤LED8個、緑LED8個の接続をテストしている画像です。
2つのスイッチの状態を、2つのLEDにモニタしています。
モータドライバに、PWM波形が来ているかのテストです。
制御ボードは、ピンでマイコンやCPLD/FPGAに接続する仕様
なので、マイコン、FPGA、CPLDの種別を気にしないでテスト
できます。
ロータリーエンコーダから出力されてくるパルスを表示する
処理を考えました。
ロータリーエンコーダの出力を、シフトレジスタでとらえて
立上りエッジがあった場合、内部カウンタに+1する仕様で
コードを記述しました。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mcrx4 is
generic (
TOPX : integer := 10 ;
RMAX : integer := 921 --;
) ;
Port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- input
RCONR : in std_logic ; -- right clock trigger
RCONL : in std_logic ; -- left clock trigger
-- OUTPUT
RCNT : out std_logic_vector(7 downto 0) ;
LCNT : out std_logic_vector(7 downto 0) ;
LED : out std_logic --;
);
end mcrx4;
architecture behavioral of mcrx4 is
-- clock generator
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 ;
-- LED handler
component loutx is
port(
-- input
CNTR : in std_logic_vector(7 downto 0) ;
CNTL : in std_logic_vector(7 downto 0) ;
-- output
OCNTR : out std_logic_vector(7 downto 0) ;
OCNTL : out std_logic_vector(7 downto 0) --;
);
end component ;
-- clock
signal iMCLK : std_logic ;
-- trigger
signal iRCONR_SFT : std_logic_vector(2 downto 0) ;
signal iRCONL_SFT : std_logic_vector(2 downto 0) ;
signal iRCONR_TRG : std_logic ;
signal iRCONL_TRG : std_logic ;
-- internal counter
signal iCNTRX : std_logic_vector(7 downto 0) ;
signal iCNTLX : std_logic_vector(7 downto 0) ;
-- output
signal iROUTCNT : std_logic_vector(7 downto 0) ;
signal iLOUTCNT : std_logic_vector(7 downto 0) ;
-- update counter
signal iCNTR : std_logic_vector(7 downto 0) ;
signal iCNTL : std_logic_vector(7 downto 0) ;
signal iUCNT : integer range 0 to 10 ;
begin
-- clock
CLKX : clkgenx generic map (TOPX,RMAX) port map (nRESET,CLOCK,iMCLK) ;
-- LED handler
LOUTXX : loutx port map (iCNTR,iCNTL,iROUTCNT,iLOUTCNT) ;
-- output data
RCNT <= iROUTCNT ;
LCNT <= iLOUTCNT ;
-- monitor
LED <= not iMCLK ;
-- trigger handler
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iRCONR_SFT <= "000" ;
iRCONL_SFT <= "000" ;
elsif rising_edge(iMCLK) then
iRCONR_SFT <= iRCONR_SFT(1 downto 0) & RCONR ;
iRCONL_SFT <= iRCONL_SFT(1 downto 0) & RCONL ;
end if ;
end process ;
iRCONR_TRG <= '1' when ( iRCONR_SFT = "011" or iRCONR_SFT = "001" ) else '0' ;
iRCONL_TRG <= '1' when ( iRCONL_SFT = "011" or iRCONL_SFT = "001" ) else '0' ;
-- counter
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iCNTRX <= (others => '0') ;
iCNTLX <= (others => '0') ;
elsif rising_edge(iMCLK) then
if ( iRCONR_TRG = '1' ) then
iCNTRX <= iCNTRX + '1' ;
end if ;
if ( iRCONL_TRG = '1' ) then
iCNTLX <= iCNTLX + '1' ;
end if ;
if ( iUCNT = 10 ) then
iCNTRX <= (others => '0') ;
iCNTLX <= (others => '0') ;
end if ;
end if ;
end process ;
-- update
process (nRESET,iMCLK)
begin
if ( nRESET = '0' ) then
iUCNT <= 0 ;
iCNTR <= (others => '0') ;
iCNTL <= (others => '0') ;
elsif rising_edge(iMCLK) then
if ( iUCNT = 10 ) then
iUCNT <= 0 ;
iCNTR <= iCNTRX ;
iCNTL <= iCNTLX ;
else
iUCNT <= iUCNT + 1;
end if ;
end if ;
end process ;
end behavioral;
制御ボードには、赤と緑のLEDがあるので、カウント値を
2進数で表示します。そのために、VHDLコードを定義して
使います。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity loutx is
port(
-- input
CNTR : in std_logic_vector(7 downto 0) ;
CNTL : in std_logic_vector(7 downto 0) ;
-- output
OCNTR : out std_logic_vector(7 downto 0) ;
OCNTL : out std_logic_vector(7 downto 0) --;
);
end loutx;
architecture Behavioral of loutx is
signal iOCNTR : std_logic_vector(7 downto 0);
signal iOCNTL : std_logic_vector(7 downto 0);
begin
-- input
iOCNTR <= CNTR ;
iOCNTL <= CNTL ;
-- output
OCNTR <= not iOCNTR ;
OCNTL <= not iOCNTL ;
end Behavioral;
クロックを分周するために、もうひとつVHDLコードを定義
しました。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clkgenx is
generic (
TOPX : integer ;
RMAX : integer --;
);
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ;
-- output
CLKOUT : out std_logic -- ;
);
end clkgenx;
architecture Behavioral of clkgenx is
signal iSCNT : std_logic_vector(TOPX-1 downto 0);
signal iCLK : std_logic ;
begin
-- output
CLKOUT <= iCLK ;
-- divider
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSCNT <= (others => '0') ;
iCLK <= '0' ;
elsif rising_edge(CLOCK) then
if ( conv_integer(iSCNT) = RMAX ) then
iSCNT <= (others => '0') ;
iCLK <= not iCLK ;
else
iSCNT <= iSCNT + '1' ;
end if ;
end if ;
end process ;
end Behavioral;
目次
前
次