kunal5959
Junior Member level 3
- Joined
- Jul 26, 2011
- Messages
- 31
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,286
- Activity points
- 1,644
I encounter this strange problem that my SDA signal is shifted by one SCl cyle and I cannot eliminate this error by any chance. I am using an ACTEL PROASIC3E Starter Kit and I want to access a ADS1015 breakout board that uses I2c bus to get command signals from FPGA.
I am poting my TOp module and Testbench code where i just trying to write som data and waiting for acknowledgement from the SLAVE(ADS1015 board). I have also attached this oscilloscope image where the white highlighting circle shows the shift of SDA towards right. That is the reason also my acknowledgement '0' from slave is received after 2 cycles and one can see the 'Z' state(marked with a green circle). Can anyone please assist me in understanding why the oscilloscope signal has a shift as compared to Modelsim simulation?
TOP module- Master code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
TestBench code with first slave acknowledgement being sent in simulation
Thanks in Advance,
Kunal
I Modelsim one can see I2CCLOCK and SDA which are the ports used for clock and data transaction on I2C bus. once can see that SDA has shifted by one cycle in Oscilloscope waveform image as compared to Modelsim Image.
I am poting my TOp module and Testbench code where i just trying to write som data and waiting for acknowledgement from the SLAVE(ADS1015 board). I have also attached this oscilloscope image where the white highlighting circle shows the shift of SDA towards right. That is the reason also my acknowledgement '0' from slave is received after 2 cycles and one can see the 'Z' state(marked with a green circle). Can anyone please assist me in understanding why the oscilloscope signal has a shift as compared to Modelsim simulation?
TOP module- Master code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
Code:
entity I2c_master is
port(
clk : in std_logic; --system clock
reset_n : in std_logic; --active low reset
SDA : inout std_logic; --data read from slave
LED : out std_logic_vector(7 downto 0);
I2CCLOCK : out std_logic);
end i2c_master;
architecture logic of I2c_master is
component countertest is
port (Aclr : in std_logic;
clock : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end component;
signal data_clk, i2c_clk,e_signal : std_logic := '1'; --clock edges for sda
signal sda_out : std_logic := '1'; --internal sda
signal ledsig1 : std_logic_vector(7 downto 0); --latched in address and read/write
signal tx1 : std_logic_vector(7 downto 0) := "00000000"; --data received from slave MSB
signal tx2 : std_logic_vector(7 downto 0) := "00000000"; --data received from slave LSB
shared variable step : integer range 0 to 13;
begin
--generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
process(data_clk, reset_n)
begin
if(reset_n = '1') then -- reset asserted
sda_out <= '1'; --- set sda pin to high impedance--- set scl pin to high impedance
i2c_clk <= '1';
elsif(data_clk'event and data_clk = '1') then
case step is
when 0 =>
sda_out <= '1';
i2c_clk <= '1';
step := step+1;
when 1 =>
sda_out <= '0';
i2c_clk <= '0';
step := step+1;
when 2 => --- 1st write byte
sda_out <= '1';
step := step+1;
when 3 =>
sda_out <= '0';
step := step+1;
when 4 =>
sda_out <= '0';
step := step+1;
when 5 =>
sda_out <= '1';
step := step+1;
when 6 =>
sda_out <= '0';
step := step+1;
when 7 =>
sda_out <= '0';
step := step+1;
when 8 =>
sda_out <= '0';
step := step+1;
when 9 =>
sda_out <= '0';
step := step+1;
when 10 =>
sda_out<='Z';
step := step+1;
when 11 =>
if SDA<='0' then
LED(0) <='1';
step := step+1;
else
LED(1) <='1';
end if;
when 12 =>
sda_out<='0';
i2c_clk<='1'; --stop Bit
step := step+1;
when 13 =>
sda_out<='1';
step:=0;
end case;
end if;
end process;
process(data_clk)
begin
if (data_clk'event and data_clk = '0'and (step >= 2) and (step <= 13)) then
I2CCLOCK <= not data_clk;
else
I2CCLOCK <= i2c_clk;
end if;
end process;
SDA<=sda_out;
data_clk <= ledsig1(7);
countertesting : countertest port map (Clock => CLK, Aclr => reset_n, Q => ledsig1);
end logic;
TestBench code with first slave acknowledgement being sent in simulation
Code:
library ieee;
use ieee.std_logic_1164.all;
entity TB is
end TB;
architecture behavioral of TB is
component i2c_master
-- ports
port
(clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --active low reset
SDA : inout std_logic;
LED : out std_logic_vector(7 downto 0);
I2CCLOCK : out std_logic);
end component;
signal clk: std_logic := '0';
--signal sw_write: std_logic := '0';
signal reset_n, I2CCLOCK: std_logic := '1';
signal SDA :std_logic:='1';
SIGNAL data_clk : STD_LOGIC:='0'; --clock edges for sda
SIGNAL sda_out : STD_LOGIC ; -- internal sda
SIGNAL data_tx : std_logic_vector(7 DOWNTO 0); -- latched in data to write to slave
SIGNAL data_rx_MSB : std_logic_vector(7 DOWNTO 0); -- data received from slave MSB
SIGNAL data_rx_LSB : std_logic_vector(7 DOWNTO 0); --data received from slave LSB
--tracks bit number in transaction SIGNAL stretch : STD_LOGIC := '0'; --identifies if slave is stretching scl
begin
clock1 : process
begin
wait for 10 ns; clk <= not clk;
end process ;
stimulus : process
begin
wait for 4040 ns; reset_n <= '0';
wait;
end process;
writing : process
begin
wait for 60576 ns ; SDA <='0';
wait;
end process;
--
i2c_master_0 : i2c_master
-- port map
port map(
-- Inputs
clk => clk,
reset_n => reset_n,
SDA => SDA,
LED=>open,
I2CCLOCK =>I2CCLOCK
);
--SDA<=ADCoutput;
end behavioral;
Thanks in Advance,
Kunal
I Modelsim one can see I2CCLOCK and SDA which are the ports used for clock and data transaction on I2C bus. once can see that SDA has shifted by one cycle in Oscilloscope waveform image as compared to Modelsim Image.