– CDC (32bits x 368.64MHz -> 64bit x 184.32MHz) – write clock domain begin 368.64MHz
-- write valid for double RAM
process (CLK)
begin
if rising_edge(CLK) then
if IQ_TICK = '1' then
wvld <= "1" ;
else
wvld <= not wvld;
end if;
if wvld = "1" then
wdata(0) <= cdc_zeros0 & cdc_rb_start & cdc_rb_last & cdc_rb_tick & cdc_rb_valid & cdc_rb_data_i & cdc_rb_data_q;
else
wdata(1) <= cdc_zeros1 & cdc_rb_start & cdc_rb_last & cdc_rb_tick & cdc_rb_valid & cdc_rb_data_i & cdc_rb_data_q;
end if;
end if;
end process;
-- write address generation
process (CLK)
begin
if rising_edge(CLK) then
if hovs_wcnt = W_HOVS-1 then
hovs_wcnt <= (others => '0');
if (waddr = 5) then
waddr <= (others => '0');
else
waddr <= waddr + 1;
end if; -- write address accumulation register
else
hovs_wcnt <= hovs_wcnt + '1'; -- write address hovs accumulation register
end if;
end if;
end process;
-- wsync for avoiding w/r address collision
process (CLK)
begin
if rising_edge(CLK) then
if waddr >= 0 and waddr <= 1 then
wsync <= '1';
else
wsync <= '0';
end if;
end if;
end process;
– read clock domain begin 184.32MHz
-- write address sync signal shift register
process (CLK_CUPE)
begin
if rising_edge(CLK_CUPE) then
wsync_d <= wsync_d(2 downto 0) & wsync;
end if;
end process;
-- resync control
process (CLK_CUPE)
begin
if rising_edge(CLK_CUPE) then
if wsync_d(1) = '1' then
if raddr >= 3 and raddr <= 5 then
resync <= '0'; --normal
else
resync <= '1'; --abnormal, resync
end if;
else
resync <= '0';
end if;
end if;
end process;
-- read address generation
process (CLK_CUPE)
begin
if rising_edge(CLK_CUPE) then
if resync = '1' then
hovs_rcnt <= (others => '0');
raddr <= std_logic_vector(to_unsigned(0, log2(BUFFER_DEPTH)));
elsif hovs_rcnt = R_HOVS-1 then
hovs_rcnt <= (others => '0');
if (raddr = 5) then
raddr <= (others => '0');
else
raddr <= raddr + 1;
end if; -- read address accumulation register
else
hovs_rcnt <= hovs_rcnt + '1'; -- read address hovs accumulation register
end if;
end if;
end process;
-- read valid generation
process (CLK_CUPE)
begin
if rising_edge(CLK_CUPE) then
if hovs_rcnt = R_HOVS-1 then
rvld <= '1'; -- output valid register
else
rvld <= '0';
end if;
end if;
end process;
u_blk_mem_cdc_odd : blk_mem_cdc
port map(
clka => CLK , --: in std_logic;
ena => '1' , --: in std_logic;
wea => wvld , --: in std_logic_vector(0 downto 0);
addra => waddr , --: in std_logic_vector(3 downto 0);
dina => wdata(0) , --: in std_logic_vector(127 downto 0);
clkb => CLK_CUPE , --: in std_logic;
enb => '1' , --: in std_logic;
addrb => raddr , --: in std_logic_vector(3 downto 0);
doutb => rdata(0) --: out std_logic_vector(127 downto 0)
);
u_blk_mem_cdc_even : blk_mem_cdc
port map(
clka => CLK , --: in std_logic;
ena => '1' , --: in std_logic;
wea => wvld , --: in std_logic_vector(0 downto 0);
addra => waddr , --: in std_logic_vector(3 downto 0);
dina => wdata(1) , --: in std_logic_vector(127 downto 0);
clkb => CLK_CUPE , --: in std_logic;
enb => '1' , --: in std_logic;
addrb => raddr , --: in std_logic_vector(3 downto 0);
doutb => rdata(1) --: out std_logic_vector(127 downto 0)
);
-- output singal
process (CLK_CUPE)
begin
if rising_edge(CLK_CUPE) then
RB_START <= rdata(0)(27) ;
RB_LAST <= rdata(1)(26) ;
RB_VALID <= rdata(0)(25) ;
RB_TICK <= rdata(0)(24) ;
RB_DATA_I <= rdata(0)(23 downto 0) ;
RB_DATA_Q <= rdata(1)(23 downto 0) ;
end if;
end process;