* .gitignore update

* Added implementation for PMOD-AD1 Controller including testbench
* Added implementation for PMOD-DA3 Controller including testbench
This commit is contained in:
Greek 2020-03-12 20:20:35 +01:00
parent d82505b819
commit 2beb7f4b4d
7 changed files with 447 additions and 2 deletions

6
.gitignore vendored
View File

@ -1,5 +1,7 @@
#Ignore complete Vivado Directory
#Ignore List
/syn/**
/modelsim/**
#Unignore Directories (Needed to unignore files in Subdirectories)
!*/
@ -7,3 +9,5 @@
#WHITELIST
#Vivado Project File
!*.xpr
#Modelsim Do files
!*.do

28
modelsim/pmod-ad1.do Normal file
View File

@ -0,0 +1,28 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /pmod_ad1_ctrl_tb/clk
add wave -noupdate /pmod_ad1_ctrl_tb/reset
add wave -noupdate /pmod_ad1_ctrl_tb/cs_n
add wave -noupdate /pmod_ad1_ctrl_tb/done
add wave -noupdate /pmod_ad1_ctrl_tb/data1
add wave -noupdate /pmod_ad1_ctrl_tb/data2
add wave -noupdate /pmod_ad1_ctrl_tb/uut/stage
add wave -noupdate /pmod_ad1_ctrl_tb/uut/count
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
quietly wave cursor active 0
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {507648 ps}

30
modelsim/pmod-da3.do Normal file
View File

@ -0,0 +1,30 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /pmod_da3_ctrl_tb/clk
add wave -noupdate /pmod_da3_ctrl_tb/reset
add wave -noupdate /pmod_da3_ctrl_tb/cs_n
add wave -noupdate /pmod_da3_ctrl_tb/start
add wave -noupdate /pmod_da3_ctrl_tb/done
add wave -noupdate /pmod_da3_ctrl_tb/sdata
add wave -noupdate /pmod_da3_ctrl_tb/ldac
add wave -noupdate /pmod_da3_ctrl_tb/data
add wave -noupdate /pmod_da3_ctrl_tb/uut/stage
add wave -noupdate /pmod_da3_ctrl_tb/uut/count
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {70507 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {961024 ps}

123
src/pmod_ad1_ctrl.vhd Normal file
View File

@ -0,0 +1,123 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- Controller for the PMOD AD1 Digilent Board.
-- The controller keeps the AD7476A in "normal mode" throughout its operation, and as long as the enable
-- signal is high, converts the ADC input signal at a rate of sclk_freq/(TRANSFER_CLK_COUNT+DELAY_CLK_CNT).
-- On conversion finish the done signal is pulsed high for a sclk cycle. The data outputs contain valid
-- data only when done is asserted. If enable is pulled low, the controller enters a standby mode and
-- waits until the enable signal is pulled high again. If the enable is pulled low during a
-- converion/transfer, the conversion/transfer is completed before entering the idle mode.
entity pmod_ad1_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
reset : in std_logic;
sdata1 : in std_logic; -- PMOD-AD1
sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic;
cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
done : out std_logic
);
end entity;
architecture arch of pmod_ad1_ctrl is
--*****TYPE DECLARATION*****
type STAGE_TYPE is (IDLE, TRANSFER, DELAY);
--*****SIGNAL DECLARATIONS*****
signal buf1, buf2, buf1_next, buf2_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 done_next : std_logic := '0';
begin
state : process(all)
begin
-- DEFAULT VALUES
buf1_next <= buf1;
buf2_next <= buf2;
stage_next <= stage;
count_next <= count;
done_next <= '0';
cs_n_next <= '1';
case stage is
when IDLE =>
if (enable = '1') then
stage_next <= TRANSFER;
cs_n_next <= '0';
count_next <= 1;
end if;
-- NOTE: This state remains longer than the width of the data word. This is by design
-- to shift out the initial zero bits of the tranfer.
when TRANSFER =>
-- Shift Bits into buffer
buf1_next <= buf1(DATA_BITS-2 downto 0) & sdata1;
buf2_next <= buf2(DATA_BITS-2 downto 0) & sdata2;
cs_n_next <= '0';
if (count = TRANSFER_CLK_COUNT) then
stage_next <= DELAY;
count_next <= 1;
cs_n_next <= '1';
done_next <= '1';
else
count_next <= count + 1;
end if;
when DELAY =>
if (count = DELAY_CLK_CNT) then
if(enable = '1') then
stage_next <= TRANSFER;
cs_n_next <= '0';
count_next <= 1;
else
stage_next <= IDLE;
end if;
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
buf1 <= (others => '0');
buf2 <= (others => '0');
stage <= IDLE;
count <= 0;
-- Output Signals
cs_n <= '1';
data1 <= (others => '0');
data2 <= (others => '0');
done <= '0';
else
-- Internal Signals
buf1 <= buf1_next;
buf2 <= buf2_next;
stage <= stage_next;
count <= count_next;
-- Output Signals
cs_n <= cs_n_next;
data1 <= buf1_next;
data2 <= buf2_next;
done <= done_next;
end if;
end if;
end process;
end architecture;

74
src/pmod_ad1_ctrl_tb.vhd Normal file
View File

@ -0,0 +1,74 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pmod_ad1_ctrl_tb is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
);
end entity;
architecture beh of pmod_ad1_ctrl_tb is
--*****COMPONENT DECLARATION*****
component pmod_ad1_ctrl is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DELAY_CLK_CNT : integer := 2;
DATA_BITS : integer := 12
);
port (
sclk : in std_logic; -- PMOD-AD1
reset : in std_logic;
sdata1 : in std_logic; -- PMOD-AD1
sdata2 : in std_logic; -- PMOD-AD1
enable : in std_logic;
cs_n : out std_logic;-- PMOD-AD1
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
done : out std_logic
);
end component;
--*****SIGNAL DEFINITIONS*****
signal clk, reset, cs_n, done : std_logic := '0';
signal data1, data2 : std_logic_vector(DATA_BITS-1 downto 0);
begin
uut : pmod_ad1_ctrl
generic map(
TRANSFER_CLK_COUNT => TRANSFER_CLK_COUNT,
DELAY_CLK_CNT => DELAY_CLK_CNT,
DATA_BITS => DATA_BITS
)
port map(
sclk => clk,
reset => reset,
sdata1 => '1',
sdata2 => '1',
enable => '1',
cs_n => cs_n,
data1 => data1,
data2 => data2,
done => done
);
clk_prc : process
begin
clk <= '1';
wait for 25 ns;
clk <= '0';
wait for 25 ns;
end process;
process
begin
--INITIALISE SIGNALS
reset <= '0';
wait;
end process;
end architecture;

109
src/pmod_da3_ctrl.vhd Normal file
View File

@ -0,0 +1,109 @@
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;

77
src/pmod_da3_ctrl_tb.vhd Normal file
View File

@ -0,0 +1,77 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pmod_da3_ctrl_tb is
generic(
TRANSFER_CLK_COUNT : integer := 16;
DATA_BITS : integer := 16
);
end entity;
architecture beh of pmod_da3_ctrl_tb is
--*****COMPONENT DECLARATION*****
component 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 component;
--*****SIGNAL DEFINITIONS*****
signal clk, reset, cs_n, start, done, sdata, ldac : std_logic := '0';
signal data : std_logic_vector(DATA_BITS-1 downto 0) := (others => '0');
begin
uut : pmod_da3_ctrl
generic map(
TRANSFER_CLK_COUNT => TRANSFER_CLK_COUNT,
DATA_BITS => DATA_BITS
)
port map(
sclk => clk,
reset => reset,
start => start,
data => data,
cs_n => cs_n,
sdata => sdata,
ldac => ldac,
done => done
);
clk_prc : process
begin
clk <= '1';
wait for 25 ns;
clk <= '0';
wait for 25 ns;
end process;
process
begin
--INITIALISE SIGNALS
reset <= '0';
wait for 5 ns;
wait until rising_edge(clk);
start <= '1';
data <= (others => '1');
wait until rising_edge(clk);
start <= '0';
data <= (others => '0');
wait until rising_edge(done);
wait;
end process;
end architecture;