- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page