Altera_Forum
Honored Contributor
15 years agoProblems with "XXXXXXXX" values...
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.