Guest
I have implemented the attached FSM code using one process. It seems
to work except that I am getting a 2 cycle clock delay between output
wr_fifo_en being aserted when frame_mrk goes high. The frame_mrk
indicates the beginning of signal which should be reflected in ouput
wr_fifo_data. This results in my fifo write enable, wr_fifo_en being
two clock cycles too late=> one cycle delay from input change to state
change, and the other from state change to output change. This
wouldn't be a problem if the wr_fifo_data output was delayed with
wr_fifo_en by 2 clock cycles so they line up=>shouldn't wr_fifo_data
be delayed w.r.t data because it is registered anyway?
Any ideas what I am doing wrong ?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity RX_FIFO_WR_CONTROL is
Port ( data_clk : in STD_LOGIC;
data:in STD_LOGIC_VECTOR (3 downto 0);
frame_mrk : in STD_LOGIC;
rxdv: in STD_LOGIC;
fifo_full : in STD_LOGIC;
frame_good: in STD_LOGIC;
frame_bad: in STD_LOGIC;
fifo_wr_data: out STD_LOGIC_VECTOR (4 downto 0);
wr_fifo_en : out STD_LOGIC;
rst: in STD_LOGIC;
prog_full_thresh: out std_logic_VECTOR(10 downto 0));
end RX_FIFO_WR_CONTROL;
architecture RTL of RX_FIFO_WR_CONTROL is
type fifo_cntrl_state is
(idle,write_fifo,over_flow,wait_end,read_frame_condition,write_frame_status);
signal state:fifo_cntrl_state;
signal ovr_flow: std_logic;
begin
prog_full_thresh<="11111111110";
process
(data_clk,rst,state,frame_mrk,rxdv,fifo_full,frame_good,frame_bad,data)
begin
if rst='1' then
state<=idle;
ovr_flow<='0';
wr_fifo_en<='0';
fifo_wr_data<="00000";
elsif rising_edge(data_clk) then
case state is
when idle =>
if frame_mrk='1' then
state<=write_fifo;
else
state<=idle;
end if;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<='0';
ovr_flow<='0';
wr_fifo_en<='0';
when write_fifo =>
wr_fifo_en<='1';
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
ovr_flow<='0';
if frame_mrk='0' then
state<= wait_end;
elsif fifo_full='1' then
state<= over_flow;
else
state<=write_fifo;
end if;
when over_flow=>
state<=wait_end;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
ovr_flow<='1';
wr_fifo_en<='0';
when wait_end =>
if rxdv='0' then
state<=read_frame_condition;
else
state<=wait_end;
end if;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
wr_fifo_en<='0';
when read_frame_condition =>
state<=write_frame_status;
wr_fifo_en<='0';
fifo_wr_data(4)<='0';
fifo_wr_data(3)<=ovr_flow;
fifo_wr_data(2)<=frame_good;
fifo_wr_data(1)<=frame_bad;
fifo_wr_data(0)<='0';
when write_frame_status =>
state<=idle;
wr_fifo_en<='1';
ovr_flow<='0';
when others =>
state <= idle;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<='0';
ovr_flow<='0';
wr_fifo_en<='0';
end case;
end if;
end process;
end RTL;
to work except that I am getting a 2 cycle clock delay between output
wr_fifo_en being aserted when frame_mrk goes high. The frame_mrk
indicates the beginning of signal which should be reflected in ouput
wr_fifo_data. This results in my fifo write enable, wr_fifo_en being
two clock cycles too late=> one cycle delay from input change to state
change, and the other from state change to output change. This
wouldn't be a problem if the wr_fifo_data output was delayed with
wr_fifo_en by 2 clock cycles so they line up=>shouldn't wr_fifo_data
be delayed w.r.t data because it is registered anyway?
Any ideas what I am doing wrong ?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity RX_FIFO_WR_CONTROL is
Port ( data_clk : in STD_LOGIC;
data:in STD_LOGIC_VECTOR (3 downto 0);
frame_mrk : in STD_LOGIC;
rxdv: in STD_LOGIC;
fifo_full : in STD_LOGIC;
frame_good: in STD_LOGIC;
frame_bad: in STD_LOGIC;
fifo_wr_data: out STD_LOGIC_VECTOR (4 downto 0);
wr_fifo_en : out STD_LOGIC;
rst: in STD_LOGIC;
prog_full_thresh: out std_logic_VECTOR(10 downto 0));
end RX_FIFO_WR_CONTROL;
architecture RTL of RX_FIFO_WR_CONTROL is
type fifo_cntrl_state is
(idle,write_fifo,over_flow,wait_end,read_frame_condition,write_frame_status);
signal state:fifo_cntrl_state;
signal ovr_flow: std_logic;
begin
prog_full_thresh<="11111111110";
process
(data_clk,rst,state,frame_mrk,rxdv,fifo_full,frame_good,frame_bad,data)
begin
if rst='1' then
state<=idle;
ovr_flow<='0';
wr_fifo_en<='0';
fifo_wr_data<="00000";
elsif rising_edge(data_clk) then
case state is
when idle =>
if frame_mrk='1' then
state<=write_fifo;
else
state<=idle;
end if;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<='0';
ovr_flow<='0';
wr_fifo_en<='0';
when write_fifo =>
wr_fifo_en<='1';
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
ovr_flow<='0';
if frame_mrk='0' then
state<= wait_end;
elsif fifo_full='1' then
state<= over_flow;
else
state<=write_fifo;
end if;
when over_flow=>
state<=wait_end;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
ovr_flow<='1';
wr_fifo_en<='0';
when wait_end =>
if rxdv='0' then
state<=read_frame_condition;
else
state<=wait_end;
end if;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<=frame_mrk;
wr_fifo_en<='0';
when read_frame_condition =>
state<=write_frame_status;
wr_fifo_en<='0';
fifo_wr_data(4)<='0';
fifo_wr_data(3)<=ovr_flow;
fifo_wr_data(2)<=frame_good;
fifo_wr_data(1)<=frame_bad;
fifo_wr_data(0)<='0';
when write_frame_status =>
state<=idle;
wr_fifo_en<='1';
ovr_flow<='0';
when others =>
state <= idle;
fifo_wr_data(3 downto 0)<=data;
fifo_wr_data(4)<='0';
ovr_flow<='0';
wr_fifo_en<='0';
end case;
end if;
end process;
end RTL;