FIFO implementation - VHDL - vhdl

I come across one more difficulty while instantiate the fifo code to my top module. I want to store some set of data say "WELCOME TO THE WORLD OF FPGA" from my serial port ( receiving subsystem) then i want to retrieve it back say when button on fpga board is pressed or FIFO is full. I have my fifo code and serial communication code written. Idea is data sent from keyboard ->receiving subsystem -> FIFO -> transmitting subsystem -> hyperterminal. I am at present using fifo of 8 bit wide and say 28 deep just to store some small data. Please help me in this regard how can I implement it.I have byte coming from receiver saved in register_save.
fifo code
inst_bit8_recieve_unit : entity work.byte_recieve_8N1
port map ( ck => ck,
reset => reset,
new_byte_in_buffer => new_byte_in_buffer,
byte_read_from_buffer => byte_read_from_buffer,
recieve_buffer => register_save,
JA_2 => JA(2));
---------------------FIFO instantiate-------------------------------
inst_of_fifo_Recieve_unit : entity work.fifo
generic map (B => data_bits, W => fifo_width)
port map ( ck => ck,
reset => reset,
rd => rd_rx,
wr => wr_rx,
write_data => num_recieved,
read_data => num_recieved_fifo,
empty => empty_rx,
full => full_rx );
inst_bit8_transmit_unit : entity work.byte_transmit_8N1
port map ( ck => ck,
reset => reset,
send_byte_ready => send_byte_ready,
send_byte_done => send_byte_done ,
send_buffer => num_send,
JAOUT_0 => JAOUT );
proc_send5byte: process(ck, reset, state_byte5, send_byte_done, num_send, state_button_0, num_recieved_fifo, rd_rx)
begin
if reset = '1' THEN
state_byte5 <= idle;
send_byte_ready <='0';
num_send <= "00000000" ;
else
if rising_edge(ck) then
case state_byte5 is
when idle => ---- in this, if btn(0) is high i.e pressed then only state_byte5 will go to next state
if state_button_0 = transit_pressed then
state_byte5 <= byte;
end if;
-----===============================================================
when byte =>
if (not empty_rx = '1') then
if send_byte_ready ='0' and send_byte_done = '0' then ----here if condition is satified the send_byte_ready will be set
send_byte_ready <='1'; --------- shows next byte is ready
num_send <= num_recieved_fifo;
rd_rx <='1';
end if;
end if;
if send_byte_ready = '1' and send_byte_done = '1' then --- during load state send_byte will be resets
send_byte_ready <='0';
rd_rx <= '0';
state_byte5 <= idle; ----------- go back to idle
end if;
--end if;
---===============================================================
when others =>
state_byte5 <= idle; ------------- for other cases state state _byte5 will be in idle
send_byte_ready <= '0';
rd_rx <= '0';
end case;
end if;
end if;
end process;
proc_recieving_byte : process (ck, reset, register_save, new_byte_in_buffer, full_rx, num_recieved, wr_rx)
begin
if reset = '1' then
byte_read_from_buffer <= '0';
else
if rising_edge(ck) then
if full_rx = '0' then
if new_byte_in_buffer = '1' and byte_read_from_buffer = '0' then
byte_read_from_buffer <= '1';
wr_rx <= '1';
num_recieved(7 downto 0 ) <= register_save( 7 downto 0);
end if;
end if;
if new_byte_in_buffer = '0' then
byte_read_from_buffer <= '0';
wr_rx <= '0';
end if;
--end if;
end if;
end if;
end process;
Just added the corrected code now which seems to be working. Problem araises when increase the depth of fifo. When depth>2 then every third byte is missing.
Please help, why I am loosing data.

The principe of a fifo is First In First Out. You have not to manage it.
You place your data on input of fifo
You set write enable bit to '1'
You wait for one clock cycle
You set write enable bit to '0'
then the data is store, you do it again to store another value.
When you want to read all data (Fifo full / any case you want)
You set Read enable bit to '1' and every clock cycle, you will receive a data.

--- process for recieving bytes and sent to fifo input with write enable signal------------
proc_recieving_byte : process (ck, reset, register_save, new_byte_in_buffer, full_rx, num_recieved, wr_rx)
begin
if reset = '1' then
byte_read_from_buffer <= '0';
else
if rising_edge(ck) then
if full_rx = '0' then
if new_byte_in_buffer = '1' and byte_read_from_buffer = '0' then
byte_read_from_buffer <= '1';
wr_rx <= '1';
num_recieved(7 downto 0 ) <= register_save( 7 downto 0);
else
wr_rx <= '0';
end if;
end if;
if new_byte_in_buffer = '0' then
byte_read_from_buffer <= '0';
wr_rx <= '0';
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------------------------------
---- this process checks first button state and then transmission occurs from fifo untill empty------
proc_send5byte: process(ck, reset, state_byte5, send_byte_done, num_send, state_button_0, num_recieved_fifo, rd_rx)
begin
if reset = '1' THEN
state_byte5 <= idle;
send_byte_ready <='0';
num_send <= "00000000" ;
else
if rising_edge(ck) then
case state_byte5 is
when idle => ---- in this, if btn(0) is high i.e pressed then only state_byte5 will go to next state
if state_button_0 = transit_pressed then
state_byte5 <= byte;
end if;
-----===============================================================
when byte =>
if (not empty_rx = '1') then
if send_byte_ready ='0' and send_byte_done = '0' then ----here if condition is satified the send_byte_ready will be set
send_byte_ready <='1'; --------- shows next byte is ready
num_send <= num_recieved_fifo;
rd_rx <='1';
else
rd_rx <='0';
end if;
end if;
if send_byte_ready = '1' and send_byte_done = '1' then --- during load state send_byte will be resets
send_byte_ready <='0';
rd_rx <= '0';
state_byte5 <= idle; ----------- go back to idle
end if;
---===============================================================
when others =>
state_byte5 <= idle;
send_byte_ready <= '0';
rd_rx <= '0';
end case;
end if;
end if;
end process;
Just found the error and corrected as above which works very well. Comments to improve are welcome.

Related

Warning (10631): VHDL Process Statement warning: inferring latch(es) for signal or variable

I'm trying learning to code in VHDL and the below code gives me no errors when compiling but gives me a latching warning. I need to get rid of this latch as I believe it is causing me problems in my next piece of code which will use this (8x8 multiplier).
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY control IS
PORT (
clk, reset_a, start : IN STD_LOGIC;
count : IN UNSIGNED (1 DOWNTO 0);
input_sel, shift_sel : OUT UNSIGNED(1 DOWNTO 0);
state_out : OUT UNSIGNED(2 DOWNTO 0);
done, clk_ena, sclr_n : OUT STD_LOGIC
);
END ENTITY control;
ARCHITECTURE logic OF control IS
type logic_state is (idle, lsb, mid, msb, calc_done, err);
signal current_state: logic_state;
signal next_state: logic_state;
BEGIN
PROCESS (clk, reset_a)
BEGIN
if reset_a = '1' then
current_state <= idle;
elsif rising_edge (clk) then
current_state <= next_state;
end if;
END PROCESS;
PROCESS (current_state, start, count)
BEGIN
CASE current_state IS
when idle =>
if start = '1' then
next_state <= lsb;
else
next_state <= idle;
end if;
when lsb =>
if start = '0' and count = "00" then
next_state <= mid;
else
next_state <= err;
end if;
when mid =>
if start = '0' then
if (count = "01") then
next_state <= mid;
elsif (count = "10") then
next_state <= msb;
else
next_state <= err;
end if;
end if;
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
when calc_done =>
if start = '0' then
next_state <= idle;
else
next_state <= err;
end if;
when err =>
if start = '1' then
next_state <= lsb;
else
next_state <= err;
end if;
END CASE;
END PROCESS;
mealy: PROCESS (current_state, start, count)
BEGIN
input_sel <= "00";
shift_sel <= "00";
done <= '0';
clk_ena <= '0';
sclr_n <= '1';
CASE current_state IS
when idle =>
if start = '1' then
sclr_n <= '0';
clk_ena <= '1';
END IF;
when lsb =>
if start = '0' and count = "00" then
sclr_n <= '1';
end if;
when mid =>
if start = '0' then
if (count = "01") then
input_sel <= "01";
shift_sel <= "01";
elsif (count = "10") then
input_sel <= "10";
shift_sel <= "01";
end if;
end if;
when msb =>
if start = '0' then
if (count = "11") then
input_sel <= "11";
shift_sel <= "10";
end if;
end if;
when calc_done =>
if start = '0' then
input_sel <= "00";
shift_sel <= "00";
done <= '1';
clk_ena <= '0';
end if;
when err =>
if start = '1' then
input_sel <= "00";
shift_sel <= "00";
done <= '0';
clk_ena <= '1';
sclr_n <= '0';
end if;
END CASE;
END PROCESS mealy;
moore: PROCESS(current_state)
BEGIN
state_out <= "000";
CASE current_state IS
WHEN idle =>
WHEN lsb =>
state_out <= "001";
WHEN mid =>
state_out <= "010";
WHEN msb =>
state_out <= "011";
WHEN calc_done =>
state_out <= "100";
WHEN err =>
state_out <= "101";
END CASE;
END PROCESS moore;
END ARCHITECTURE logic;
I get the following warning:
Warning (10631): VHDL Process Statement warning at mult_control.vhd(65): inferring latch(es) for signal
or variable "next_state", which holds its previous value in one or more paths through the process
That points to this node (line 33):
PROCESS (current_state, start, count)
And that warning leads to other warnings (for every type .idle, .mid, .msb, etc.):
Warning (13012): Latch next_state.idle_218 has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal start
Thank you!
line 33 is in the second process (with no label).
Why are there inferred latches?
See IEEE Std 1076.6-2004 (withdrawn) RTL Synthesis
6.2.1.1 Level-sensitive storage from process with sensitivity list
A level-sensitive storage element shall be modeled for a signal (or variable) when all the following apply:
a) The signal (or variable) has an explicit assignment.
b) The signal (or variable) does not have an execution path with as a condition.
c) There are executions of the process that do not execute an explicit assignment (via an assignment statement) to the signal (or variable).
By default, the effect of an identity assignment of the signal (or variable) shall be as though the assignment was not present.
If the combinational attribute decorates the signal (or variable), combinational logic with feedback shall be synthesized.
To avoid unintentional latches as condition c) has to be invalid.
An example in the question code that can cause latches:
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
This is missing an else for the outer if statement and meets rule c) quoted above. That can be cured:
when msb =>
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
else -- now all binary values of start in state msb assign next_state
next_state <= msb;
end if;
You can assign a value to a target before an if statement that otherwise meets c):
when msb =>
next_state <= msb; -- not always assigned in the if statement
if start = '0' then
if (count = "11") then
next_state <= calc_done;
else
next_state <= err;
end if;
end if;
In a sequence of statements the 'default' assignment occurs unless overwritten by a subsequent assignment in the if statement.
The question's code has other occurrences of c) issues (including in other processes) that can be similarly treated.

Generating 2 clock pulses in VHDL

How do I generate two clock pulses based on a trigger signal. I have found this code (which works very well) here in stackoverflow :
get_data:process(clk, reset)
variable idle : boolean;
begin
if reset = '1' then
idle := true;
elsif rising_edge(clk) then
clr_flag <= '0'; -- default action
if idle then
if flag = '1' then
clr_flag <= '1'; -- overrides default FOR THIS CYCLE ONLY
idle <= false;
end if;
else
if flag = '0' then
idle := true;
end if;
end if;
end if;
end process;
I was wondering if someone can help me in generating a flag that lasts 2 clock pulses instead of one.
I would just do this:
signal s_flag, s_flag_1z : std_logic := '0';
begin
get_data:process(clk, reset)
variable idle : boolean;
begin
if reset = '1' then
idle := true;
s_flag <= '0';
s_flag_1z <= '0';
elsif rising_edge(clk) then
s_flag <= '0'; -- default action
s_flag_1z <= s_flag;
if idle then
if flag = '1' then
s_flag <= '1'; -- overrides default FOR THIS CYCLE ONLY
idle <= false;
end if;
else
if flag = '0' then
idle := true;
end if;
end if;
end if;
end process;
cl_flag <= '1' when (s_flag & s_flag_1) /= "00" else '0';
Now the flag will be 2 clock cycles high and only a small addition was required.
/Ben
A variable length pulse is cleanest and easiest with a tap at the top of a shift register
get_data:process(clk, reset) --make sure you really want asynchronous reset
variable pulse_line : std_logic_vector(1 downto 0); --set the width to how many clocks you want the pulse
begin
if reset = '1' then --again make sure you really want asynchronous reset
pulse_line := (others => '1');
elsif rising_edge(clk) then
if flag = '1' then
pulse_line := (others => '1'); --reset the shift register
else
pulse_line := pulse_line(pulse_line'high-1 downto 0) & '0'; --push a 0 onto bottom of the shift register
end if;
clr_flag <= pulse_line(pulse_line'high); --tap out the top of the shift register
end if;
end process;

how to call a state machine from another state machine and get the response back in VHDL

I want to do VHDL programming of a state machine. In this state machine one state is itself another state machine. how can i call this state machine from the main state machine?
Example of what i actually want to do is as follows:
main state machine (sm_main.vhd) :-
clk_process : process (clk, reset)
begin
if(reset = '1') then
state_reg <= start;
elsif (clk'event and clk =' 1' ) then
state_reg <= state_next;
end if;
end process;
state_process : process (state_reg,input,enable)
begin
case state_reg is
when start =>
if (input =1) then
state_next <= wait;
else
state_next <= start;
end if;
when wait =>
if (enable =1) then
output <= '1';
state_next <= execute;
else
output <='0';
state_next <= wait;
end if ;
when execute =>
if (enable =1) then
state_next <= done;
else
state_next <= start;
end if;
when done =>
if(result = 1) then
state_next <= execute;
else
state_next <= start;
end if;
end case;
end process;
sub state machine (sm_execute.vhd):-
The execute state of the above state machine is itself another state machine program.
state_process : process (state_reg,a,b)
begin
case state_reg is
when start =>
if (a=1) then
state_next <= s1;
else
state_next <= s2;
end if;
when s1 =>
if (b =1) then
state_next <= s3;
else
state_next <= s3;
end if ;
when s3=>
if(c=1) then
result <= '1';
state_next <= s3
else
result <='0';
state_next <= start
end case;
end process;
What i want is to call this sm_execute.vhd in the execute state of sm_main.vhd. The output from the sm_execute which is result, is to be used as an input to determine the next state after execute in sm_main.vhd. That means i want to call the sub state machine program and also return the value to main state machine program once the sub state machine program finishes its execution.
thanks in advance
Sruthi Rajan
Handshaking. The first machine signals the second one to start, and waits for it to acknowledge. Then it retracts the start signal and waits for the second one to complete.
This is not the only way, but where you can separate the second state machine into its own process, it is probably the simplest.
First SM (master):
SM_1 : process(clock,reset)
begin
if reset = '1' then
State_1 <= Idle;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;
Second SM (slave) :
SM_2 : process(clock,reset)
begin
if reset = '1' then
State_2 <= Idle;
elsif rising_edge(clock) then
case State_2 is
when Idle =>
Done <= '1';
if Start = '1' then
Done <= '0';
State_2 <= Start_Process;
end if;
when Start_Process =>
State_2 <= Process_Done;
when Process_Done =>
Done <= '1';
if Start = '0' then
State_2 <= Idle;
end if;
when others => State_2 <= Idle;
end case;
end if;
end process;
Notice that in this implementation, the master waits for the slave to start processing (done = '0';). This covers cases where the slave may not be able to respond immediately. It does not cover cases where Done='0' already because the slave is processing data for another master.
Also the slave waits for the master to retract Start before returning to Idle. Usually Start will already be '0' but if it isn't, you probably don't want the slave to retrigger immediately.
If you can guarantee neither of these cases will happen you can simplify the handshaking a little, but the design becomes more sensitive to changes in signal timings.
Notice also that Start defaults to '0', because of the default assignment, but Done has no default assignment so it retains its state during processing. Unless you return to Idle (perhaps via an error path) when Done is set to indicate that processing has stopped.
If there is uncertainty about whether processing will complete, you may want the master to time out, rather than deadlock waiting for something that won't happen. I do this by adding a delay timer which can be used by different states for different purposes : here it detects a frozen slave and lets us handle the error.
First SM (master):
SM_1 : process(clock,reset)
variable Delay : natural range 0 to 100;
constant Timeout : natural := 50;
begin
if reset = '1' then
State_1 <= Idle;
Delay := 0;
elsif rising_edge(clock) then
-- default actions
Start <= '0';
if Delay > 0 then
Delay := Delay - 1;
end if;
-- state machine proper
case State_1 is
...
when Need_Result =>
Start <= '1';
-- wait here until slave SM starts processing
if Done = '0' then
Delay := Timeout;
State_1 <= Wait_Result;
end if;
when Wait_Result =>
if Done = '1' then
State_1 <= Have_Result;
elsif Delay = 0 then
State_1 <= Timed_Out; -- do error processing
end if;
...
when others => State_1 <= Idle;
end case;
end if;
end process;

Simplifying A State Machine To Reduce Logic Levels and Meet Timing

My design at the moment isn't meeting timing. I've tried putting it on a slower clock and pipelining the inputs/outputs. The problem is always the same - too many levels of logic. Have any of you got any tips on making this logic more clock friendly?
signal ctr : std_logic_vector(9 downto 0);
signal sig_bit_shift : std_logic_vector (15 downto 0);
begin
process(clk_p)
begin
if rising_edge(clk_p) then
if rst_i = '1' or nuke = '1' then
ctr <= (others => '0');
state <= ST_IDLE;
elsif unsigned(event_settings) < 1 then -- disables
state <= ST_IDLE;
elsif unsigned(event_settings) = 1 then -- always on
state <= ST_ENABLE;
else
case state is
when ST_IDLE =>
if ctr = (unsigned(event)-2) then
state <= ST_ENABLE;
elsif unsigned(ctr) = 1 and sig = '0' then --catches first word
state <= ST_ENABLE;
elsif sig = '1' then
ctr <= ctr + 1;
end if;
when ST_ENABLE =>
if s_sig = '1' then
state <= ST_IDLE;
if unsigned(s_evt) > 1 then
ctr <= (others => '0');
end if;
end if;
end case;
end if;
end if;
end process;
UPDATE:
process(clk_p)
begin
if rising_edge(clk_p) then
if rst_i = '1' or nuke = '1' then
ctr <= x"00" & "10";
state <= ST_IDLE;
elsif settings = '1' then
case state is
when ST_IDLE =>
if ctr = (unsigned(event)) then
state <= ST_ENABLE;
elsif unsigned(ctr) = 1 and sig = '0' then --catches first word -- this is the part which when added, fails timing
state <= ST_ENABLE;
elsif sig = '1' then
ctr <= ctr + 1;
end if;
when ST_ENABLE =>
if s_sig = '1' then
state <= ST_IDLE;
if unsigned(s_evt) > 1 then
ctr <= X"00" & "10";
end if;
end if;
end case;
end if;
end if;
end process;
I think too it's slowed down by where the signal comes from:
sig <= sig_token when unsigned(SIG_DELAY) < 1 else (sig_bit_shift(to_integer(unsigned(SIG_DELAY)-1)));
process(clk_p) -- delays sig
begin
if rising_edge(clk_p) then
if rst = '1' then
sig_bit_shift <= (others => '0');
else
sig_bit_shift <= l1a_bit_shift(sig_bit_shift'high-1 downto 0) & sig_token;
end if;
end if;
end process;
UPDATE 2 :
Seems like half the routing went into the above delay so i'm going to try and fix with this:
signal sig_del_en : std_logic;
signal sig_del_sel : integer;
begin
process(clk_p)
begin
if rising_edge(clk_p) then
if unsigned(SIG_DELAY) = 0 then
sig_del_en <= '0';
else
sig_del_en <= '1';
end if;
sig_del_sel <= to_integer(unsigned(SIG_DELAY)-1);
end if;
end process;
sig <= sig_token when sig_del_en = '0' else (sig_bit_shift(sig_del_sel));
Some of the "slow" operations are array = which requires compare over all bits in the argument, and < and > which requires subtraction over all bits in the argument. So you may improve timing in a cycle, if there is sufficient time in the previous cycle to generate the compare result up front as a std_logic. It may be relevant for these:
unsigned(event_settings) < 1
unsigned(event_settings) = 1
ctr = (unsigned(event)-2)
unsigned(ctr) = 1
unsigned(s_evt) > 1
The code to generate the different std_logic values depends on the way the related signal is generated, but an example can be:
process (clk) is
variable event_settings_v : event_settings'range;
begin
if rising_edge(clk) then
...
event_settings_v := ... code for generating event_settings; -- Variable with value
event_settings <= event_settings_v; -- Signal drive from variable
if unsigned(event_settings_v) < 1 then
unsigned_event_settings_tl_1 <= '1';
else
unsigned_event_settings_tl_1 <= '0';
end if;
end if;
end process;
The code unsigned(event_settings) < 1 in the state machine can then be changed to unsigned_event_settings_tl_1 = '1', which may improve timing if this compare is in the critical path.
Using the asynchronous reset typically available on the the flip-flop for rst_i = '1' may also improve timing, since it removes logic from the synchronous part. It is unlikely to give a significant improvement, but it's typically a good design practice in order to maximize the time for synchronous logic. The asynchronous reset is used through coding style like:
process (rst_i, clk_p) is
begin
if rst_i = '1' then
... Apply asynchronous reset value to signals
elsif rising_edge(clk_p) then
... Synchronous update of signals

VHDL state machine is not looping

Fellow SO users,
I'm programming my ADC (ADC0804 which is mounted on a breadboard connected to a Spartan-3 FPGA board). Now, I'm using this ADC to provide digital output for my humidity sensor. The ADC outputs an 8-bit value which I'm displaying on the LEDs on the FPGA board.
Now, I'm writing the state machine in such a way that the ADC would always continue to keep outputting values even when I vary the humidity level. But as for the current implementation I have, eventhough I'm looping back to the first state, I'm not getting a continuous stream of values. I'm only getting one 8-bit value at a time (I.E.; I have to keep pressing the reset button to update the value displayed on the LEDs). The following is my code.
FSM_NEXT_STATE_INIT : PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
CURR_STATE <= STARTUP;
ELSIF (CLK'EVENT AND CLK = '1') THEN
CURR_STATE <= NEXT_STATE;
END IF;
END PROCESS;
START_FSM : PROCESS (CURR_STATE, INTR)
BEGIN
CASE CURR_STATE IS
WHEN STARTUP =>
NEXT_STATE <= CONVERT;
WR <= '0';
READ_DATA <= '0';
WHEN CONVERT =>
IF (INTR = '0') THEN
NEXT_STATE <= READ1;
ELSE
NEXT_STATE <= CONVERT;
END IF;
WR <= '1';
READ_DATA <= '0';
WHEN READ1 =>
NEXT_STATE <= READ2;
WR <= '1';
READ_DATA <= '1';
WHEN READ2 =>
NEXT_STATE <= STARTUP;
WR <= '1';
READ_DATA <= '0';
WHEN OTHERS =>
NEXT_STATE <= STARTUP;
END CASE;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
Y <= (OTHERS => '0');
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (READ_DATA = '1') THEN
Y <= D7&D6&D5&D4&D3&D2&D1&D0; --Concatenate the 8-bit ADC output
END IF;
END IF;
END PROCESS;
You'll notice that in state 'READ2', I'm looping back to the beginning (so that I can keep reading values continuously as the states transition) but somehow I don't think this is working. Could anyone please provide some assistance on how to go about solving this?
After a look on the data sheet for the ADC0804 I found following which could be the/a possible reason:
Note: Read strobe must occur 8 clock periods (8/fCLK) after assertion of interrupt to guarantee reset of INTR.
Inserting a WAIT state between CONVERT and READ1 might fix the problem.

Resources