* 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/cs_n
|
||||
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/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
|
||||
WaveRestoreCursors {{Cursor 1} {99527 ps} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
@ -25,4 +25,4 @@ configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ps
|
||||
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(
|
||||
TRANSFER_CLK_COUNT : integer := 16;
|
||||
DELAY_CLK_CNT : integer := 2;
|
||||
DATA_BITS : integer := 12
|
||||
DATA_WIDTH : integer := 12
|
||||
);
|
||||
end entity;
|
||||
|
||||
@ -17,7 +17,7 @@ architecture beh of pmod_ad1_ctrl_tb is
|
||||
generic(
|
||||
TRANSFER_CLK_COUNT : integer := 16;
|
||||
DELAY_CLK_CNT : integer := 2;
|
||||
DATA_BITS : integer := 12
|
||||
DATA_WIDTH : integer := 12
|
||||
);
|
||||
port (
|
||||
sclk : in std_logic; -- PMOD-AD1
|
||||
@ -26,15 +26,15 @@ architecture beh of pmod_ad1_ctrl_tb is
|
||||
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);
|
||||
data1 : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
data2 : out std_logic_vector(DATA_WIDTH-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);
|
||||
signal clk, reset, cs_n, done, sdata1, sdata2 : std_logic := '0';
|
||||
signal data1, data2 : std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
@ -42,13 +42,13 @@ begin
|
||||
generic map(
|
||||
TRANSFER_CLK_COUNT => TRANSFER_CLK_COUNT,
|
||||
DELAY_CLK_CNT => DELAY_CLK_CNT,
|
||||
DATA_BITS => DATA_BITS
|
||||
DATA_WIDTH => DATA_WIDTH
|
||||
)
|
||||
port map(
|
||||
sclk => clk,
|
||||
reset => reset,
|
||||
sdata1 => '1',
|
||||
sdata2 => '1',
|
||||
sdata1 => sdata1,
|
||||
sdata2 => sdata2,
|
||||
enable => '1',
|
||||
cs_n => cs_n,
|
||||
data1 => data1,
|
||||
@ -64,9 +64,19 @@ begin
|
||||
wait for 25 ns;
|
||||
end process;
|
||||
|
||||
data_prc : process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
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;
|
||||
|
||||
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