UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
702 Views
Registered: ‎07-24-2018

Bug introduced in 2018.1: sequential state machine producing invalid state transitions

Hi

 

I've got a sequential process which changed behaviour when switching to Vivado 2018.1 (and 2018.2). Was working fine up to Vivado 2017.4

 

I investigated the error and found a work around but in my opinion, Vivado is not synthesizing correctly in versions 2018.1 and following...

 

The work around I found is about assigning state <= idleState although I am already in the idleState, so I don't change anything and it should not be required. For sure it was not required in Vivado 2017.4.

 

In 2018.2 I see invalid states being assigned and/or invalid transitions happening.

 

Does anybody have some insight into this? Any help would be very much appreciated... (I have similar code all over my project and don't want to change all my code).

 

Best regards,

Daniel

 

 

See the code below:

 

type STATE_RX is (stIdle, stRxData1, stRxData2, stAddToCmdQueue);
signal iStateRx : STATE_RX := stIdle;

--- ... ---

 

prRxPacketHandler : process(Clk)
begin
  if rising_edge(Clk) then
    case iStateRx is
      when stIdle =>
        iCmdAddr      <= (others => '0');
        iCmdHiByte    <= (others => '0');
        iCmdLowByte   <= (others => '0');
        iCmdWrEn      <= '0';
        iTriggerLines <= (others => '0');
        case iSerdesRxData(9 downto 8) is
          when "01" =>
            iCmdAddr <= '0' & iSerdesRxData(6 downto 0);
            iStateRx <= stAddToCmdQueue;
          when "10" =>
            iCmdAddr <= '1' & iSerdesRxData(6 downto 0);
            iStateRx <= stRxData1;
          when "11" =>
            iTriggerLines <= iSerdesRxData(7 downto 0);
          when others =>              -- idle command, "00"
            null;
        end case;

      when stRxData1 =>
        iCmdHiByte <= iSerdesRxData(7 downto 0);
        iStateRx   <= stRxData2;

      when stRxData2 =>
        iCmdLowByte <= iSerdesRxData(7 downto 0);
        iStateRx    <= stAddToCmdQueue;

      when stAddToCmdQueue =>
        iStateRx <= stIdle;
        iCmdWrEn <= '1';

      when others =>
        iStateRx <= stIdle;
    end case;
  end if;
end process;


--------------------------------------------------------------------------
-- workaround required for 2018.2: had to add 'iStateRx <= stIdle;'
-- although I am already in idle state. Not required for 2017.4
--------------------------------------------------------------------------

prRxPacketHandler : process(Clk)
begin
  if rising_edge(Clk) then
    case iStateRx is
      when stIdle =>
        iCmdAddr      <= (others => '0');
        iCmdHiByte    <= (others => '0');
        iCmdLowByte   <= (others => '0');
        iCmdWrEn      <= '0';
        iTriggerLines <= (others => '0');
        case iSerdesRxData(9 downto 8) is
          when "01" =>
            iCmdAddr <= '0' & iSerdesRxData(6 downto 0);
            iStateRx <= stAddToCmdQueue;
          when "10" =>
            iCmdAddr <= '1' & iSerdesRxData(6 downto 0);
            iStateRx <= stRxData1;
          when "11" =>
            iTriggerLines <= iSerdesRxData(7 downto 0);
            iStateRx      <= stIdle;  -- ADDED. stay here...
          when others =>              -- idle command, "00"
            iStateRx <= stIdle;       -- CHANGED. stay here...
        end case;

      when stRxData1 =>
        iCmdHiByte <= iSerdesRxData(7 downto 0);
        iStateRx   <= stRxData2;

      when stRxData2 =>
        iCmdLowByte <= iSerdesRxData(7 downto 0);
        iStateRx    <= stAddToCmdQueue;

      when stAddToCmdQueue =>
        iStateRx <= stIdle;
        iCmdWrEn <= '1';

      when others =>
        iStateRx <= stIdle;
    end case;
  end if;
end process;

0 Kudos
3 Replies
Scholar richardhead
Scholar
684 Views
Registered: ‎08-01-2012

Re: Bug introduced in 2018.1: sequential state machine producing invalid state transitions

Please explain exactly what you mean? Do you mean FPGA hardware is not behaving as coded? state transitions are occuring when one should not occur?

 

Are you seeing this issue in simulation? or just synthesis?

If the above is true for all cases, I would be concerned as we plan to migrate to 18.2 from 17.2, and we have many state machines coded this way.

0 Kudos
679 Views
Registered: ‎07-24-2018

Re: Bug introduced in 2018.1: sequential state machine producing invalid state transitions

I see the FPGA is not behaving as coded... I did measure invalid state transitions on the implemented FPGA (with debug signals hooked up to the oscilloscope).

 

Simulation of the VHDL source code is fine (but using another simulation tool anyhow)

0 Kudos
Scholar richardhead
Scholar
670 Views
Registered: ‎08-01-2012

Re: Bug introduced in 2018.1: sequential state machine producing invalid state transitions

I have run the code through synthesis in 2017.2 and 2018.2

 

They are roughly the same, but there is one subtle difference in the state bit D connections that wont cause an issue. In 17.2, it simply inverts the state(0) back to itself. In 18.2, it uses state(0) and state(1) to do the same function (the truth table imlies it is still and inversion of state(0))

 

Having analysed the clock enable for the state bits, this matches your code as expected.

 

So Unless there is a bug in implementation (which I would be surprised at) I find it hard to believe this is causing the issue. Have you got some CDC somewhere in the design? could this be failing on one of the two builds and passing in the other?

 

 

 

0 Kudos