Forum Discussion
Altera_Forum
Honored Contributor
12 years ago
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Test_FT245 is
port (
clk : in std_logic; -- 50Mhz
reset : in std_logic;
-- FT2232 Bus Signals
usb_data : inout std_logic_vector(7 downto 0);
usb_rd_n : out std_logic;
usb_wr : out std_logic;
usb_rxf_n : in std_logic;
usb_txe_n : in std_logic;
debug_led : out std_logic;
debug_led2 : out std_logic;
debug_led3 : out std_logic
);
end entity Test_FT245;
architecture behavioral of Test_FT245 is
constant CMDDELAY : integer := 10; -- 10*20ns for 50Mhz clock = 200ns
signal Period1uS, Period1mS, Period1S: STD_LOGIC;
signal Period1S_Reg : STD_LOGIC;
signal usb_input : STD_LOGIC_VECTOR (7 DOWNTO 0);
signal usb_output_next: STD_LOGIC_VECTOR (7 DOWNTO 0);
signal usb_output_reg : STD_LOGIC_VECTOR (7 DOWNTO 0);
signal recv_data_reg : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal recv_data_next : STD_LOGIC_VECTOR(7 DOWNTO 0);
signal rd_n_reg : STD_LOGIC; -- Registered RD_N (to be written)
signal rd_n_next : STD_LOGIC; -- Next RD_N (to be registered)
signal wr_reg : STD_LOGIC; -- Registered WR (to be written)
signal wr_next : STD_LOGIC; -- Next WR (to be registered)
signal rxf_reg : STD_LOGIC; -- Status of RX_F flag
signal txe_n_reg : STD_LOGIC; -- Status of TXE_N flag
signal oe_reg : STD_LOGIC; -- For Bi-Di bus (to be written)
signal oe_next : STD_LOGIC; -- For Bi-Di bus (next output enable state - to be registered)
signal delay_reg : integer range 0 to CMDDELAY; -- Delay counter (for start next state)
signal delay_next: integer range 0 to CMDDELAY; -- Delay counter (for start next state)
signal debug_led_reg : STD_LOGIC;
signal debug_led_next : STD_LOGIC;
signal debug_led2_reg : STD_LOGIC;
signal debug_led2_next: STD_LOGIC;
signal debug_led3_reg : STD_LOGIC;
signal debug_led3_next: STD_LOGIC;
-- Build an enumerated type for the state machine
type state_type is (init, idle, reading_prepare, reading_strobe, reading_end, write_prepare, write_strobe, write_end);
-- Register to hold the current state
signal state_now : state_type;
signal state_next : state_type;
begin
PROCESS( reset, clk, Period1uS, Period1mS )
VARIABLE Count : STD_LOGIC_VECTOR(5 DOWNTO 0);
VARIABLE Count1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
VARIABLE Count2 : STD_LOGIC_VECTOR(9 DOWNTO 0);
BEGIN
--Period: 1uS
IF( reset = '0' ) THEN
Count := "000000";
ELSIF( rising_edge(clk)) THEN
IF( Count>"110000" ) THEN Count := "000000"; -- 110000:48 50/50M = 1us
ELSE Count := Count + 1;
END IF;
Period1uS <= Count(5);
END IF;
--Period: 1mS
IF( Period1uS'EVENT AND Period1uS='1' ) THEN
IF( Count1>"1111100110" ) THEN Count1 := "0000000000"; -- 1111100110:998 1000*1us = 1ms
ELSE Count1 := Count1 + 1;
END IF;
Period1mS <= Count1(9);
END IF;
--Period: 1S (1111100110: 998)
IF( Period1mS'EVENT AND Period1mS='1' ) THEN
IF( Count2>"1111100110" ) THEN
Count2 := "0000000000";
ELSE
Count2 := Count2 + 1;
END IF;
Period1S <= Count2(9);
END IF;
END PROCESS;
process (clk, reset)
begin
if (rising_edge(clk)) then
if (reset = '0') then
delay_reg <= 0;
else
if (delay_reg = 0) then
state_now <= state_next;
delay_reg <= delay_next;
else
delay_reg <= delay_reg - 1;
end if;
end if;
end if;
end process;
process (clk)
begin
if (rising_edge(clk)) then
rd_n_reg <= rd_n_next; -- Register RD_N output
wr_reg <= wr_next; -- Register WR output
rxf_reg <= usb_rxf_n; -- Register RXF input
txe_n_reg <= usb_txe_n; -- Register TXE_N input
oe_reg <= oe_next; -- Register Bi-Di OE flag
debug_led_reg <= debug_led_next;
debug_led2_reg <= debug_led2_next;
debug_led3_reg <= debug_led3_next;
usb_output_reg <= usb_output_next;
recv_data_reg <= recv_data_next;
Period1S_Reg <= Period1S;
end if;
end process;
process (clk, reset, state_now)
begin
if (reset = '0') then
rd_n_next <= '1';
wr_next <= '0';
oe_next <= '1'; -- default in output bus
usb_output_next <= (others=>'0');
recv_data_next <= (others=>'0');
delay_next <= 0;
debug_led_next <= '0';
debug_led2_next <= '0';
debug_led3_next <= '0';
state_next <= init;
else
rd_n_next <= rd_n_reg;
wr_next <= wr_reg;
oe_next <= oe_reg;
delay_next <= delay_reg;
state_next <= state_now;
debug_led_next <= debug_led_reg;
debug_led2_next <= debug_led2_reg;
debug_led3_next <= debug_led3_reg;
usb_output_next <= usb_output_reg;
recv_data_next <= recv_data_reg;
if(Period1S_Reg = '1') then
debug_led_next <= not debug_led_reg;
end if;
case state_now is
when init =>
rd_n_next <= '1';
wr_next <= '0';
oe_next <= '1'; -- default in output bus
usb_output_next <= (others=>'0');
delay_next <= 0;
state_next <= idle;
when idle =>
delay_next <= 0;
if(rxf_reg = '0') then
state_next <= reading_prepare;
elsif(Period1S_Reg = '1') then -- Send data every 1 second
state_next <= write_prepare;
end if;
when write_prepare =>
debug_led2_next <= '1';
if(txe_n_reg = '0') then -- wait until TX fifo has space
oe_next <= '1';
--usb_output_next <= "01000001";
usb_output_next <= recv_data_reg;
delay_next <= 0;
state_next <= write_strobe;
end if;
when write_strobe =>
wr_next <= '1';
delay_next <= CMDDELAY;
state_next <= write_end;
when write_end =>
debug_led2_next <= '0';
wr_next <= '0';
delay_next <= CMDDELAY;
state_next <= idle;
when reading_prepare =>
debug_led3_next <= '1';
oe_next <= '0';
delay_next <= 0;
state_next <= reading_strobe;
when reading_strobe =>
rd_n_next <= '0';
delay_next <= CMDDELAY;
state_next <= reading_end;
when reading_end =>
debug_led3_next <= '0';
recv_data_next <= usb_input;
rd_n_next <= '1';
delay_next <= 0;
state_next <= idle;
when others =>
rd_n_next <= rd_n_reg;
wr_next <= wr_reg;
oe_next <= oe_reg;
state_next <= init;
delay_next <= 0;
end case;
end if;
end process;
usb_rd_n <= rd_n_reg;
usb_wr <= wr_reg;
debug_led <= debug_led_reg;
debug_led2 <= debug_led2_reg;
debug_led3 <= usb_rxf_n;
usb_data <= usb_output_reg when oe_reg = '1' else (others => 'Z');
usb_input <= usb_data when oe_reg = '0';
end behavioral;