I have a question concerning my code in VHDL; I would like to implement a driver for an ADC (AD7476A) on my Arty board as well as a 16-bit output vector labeled sDATA.
I would like the ADC to be configurable (choose how much we want to have), that's why I made a package.
I have a problem with my code AD747_CTRL which is a deserializer; I would like to set up my Shift register in a tempory register of 16 bits but how can I set it in my data out which is a register of 12 bits ?
Also, I would like to test my code in the testbench, to send a data ( a ramp for example) and see the serial data on the waveform. Can you help me? Thank you very much.
AD747XA_pkg.vhd :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
package AD747X is
SUBTYPE ad747X_sample IS std_logic_vector( 11 downto 0 );
TYPE ad747X_sample_v IS ARRAY (natural range<>) OF ad747X_sample;
end package;
AD747XA.vhd :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity AD747XA is
Port (
serial_clk : in STD_LOGIC; --ADC serial clock
sdata : out STD_LOGIC;
cs_n : in STD_LOGIC
);
end AD747XA;
architecture Behavioral of AD747XA is
--Timing specifications
constant tsclk : time := 1 sec/20000000; --Fsclk -> 20 MHz
constant tconvert : time := 16*tsclk;
constant tquiet : time := 50 ns;
constant tpowerup : time := 1 us;
constant t1 : time := 10 ns;
constant t2 : time := 10 ns;
constant t3 : time := 22 ns;
constant t4 : time := 40 ns;
constant t5 : time := 0.4*tsclk;
constant t6 : time := 0.4*tsclk;
constant t7 : time := 9.5 ns; --To modify according to the value of VDD
constant t8 : time := 36 ns; --max value
--Signals declaration
signal data : STD_LOGIC_VECTOR(15 downto 0) := (others=>'0');
begin
process
begin
wait until falling_edge(cs_n);
wait for t2;
for i in 0 to 3 loop
wait until falling_edge(serial_clk);
wait for t4;
sdata <= data(i);
end loop;
for i in 3 to 15 loop
wait until falling_edge(serial_clk);
wait for t7;
sdata <= data(i);
end loop;
data <= STD_LOGIC_VECTOR(unsigned(data) + 1);
end process;
end Behavioral;
AD747XA_CTRL.vhd :
library IEEE;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_1164.ALL;
library WORK;
use WORK.AD747X.all;
entity AD747XA_CTRL is
generic (
chan_count : integer := 2
);
Port ( clk : in STD_LOGIC;
rstn : in STD_LOGIC;
serial_clk : in STD_LOGIC;
sdata : in ad747X_sample_v(chan_count-1 downto 0);
ready : out STD_LOGIC;
data : out ad747X_sample_v(chan_count-1 downto 0)
);
end AD747XA_CTRL;
architecture Behavioral of AD747XA_CTRL is
signal rx_counter : integer := 0 ;
signal reg : ad747X_sample_v (chan_count-1 downto 0);
type TYPE_STATE is (Idle,ShiftIn);
type temp is array (0 to chan_count-1) of std_logic_vector(15 downto 0);
signal temp_reg : temp;
signal CURRENT_STATE : TYPE_STATE := Idle;
signal i_enable_conv : std_logic := '0';
begin
process(clk,rstn)
begin
if (rstn = '0') then
for i in chan_count-1 downto 0 loop
reg(i) <= (others => '0');
end loop;
rx_counter <= 0;
i_enable_conv <='0';
CURRENT_STATE <= Idle;
elsif (clk = '1' and clk'event) then
case CURRENT_STATE is
when Idle =>
rx_counter <= 0;
if (i_enable_conv = '1' ) then
CURRENT_STATE <= ShiftIn;
end if;
when ShiftIn =>
i_enable_conv <= '0';
for i in chan_count-1 downto 0 loop
temp_reg(i) <= sdata(i) & temp_reg(i)(15 downto 1);
end loop;
rx_counter <= rx_counter + 1;
if (rx_counter = 15) then
CURRENT_STATE <= Idle;
rx_counter <= 0;
else
CURRENT_STATE <= ShiftIn;
rx_counter <= rx_counter + 1;
end if;
end case;
end if;
end process;
data <= reg;
end Behavioral;
tb_AD747XA.vhd :
entity tb_AD747XA is
end tb_AD747XA;
architecture Behavioral of tb_AD747XA is
constant chan_count : integer := 2 ;
COMPONENT AD747XA_CTRL is
generic (chan_count : integer := 2 );
Port (
clk : in STD_LOGIC;
rstn : in STD_LOGIC;
serial_clk : in STD_LOGIC;
enable : in STD_LOGIC;
data : in ad747X_sample_v(chan_count-1 downto 0);
sdata : out ad747X_sample_v(chan_count-1 downto 0)
);
end COMPONENT;
signal clk : STD_LOGIC := '1';
signal rstn : STD_LOGIC;
signal enable : std_logic := '0';
signal serial_clk : STD_LOGIC;
signal sdata : ad747X_sample_v(chan_count-1 downto 0);
signal data : ad747X_sample_v(chan_count-1 downto 0);
SIGNAL end_of_simu : STD_LOGIC := '0';
begin
--AD1.vhd
ad747X : AD747XA_CTRL
generic map(chan_count => 2)
Port map(
clk => clk,
rstn => rstn ,
enable => enable ,
serial_clk => serial_clk,
sdata => sdata ,
data => data
);
process
begin
enable <= '0';
wait for 150 ns;
enable <= '1';
wait;
end process;
process
begin
rstn <= '0';
wait for 100 ns;
rstn <= '1';
if enable = '0' then
wait until enable = '1';
end if;
data(0) <= "000000000000";
wait for 50 ns;
data(0) <= "000000000001";
wait for 50 ns;
data(0) <= "000000000010";
wait for 50 ns;
data(0) <= "000000000100";
wait for 50 ns;
data(0) <= "000000001000";
end_of_simu <= '1';
wait;
end process;
process
begin
IF end_of_simu /= '1' THEN
clk <= not clk;
wait for 5 ns;
ELSE
assert false report "end of test" severity note;
WAIT;
END IF;
end process;
end Behavioral;