- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am now using the FT2232H usb chip in FT245 Sync Fifo mode. I tried to write some bytes from PC to FPGA and then read them back. But the following code is not working: what I read back is always 0x55, not what I wrote to FPGA. Here is the code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FTDI_Controller is
port(
FTDI_RXF_n : in std_logic;
FTDI_TXE_n : in std_logic;
FTDI_RD_n : out std_logic;
FTDI_WR_n : out std_logic;
FTDI_OE_n : out std_logic;
FTDI_Data : inout std_logic_vector(7 downto 0);
CLK_FTDI : in std_logic
);
end FTDI_Controller;
architecture RTL of FTDI_Controller is
begin
process(CLK_FTDI)
variable rCS: integer range 0 to 2:=0;
variable wCS: integer range 0 to 1:=0;
variable D_Readed: std_logic_vector(7 downto 0):=x"55";
begin
if rising_edge(CLK_FTDI) then
--read operations
if (FTDI_RXF_n = '0') then
FTDI_WR_n <= '1';
wCS:=0;
CASE rCS is
when 0 =>
FTDI_OE_n <= '0';
rCS:=1;
when 1 =>
FTDI_RD_n <= '0';
rCS:=2;
when 2 =>
D_Readed := FTDI_Data;
when others =>
rCS:=0;
end CASE;
else
FTDI_RD_n <= '1';
FTDI_OE_n <= '1';
rCS:=0;
--write operations
if(FTDI_TXE_n ='0') then
CASE wCS is
when 0 =>
FTDI_WR_n <= '0';
wCS:=1;
when 1 =>
FTDI_Data <= D_Readed;
when others =>
wCS:=0;
end CASE;
else
FTDI_WR_n <= '1';
wCS:=0;
end if;
end if;
end if;
end process;
end RTL;
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe D_Readed needs to be a registered signal, not a variable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I believe D_Readed needs to be a registered signal, not a variable. --- Quote End --- I have tried to change D_Readed to a registered signal, but the result is the same. I stuck in this problem for a long time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't drive a bidirectional bus in such a simple manner. You need some logic to determine when to drive the bus and when not to.
Try this. I hope it helps and points you in the right direction.library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FTDI_Controller is
port(
FTDI_RXF_n : in std_logic;
FTDI_TXE_n : in std_logic;
FTDI_RD_n : out std_logic;
FTDI_WR_n : out std_logic;
FTDI_OE_n : out std_logic;
FTDI_Data : inout std_logic_vector(7 downto 0);
CLK_FTDI : in std_logic
);
end FTDI_Controller;
architecture RTL of FTDI_Controller is
signal D_Readed: std_logic_vector(7 downto 0);
signal drive_bus: std_logic; -- Use this to determine control drive of the 'FTDI_Data' bus
begin
process(CLK_FTDI)
variable rCS: integer range 0 to 2:=0;
variable wCS: integer range 0 to 1:=0;
begin
if rising_edge(CLK_FTDI) then
drive_bus <= '0'; -- Ensure the bus isnt driven when it shouldn't be
--read operations
if (FTDI_RXF_n = '0') then
FTDI_WR_n <= '1';
wCS:=0;
CASE rCS is
when 0 =>
FTDI_OE_n <= '0';
rCS:=1;
when 1 =>
FTDI_RD_n <= '0';
rCS:=2;
when 2 =>
D_Readed <= FTDI_Data;
when others =>
rCS:=0;
end CASE;
else
FTDI_RD_n <= '1';
FTDI_OE_n <= '1';
rCS:=0;
--write operations
if(FTDI_TXE_n ='0') then
CASE wCS is
when 0 =>
FTDI_WR_n <= '0';
drive_bus <= '1'; -- You're writing, so drive the bus...
wCS:=1;
when 1 =>
drive_bus <= '0'; -- ... for a bit. Then stop.
when others =>
wCS:=0;
end CASE;
else
FTDI_WR_n <= '1';
wCS:=0;
end if;
end if;
end if;
end process;
-- Control the data being driven onto the FTDI_Data bus here:
FTDI_Data <= D_Readed when drive_bus = '1' else (others => 'Z');
end RTL;
Cheers, Alex
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- You can't drive a bidirectional bus in such a simple manner. You need some logic to determine when to drive the bus and when not to. Try this. I hope it helps and points you in the right direction.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FTDI_Controller is
port(
FTDI_RXF_n : in std_logic;
FTDI_TXE_n : in std_logic;
FTDI_RD_n : out std_logic;
FTDI_WR_n : out std_logic;
FTDI_OE_n : out std_logic;
FTDI_Data : inout std_logic_vector(7 downto 0);
CLK_FTDI : in std_logic
);
end FTDI_Controller;
architecture RTL of FTDI_Controller is
signal D_Readed: std_logic_vector(7 downto 0);
signal drive_bus: std_logic; -- Use this to determine control drive of the 'FTDI_Data' bus
begin
process(CLK_FTDI)
variable rCS: integer range 0 to 2:=0;
variable wCS: integer range 0 to 1:=0;
begin
if rising_edge(CLK_FTDI) then
drive_bus <= '0'; -- Ensure the bus isnt driven when it shouldn't be
--read operations
if (FTDI_RXF_n = '0') then
FTDI_WR_n <= '1';
wCS:=0;
CASE rCS is
when 0 =>
FTDI_OE_n <= '0';
rCS:=1;
when 1 =>
FTDI_RD_n <= '0';
rCS:=2;
when 2 =>
D_Readed <= FTDI_Data;
when others =>
rCS:=0;
end CASE;
else
FTDI_RD_n <= '1';
FTDI_OE_n <= '1';
rCS:=0;
--write operations
if(FTDI_TXE_n ='0') then
CASE wCS is
when 0 =>
FTDI_WR_n <= '0';
drive_bus <= '1'; -- You're writing, so drive the bus...
wCS:=1;
when 1 =>
drive_bus <= '0'; -- ... for a bit. Then stop.
when others =>
wCS:=0;
end CASE;
else
FTDI_WR_n <= '1';
wCS:=0;
end if;
end if;
end if;
end process;
-- Control the data being driven onto the FTDI_Data bus here:
FTDI_Data <= D_Readed when drive_bus = '1' else (others => 'Z');
end RTL;
Cheers, Alex --- Quote End --- Finally I got it working with your tips. Thanks so much, Alex. :)

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