A
axr0284
Guest
Hey guys,
I have a weird problem with a spartan 3E FPGA. I don't know if you
have ever seen this.
I have a simple state machine to read data from an ADC. The code is
below:
<CODE>
--
-- Sequential part of state machine
--
seq_state_machine: process(reset, clk_120, nextState,
next_write_flag, next_data_valid_internal,
next_cs_zero_l, next_cs_one_l, next_rd_l, next_conv_l,
next_adc_zero_data_A_one, next_adc_zero_data_A_two,
next_adc_one_data_A_one, next_adc_one_data_A_two,
next_gamma_sign, next_reset_skip_count, next_busy_flag)
begin
if (clk_120'event and clk_120 = '1') then
if (reset='1') then -- Synchronous active low reset
currentState <= IDLE;
internal_cs_zero_l <= '1';
internal_cs_one_l <= '1';
internal_rd_l <= '1';
internal_conv_l <= '1';
internal_adc_zero_data_A_one <= (others => '0');
internal_adc_zero_data_A_two <= (others => '0');
internal_adc_one_data_A_one <= (others => '0');
internal_adc_one_data_A_two <= (others => '0');
internal_gamma_sign <= '0';
reset_skip_count <= '1';
busy_flag <= '0';
write_flag <= '0';
data_valid_internal <= '0';
else
currentState <= nextState;
internal_cs_zero_l <= next_cs_zero_l;
internal_cs_one_l <= next_cs_one_l;
internal_rd_l <= next_rd_l;
internal_conv_l <= next_conv_l;
internal_adc_zero_data_A_one <= next_adc_zero_data_A_one;
internal_adc_zero_data_A_two <= next_adc_zero_data_A_two;
internal_adc_one_data_A_one <= next_adc_one_data_A_one;
internal_adc_one_data_A_two <= next_adc_one_data_A_two;
internal_gamma_sign <= next_gamma_sign;
reset_skip_count <= next_reset_skip_count;
busy_flag <= next_busy_flag;
write_flag <= next_write_flag;
data_valid_internal <= next_data_valid_internal;
end if;
end if;
end process seq_state_machine;
--
-- Combinational part of state machine
--
comb_state_machine: process(currentState, adc_busy_zero,
adc_busy_one, adc_data, data_valid_internal,
internal_cs_zero_l, internal_cs_one_l, internal_rd_l,
internal_conv_l, gamma_sign,
internal_adc_zero_data_A_one, internal_adc_zero_data_A_two,
internal_adc_one_data_A_one, internal_adc_one_data_A_two,
internal_gamma_sign, reset_skip_count, busy_flag, skip_count,
write_flag, convert_count)
begin
nextState <= currentState;
next_cs_zero_l <= internal_cs_zero_l;
next_cs_one_l <= internal_cs_one_l;
next_rd_l <= internal_rd_l;
next_conv_l <= internal_conv_l;
next_adc_zero_data_A_one <= internal_adc_zero_data_A_one;
next_adc_zero_data_A_two <= internal_adc_zero_data_A_two;
next_adc_one_data_A_one <= internal_adc_one_data_A_one;
next_adc_one_data_A_two <= internal_adc_one_data_A_two;
next_gamma_sign <= internal_gamma_sign;
next_reset_skip_count <= reset_skip_count;
next_busy_flag <= busy_flag;
next_write_flag <= write_flag;
next_data_valid_internal <= data_valid_internal;
case currentState is
when IDLE =>
next_write_flag <= '0';
next_conv_l <= '1';
next_cs_zero_l <= '1';
next_cs_one_l <= '1';
next_rd_l <= '1';
next_reset_skip_count <= '1';
next_busy_flag <= '0';
next_data_valid_internal <= '0';
nextState <= START_THE_CONVERSION_ZERO;
when START_THE_CONVERSION_ZERO =>
if(convert_count = b"0110") then -- assert convert for
50 ns
next_conv_l <= '1';
nextState <= WAIT_FOR_BUSY_HIGH;--
STOP_THE_CONVERSION_ZERO;--
else
next_conv_l <= '0';
nextState <= START_THE_CONVERSION_ZERO;
end if;
when WAIT_FOR_BUSY_HIGH =>
if(adc_busy_zero = '1' AND adc_busy_one = '1') then --
Wait for busy signal to go high
nextState <= WAIT_FOR_BUSY_LOW;
else
nextState <= WAIT_FOR_BUSY_HIGH;
end if;
when WAIT_FOR_BUSY_LOW =>
if(adc_busy_zero = '0' AND adc_busy_one = '0') then --
Wait for busy signal to go high
next_cs_zero_l <= '0';
next_rd_l <= '0';
next_reset_skip_count <= '0';
nextState <= READ_DATA_ZERO; -- Read the data
else
nextState <= WAIT_FOR_BUSY_LOW;
end if;
when READ_DATA_ZERO =>
next_reset_skip_count <= '0';
if(skip_count = b"0001100") then
next_adc_zero_data_A_one <= adc_data; -- Store the data A1
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0001111") then
next_rd_l <= '1';
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0010011") then
next_rd_l <= '0';
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0010111") then
next_adc_zero_data_A_two <= adc_data; -- Store the
data A1
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0100011") then -- 2 cycles later
deassert chip select
next_rd_l <= '1';
next_cs_zero_l <= '1';
nextState <= SWITCH_TO_ADC_ONE; -- Read the data
else
nextState <= READ_DATA_ZERO; -- Read the data
end if;
when SWITCH_TO_ADC_ONE =>
if(skip_count = b"0101011") then
next_cs_one_l <= '0';
next_rd_l <= '0';
next_reset_skip_count <= '1';
nextState <= READ_DATA_ONE; -- Read the
data
else
nextState <= SWITCH_TO_ADC_ONE; -- Read the
data
end if;
when READ_DATA_ONE =>
next_reset_skip_count <= '0';
if(skip_count = b"0001100") then
next_adc_one_data_A_one <= adc_data; -- Store the
data A1
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0001111") then
next_rd_l <= '1';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0010011") then
next_rd_l <= '0';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0010111") then
next_adc_zero_data_A_two <= adc_data; -- Store the
data A1
next_gamma_sign <= gamma_sign;
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"100001") then -- Skip 60 cycles
next_cs_one_l <= '1';
next_rd_l <= '1';
next_write_flag <= '1';
next_data_valid_internal <= '1';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"1011101") then -- Skip 60 cycles
next_reset_skip_count <= '1';
nextState <= IDLE; -- Read the data
else
nextState <= READ_DATA_ONE; -- Read the data
end if;
when OTHERS =>
nextState <= IDLE; -- Read the data
end case;
end process comb_state_machine;
</CODE>
In the state machine if I don't have
when OTHERS =>
nextState <= IDLE;
the state machine CONSISTENTLY goes into an unknown state and locks
up. That does not seem right to me. I am wondering if you guys can
take a look at the code and tell me if there is a bug because I can't
find any. Thanks,
Amish
I have a weird problem with a spartan 3E FPGA. I don't know if you
have ever seen this.
I have a simple state machine to read data from an ADC. The code is
below:
<CODE>
--
-- Sequential part of state machine
--
seq_state_machine: process(reset, clk_120, nextState,
next_write_flag, next_data_valid_internal,
next_cs_zero_l, next_cs_one_l, next_rd_l, next_conv_l,
next_adc_zero_data_A_one, next_adc_zero_data_A_two,
next_adc_one_data_A_one, next_adc_one_data_A_two,
next_gamma_sign, next_reset_skip_count, next_busy_flag)
begin
if (clk_120'event and clk_120 = '1') then
if (reset='1') then -- Synchronous active low reset
currentState <= IDLE;
internal_cs_zero_l <= '1';
internal_cs_one_l <= '1';
internal_rd_l <= '1';
internal_conv_l <= '1';
internal_adc_zero_data_A_one <= (others => '0');
internal_adc_zero_data_A_two <= (others => '0');
internal_adc_one_data_A_one <= (others => '0');
internal_adc_one_data_A_two <= (others => '0');
internal_gamma_sign <= '0';
reset_skip_count <= '1';
busy_flag <= '0';
write_flag <= '0';
data_valid_internal <= '0';
else
currentState <= nextState;
internal_cs_zero_l <= next_cs_zero_l;
internal_cs_one_l <= next_cs_one_l;
internal_rd_l <= next_rd_l;
internal_conv_l <= next_conv_l;
internal_adc_zero_data_A_one <= next_adc_zero_data_A_one;
internal_adc_zero_data_A_two <= next_adc_zero_data_A_two;
internal_adc_one_data_A_one <= next_adc_one_data_A_one;
internal_adc_one_data_A_two <= next_adc_one_data_A_two;
internal_gamma_sign <= next_gamma_sign;
reset_skip_count <= next_reset_skip_count;
busy_flag <= next_busy_flag;
write_flag <= next_write_flag;
data_valid_internal <= next_data_valid_internal;
end if;
end if;
end process seq_state_machine;
--
-- Combinational part of state machine
--
comb_state_machine: process(currentState, adc_busy_zero,
adc_busy_one, adc_data, data_valid_internal,
internal_cs_zero_l, internal_cs_one_l, internal_rd_l,
internal_conv_l, gamma_sign,
internal_adc_zero_data_A_one, internal_adc_zero_data_A_two,
internal_adc_one_data_A_one, internal_adc_one_data_A_two,
internal_gamma_sign, reset_skip_count, busy_flag, skip_count,
write_flag, convert_count)
begin
nextState <= currentState;
next_cs_zero_l <= internal_cs_zero_l;
next_cs_one_l <= internal_cs_one_l;
next_rd_l <= internal_rd_l;
next_conv_l <= internal_conv_l;
next_adc_zero_data_A_one <= internal_adc_zero_data_A_one;
next_adc_zero_data_A_two <= internal_adc_zero_data_A_two;
next_adc_one_data_A_one <= internal_adc_one_data_A_one;
next_adc_one_data_A_two <= internal_adc_one_data_A_two;
next_gamma_sign <= internal_gamma_sign;
next_reset_skip_count <= reset_skip_count;
next_busy_flag <= busy_flag;
next_write_flag <= write_flag;
next_data_valid_internal <= data_valid_internal;
case currentState is
when IDLE =>
next_write_flag <= '0';
next_conv_l <= '1';
next_cs_zero_l <= '1';
next_cs_one_l <= '1';
next_rd_l <= '1';
next_reset_skip_count <= '1';
next_busy_flag <= '0';
next_data_valid_internal <= '0';
nextState <= START_THE_CONVERSION_ZERO;
when START_THE_CONVERSION_ZERO =>
if(convert_count = b"0110") then -- assert convert for
50 ns
next_conv_l <= '1';
nextState <= WAIT_FOR_BUSY_HIGH;--
STOP_THE_CONVERSION_ZERO;--
else
next_conv_l <= '0';
nextState <= START_THE_CONVERSION_ZERO;
end if;
when WAIT_FOR_BUSY_HIGH =>
if(adc_busy_zero = '1' AND adc_busy_one = '1') then --
Wait for busy signal to go high
nextState <= WAIT_FOR_BUSY_LOW;
else
nextState <= WAIT_FOR_BUSY_HIGH;
end if;
when WAIT_FOR_BUSY_LOW =>
if(adc_busy_zero = '0' AND adc_busy_one = '0') then --
Wait for busy signal to go high
next_cs_zero_l <= '0';
next_rd_l <= '0';
next_reset_skip_count <= '0';
nextState <= READ_DATA_ZERO; -- Read the data
else
nextState <= WAIT_FOR_BUSY_LOW;
end if;
when READ_DATA_ZERO =>
next_reset_skip_count <= '0';
if(skip_count = b"0001100") then
next_adc_zero_data_A_one <= adc_data; -- Store the data A1
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0001111") then
next_rd_l <= '1';
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0010011") then
next_rd_l <= '0';
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0010111") then
next_adc_zero_data_A_two <= adc_data; -- Store the
data A1
nextState <= READ_DATA_ZERO; -- Read the data
elsif(skip_count = b"0100011") then -- 2 cycles later
deassert chip select
next_rd_l <= '1';
next_cs_zero_l <= '1';
nextState <= SWITCH_TO_ADC_ONE; -- Read the data
else
nextState <= READ_DATA_ZERO; -- Read the data
end if;
when SWITCH_TO_ADC_ONE =>
if(skip_count = b"0101011") then
next_cs_one_l <= '0';
next_rd_l <= '0';
next_reset_skip_count <= '1';
nextState <= READ_DATA_ONE; -- Read the
data
else
nextState <= SWITCH_TO_ADC_ONE; -- Read the
data
end if;
when READ_DATA_ONE =>
next_reset_skip_count <= '0';
if(skip_count = b"0001100") then
next_adc_one_data_A_one <= adc_data; -- Store the
data A1
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0001111") then
next_rd_l <= '1';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0010011") then
next_rd_l <= '0';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"0010111") then
next_adc_zero_data_A_two <= adc_data; -- Store the
data A1
next_gamma_sign <= gamma_sign;
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"100001") then -- Skip 60 cycles
next_cs_one_l <= '1';
next_rd_l <= '1';
next_write_flag <= '1';
next_data_valid_internal <= '1';
nextState <= READ_DATA_ONE; -- Read the data
elsif(skip_count = b"1011101") then -- Skip 60 cycles
next_reset_skip_count <= '1';
nextState <= IDLE; -- Read the data
else
nextState <= READ_DATA_ONE; -- Read the data
end if;
when OTHERS =>
nextState <= IDLE; -- Read the data
end case;
end process comb_state_machine;
</CODE>
In the state machine if I don't have
when OTHERS =>
nextState <= IDLE;
the state machine CONSISTENTLY goes into an unknown state and locks
up. That does not seem right to me. I am wondering if you guys can
take a look at the code and tell me if there is a bug because I can't
find any. Thanks,
Amish