📄 dac5662_spi.vhd
字号:
-- ###########################################################################
-- Module: DAC_SPI
-- Description:
-- This module communicates with the DAC chip DAC8532 from TI via SPI.
-- When the host wants to update a DAC, it will set the DAC_CHNL and the DAC_DIN first,
-- then assert the DAC_EN for at least one SCLK wide. Then this DAC_SPI module will write
-- the data to the data buffer of the specified DAC channel and load it.
-- Designed by: Ahrong
-- E-mail: jeawen.lin@163.com
-- Revision History:
-- 1.0 2005-12-28 Ahrong
-- Initial version
-- End
-- ###########################################################################
-- Application side interface between PCI core signals and user logic.
-- Signals with "_N" suffix are active low.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
-- library UNISIM;
-- use UNISIM.VComponents.all;
entity DAC5662_SPI is
port (
-- System signals
CLK : in std_logic; --System clock, 33MHZ
RST : IN STD_LOGIC;
-- signals to/from other modules
SCLK_RISE : IN STD_LOGIC; --CLOCK FOR DAC SPI
SCLK_FALL : IN STD_LOGIC;
-- DAC_CHNL : IN STD_LOGIC;
DAC_DIN : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
DAC_EN : IN STD_LOGIC; -- one SCLK wide
DAC_FINISH : OUT STD_LOGIC; -- to indecate the completion of the DAC SPI
-- signals to DAC CHIP
DAC_SCLK : OUT STD_LOGIC;
-- DAC_LDAC : OUT STD_LOGIC;
DAC_SYNC_N : OUT STD_LOGIC;
DAC_DO : OUT STD_LOGIC
);
end DAC5662_SPI;
architecture Behavioral of DAC5662_SPI is
signal reg_DacData : std_logic_vector(23 downto 0);
signal flg_DelayOver : std_logic;
signal reg_Delay : std_logic_vector(23 downto 0) := "000000000000000000000001";
signal reg_SRL24E_ENABLE : std_logic;
subtype state is std_logic_vector(3 downto 0);
signal STATE_CS,STATE_NS: state;
constant IDLE : state := "0001";
constant READY : state := "0010";
constant BUSY : state := "0100";
constant FINISH : state := "1000";
signal state_IDLE : std_logic;
signal state_READY : std_logic;
signal state_BUSY : std_logic;
signal state_FINISH : std_logic;
begin
--------------------------------------------------------------------------------
state_IDLE <= STATE_CS(0);
state_READY <= STATE_CS(1);
state_BUSY <= STATE_CS(2);
state_FINISH <= STATE_CS(3);
--DAC_LDAC <= '0'; -- Use software to Load DACs. Connect the LDAC pin of DAC8554 to GND permanently.
--------------------------------------------------------------------------------
process(RST,CLK)
begin
if RST = '1' then
STATE_CS <= IDLE;
elsif rising_edge(CLK) then
STATE_CS <= STATE_NS;
end if;
end process;
--------------------------------------------------------------------------------
FSM_DAC:
process(CLK, RST) --The finite state machine
begin
if RST = '1' then
STATE_NS <= IDLE;
elsif rising_edge(CLK) and (SCLK_RISE = '1') then
case STATE_CS is
when IDLE =>
if DAC_EN = '1' then
STATE_NS <= READY;
else
STATE_NS <= IDLE;
end if;
when READY =>
STATE_NS <= BUSY;
when BUSY =>
if flg_DelayOver = '1' then --finished shifting
STATE_NS <= FINISH;
end if;
when FINISH =>
STATE_NS <= IDLE;
when others =>
STATE_NS <= IDLE;
end case;
end if;
end process; --FSM_DAC:
--------------------------------------------------------------------------------
-- determine reg_SRL16E_ENABLE
reg_SRL24E_ENABLE <= SCLK_FALL when state_BUSY = '1' else '0'; -- IN SCLK_FALL
--delay block for the 24-bit data shifting
process(CLK)
begin
if rising_edge(CLK) then
if reg_SRL24E_ENABLE = '1' then
reg_Delay <= reg_Delay(22 downto 0) & reg_Delay(23); -- left shift
end if;
end if;
end process;
flg_DelayOver <= reg_Delay(0);
--------------------------------------------------------------------------------
DAC_FINISH <= '1' when state_FINISH = '1' else '0';
--------------------------------------------------------------------------------
-- OUTPUT DAC_SCLK
process(CLK,RST)
begin
if RST = '1' then
DAC_SCLK <= '1';
elsif rising_edge(CLK) then
if (state_READY = '1' or state_BUSY = '1') and SCLK_RISE = '1' then
DAC_SCLK <= '1';
end if;
if state_BUSY = '1' and SCLK_FALL = '1' then
DAC_SCLK <= '0';
end if;
end if;
end process;
--------------------------------------------------------------------------------
-- OUTPUT DAC_SYNC_N (DAC chip select signal,active low)
process(CLK,RST)
begin
if RST = '1' then
DAC_SYNC_N <= '1';
elsif rising_edge(CLK) and SCLK_RISE = '1' then
if state_READY = '1'then
DAC_SYNC_N <= '0';
elsif state_IDLE = '1' or state_FINISH = '1'then -- it's safer here than in FINISH state
DAC_SYNC_N <= '1';
end if;
end if;
end process;
---------------------------------------------------------------------------------
-- DAC DATA output
--| Chip address is 00;
--| DAC X output settles to specified value upon completion;
--| No power down.
process(CLK,RST)
begin
if RST = '1' then
reg_DacData <= (others => '0');
-- should turned in SCLK_RISE, then device can read in SCLK_FALL
elsif rising_edge(CLK) and SCLK_RISE = '1' then
if state_READY = '1' then
reg_DacData <= "00000000" & DAC_DIN;
elsif state_BUSY = '1' then
reg_DacData <= reg_DacData(22 downto 0) & '0';
end if;
end if;
end process;
DAC_DO <= reg_DacData(23);
--------------------------------------------------------------------------------
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -