Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Problems with "XXXXXXXX" values...

Altera_Forum
Honored Contributor II
1,950 Views

Hi all, 

 

Sorry for probably one of the weakest posts on the forum, but I'm stuck. 

 

I am using the FTDI Morph-IC-II board which has an FT2232H USB bridge and an Altera Cyclone II on board. 

 

Basically at the moment all I want to do, is send a string to the FTDI chip, when this has recieved something it will put its RXF line low. 

 

My control logic should then let me read each of the bytes out of its RX FIFO into my own internal RX FIFO on the FPGA. 

 

I am then writing the data from the RX FIFO to a TX FIFO on the FPGA. 

 

This then I want to send back to the FTDI's TX FIFO. 

 

It sounds simple and it should be, but I am struggling and obviously have some flaw in my design as at the moment I am getting 4 clock cycles worth of "XXXXXXXX" on my line before the data I am sending back. And it seems to be appearing between my RX FIFO buffer input (RX_BUF_IN) and my RX FIFO buffer's output (RX_BUF_OUT). 

 

Below I have included most of my code and a copy of my simulation output in the hope that someone can see any major mistakes I have made, as being new to VHDL and having written this I probably can't see the wood for the trees, and can't work out why things aren't working. 

 

Apologies for the basic level of coding. I know it could be much neater, but thanks for any help and any time taken looking at this... 

 

BEGIN -------------------------------------------------------------------------------- -- Register the inputs -------------------------------------------------------------------------------- regip : process (FT_CLK, rst) begin if (rst = '1') then intRXF <= '0'; intTXE <= '0'; elsif ((FT_CLK'EVENT) and (FT_CLK='1')) then intRXF <= not nRXF; --(Inverts to active high) intTXE <= not nTXE; --(Inverts to active high) end if; end process regip; -------------------------------------------------------------------------------- -- Hold or Load Data into Register -------------------------------------------------------------------------------- reglddata : process (FT_CLK, rst) begin if ((FT_CLK'EVENT) and (FT_CLK='1')) then -- store input data in RX buffer when RX buffer write is enabled. if ((RX_BUF_WE = '1') and (RX_BUF_FULL = '0')) then RX_BUF_IN <= FT_Din; end if; end if; end process reglddata; -------------------------------------------------------------------------------- -- State machine to Transfer data from RX_FIFO to TX_FIFO -------------------------------------------------------------------------------- echodata : process (FT_CLK, rst) begin if (rst = '1') then RX_BUF_RE <= '0'; TX_BUF_WE <= '0'; EchoState <= EchoIDLE; elsif ((FT_CLK'EVENT) and (FT_CLK='1')) then case EchoState is when EchoIDLE => if (RX_BUF_EMPTY = '0') and (TX_BUF_FULL = '0') then EchoState <= EchoWAIT1; RX_BUF_RE <= '0'; TX_BUF_WE <= '0'; TX_BUF_IN <= RX_BUF_OUT; end if; --delay before read enable to avoid 'X' data byte when EchoWAIT1 => EchoState <= ECHO1; RX_BUF_RE <= '1'; TX_BUF_WE <= '1'; TX_BUF_IN <= RX_BUF_OUT; -- Allows one more write to TX buffer after final read from RX buffer. when ECHO1 => if (RX_BUF_EMPTY = '1') then EchoState <= ECHO2; RX_BUF_RE <= '0'; TX_BUF_WE <= '1'; else EchoState <= ECHO1; RX_BUF_RE <= '1'; TX_BUF_WE <= '1'; end if; TX_BUF_IN <= RX_BUF_OUT; --Resets EchoState back to EchoIDLE once the transfer from RX buffer to TX buffer has been completed. when ECHO2 => EchoState <= EchoIDLE; RX_BUF_RE <= '0'; TX_BUF_WE <= '0'; -- default state - return to IDLE when others => EchoState <= EchoIDLE; RX_BUF_RE <= '0'; TX_BUF_WE <= '0'; end case; end if; end process echodata; -------------------------------------------------------------------------------- -- Rx State Machine control -------------------------------------------------------------------------------- RxStatep : process (FT_CLK, rst) begin if (rst = '1') then RxState <= RxIDLE; intRD <= '1'; --Active low intOE_n <= '1'; --Active low RX_BUF_WE <= '0'; elsif ((FT_CLK'EVENT) and (FT_CLK='1')) then case RxState is -- Wait for Rx FIFO to signal that it has data to send -- And RX buffer is not full. when RxIDLE => if (intRXF = '1' and (RX_BUF_FULL = '0')) then RxState <= RxWAIT1; intOE_n <= '0'; intRD <= '1'; else RxState <= RxIDLE; intOE_n <= '1'; intRD <= '1'; end if; RX_BUF_WE <= '0'; -- RD is set low one cycle after OE_n goes low to read the data from FIFO when RxWAIT1 => RxState <= RxDATA1; intRD <= '0'; intOE_n <= '0'; RX_BUF_WE <= '1'; -- Remain in this state until FIFO indicates Rd cycle is complete when RxDATA1 => if ((intRXF = '1') and (RX_BUF_FULL = '0')) then RxState <= RxDATA1; intRD <= '0'; intOE_n <= '0'; RX_BUF_WE <= '1'; else RxState <= RxIDLE; intRD <= '1'; intOE_n <= '1'; RX_BUF_WE <= '0'; end if; -- default state - return to IDLE when others => RxState <= RxIDLE; intRD <= '1'; intOE_n <= '1'; RX_BUF_WE <= '0'; end case; end if; end process RxStatep; -------------------------------------------------------------------------------- -- Tx State Machine - controls writing of FT232 Data and WR signals -------------------------------------------------------------------------------- TxStatep : process (FT_CLK, rst) begin if (rst = '1') then TxState <= TxIDLE; intWR <= '1'; -- ACTIVE LOW TX_BUF_RE <= '0'; elsif ((FT_CLK'EVENT) and (FT_CLK = '1')) then case TxState is -- In this application read has priority over write cycles. So wait until FTDI Fifo is ready to be written to, -- There is nothing to be read, and the TX buffer is not empty. when TxIDLE => if ((intRXF = '0') and (intRD = '1') and (intTXE = '1') and (TX_BUF_EMPTY = '0')) then TxState <= TxDATA1; TX_BUF_RE <= '1'; intWR <= '0'; else TxState <= TxIDLE; TX_BUF_RE <= '0'; intWR <= '1'; -- ACTIVE LOW end if; -- Allow data to be read from TX buffer to while FTDI FIFO is ready and the TX buffer is not empty. when TxDATA1 => if ((intTXE = '1') or (TX_BUF_EMPTY = '0')) then TxState <= TxDATA1; TX_BUF_RE <= '1'; intWR <= '0'; else TxState <= TxIDLE; TX_BUF_RE <= '0'; intWR <= '1'; end if; -- default state - return to IDLE when others => TxState <= TxIDLE; intWR <= '1'; TX_BUF_RE <= '0'; end case; end if; end process TxStatep; -------------------------------------------------------------------------------- -- Port Mapping for RX_FIFO -------------------------------------------------------------------------------- RX_Portmap: RX_FIFO PORT MAP( RX_aclr => rst, RX_clock => FT_CLK, RX_data => RX_BUF_IN, RX_rdreq => RX_BUF_RE, RX_wrreq => RX_BUF_WE, RX_empty => RX_BUF_EMPTY, RX_full => RX_BUF_FULL, RX_q => RX_BUF_OUT -- usedw : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) -- not used ); -------------------------------------------------------------------------------- -- Port Mapping for TX_FIFO -------------------------------------------------------------------------------- TX_Portmap: TX_FIFO PORT MAP( TX_aclr => rst, TX_clock => FT_CLK, TX_data => TX_BUF_IN, TX_rdreq => TX_BUF_RE, TX_wrreq => TX_BUF_WE, TX_empty => TX_BUF_EMPTY, TX_full => TX_BUF_FULL, TX_q => TX_BUF_OUT -- TX_usedw : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) -- not used ); -------------------------------------------------------------------------------- -- Assign other outputs -------------------------------------------------------------------------------- FT_DEn <= not intWR; -- FT_DEN is active high and intWR is active low. Hence the not. FT_Dout <= TX_BUF_OUT; nRD <= intRD; oe_n <= intOE_n; nWR <= intWR; --debug outputs dbg_nRXF <= nRXF; dbg_TXE <= nTXE; END behaviour;  

 

This isnt the top level of the heirarchy but I'm pretty sure its where the problem lies.
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
1,139 Views

First you need to know if it is 'X' or 'U'. When you have a vector with X or U 's in it, Modelsim will sometimes replace the vector value by 'X'. Looking at the individual bits should tell you which one of those two it is. 

'U' means uninitialized. All signals start in this state, and if you forget to initialize some vectors to a value, they will be in that state. 

'X' means unknown. It usually has two possible causes:[list][*]you are trying to drive the signals from two places, one with '0' and one with '1'[*]you are doing a logical operation with at least one of the input signals in the 'U', 'X', or 'Z' state[/list] 

I think you should first give an initial value to all your signals. This ensures that you start in a good state. If then you still have 'X', it means that you are either driving the same signal from two places, or that you are reading a signal while it is in high impedance state ('Z'). I think that the latter is what is happening in your case, there is a one cycle delay between ft_din and rx_buf_in, so when you put rx_buf_re to 1 you are in fact putting in the FIFO the previous value of ft_din, which is in a high impedance state for at least one cycle.
0 Kudos
Altera_Forum
Honored Contributor II
1,139 Views

 

--- Quote Start ---  

First you need to know if it is 'X' or 'U'. When you have a vector with X or U 's in it, Modelsim will sometimes replace the vector value by 'X'. Looking at the individual bits should tell you which one of those two it is. 

'U' means uninitialized. All signals start in this state, and if you forget to initialize some vectors to a value, they will be in that state. 

 

 

'X' means unknown. It usually has two possible causes: 

  • you are trying to drive the signals from two places, one with '0' and one with '1' 

  • you are doing a logical operation with at least one of the input signals in the 'U', 'X', or 'Z' state 

I think you should first give an initial value to all your signals. This ensures that you start in a good state. If then you still have 'X', it means that you are either driving the same signal from two places, or that you are reading a signal while it is in high impedance state ('Z'). I think that the latter is what is happening in your case, there is a one cycle delay between ft_din and rx_buf_in, so when you put rx_buf_re to 1 you are in fact putting in the FIFO the previous value of ft_din, which is in a high impedance state for at least one cycle. 

--- Quote End ---  

 

 

Hi, and first of all cheers for your help. 

 

I have now delayed my rx_buf_we so that the write from ft_din to the rx_buf_in is one clock cycle later, but it doesn't seem to have done anything for the problem except to shift everything one clock cycle back.  

 

I looked at my simulation to check which of my 'X' values were really X and which were U. 

 

The rx_buf_in signal is just unitialised before it reads data, however the rx_buf_out signal is "XXXXXXXX" then when the rx buffers read enable goes high there is one clock where it stays "XXXXXXXX" then one clock of "UUUUUUUU" before it holds the test data expected. 

 

On my transmit, before the data expected I also get 3 clock cycles of "XXXXXXXX" then one of "UUUUUUUU" before the expected test data is output from the tx buffer. I have a feeling that these bytes have been passed from the rx_buf_out signal though as the tx_buf_in is just uninitialised before having 3 bytes of "XXXXXXXX" one byte of "UUUUUUUU" then the expected data. 

 

If I can sort out the data coming out of the RX buf then I think the bit on the TX_buffer will disappear. 

 

Unfortunately I have very little to no experience of VHDL and FPGAs previous to this, so I'm learning as I go.... I am pretty sure that I am not driving these signals from two places, but have no idea why I am clocking out uninitialised bytes from one side of my FIFO to the other... Any things to look for? or things that may be common practise with FIFOs that I may have missed? 

 

Cheers, 

 

Lee H
0 Kudos
Altera_Forum
Honored Contributor II
1,139 Views

I have had some success.... I managed to remove the 'X' values which I think were produced by trying to pass signals straight away when enabling the reads and writes.... letting a read or write enable go high one clock before I try to move the data got rid of the 'X' values... now I just need to try to get rid of a couple of uninitialised bytes slipping through.... 

 

Cheers again!
0 Kudos
Reply