- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am a newbie in FPGA programming and VHDL, however I did some projects on Altera boards (simple 7 segments, etc). I am using wayengineer.com Cyclone IV board and FT245 breakout board for it. It runs on 50Mhz clock. I did a code that can read a single byte from the FT245 and then it will send it back. Problem is that every 1 second, I want the data - last byte received to be sent back. However, code constantly sends data out. It does read it correctly, so if you type 'a' it will send 'a' all the time and not when PeriodS_Reg = '1'. Debug led that blinks every 1 second, does blink in that interval. If I comment out in idle state elsif(PeriodS='1') and in reading_end I go to writing_prepare state, code correctly echo's back the last read character. So I think this elsif(PeriodS='1') in idle state is the problem since it always goes in it. Do you have any suggestions?Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found out what the problem was. Period1S was high for 1ms, so while in idle state it would send bunch of data out since Period1S = '1' would be satisfied.
I have fixed the problem with the edge detector:
library ieee;
use ieee.std_logic_1164.all;
entity edge_detector is
port (
clk_50mhz : in std_logic;
rst : in std_logic;
din : in std_logic;
change : out std_logic;
rising : out std_logic;
falling : out std_logic
);
end edge_detector;
architecture bhv of edge_detector is
signal din_delayed1 :std_logic;
begin
process(clk_50mhz)
begin
if rising_edge(clk_50mhz) then
if rst = '0' then
din_delayed1 <= '0';
else
din_delayed1 <= din;
end if;
end if;
end process;
change <= (din_delayed1 xor din); --rising or falling edge (0 -> 1 xor 1 -> 0)
rising <= ( (not din_delayed1) and din);
falling <= (din_delayed1 and (not din));
end bhv;
Now in my main code:
signal PeriodRising : STD_LOGIC;
component edge_detector is
port (
clk_50mhz : in std_logic;
rst : in std_logic;
din : in std_logic;
change : out std_logic;
rising : out std_logic;
falling : out std_logic
);
end component;
....
edetect : edge_detector port map
(
rst => reset,
clk_50mhz => clk,
din => Period1mS,
rising => PeriodRising
);
...
when idle =>
delay_next <= 0;
write_cnt_next <= 0;
if(rxf_reg = '0') then
state_next <= reading_prepare;
elsif(PeriodRising = '1') then -- Send data every 1 second
state_next <= write_prepare;
end if;

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page