[新連載]CPLD入門!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使うことになるだろうと思ってはいたのですが。
何を今頃になって、というようなものですが。
ようやく本気で、CPLDと四つに取り組みます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第128回]
●CPLDロジアナ(17)VHDLプログラム(1)
下はCPLDロジアナのVHDLプログラムです。
--logiana
--19/4/29 4/30 5/22 5/23 5/24
--6/12
--10/14 from logiana1b
--10/15 10/16 11/13
--20/1/12 1/13 1/14
--10/27 10/28
--21/12/31
--22/1/3 1/8 1/9 1/12 1/19 1/20 1/31
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library ARITHMETIC;
use ARITHMETIC.std_logic_arith.all;
entity logiana3a is
PORT (
P4:out std_logic;--not used
P8:out std_logic;--not used
P37:out std_logic;--not used
P40:out std_logic;--not used
P41:out std_logic;--end mark=a15_
P45:out std_logic;--not used
P58:in std_logic;--not used
P73:in std_logic;--not used
P74:in std_logic;--not used
RC:inout std_logic_vector(7 downto 0);--pic rc
IORD:in std_logic;
IOWR:in std_logic;
ADSELECT:in std_logic;
CLK:in std_logic;--100MHz
PBIN:in std_logic_vector(7 downto 0);--plobe
PBINH_nc:out std_logic_vector(7 downto 0);
MAOUT:out std_logic_vector(14 downto 0);
MDINOUT:inout std_logic_vector(7 downto 0);
MWR:out std_logic);
end logiana3a;
architecture rtl of logiana3a is
signal res_clr:std_logic;
signal cntrs:std_logic;
signal cntrswk:std_logic;
signal r_w:std_logic;
signal cntonmk:std_logic;
signal cntrclk:std_logic;
signal clkwk:std_logic_vector(2 downto 0);
signal clkwk2:std_logic;
signal clk2mwk:std_logic_vector(3 downto 0);
signal clk2m:std_logic;
signal clk2mwk2:std_logic_vector(1 downto 0);
signal cntrL:std_logic_vector(2 downto 0);
signal cntrH:std_logic_vector(15 downto 0);
signal trigedge:std_logic;
signal clkslct:std_logic_vector(2 downto 0);
signal trigprobe:std_logic_vector(3 downto 0);
signal pbinL:std_logic_vector(7 downto 0);
signal trigon:std_logic;
signal trigonL:std_logic;--see 6/12 note
signal trigonH:std_logic;
signal trigin:std_logic;
signal resadrs3b:std_logic_vector(2 downto 0);
signal trigedge3b:std_logic_vector(2 downto 0);
signal clk0:std_logic;
signal clk1:std_logic;
signal clk2:std_logic;
signal clk3:std_logic;
--
begin
-- i/o adrsselect
process(ADSELECT)
begin
if ADSELECT'event and ADSELECT='0' then
-----------------
-- command set
if RC="00000000" then
res_clr<='0';--00,06 reset,01,07 start
r_w<='0';
elsif RC="00000001" then
res_clr<='1';
r_w<='0';
elsif RC="00000110" then
res_clr<='0';
r_w<='1';
elsif RC="00000111" then
res_clr<='1';
r_w<='1';
--trigger edge
elsif RC(7 downto 1)="0000010" then--04,05
trigedge<=RC(0);
-- clock select
elsif RC(7 downto 4)="0001" then--1x
clkslct<=RC(2 downto 0);
--trigger mask
elsif RC(7 downto 5)="001" then--2x,3x
trigprobe<=RC(3 downto 0);
end if;
end if;
end process;
--
-- select trigger probe
--
trigin<=PBIN(0) when trigprobe="0000" else
PBIN(1) when trigprobe="0001" else
PBIN(2) when trigprobe="0010" else
PBIN(3) when trigprobe="0011" else
PBIN(4) when trigprobe="0100" else
PBIN(5) when trigprobe="0101" else
PBIN(6) when trigprobe="0110" else
PBIN(7); --trigprobe="0111"
--
-- trigger on
--
process(trigin,res_clr)
begin
if res_clr='0' then
trigonH<='0';
trigonL<='0';
elsif trigin'event and trigin='0' and trigedge='0' then
trigonL<='1';
elsif trigin'event and trigin='1' and trigedge='1' then
trigonH<='1';
end if;
end process;
trigon<=trigonH or trigonL;
--
--make clock for 50MHz,10MHz,5MHz
--clkwk(0)=50MHz clkwk(1)=25MHz
--
process(CLK)
begin
if CLK'event and CLK='0' then
clkwk<=clkwk+"01";--10M,5M
end if;
end process;
--
--make clk2mwk for 2MHz
--clk2mwk(3)=10mhz
--
process(CLK)
begin
if CLK'event and CLK='0' then
if clk2mwk="1001" then
clk2mwk<="0000";
else
clk2mwk<=clk2mwk+"0001";
end if;
end if;
end process;
--
--make clk2mwk2
--clk2mwk2(0)=5mhz clk2mwk2(1)=2.5mhz
--
clk2m<=clk2mwk(3);--10mhz
--
process(clk2m)
begin
if clk2m'event and clk2m='0' then
clk2mwk2<=clk2mwk2+"01";--1M,500k
end if;
end process;
--
-- select clock
--
clkwk2<=CLK when clkslct<="010" else --20MHz
clkwk(0) when clkslct="011" else --10MHz
clkwk(1) when clkslct="100" else --5MHz
clk2m when clkslct="101" else --2MHz
clk2mwk2(0) when clkslct="110" else --1MHz
clk2mwk2(1) when clkslct="111" else --500KHz
'1';
--
--make cntrL --- cntrL(2)=1/5clkwk2
--
process(clkwk2,res_clr)
begin
if res_clr='0' then
cntrL<="000";
elsif clkwk2'event and clkwk2='0' then
if cntrL="100" then
cntrL<="000";
else
cntrL<=cntrL+"001";
end if;
end if;
end process;
--
-- make cntrs
--
--for MEMORY address up,PBIN latch,MEMWR
--
-- select cntrs
--
cntrswk<=CLK when clkslct="000" else --100MHz
clkwk(0) when clkslct="001" else --50MHz
cntrL(2);--20MHz-500KHz
--
cntrs<=cntrswk when r_w='0' and trigon='1' else IORD;
--
-- cntrH up for MEMORY ADDRESS
--
process(cntrs,res_clr)
begin
if res_clr='0' then
cntrH<="0000000000000000";
elsif cntrs'event and cntrs='1' and cntrH(15)='0' then
cntrH<=cntrH+"0000000000000001";
end if;
end process;
--
-- PBIN latch
--
process(cntrs)
begin
if cntrs'event and cntrs='0' then
pbinL<=PBIN(7 downto 0);
end if;
end process;
--
--data out to pic
--
RC<=MDINOUT when IORD='0' else "ZZZZZZZZ";
--
--PBDATA to RAM
--
MDINOUT<=pbinL when r_w='0' else "ZZZZZZZZ";
--
P41<=not cntrH(15);--end mark
--
--MEMWR
--
MWR<=cntrs or r_w or cntrH(15);--MWR_=cntrs='0' and r_w='0'
--
MAOUT<=cntrH(14 downto 0);
--
end rtl;
|
結構長いプログラムです。
ざっと全体を見ていただいたところで少しずつ区切って説明をしていきます。
先頭のPORTやsignalの宣言のところは省きます。
最初のprocess文です。
process(ADSELECT)
begin
if ADSELECT'event and ADSELECT='0' then
-----------------
-- command set
if RC="00000000" then
res_clr<='0';--00,06 reset,01,07 start
r_w<='0';
elsif RC="00000001" then
res_clr<='1';
r_w<='0';
elsif RC="00000110" then
res_clr<='0';
r_w<='1';
elsif RC="00000111" then
res_clr<='1';
r_w<='1';
--trigger edge
elsif RC(7 downto 1)="0000010" then--04,05
trigedge<=RC(0);
-- clock select
elsif RC(7 downto 4)="0001" then--1x
clkslct<=RC(2 downto 0);
--trigger mask
elsif RC(7 downto 5)="001" then--2x,3x
trigplobe<=RC(3 downto 0);
end if;
end if;
end process;
|
CPLDロジアナのpic18F14K50はもともとWindowsパソコンとUSB接続をしてその先に82C55を接続することでWindowsパソコンでIO制御をするように考えたものを利用しています。
汎用I/OとするためにRC0〜RC7をI/OアドレスをセットするためとI/Oデータの入出力に使います。
I/OアドレスをセットするときはADSELECT(RB4)をアクティブロウにします。
信号名、端子名については前回の回路図を参照してください。
RCポートをデータの入出力に使うときはIORD、IOWR(RB5、RB7)をアクティブロウにします。
CPLDをロジアナとして使うために最初に色々な機能を設定します。
その機能設定のためのコマンドとしてI/Oアドレスを使います。
00Hは測定開始のためのメモリアドレスクリアコマンドです。
リセットクリアON(res_clr=0)
書き込みモードON(r_w=0)
にします。
01Hは測定開始コマンドです。
リセットクリアOFF(res_clr=1)
書き込みモードON(r_w=0)
にします。
06Hはデータ読み出しのためのメモリアドレスクリアコマンドです。
リセットクリアON(res_clr=0)
読み出しモードON(r_w=1)
にします。
07Hはデータ読み出し開始コマンドです。
リセットクリアOFF(res_clr=1)
読み出しモードON(r_w=1)
にします。
04H、05Hはトリガエッジ指定コマンドです。
04は下がりエッジ、05は上がりエッジ指定です。
1XHはサンプリングクロック指定コマンドです。
上位4ビットが0001のとき下位3ビット(000〜111)でサンプリングクロックを指定します。
000が100MHzで111が500KHzです。
上位3ビットが001のとき(2XH、3XH)下位4ビット(0000〜1111)でトリガプローブを指定します。
0000がPROBE0で0111がPROBE7です。
1000〜1111は未使用です。
本日は時間がなくなってしまいました。
続きは次回に書くことにいたします。
CPLD入門![第128回]
2022.2.2upload
前へ
次へ
ホームページトップへ戻る