Hi rbugalho,
I have couple of questions about data recovery that you proposed according to xapp224.
I have downloaded the code and tried to make smth usefull of it. Here are my questions:
1) I used the "more pipedlined" version, it's supposed to be "fast". When use more pipelined version and when normal ?
2) There are special attributes for flip flops:
attribute RLOC : string ;
attribute IOB : string ;
attribute RLOC of ff_a0 : label is "X0Y0";
attribute IOB of ff_a0 : label is "FALSE";
attribute RLOC of ff_a1 : label is "X0Y0";
attribute RLOC of ff_a2 : label is "X3Y1";
attribute RLOC of ff_a3 : label is "X3Y1";
Should i do anything similiar with altera's flip flops?
3) This xapp224 application note says that delay from input pin to flip flops must be almost equal. This is easily achieved by giving a MAXSKEW parameter of 500 ps for example. Is it really that essential ? how to do that in TimeQuest sdc. And also MAXDELAY parameter of 1.0ns for each net.
4) I'm using data_recovery_virtex2_fast.vhd, it's component is :
component data_recovery_virtex2_fast port (
clk : in std_logic;
clk90 : in std_logic;
data : in std_logic;
rst : in std_logic;
sdata : out std_logic_vector(1 downto 0) ;
dv : out std_logic_vector(1 downto 0)) ;
end component;
I will use that component in data recovery, i have changed in it, all xilinx flip flops
ff_a0 : fdc port map(d => data, c => clk, clr => rst, q => az(0));
...
...
to altera's DFF as:
ff_a0 : DFF port map(d => data, clk => clk, clrn => rst,prn => '1', q => az(0));
5) So far my code was:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
entity nrzi_in_data_to_fifo is
port(
clock_recovered : in std_logic; -- 125 MHz
data_recovered : in std_logic;
wrreq_to_nrzi_in_fifo : out std_logic; -- drivers wrreq of fifo
data_to_nrzi_in_fifo : out std_logic_vector(3 downto 0); -- data from the decoder - latched with 25 mhz derived clock
shift_register : out std_logic_vector(14 DOWNTO 0);
test_channel_counter : out integer range 0 to 2560
);
end nrzi_in_data_to_fifo;
architecture arch of nrzi_in_data_to_fifo is
signal synchronized : std_logic;
signal nrzi_in_shift_register : std_logic_vector(14 DOWNTO 0);
signal fifo_wrreq : std_logic;
signal channel_counter : natural := 2700;
signal data_counter : integer range 0 to 7;
signal data_decoded : std_logic_vector(3 downto 0);
begin
shift_register <= nrzi_in_shift_register;
test_channel_counter <= channel_counter;
wrreq_to_nrzi_in_fifo <= fifo_wrreq;
data_to_nrzi_in_fifo <= data_decoded;
shift_register_process : process (clock_recovered)
begin
if rising_edge(clock_recovered) then
nrzi_in_shift_register <= nrzi_in_shift_register(13 downto 0) & data_recovered;
end if;
end process shift_register_process;
sync_detect : process (nrzi_in_shift_register)
begin
if (( nrzi_in_shift_register(14 downto 5) = "1100010001") and (nrzi_in_shift_register(4 downto 0) /= "11000")) THEN
synchronized <= '1';
else
synchronized <= '0';
end if;
end process sync_detect;
data_counter_process : process (clock_recovered, synchronized)
begin
if rising_edge(clock_recovered) then
if data_counter = 4 or synchronized = '1' then
data_counter <= 0;
else
data_counter <= data_counter + 1;
end if;
end if;
end process data_counter_process;
channel_counter_process : process (clock_recovered, synchronized)
begin
if rising_edge(clock_recovered) then
if synchronized = '1' then--or channel_counter = 2555 then
channel_counter <= 0;
else
channel_counter <= channel_counter + 1;
end if;
end if;
end process channel_counter_process;
nrzi_in_fifo_wrreq_gen : process(data_counter, channel_counter, synchronized)
begin
if (data_counter = 4 and channel_counter < 2555) or synchronized = '1' then
fifo_wrreq <= '1';
else
fifo_wrreq <= '0';
end if;
end process nrzi_in_fifo_wrreq_gen;
-- 5b/4b decoding
with nrzi_in_shift_register(4 downto 0) select
data_decoded <= "0000" when "11110",
"0001" when "01001",
"0010" when "10100",
"0011" when "10101",
"0100" when "01010",
"0101" when "01011",
"0110" when "01110",
"0111" when "01111",
"1000" when "10010",
"1001" when "10011",
"1010" when "10110",
"1011" when "10111",
"1100" when "11010",
"1101" when "11011",
"1110" when "11100",
"1111" when "11101",
"0000" when others;
end architecture arch;
I was simply waiting for the synchronization flag - and then generating wrreq fifo ticks with data_counter (mod 5 counter), and also using the channel counter to constrain wrreq flags only to channel.
6) This was with the earlier method of data recovery. To use the new method i changed quickly:
data_recovery_module : data_recovery port map (
clk => clk,
clk90 => clk90,
data => nrzi_data,
rst => '1',
sdata => data_recovered,
dv => data_valid
);
...
...
shift_register_process : process (clk, synchronized)
begin
if rising_edge(clk) then
if data_counter = 4 or synchronized = '1' then
data_counter <= 0;
else
case data_valid is
when "00" =>
nrzi_in_shift_register <= nrzi_in_shift_register;
data_counter <= data_counter;
when "01" =>
nrzi_in_shift_register <= nrzi_in_shift_register(13 downto 0) & data_recovered(0);
data_counter <= data_counter + 1;
when "10" =>
nrzi_in_shift_register <= nrzi_in_shift_register(13 downto 0) & data_recovered(1);
data_counter <= data_counter + 1;
when "11" =>
nrzi_in_shift_register <= nrzi_in_shift_register(12 downto 0) & data_recovered(1) & data_recovered(0);
data_counter <= data_counter + 2;
end case;
end if;
end if;
end process shift_register_process;
Of course in simulation it doesnt work :) - i get no wrreq pulses or synchronization.
I suppose that i will have to adjust the rest of the code, but i suppose it's a good direction ?
Anything else i should think about ?
Best regards
madness