* Added implementation for PMOD-AD1 Controller including testbench * Added implementation for PMOD-DA3 Controller including testbench
110 lines
3.6 KiB
VHDL
110 lines
3.6 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
-- Controller for the PMOD DA3 Digilent Board.
|
|
-- The controller sends the input 'data' word to the DAC when 'start' is asserted. The 'data' input has
|
|
-- to be valid only during the period 'start' is asserted, as for the transfer the word is latched
|
|
-- internally. When the transfer is done, the 'done' signal is asserted for one clock cycle. The 'start'
|
|
-- and 'done' cycle can be high at the same time, allowing the done signal to be asynchronously connected
|
|
-- to the 'start' signal to save on latency.
|
|
|
|
|
|
entity pmod_da3_ctrl is
|
|
generic(
|
|
TRANSFER_CLK_COUNT : integer := 16;
|
|
DATA_BITS : integer := 16
|
|
);
|
|
port (
|
|
sclk : in std_logic; -- PMOD-DA3
|
|
reset : in std_logic;
|
|
start : in std_logic;
|
|
data : in std_logic_vector(DATA_BITS-1 downto 0);
|
|
cs_n : out std_logic;-- PMOD-DA3
|
|
sdata : out std_logic;-- PMOD-DA3
|
|
ldac : out std_logic;-- PMOD-DA3
|
|
done : out std_logic
|
|
);
|
|
end entity;
|
|
|
|
architecture arch of pmod_da3_ctrl is
|
|
|
|
--*****TYPE DECLARATION*****
|
|
type STAGE_TYPE is (IDLE, TRANSFER);
|
|
|
|
--*****SIGNAL DECLARATIONS*****
|
|
signal buf, buf_next : std_logic_vector(DATA_BITS-1 downto 0) := (others => '0');
|
|
signal stage, stage_next : STAGE_TYPE := IDLE;
|
|
signal count, count_next : integer range 0 to 16 := 0;
|
|
-- Output Signals
|
|
signal cs_n_next : std_logic := '1';
|
|
signal sdata_next : std_logic := '0';
|
|
signal done_next : std_logic := '0';
|
|
|
|
begin
|
|
|
|
--LDAC Hardwired to ground
|
|
ldac <= '0';
|
|
|
|
state : process(all)
|
|
begin
|
|
-- DEFAULT VALUES
|
|
buf_next <= buf;
|
|
stage_next <= stage;
|
|
count_next <= count;
|
|
done_next <= '0';
|
|
cs_n_next <= '1';
|
|
sdata_next <= '0';
|
|
|
|
case stage is
|
|
when IDLE =>
|
|
if (start = '1') then
|
|
stage_next <= TRANSFER;
|
|
cs_n_next <= '0';
|
|
count_next <= 1;
|
|
-- Shift first bit into DAC
|
|
buf_next <= data(DATA_BITS-2 downto 0) & '0';
|
|
sdata_next <= data(DATA_BITS-1);
|
|
end if;
|
|
when TRANSFER =>
|
|
-- Shift Bits into DAC
|
|
buf_next <= buf(DATA_BITS-2 downto 0) & '0';
|
|
sdata_next <= buf(DATA_BITS-1);
|
|
cs_n_next <= '0';
|
|
if (count = TRANSFER_CLK_COUNT) then
|
|
cs_n_next <= '1';
|
|
stage_next <= IDLE;
|
|
done_next <= '1';
|
|
else
|
|
count_next <= count + 1;
|
|
end if;
|
|
end case;
|
|
end process;
|
|
|
|
sync : process(sclk)
|
|
begin
|
|
if (rising_edge(sclk)) then
|
|
if (reset = '1') then
|
|
-- Internal Signals
|
|
buf <= (others => '0');
|
|
stage <= IDLE;
|
|
count <= 0;
|
|
-- Output Signals
|
|
cs_n <= '1';
|
|
sdata <= '0';
|
|
done <= '0';
|
|
else
|
|
-- Internal Signals
|
|
buf <= buf_next;
|
|
stage <= stage_next;
|
|
count <= count_next;
|
|
-- Output Signals
|
|
cs_n <= cs_n_next;
|
|
sdata <= sdata_next;
|
|
done <= done_next;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
end architecture;
|