library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity DAC is
Port (
CLK, RST, START : in std_logic;
D1, D2, CLK_OUT, nSYNC,DONE : out std_logic;
DATA1, DATA2 : in std_logic_vector(11 downto 0));
end DAC;
architecture Behavioral of DAC is
type states is (Idle,ShiftOut,SyncData);
signal current_state : states;
signal next_state : states;
signal temp1, temp2 : std_logic_vector(15 downto 0);
signal clk_div, shiftCounter, enShiftCounter, enParalelLoad : std_logic;
begin
clkdiv: process(clk, rst)
variable clk_counter : integer range 0 to 5; --for 120MHz system clock. 120/5 = 24MHz serial clock.
begin
if (rising_edge(clk)) then
if (rst = '1') then
clk_div <= '0';
clk_out <= '0';
clk_counter := 0;
else
if (clk_counter = 5) then
clk_div <= '1';
clk_out <= '1';
clk_counter := 0;
else
clk_div <= '0';
clk_out <= '0';
clk_counter := clk_counter + 1;
end if;
end if;
end if;
end process;
counter : process(clk_div, shiftcounter, enParalelLoad, enShiftCounter, DATA1, DATA2)
variable count : integer range 0 to 15;
begin
if (rising_edge(clk_div)) then
if (enParalelLoad = '1') then
shiftCounter <= '0';
temp1 <= "0000" & DATA1;
temp2 <= "0000" & DATA2;
elsif (enShiftCounter = '1') then
temp1 <= temp1(14 downto 0)&temp1(15);
temp2 <= temp2(14 downto 0)&temp2(15);
count := count + 1;
if (count = 15) then
shiftcounter <= '1';
end if;
end if;
end if;
end process;
D1 <= temp1(15);
D2 <= temp2(15);
SYNC_PROC: process (clk_div, rst)
begin
if (rising_edge(clk_div)) then
if (rst = '1') then
current_state <= Idle;
else
current_state <= next_state;
end if;
end if;
end process;
OUTPUT_DECODE: process (CLK, current_state)
begin
if (rising_edge(CLK)) then
if (current_state = Idle) then
enShiftCounter <='0';
DONE <='1';
nSYNC <='1';
enParalelLoad <= '1';
elsif (current_state = ShiftOut) then
enShiftCounter <='1';
DONE <='0';
nSYNC <='0';
enParalelLoad <= '0';
else
enShiftCounter <='0';
DONE <='0';
nSYNC <='1';
enParalelLoad <= '0';
end if;
end if;
end process;
NEXT_STATE_DECODE: process (CLK, current_state, START, shiftCounter)
begin
if (rising_edge(CLK)) then
next_state <= current_state;
case (current_state) is
when Idle =>
if (START = '1') then
next_state <= ShiftOut;
end if;
when ShiftOut =>
if (shiftCounter = '1') then
next_state <= SyncData;
end if;
when SyncData =>
if (START = '0') then
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end if;
end process;
end Behavioral;