目次
前
次
DAC emulator
SPIインタフェースを利用したD/Aコンバータを
入手する前に、マイクロコンピュータとの接続
をテストするために、エミュレータを考えた。
利用するDACは、Microchip Technologyのデバイス
で、次のインタフェースを持つ。
SPIのインタフェースと異なる点は、以下。
- MOSIは、16ビットデータで転送。
- nLOADで内部レジスタに情報転送。
- MISOが存在しない。
他は、通常のSPIスレーブモード3と同じ。
16ビットのデータ転送は、シフトレジスタに
16ビットを用意しnSSの状態で、ビットデータ
を保存する。
process (nRESET,SCK)
begin
if ( nRESET = '0' ) then
iMOSI_SFT <= X"0000" ;
elsif rising_edge(SCK) then
if ( iSS = '1' ) then
iMOSI_SFT <= iMOSI_SFT(14 downto 0) & iMOSI ;
end if ;
end if ;
end process ;
CPLD/FPGA内部では、正論理で動かすとして
SSを論理反転して扱う。
iSS <= not nSS ;
正論理で扱えば、iSSが'1'のときに
内部シフトレジスタにMOSIの信号を
入力していく。
内部シフトレジスタにデータが入った後
制御コードとデータに分割してCPLD外部
に出力する。
nLOAD信号は、データ転送が終わるとH→L→Hと
変化させて、出力に反映させる。変化を捉えて
転送終了を、後処理回路に通知する。
エッジを捉えるには、シフトレジスタを利用する。
iLOAD <= not nLOAD ;
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iLOAD_SFT <= "000" ;
elsif rising_edge(CLOCK) then
iLOAD_SFT <= iLOAD_SFT(1 downto 0) & iLOAD ;
end if ;
end process ;
iSTRG <= '1' when ( iLOAD_SFT = "110" ) else '0' ;
iSTRGを後処理回路の動作開始トリガーに利用。
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
iREG <= (others => '0') ;
elsif rising_edge(CLOCK) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iSTRG = '1' ) then
iSTATE <= "01" ;
else
iSTATE <= "00" ;
end if ;
-- copy
when 1 => iSTATE <= "11" ;
iREG <= iMOSI_SFT ;
-- clear register
when 3 => iSTATE <= "10" ;
iREG <= (others => '0') ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
まとめると以下。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dacemu is
port (
-- system
nRESET : in std_logic ;
CLOCK : in std_logic ; -- 4MHz
-- SPI
SCK : in std_logic ;
nSS : in std_logic ;
MOSI : in std_logic ;
nLOAD : in std_logic ;
-- control code outpu
CDOUT : out std_logic_vector(3 downto 0) ;
-- register output
REGOUT : out std_logic_vector(11 downto 0) --;
);
end dacemu ;
architecture behavioral of dacemu is
-- BUS interface
signal iSS : std_logic ;
signal iMOSI : std_logic ;
signal iLOAD : std_logic ;
-- synchronizer
signal iLOAD_SFT : std_logic_vector(2 downto 0) ;
signal iSTRG : std_logic ;
-- internal shift register
signal iMOSI_SFT : std_logic_vector(15 downto 0) ;
-- internal register
signal iREG : std_logic_vector(15 downto 0) ;
-- sequencer
signal iSTATE : std_logic_vector(1 downto 0) ;
begin
-- input
iSS <= not nSS ;
iMOSI <= MOSI ;
iLOAD <= not nLOAD ;
-- output
CDOUT <= iREG(15 downto 12) ;
REGOUT <= iREG(11 downto 0) ;
-- synchronizer
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iLOAD_SFT <= "000" ;
elsif rising_edge(CLOCK) then
iLOAD_SFT <= iLOAD_SFT(1 downto 0) & iLOAD ;
end if ;
end process ;
iSTRG <= '1' when ( iLOAD_SFT = "110" ) else '0' ;
-- internal register
process (nRESET,SCK)
begin
if ( nRESET = '0' ) then
iMOSI_SFT <= X"0000" ;
elsif rising_edge(SCK) then
if ( iSS = '1' ) then
iMOSI_SFT <= iMOSI_SFT(14 downto 0) & iMOSI ;
end if ;
end if ;
end process ;
-- sequencer
process (nRESET,CLOCK)
begin
if ( nRESET = '0' ) then
iSTATE <= "00" ;
iREG <= (others => '0') ;
elsif rising_edge(CLOCK) then
case conv_integer(iSTATE) is
-- wait trigger
when 0 => if ( iSTRG = '1' ) then
iSTATE <= "01" ;
else
iSTATE <= "00" ;
end if ;
-- copy
when 1 => iSTATE <= "11" ;
iREG <= iMOSI_SFT ;
-- clear register
when 3 => iSTATE <= "10" ;
iREG <= (others => '0') ;
-- return first state
when 2 => iSTATE <= "00" ;
-- default
when others =>
iSTATE <= "00" ;
end case ;
end if ;
end process ;
end behavioral;
DUTY比を格納したレジスタの値を確認できる
ように、6ビットの出力を用意。左右を指定
するためのセレクタビットを入れてある。
ピンアサインは、以下。
# system
NET "CLOCK" LOC = "P5" ;
NET "nRESET" LOC = "P39" ;
# SPI interface
NET "nSS" LOC = "P1" ;
NET "MOSI" LOC = "P2" ;
NET "nLOAD" LOC = "P3" ;
NET "SCK" LOC = "P6" ;
# register output
NET "REGOUT<0>" LOC = "P11" ;
NET "REGOUT<1>" LOC = "P12" ;
NET "REGOUT<2>" LOC = "P13" ;
NET "REGOUT<3>" LOC = "P14" ;
NET "REGOUT<4>" LOC = "P18" ;
NET "REGOUT<5>" LOC = "P19" ;
NET "REGOUT<6>" LOC = "P20" ;
NET "REGOUT<7>" LOC = "P22" ;
NET "REGOUT<8>" LOC = "P24" ;
NET "REGOUT<9>" LOC = "P25" ;
NET "REGOUT<10>" LOC = "P26" ;
NET "REGOUT<11>" LOC = "P27" ;
# code output
NET "CDOUT<0>" LOC = "P28" ;
NET "CDOUT<1>" LOC = "P29" ;
NET "CDOUT<2>" LOC = "P33" ;
NET "CDOUT<3>" LOC = "P34" ;
ターゲットにしたDACは、MCP4922。
目次
前
次