* Modify PMOD-AS1 testbench
* Add reference PMOD AD1 controller - Including testbench
This commit is contained in:
parent
ae928c116b
commit
131a9b3a6e
@ -4,13 +4,13 @@ add wave -noupdate /pmod_ad1_ctrl_tb/clk
|
|||||||
add wave -noupdate /pmod_ad1_ctrl_tb/reset
|
add wave -noupdate /pmod_ad1_ctrl_tb/reset
|
||||||
add wave -noupdate /pmod_ad1_ctrl_tb/cs_n
|
add wave -noupdate /pmod_ad1_ctrl_tb/cs_n
|
||||||
add wave -noupdate /pmod_ad1_ctrl_tb/done
|
add wave -noupdate /pmod_ad1_ctrl_tb/done
|
||||||
|
add wave -noupdate /pmod_ad1_ctrl_tb/sdata1
|
||||||
add wave -noupdate /pmod_ad1_ctrl_tb/data1
|
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/stage
|
||||||
add wave -noupdate /pmod_ad1_ctrl_tb/uut/count
|
add wave -noupdate /pmod_ad1_ctrl_tb/uut/count
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
|
WaveRestoreCursors {{Cursor 1} {99527 ps} 0}
|
||||||
quietly wave cursor active 0
|
quietly wave cursor active 1
|
||||||
configure wave -namecolwidth 150
|
configure wave -namecolwidth 150
|
||||||
configure wave -valuecolwidth 100
|
configure wave -valuecolwidth 100
|
||||||
configure wave -justifyvalue left
|
configure wave -justifyvalue left
|
||||||
@ -25,4 +25,4 @@ configure wave -griddelta 40
|
|||||||
configure wave -timeline 0
|
configure wave -timeline 0
|
||||||
configure wave -timelineunits ps
|
configure wave -timelineunits ps
|
||||||
update
|
update
|
||||||
WaveRestoreZoom {0 ps} {507648 ps}
|
WaveRestoreZoom {0 ps} {1015296 ps}
|
||||||
|
|||||||
269
src/PMOD_AD1.vhd
Normal file
269
src/PMOD_AD1.vhd
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- AD1_controller.VHD
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Author : Todd Harless
|
||||||
|
-- CopyRight 2005 Digilent, Inc.
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Description : This file is the VHDL code for a PMOD-AD1 controller.
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Revision History:
|
||||||
|
-- 07/11/2005 Created (Todd Harless)
|
||||||
|
-- 08/09/2005 revision 0.1 (Todd Harless)
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||||
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
--Title : AD1 controller entity
|
||||||
|
--
|
||||||
|
-- Inputs : 3
|
||||||
|
-- Outputs : 3
|
||||||
|
--
|
||||||
|
-- Description : This is the AD1 controller entity. The input ports are
|
||||||
|
-- a 50 MHz clock and an asynchronous
|
||||||
|
-- reset button along with the data from the ADC7476 that
|
||||||
|
-- is serially shifted in on each clock cycle. The outputs
|
||||||
|
-- are the SCLK signal which clocks the PMOD-AD1 board at
|
||||||
|
-- 12.5 MHz and a chip select signal (CS) that latches the
|
||||||
|
-- data into the PMOD-AD1 board as well as an 12-bit output
|
||||||
|
-- vector labeled DATA_OUT which can be used by any
|
||||||
|
-- external components.
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
entity AD1_controller is
|
||||||
|
Port (
|
||||||
|
--General usage
|
||||||
|
CLK : in std_logic; -- System Clock (50MHz)
|
||||||
|
RST : in std_logic;
|
||||||
|
|
||||||
|
--Pmod interface signals
|
||||||
|
SDATA1 : in std_logic;
|
||||||
|
SDATA2 : in std_logic;
|
||||||
|
SCLK : out std_logic;
|
||||||
|
CS : out std_logic;
|
||||||
|
|
||||||
|
--User interface signals
|
||||||
|
DATA1 : out std_logic_vector(11 downto 0);
|
||||||
|
DATA2 : out std_logic_vector(11 downto 0);
|
||||||
|
START : in std_logic;
|
||||||
|
DONE : out std_logic
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
end AD1_controller;
|
||||||
|
|
||||||
|
architecture AD1 of AD1_controller is
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
--Title : Local signal assignments
|
||||||
|
--
|
||||||
|
-- Description : The following signals will be used to drive the processes of
|
||||||
|
-- this VHDL file.
|
||||||
|
--
|
||||||
|
-- current_state: This signal will be the pointer that will point at the
|
||||||
|
-- current state of the Finite State Machine of the
|
||||||
|
-- controller.
|
||||||
|
-- next_state : This signal will be the pointer that will point at the
|
||||||
|
-- current state of the Finite State Machine of the
|
||||||
|
-- controller.
|
||||||
|
-- temp1 : This is a 16-bit vector that will store the 16-bits of data
|
||||||
|
-- that are serially shifted-in form the first ADC7476 chip inside the
|
||||||
|
-- PMOD-AD1 board.
|
||||||
|
-- temp2 : This is a 16-bit vector that will store the 16-bits of data
|
||||||
|
-- that are serially shifted-in form the second ADC7476 chip inside the
|
||||||
|
-- PMOD-AD1 board.
|
||||||
|
-- dat1 : This is a 12-bit vector that will store the 12-bits of actual data
|
||||||
|
-- that are serially shifted-in form the first ADC7476 chip inside the
|
||||||
|
-- PMOD-AD1 board.
|
||||||
|
-- dat2 : This is a 12-bit vector that will store the 12-bits of actual data
|
||||||
|
-- that are serially shifted-in form the second ADC7476 chip inside the
|
||||||
|
-- PMOD-AD1 board.
|
||||||
|
-- clk_div : This will be the divided 12.5 MHz clock signal that will
|
||||||
|
-- clock the PMOD-AD1 board
|
||||||
|
-- clk_counter : This counter will be used to create a divided clock signal.
|
||||||
|
--
|
||||||
|
-- shiftCounter : This counter will be used to count the shifted data from the
|
||||||
|
-- ADC7476 chip inside the PMOD-AD1 board.
|
||||||
|
-- enShiftCounter : This signal will be used to enable the counter for the shifted
|
||||||
|
-- data from the ADC7476 chip inside the PMOD-AD1 board.
|
||||||
|
-- enParalelLoad : This signal will be used to enable the load in a register the shifted
|
||||||
|
-- data.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type states is (Idle,
|
||||||
|
ShiftIn,
|
||||||
|
SyncData);
|
||||||
|
signal current_state : states;
|
||||||
|
signal next_state : states;
|
||||||
|
|
||||||
|
signal temp1 : std_logic_vector(15 downto 0) := (others => '0');
|
||||||
|
signal temp2 : std_logic_vector(15 downto 0) := (others => '0');
|
||||||
|
signal dat1 : std_logic_vector(11 downto 0):= x"000";
|
||||||
|
signal dat2 : std_logic_vector(11 downto 0):= x"000";
|
||||||
|
signal clk_div : std_logic;
|
||||||
|
signal clk_counter : std_logic_vector(27 downto 0);
|
||||||
|
signal shiftCounter : std_logic_vector(3 downto 0) := x"0";
|
||||||
|
signal enShiftCounter: std_logic;
|
||||||
|
signal enParalelLoad : std_logic;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
--Title : clock divider process
|
||||||
|
--
|
||||||
|
-- Description : This is the process that will divide the 50 MHz clock
|
||||||
|
-- down to a clock speed of 12.5 MHz to drive the ADC7476 chip.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
clock_divide : process(rst,clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
clk_counter <= "0000000000000000000000000000";
|
||||||
|
elsif (clk = '1' and clk'event) then
|
||||||
|
clk_counter <= clk_counter + '1';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
clk_div <= clk_counter(1);
|
||||||
|
SCLK <= not clk_counter(1);
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Title : counter
|
||||||
|
--
|
||||||
|
-- Description: This is the process were the teporary registers will be loaded and
|
||||||
|
-- shifted.When the enParalelLoad signal is generated inside the state
|
||||||
|
-- the temp1 and temp2 registers will be loaded with the 8 bits of control
|
||||||
|
-- concatenated with the 8 bits of data. When the enShiftCounter is
|
||||||
|
-- activated, the 16-bits of data inside the temporary registers will be
|
||||||
|
-- shifted. A 4-bit counter is used to keep shifting the data
|
||||||
|
-- inside temp1 and temp2 for 16 clock cycles.
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
counter : process(clk_div, enParalelLoad, enShiftCounter)
|
||||||
|
begin
|
||||||
|
if (clk_div = '1' and clk_div'event) then
|
||||||
|
|
||||||
|
if (enShiftCounter = '1') then
|
||||||
|
temp1 <= temp1(14 downto 0) & SDATA1;
|
||||||
|
temp2 <= temp2(14 downto 0) & SDATA2;
|
||||||
|
shiftCounter <= shiftCounter + '1';
|
||||||
|
elsif (enParalelLoad = '1') then
|
||||||
|
shiftCounter <= "0000";
|
||||||
|
dat1 <= temp1(11 downto 0);
|
||||||
|
dat2 <= temp2(11 downto 0);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
DATA1 <= dat1 ;
|
||||||
|
DATA2 <= dat2 ;
|
||||||
|
---------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Title : Finite State Machine
|
||||||
|
--
|
||||||
|
-- Description: This 3 processes represent the FSM that contains three states. The first
|
||||||
|
-- state is the Idle state in which a temporary registers are
|
||||||
|
-- assigned the updated value of the input "DATA1" and "DATA2". The next state
|
||||||
|
-- is the ShiftIn state where the 16-bits of
|
||||||
|
-- data from each of the ADCS7476 chips are left shifted in the temp1 and temp2 shift registers.
|
||||||
|
-- The third
|
||||||
|
-- state SyncData drives the output signal CS high for
|
||||||
|
-- 1 clock period, and the second one in the Idle state telling the ADCS7476 to mark the end of the conversion.
|
||||||
|
-- Notes: The data will change on the lower edge of the clock signal. Their
|
||||||
|
-- is also an asynchronous reset that will reset all signals to their
|
||||||
|
-- original state.
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Title : SYNC_PROC
|
||||||
|
--
|
||||||
|
-- Description: This is the process were the states are changed synchronously. At
|
||||||
|
-- reset the current state becomes Idle state.
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
SYNC_PROC: process (clk_div, rst)
|
||||||
|
begin
|
||||||
|
if (clk_div'event and clk_div = '1') then
|
||||||
|
if (rst = '1') then
|
||||||
|
current_state <= Idle;
|
||||||
|
else
|
||||||
|
current_state <= next_state;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Title : OUTPUT_DECODE
|
||||||
|
--
|
||||||
|
-- Description: This is the process were the output signals are generated
|
||||||
|
-- unsynchronously based on the state only (Moore State Machine).
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
OUTPUT_DECODE: process (current_state)
|
||||||
|
begin
|
||||||
|
if current_state = Idle then
|
||||||
|
enShiftCounter <='0';
|
||||||
|
DONE <='1';
|
||||||
|
CS <='1';
|
||||||
|
enParalelLoad <= '0';
|
||||||
|
elsif current_state = ShiftIn then
|
||||||
|
enShiftCounter <='1';
|
||||||
|
DONE <='0';
|
||||||
|
CS <='0';
|
||||||
|
enParalelLoad <= '0';
|
||||||
|
else --if current_state = SyncData then
|
||||||
|
enShiftCounter <='0';
|
||||||
|
DONE <='0';
|
||||||
|
CS <='1';
|
||||||
|
enParalelLoad <= '1';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- Title : NEXT_STATE_DECODE
|
||||||
|
--
|
||||||
|
-- Description: This is the process were the next state logic is generated
|
||||||
|
-- depending on the current state and the input signals.
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------
|
||||||
|
NEXT_STATE_DECODE: process (current_state, START, shiftCounter)
|
||||||
|
begin
|
||||||
|
|
||||||
|
next_state <= current_state; --default is to stay in current state
|
||||||
|
|
||||||
|
case (current_state) is
|
||||||
|
when Idle =>
|
||||||
|
if START = '1' then
|
||||||
|
next_state <= ShiftIn;
|
||||||
|
end if;
|
||||||
|
when ShiftIn =>
|
||||||
|
if shiftCounter = x"F" 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 process;
|
||||||
|
|
||||||
|
|
||||||
|
end AD1;
|
||||||
@ -6,7 +6,7 @@ entity pmod_ad1_ctrl_tb is
|
|||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DELAY_CLK_CNT : integer := 2;
|
DELAY_CLK_CNT : integer := 2;
|
||||||
DATA_BITS : integer := 12
|
DATA_WIDTH : integer := 12
|
||||||
);
|
);
|
||||||
end entity;
|
end entity;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ architecture beh of pmod_ad1_ctrl_tb is
|
|||||||
generic(
|
generic(
|
||||||
TRANSFER_CLK_COUNT : integer := 16;
|
TRANSFER_CLK_COUNT : integer := 16;
|
||||||
DELAY_CLK_CNT : integer := 2;
|
DELAY_CLK_CNT : integer := 2;
|
||||||
DATA_BITS : integer := 12
|
DATA_WIDTH : integer := 12
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
sclk : in std_logic; -- PMOD-AD1
|
sclk : in std_logic; -- PMOD-AD1
|
||||||
@ -26,15 +26,15 @@ architecture beh of pmod_ad1_ctrl_tb is
|
|||||||
sdata2 : in std_logic; -- PMOD-AD1
|
sdata2 : in std_logic; -- PMOD-AD1
|
||||||
enable : in std_logic;
|
enable : in std_logic;
|
||||||
cs_n : out std_logic;-- PMOD-AD1
|
cs_n : out std_logic;-- PMOD-AD1
|
||||||
data1 : out std_logic_vector(DATA_BITS-1 downto 0);
|
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
data2 : out std_logic_vector(DATA_BITS-1 downto 0);
|
data2 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
done : out std_logic
|
done : out std_logic
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
--*****SIGNAL DEFINITIONS*****
|
--*****SIGNAL DEFINITIONS*****
|
||||||
signal clk, reset, cs_n, done : std_logic := '0';
|
signal clk, reset, cs_n, done, sdata1, sdata2 : std_logic := '0';
|
||||||
signal data1, data2 : std_logic_vector(DATA_BITS-1 downto 0);
|
signal data1, data2 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -42,13 +42,13 @@ begin
|
|||||||
generic map(
|
generic map(
|
||||||
TRANSFER_CLK_COUNT => TRANSFER_CLK_COUNT,
|
TRANSFER_CLK_COUNT => TRANSFER_CLK_COUNT,
|
||||||
DELAY_CLK_CNT => DELAY_CLK_CNT,
|
DELAY_CLK_CNT => DELAY_CLK_CNT,
|
||||||
DATA_BITS => DATA_BITS
|
DATA_WIDTH => DATA_WIDTH
|
||||||
)
|
)
|
||||||
port map(
|
port map(
|
||||||
sclk => clk,
|
sclk => clk,
|
||||||
reset => reset,
|
reset => reset,
|
||||||
sdata1 => '1',
|
sdata1 => sdata1,
|
||||||
sdata2 => '1',
|
sdata2 => sdata2,
|
||||||
enable => '1',
|
enable => '1',
|
||||||
cs_n => cs_n,
|
cs_n => cs_n,
|
||||||
data1 => data1,
|
data1 => data1,
|
||||||
@ -64,9 +64,19 @@ begin
|
|||||||
wait for 25 ns;
|
wait for 25 ns;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
data_prc : process
|
||||||
|
begin
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
sdata1 <= not sdata1;
|
||||||
|
sdata2 <= not sdata2;
|
||||||
|
end process;
|
||||||
|
|
||||||
process
|
process
|
||||||
begin
|
begin
|
||||||
--INITIALISE SIGNALS
|
--INITIALISE SIGNALS
|
||||||
|
reset <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
reset <= '0';
|
reset <= '0';
|
||||||
wait;
|
wait;
|
||||||
end process;
|
end process;
|
||||||
|
|||||||
78
src/sim/pmod_ad1_tb.vhd
Normal file
78
src/sim/pmod_ad1_tb.vhd
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity pmod_ad1_tb is
|
||||||
|
end entity;
|
||||||
|
|
||||||
|
architecture beh of pmod_ad1_tb is
|
||||||
|
|
||||||
|
--*****COMPONENT DECLARATION*****
|
||||||
|
component AD1_controller is
|
||||||
|
port (
|
||||||
|
--General usage
|
||||||
|
CLK : in std_logic; -- System Clock (50MHz)
|
||||||
|
RST : in std_logic;
|
||||||
|
--Pmod interface signals
|
||||||
|
SDATA1 : in std_logic;
|
||||||
|
SDATA2 : in std_logic;
|
||||||
|
SCLK : out std_logic;
|
||||||
|
CS : out std_logic;
|
||||||
|
--User interface signals
|
||||||
|
DATA1 : out std_logic_vector(11 downto 0);
|
||||||
|
DATA2 : out std_logic_vector(11 downto 0);
|
||||||
|
START : in std_logic;
|
||||||
|
DONE : out std_logic
|
||||||
|
);
|
||||||
|
end component;
|
||||||
|
|
||||||
|
--*****SIGNAL DEFINITIONS*****
|
||||||
|
signal clk, reset, cs_n, done, sclk : std_logic := '0';
|
||||||
|
signal sdata1, sdata2 : std_logic := '0';
|
||||||
|
signal data1, data2 : std_logic_vector(11 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
uut : AD1_controller
|
||||||
|
port map (
|
||||||
|
--General usage
|
||||||
|
CLK => clk,
|
||||||
|
RST => reset,
|
||||||
|
--Pmod interface signals
|
||||||
|
SDATA1 => sdata1,
|
||||||
|
SDATA2 => sdata2,
|
||||||
|
SCLK => sclk,
|
||||||
|
CS => cs_n,
|
||||||
|
--User interface signals
|
||||||
|
DATA1 => data1,
|
||||||
|
DATA2 => data2,
|
||||||
|
START => done,
|
||||||
|
DONE => done
|
||||||
|
);
|
||||||
|
|
||||||
|
clk_prc : process
|
||||||
|
begin
|
||||||
|
clk <= '1';
|
||||||
|
wait for 25 ns;
|
||||||
|
clk <= '0';
|
||||||
|
wait for 25 ns;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
data_prc : process
|
||||||
|
begin
|
||||||
|
wait until falling_edge(sclk);
|
||||||
|
sdata1 <= not sdata1;
|
||||||
|
sdata2 <= not sdata2;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process
|
||||||
|
begin
|
||||||
|
--INITIALISE SIGNALS
|
||||||
|
reset <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
reset <= '0';
|
||||||
|
wait;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end architecture;
|
||||||
Loading…
Reference in New Issue
Block a user