I have this ADS4249 ADC from Texas Instruments. I want the data output interface to be CMOS therefore I need to write REG 41 with the data "11000000" (datasheet p.41 and p.46). In the image below you can see the timing diagram for this ADC. Datasheet for the ADC: https://www.ti.com/lit/ds/symlink/ads4249.pdf
Below you can see my code. I am using an ODDR to forward my systemclock (SYSCLK) to the ADCs SCLK(SCLK_ADC) input
and connected them properly in the top level domain. I can't get the ADC to output CMOS signals. I think my fault is somewhere in the ADC entity.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ADC is
Port
(
SYSCLK: in STD_LOGIC;
RST_ADC : out STD_LOGIC;
SCLK_ADC : out STD_LOGIC;
SDATA_ADC : out STD_LOGIC;
SEN_ADC : out STD_LOGIC
);
end ADC;
architecture Behavioral of ADC is
signal count : integer range 0 to 4 := 0;
signal ADDR : STD_LOGIC_VECTOR (7 downto 0) := "01000001";
signal DATA : STD_LOGIC_VECTOR (7 downto 0) := "11010000";
signal ADDR_DATA : STD_LOGIC_VECTOR (15 downto 0) := ADDR & DATA;
begin
process(SYSCLK, count)
begin
if(rising_edge(SYSCLK)) then
if(count = 0) then
SEN_ADC <= '1';
elsif(count = 1) then
RST_ADC <= '1';
elsif(count = 2) then
RST_ADC <= '0';
elsif(count = 3) then
SEN_ADC <= '0';
elsif(count = 4) then
for I in 15 downto 0 loop
SDATA_ADC <= ADDR_DATA(I);
end loop;
end if;
count <= count + 1;
end if;
end process;
end Behavioral;
EDIT:
@MituRaj thanks for your help. My code looks like this now but it is still not working.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ADC is
Port
(
ADCINIT: in STD_LOGIC;
ADCINITRDY: out STD_LOGIC;
SYSCLK: in STD_LOGIC;
RST_ADC : out STD_LOGIC;
SDATA_ADC : out STD_LOGIC;
SEN_ADC : out STD_LOGIC
);
end ADC;
architecture Behavioral of ADC is
signal count : integer range 0 to 20 := 0;
signal bitcount : integer range 15 downto 0 := 0;
signal ADDR : STD_LOGIC_VECTOR (7 downto 0) := "01000001";
signal DATA : STD_LOGIC_VECTOR (7 downto 0) := "11010000";
signal ADDR_DATA : STD_LOGIC_VECTOR (15 downto 0) := ADDR & DATA;
begin
process(SYSCLK, count, ADCINIT)
begin
if(rising_edge(SYSCLK) AND ADCINIT = '1') then
if(count = 0) then
SEN_ADC <= '1';
count <= count + 1;
elsif(count = 1) then
RST_ADC <= '1';
count <= count + 1;
elsif(count = 2) then
RST_ADC <= '0';
count <= count + 1;
elsif(count = 3) then
SEN_ADC <= '0';
count <= count + 1;
elsif(count = 4) then
SDATA_ADC <= ADDR_DATA(bitcount);
bitcount <= bitcount - 1;
if(bitcount = 0) then
count <= count + 1;
end if;
elsif(count = 5) then
SEN_ADC <= '1';
ADCINITRDY <= '1';
end if;
end if;
end process;
end Behavioral;
Here is my ODDR:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;
entity ODDR_instiation is
Port ( SYSCLK : in STD_LOGIC; --systemclock
OUTCLK : out STD_LOGIC); --sclk adc
end ODDR_instiation;
architecture Behavioral of ODDR_instiation is
begin
DDR_inst : ODDR
generic map(
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC") -- Reset Type ("ASYNC" or "SYNC")
port map (
Q => OUTCLK, -- 1-bit DDR output
C => SYSCLK, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => '1', -- 1-bit data input (positive edge)
D2 => '0', -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
end Behavioral;
Here is my top-level module:
entity TT is
Port
(
--SYSCLK
SYSCLK: in STD_LOGIC;
--ADC
SCLK_ADC : out STD_LOGIC;
SDATA_ADC : out STD_LOGIC;
SEN_ADC : out STD_LOGIC;
PDN_ADC : out STD_LOGIC;
RST_ADC : out STD_LOGIC;
);
end TT;
architecture Behavioral of TT is
signal ADCINIT, ADCINITRDY := '0';
component ADC
Port
(
ADCINIT : IN STD_LOGIC;
ADCINITRDY : OUT STD_LOGIC;
SYSCLK: in STD_LOGIC;
RST_ADC : out STD_LOGIC;
SDATA_ADC : out STD_LOGIC;
SEN_ADC : out STD_LOGIC
);
end component;
component ODDR_instiation is
Port
(
SYSCLK : in STD_LOGIC; --systemclock
OUTCLK : out STD_LOGIC
); --sclk adc
end component;
begin
ODDRS:
ODDR_instiation port map
(
SYSCLK => SYSCLK,
OUTCLK => SCLK_ADC
);
ADCS:
ADC port map
(
ADCINITRDY => ADCINITRDY,
ADCINIT => ADCINIT,
SYSCLK => SYSCLK,
RST_ADC => RST_ADC,
SDATA_ADC => SDATA_ADC,
SEN_ADC => SEN_ADC
);
process(SYSCLK, ADCINITRDY)
begin
if(rising_edge(SYSCLK)) then
ADCINIT <= '1';
if(ADCINITRDY = '1') then
ADCINIT <= '0';
end if;
end if;
end process;
end Behavioral;
EDIT: I added this two lines in the top-level module
attribute IOB : string;
attribute IOB of SDATA_ADC: signal is "{TRUE}";
for
does not behave the way you might expect it would when coming from sequential programming languages \$\endgroup\$