labor-mst/src/pmod_da3_ctrl.vhd
Greek 779cd73e8d * Moved config/constants to central package
* Made cap of addsub selectable via signal
* Added debug reporting
    - MAX ADC Input 1
    - MAX ADC Input 2
    - MAX Scaler output
    - MAX DAC Output
* Added Async FIFO
* Added Simple Dual Port RAM
* Added Feedback Controller
* Added Xillybus Link
* Moved testbenches to seperate directory
2020-04-26 11:35:46 +02:00

108 lines
3.5 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_WIDTH : integer := 16
);
port (
sclk : in std_logic; -- PMOD-DA3
reset : in std_logic;
start : in std_logic;
data : in std_logic_vector(DATA_WIDTH-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_WIDTH-1 downto 0) := (others => '0');
signal stage, stage_next : STAGE_TYPE := IDLE;
signal count, count_next : integer range 0 to TRANSFER_CLK_COUNT := 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_WIDTH-2 downto 0) & '0';
sdata_next <= data(DATA_WIDTH-1);
end if;
when TRANSFER =>
-- Shift Bits into DAC
buf_next <= buf(DATA_WIDTH-2 downto 0) & '0';
sdata_next <= buf(DATA_WIDTH-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, reset)
begin
if (reset = '1') then
-- Internal Signals
buf <= (others => '0');
stage <= IDLE;
count <= 0;
-- Output Signals
cs_n <= '1';
sdata <= '0';
done <= '0';
elsif (rising_edge(sclk)) then
-- 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 process;
end architecture;