LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY dac IS
GENERIC(
CLK_DIV: Integer:=63;
CLK_DIV_BITS: Integer:=6
);
PORT(
clock: IN STD_LOGIC;
rst: IN STD_LOGIC;
wr_data: IN STD_LOGIC_VECTOR(10 DOWNTO 0);--DAC 11位数据输入.
--//bit[10:9] 通道选择00:CHA; 01:CHB; 10:CHC; 11:CHD.
--//bit[8] RNG bit输出电压(0:参考电压到地;1:两倍参考电压到地)
--//bit[7:0] DAC转换代码,范围0~255.
--//输出电压Vo=REF*(CODE/256)*(1+RNG bit)
wr_act: IN STD_LOGIC;--写控制.
dac_clk: OUT STD_LOGIC;--DAC时钟输出
dac_data: OUT STD_LOGIC;--DAC数据输出
dac_load: OUT STD_LOGIC;--DAC数据加载信号输出
dac_ldac: OUT STD_LOGIC--DAC更新锁存信号输出.
);
END;
ARCHITECTURE one OF dac IS
SIGNAL counter: STD_LOGIC_VECTOR(CLK_DIV_BITS-1 DOWNTO 0);
SIGNAL dac_clk_r: STD_LOGIC;
SIGNAL dac_data_r: STD_LOGIC;
SIGNAL dac_load_r: STD_LOGIC;
SIGNAL bit_counter: STD_LOGIC_VECTOR(4 DOWNTO 0);--DAC数据输出位计数器.
SIGNAL div_clk: STD_LOGIC;--分频时钟
SIGNAL bit_counter_rst:STD_LOGIC;--位计数器复位信号.
SIGNAL dac_dat_send_finish: STD_LOGIC;
TYPE states IS (dac_idle,dac_send,dac_store);--状态机
SIGNAL dac_sta,dac_sta_next: states;
BEGIN
PROCESS(clock,rst)
BEGIN
IF RISING_EDGE(clock) THEN
IF rst='1' THEN
counter<="000000";
ELSE
IF counter<CLK_DIV THEN
counter<=counter + 1;
div_clk<='0';
ELSE
counter<="000000";
div_clk<='1';
END IF;
END IF;
END IF;
END PROCESS;
--<<状态机
PROCESS(clock,rst)
BEGIN
IF RISING_EDGE(clock) THEN
IF rst='1' THEN
dac_sta<=dac_idle;
ELSE
dac_sta<=dac_sta_next;
END IF;
END IF;
END PROCESS;
PROCESS(dac_sta,wr_act,div_clk,dac_dat_send_finish)--状态描述
BEGIN
dac_load_r<='1';
bit_counter_rst<='0';
dac_sta_next<=dac_idle;
CASE dac_sta IS
WHEN dac_idle=>
bit_counter_rst<='1'; --空闲时复位发送位计数器.
IF wr_act='1' THEN --有写数据信号时,进入发送状态.
dac_sta_next<=dac_send;
ELSE
dac_sta_next<=dac_idle;
END IF;
WHEN dac_send=>--位数据发送完成后进入数据锁存状态
IF dac_dat_send_finish ='1' THEN
dac_sta_next<=dac_store;
ELSE
dac_sta_next<=dac_send;
END IF;
WHEN dac_store=>
bit_counter_rst<='1';--发送位计数器复位.
dac_load_r<='0';--Load 变低进行数据锁存.
IF div_clk ='1' THEN
dac_sta_next<=dac_idle;
ELSE
dac_sta_next<=dac_store;
END IF;
END CASE;
END PROCESS;
PROCESS( clock)
BEGIN
IF rising_edge(clock) THEN
IF bit_counter_rst='1' THEN
bit_counter<="00000"; --发送位计数器清0
ELSIF div_clk='1' THEN --发送位计数器累加
bit_counter<=bit_counter + 1;
END IF;
END IF;
END PROCESS;
--当发送位计数器计数到24时,发送完毕.
dac_dat_send_finish<='1' WHEN bit_counter=24 else '0';
PROCESS(bit_counter(4 DOWNTO 1),wr_data)
BEGIN
CASE bit_counter(4 DOWNTO 1) IS --发送计数器每4:1位变换换时,发送1bit数据.
WHEN "0001"=> dac_data_r<=wr_data(10);--先高位.
WHEN "0010"=> dac_data_r<=wr_data(9);
WHEN "0011"=> dac_data_r<=wr_data(8);
WHEN "0100"=> dac_data_r<=wr_data(7);
WHEN "0101"=> dac_data_r<=wr_data(6);
WHEN "0110"=> dac_data_r<=wr_data(5);
WHEN "0111"=> dac_data_r<=wr_data(4);
WHEN "1000"=> dac_data_r<=wr_data(3);
WHEN "1001"=> dac_data_r<=wr_data(2);
WHEN "1010"=> dac_data_r<=wr_data(1);
WHEN "1011"=> dac_data_r<=wr_data(0);
WHEN OTHERS=> dac_data_r<='1';
END CASE;
END PROCESS;
PROCESS(bit_counter)--在发送位计数器2-24间产生dac clk
BEGIN
IF (bit_counter< 24) AND (bit_counter>=2) THEN
dac_clk_r<=NOT bit_counter(0);
ELSE
dac_clk_r<='0';
END IF;
END PROCESS;
dac_clk<=dac_clk_r;
dac_data<=dac_data_r;
dac_load<=dac_load_r;
dac_ldac<='0';
END;