URL
https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk
Subversion Repositories funbase_ip_library
Compare Revisions
- This comparison shows the changes necessary to convert path
/funbase_ip_library
- from Rev 17 to Rev 18
- ↔ Reverse comparison
Rev 17 → Rev 18
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Testbenches/tb_mixed_clk_fifo_v3.vhd
0,0 → 1,229
------------------------------------------------------------------------------- |
-- Title : Testbench for design "mixed_clk_fifo" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_mixed_clk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 14.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_1164.all; |
use work.txt_util.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_mixed_clk_fifo is |
|
end tb_mixed_clk_fifo; |
|
------------------------------------------------------------------------------- |
|
architecture rtl of tb_mixed_clk_fifo is |
|
-- component generics |
-- constant re_freq_g : integer := 1; |
-- constant we_freq_g : integer := 3; |
-- constant Period_re : time := 30 ns; |
-- constant Period_we : time := 10 ns; |
constant re_freq_g : integer := 2; |
constant we_freq_g : integer := 1; |
constant Period_re : time := 14 ns; |
constant Period_we : time := 18 ns; -- HAS TO BE EVEN due to divide |
constant re_faster_c : integer := 1; |
|
constant depth_g : integer := 3; |
constant data_width_g : integer := 4; |
|
-- component ports |
signal clk_re : std_logic; |
signal clk_we : std_logic; |
signal clk_ps_re : std_logic; |
signal clk_ps_we : std_logic; |
signal rst_n : std_logic; |
signal data_to_dut : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_dut : std_logic; |
signal full_from_dut : std_logic; |
signal one_p_from_dut : std_logic; |
signal re_to_dut : std_logic; |
signal data_from_dut : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_dut : std_logic; |
signal one_d_from_dut : std_logic; |
signal data_cnt_r : std_logic_vector(data_width_g-1 downto 0); |
|
-- to create periods of not reading or not writing, |
-- full and empty cases |
constant write_phase_c : integer := 7; |
constant read_phase_c : integer := 6; |
signal read_phase_r : integer; |
signal write_phase_r : integer; |
signal int_re_r : std_logic; |
signal int_we_r : std_logic; |
|
begin -- rtl |
|
-- component instantiation |
DUT : entity work.mixed_clk_fifo |
generic map ( |
re_faster_g => re_faster_c, |
depth_g => depth_g, |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_we => clk_we, |
clk_ps_re => clk_ps_re, |
clk_ps_we => clk_ps_we, |
rst_n => rst_n, |
data_in => data_to_dut, |
we_in => we_to_dut, |
full_out => full_from_dut, |
one_p_out => one_p_from_dut, |
re_in => re_to_dut, |
data_out => data_from_dut, |
empty_out => empty_from_dut, |
one_d_out => one_d_from_dut |
); |
|
we_to_dut <= (not full_from_dut) and int_we_r; |
|
wr : process (clk_we, rst_n) |
begin -- process write |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_dut <= (others => '0'); |
write_phase_r <= 0; |
int_we_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if we_to_dut = '1' then |
if data_to_dut /= data_to_dut'high then |
data_to_dut <= data_to_dut+1; |
else |
data_to_dut <= (others => '0'); |
end if; |
else |
data_to_dut <= data_to_dut; |
end if; |
|
if write_phase_r < write_phase_c then |
write_phase_r <= write_phase_r+1; |
int_we_r <= '1'; |
|
else |
if write_phase_r < write_phase_c*2 then |
int_we_r <= '0'; |
write_phase_r <= write_phase_r+1; |
else |
write_phase_r <= 0; |
end if; |
end if; |
|
end if; |
|
end process wr; |
|
re_to_dut <= not empty_from_dut and int_re_r; |
|
re : process (clk_re, rst_n) |
begin -- process re |
if rst_n = '0' then -- asynchronous reset (active low) |
data_cnt_r <= conv_std_logic_vector(0, data_width_g); |
read_phase_r <= 0; |
int_re_r <= '1'; |
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
|
if re_to_dut = '1' then |
assert data_cnt_r = data_from_dut report "wrong value read: " & str(data_from_dut) & "wait: " & str(data_cnt_r) severity error; |
if data_cnt_r /= data_cnt_r'high then |
data_cnt_r <= data_cnt_r+1; |
else |
data_cnt_r <= (others => '0'); |
end if; |
else |
data_cnt_r <= data_cnt_r; |
end if; |
|
if read_phase_r < read_phase_c then |
int_re_r <= '1'; |
read_phase_r <= read_phase_r+1; |
|
else |
if read_phase_r < read_phase_c*2 then |
int_re_r <= '0'; |
read_phase_r <= read_phase_r+1; |
else |
int_re_r <= '0'; |
read_phase_r <= 0; |
end if; |
end if; |
|
end if; |
end process re; |
|
|
|
-- clock generation |
-- PROC |
CLOCK1 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_re <= clktmp; |
wait for Period_re/2; |
end process CLOCK1; |
|
CLOCK2 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_we <= clktmp; |
wait for Period_we/2; |
end process CLOCK2; |
|
CLOCK3 : process -- generate clock signal for design |
begin |
clk_ps_re <= '1'; |
wait for 2 ns; |
clk_ps_re <= '0'; |
wait for (Period_re -4 ns); |
clk_ps_re <= '1'; |
wait for 2 ns; |
end process CLOCK3; |
|
CLOCK4 : process -- generate clock signal for design |
begin |
clk_ps_we <= '1'; |
wait for 2 ns; |
clk_ps_we <= '0'; |
wait for (Period_we -4 ns); |
clk_ps_we <= '1'; |
wait for 2 ns; |
end process CLOCK4; |
|
-- clk_ps_we <= clk_we; |
-- clk_ps_re <= clk_re; |
|
-- PROC |
RESET : process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*Period_re; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end rtl; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Testbenches/tb_mixed_clk_fifo_v2_fpga.vhd
0,0 → 1,181
------------------------------------------------------------------------------- |
-- Title : Testbench for design "mixed_clk_fifo" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_mixed_clk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 08.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_1164.all; |
use work.txt_util.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_mixed_clk_fifo is |
port ( |
clk_we : in std_logic; |
clk_re : in std_logic; |
clk_ps_re : in std_logic; |
clk_ps_we : in std_logic; |
error_out : out std_logic; |
rst_n : in std_logic |
); |
end tb_mixed_clk_fifo; |
|
------------------------------------------------------------------------------- |
|
architecture rtl of tb_mixed_clk_fifo is |
|
-- component generics |
|
constant depth_g : integer := 3; |
constant data_width_g : integer := 4; |
|
-- component ports |
-- signal clk_re : std_logic; |
-- signal clk_we : std_logic; |
-- signal clk_ps_re : std_logic; |
-- signal clk_ps_we : std_logic; |
-- signal rst_n : std_logic; |
signal data_to_dut : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_dut : std_logic; |
signal full_from_dut : std_logic; |
signal one_p_from_dut : std_logic; |
signal re_to_dut : std_logic; |
signal data_from_dut : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_dut : std_logic; |
signal one_d_from_dut : std_logic; |
signal data_cnt_r : std_logic_vector(data_width_g-1 downto 0); |
|
-- to create periods of not reading or not writing, |
-- full and empty cases |
constant write_phase_c : integer := 7; |
constant read_phase_c : integer := 6; |
signal read_phase_r : integer; |
signal write_phase_r : integer; |
signal int_re_r : std_logic; |
signal int_we_r : std_logic; |
|
begin -- rtl |
|
-- component instantiation |
DUT : entity work.mixed_clk_fifo |
generic map ( |
depth_g => depth_g, |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_we => clk_we, |
clk_ps_re => clk_ps_re, |
clk_ps_we => clk_ps_we, |
rst_n => rst_n, |
data_in => data_to_dut, |
we_in => we_to_dut, |
full_out => full_from_dut, |
one_p_out => one_p_from_dut, |
re_in => re_to_dut, |
data_out => data_from_dut, |
empty_out => empty_from_dut, |
one_d_out => one_d_from_dut |
); |
|
we_to_dut <= (not full_from_dut) and int_we_r; |
|
wr : process (clk_we, rst_n) |
begin -- process write |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_dut <= (others => '0'); |
-- we_to_dut <= '0'; |
write_phase_r <= 0; |
int_we_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if we_to_dut = '1' then |
if data_to_dut /= data_to_dut'high then |
data_to_dut <= data_to_dut+1; |
else |
data_to_dut <= (others => '0'); |
end if; |
else |
-- we_to_dut <= '1'; |
data_to_dut <= data_to_dut; |
end if; |
|
if write_phase_r < write_phase_c then |
write_phase_r <= write_phase_r+1; |
int_we_r <= '1'; |
|
else |
if write_phase_r < write_phase_c*2 then |
int_we_r <= '0'; |
-- we_to_dut <= '0'; |
write_phase_r <= write_phase_r+1; |
else |
write_phase_r <= 0; |
-- we_to_dut <= '1'; |
end if; |
end if; |
|
end if; |
|
end process wr; |
|
re_to_dut <= not empty_from_dut and int_re_r; |
|
re : process (clk_re, rst_n) |
begin -- process re |
if rst_n = '0' then -- asynchronous reset (active low) |
-- re_to_dut <= '0'; |
data_cnt_r <= conv_std_logic_vector(0, data_width_g); |
read_phase_r <= 0; |
int_re_r <= '1'; |
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
error_out <= '0'; |
if re_to_dut = '1' then |
if data_cnt_r /= data_from_dut then |
error_out <= '1'; |
assert data_cnt_r = data_from_dut report "wrong value read: " & str(data_from_dut) & "wait: " & str(data_cnt_r) severity error; |
end if; |
if data_cnt_r /= data_cnt_r'high then |
data_cnt_r <= data_cnt_r+1; |
else |
data_cnt_r <= (others => '0'); |
end if; |
else |
data_cnt_r <= data_cnt_r; |
end if; |
|
if read_phase_r < read_phase_c then |
int_re_r <= '1'; |
read_phase_r <= read_phase_r+1; |
|
else |
if read_phase_r < read_phase_c*2 then |
int_re_r <= '0'; |
read_phase_r <= read_phase_r+1; |
else |
int_re_r <= '0'; |
read_phase_r <= 0; |
end if; |
end if; |
|
end if; |
end process re; |
|
|
end rtl; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Testbenches/tb_multiclk_fifo.vhd
0,0 → 1,231
------------------------------------------------------------------------------- |
-- Title : Testbench for design "multiclk_fifo" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_multiclk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 16.12.2005 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_1164.all; |
use work.txt_util.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_multiclk_fifo is |
|
end tb_multiclk_fifo; |
|
------------------------------------------------------------------------------- |
|
architecture rtl of tb_multiclk_fifo is |
|
component multiclk_fifo |
generic ( |
re_freq_g : integer; |
we_freq_g : integer; |
depth_g : integer; |
data_width_g : integer); |
port ( |
clk_re : in std_logic; |
clk_we : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
-- component generics |
constant re_freq_g : integer := 3; |
constant we_freq_g : integer := 1; |
constant Period_re : time := 10 ns; |
constant Period_we : time := 30 ns; |
-- constant re_freq_g : integer := 1; |
-- constant we_freq_g : integer := 3; |
-- constant Period_re : time := 30 ns; |
-- constant Period_we : time := 10 ns; |
constant re_freq_g : integer := 1; |
constant we_freq_g : integer := 1; |
constant Period_re : time := 10 ns; |
constant Period_we : time := 10 ns; |
|
constant depth_g : integer := 3; |
constant data_width_g : integer := 4; |
|
-- component ports |
signal clk_re : std_logic; |
signal clk_we : std_logic; |
signal rst_n : std_logic; |
signal data_to_dut : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_dut : std_logic; |
signal full_from_dut : std_logic; |
signal one_p_from_dut : std_logic; |
signal re_to_dut : std_logic; |
signal data_from_dut : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_dut : std_logic; |
signal one_d_from_dut : std_logic; |
signal data_cnt_r : std_logic_vector(data_width_g-1 downto 0); |
|
-- to create periods of not reading or not writing, |
-- full and empty cases |
constant write_phase_c : integer := 7; |
constant read_phase_c : integer := 6; |
signal read_phase_r : integer; |
signal write_phase_r : integer; |
signal int_re_r : std_logic; |
signal int_we_r : std_logic; |
|
begin -- rtl |
|
-- component instantiation |
DUT : multiclk_fifo |
generic map ( |
re_freq_g => re_freq_g, |
we_freq_g => we_freq_g, |
depth_g => depth_g, |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_we => clk_we, |
rst_n => rst_n, |
data_in => data_to_dut, |
we_in => we_to_dut, |
full_out => full_from_dut, |
one_p_out => one_p_from_dut, |
re_in => re_to_dut, |
data_out => data_from_dut, |
empty_out => empty_from_dut, |
one_d_out => one_d_from_dut |
); |
|
we_to_dut <= (not full_from_dut) and int_we_r; |
|
wr : process (clk_we, rst_n) |
begin -- process write |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_dut <= (others => '0'); |
-- we_to_dut <= '0'; |
write_phase_r <= 0; |
int_we_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if we_to_dut = '1' then |
if data_to_dut /= data_to_dut'high then |
data_to_dut <= data_to_dut+1; |
else |
data_to_dut <= (others => '0'); |
end if; |
else |
-- we_to_dut <= '1'; |
data_to_dut <= data_to_dut; |
end if; |
|
if write_phase_r < write_phase_c then |
write_phase_r <= write_phase_r+1; |
int_we_r <= '1'; |
|
else |
if write_phase_r < write_phase_c*2 then |
int_we_r <= '0'; |
-- we_to_dut <= '0'; |
write_phase_r <= write_phase_r+1; |
else |
write_phase_r <= 0; |
-- we_to_dut <= '1'; |
end if; |
end if; |
|
end if; |
|
end process wr; |
|
re_to_dut <= not empty_from_dut and int_re_r; |
|
re : process (clk_re, rst_n) |
begin -- process re |
if rst_n = '0' then -- asynchronous reset (active low) |
-- re_to_dut <= '0'; |
data_cnt_r <= conv_std_logic_vector(0, data_width_g); |
read_phase_r <= 0; |
int_re_r <= '1'; |
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
|
if re_to_dut = '1' then |
assert data_cnt_r = data_from_dut report "wrong value read: " & str(data_from_dut) & "wait: " & str(data_cnt_r) severity error; |
if data_cnt_r /= data_cnt_r'high then |
data_cnt_r <= data_cnt_r+1; |
else |
data_cnt_r <= (others => '0'); |
end if; |
else |
data_cnt_r <= data_cnt_r; |
end if; |
|
if read_phase_r < read_phase_c then |
int_re_r <= '1'; |
read_phase_r <= read_phase_r+1; |
|
else |
if read_phase_r < read_phase_c*2 then |
int_re_r <= '0'; |
read_phase_r <= read_phase_r+1; |
else |
int_re_r <= '0'; |
read_phase_r <= 0; |
end if; |
end if; |
|
end if; |
end process re; |
|
|
|
-- clock generation |
-- PROC |
CLOCK1 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_re <= clktmp; |
wait for Period_re/2; |
end process CLOCK1; |
|
CLOCK2 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_we <= clktmp; |
wait for Period_we/2; |
end process CLOCK2; |
|
-- PROC |
RESET : process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*Period_re; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end rtl; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Testbenches/tb_mixed_clk_fifo_v3_fpga.vhd
0,0 → 1,179
------------------------------------------------------------------------------- |
-- Title : Testbench for design "mixed_clk_fifo" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_mixed_clk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 14.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_1164.all; |
use work.txt_util.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_mixed_clk_fifo is |
generic ( |
re_faster_g : integer := 0); -- 0 we faster, 1 re |
port ( |
clk_we : in std_logic; |
clk_re : in std_logic; |
clk_ps_re : in std_logic; |
clk_ps_we : in std_logic; |
error_out : out std_logic; |
rst_n : in std_logic |
); |
end tb_mixed_clk_fifo; |
|
------------------------------------------------------------------------------- |
|
architecture rtl of tb_mixed_clk_fifo is |
|
-- component generics |
|
constant depth_g : integer := 3; |
constant data_width_g : integer := 4; |
|
-- component ports |
-- signal clk_re : std_logic; |
-- signal clk_we : std_logic; |
-- signal clk_ps_re : std_logic; |
-- signal clk_ps_we : std_logic; |
-- signal rst_n : std_logic; |
signal data_to_dut : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_dut : std_logic; |
signal full_from_dut : std_logic; |
signal one_p_from_dut : std_logic; |
signal re_to_dut : std_logic; |
signal data_from_dut : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_dut : std_logic; |
signal one_d_from_dut : std_logic; |
signal data_cnt_r : std_logic_vector(data_width_g-1 downto 0); |
|
-- to create periods of not reading or not writing, |
-- full and empty cases |
constant write_phase_c : integer := 7; |
constant read_phase_c : integer := 6; |
signal read_phase_r : integer; |
signal write_phase_r : integer; |
signal int_re_r : std_logic; |
signal int_we_r : std_logic; |
|
begin -- rtl |
|
-- component instantiation |
DUT : entity work.mixed_clk_fifo |
generic map ( |
re_faster_g => re_faster_g, |
depth_g => depth_g, |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_we => clk_we, |
clk_ps_re => clk_ps_re, |
clk_ps_we => clk_ps_we, |
rst_n => rst_n, |
data_in => data_to_dut, |
we_in => we_to_dut, |
full_out => full_from_dut, |
one_p_out => one_p_from_dut, |
re_in => re_to_dut, |
data_out => data_from_dut, |
empty_out => empty_from_dut, |
one_d_out => one_d_from_dut |
); |
|
we_to_dut <= (not full_from_dut) and int_we_r; |
|
wr : process (clk_we, rst_n) |
begin -- process write |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_dut <= (others => '0'); |
write_phase_r <= 0; |
int_we_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if we_to_dut = '1' then |
if data_to_dut /= data_to_dut'high then |
data_to_dut <= data_to_dut+1; |
else |
data_to_dut <= (others => '0'); |
end if; |
else |
data_to_dut <= data_to_dut; |
end if; |
|
if write_phase_r < write_phase_c then |
write_phase_r <= write_phase_r+1; |
int_we_r <= '1'; |
|
else |
if write_phase_r < write_phase_c*2 then |
int_we_r <= '0'; |
write_phase_r <= write_phase_r+1; |
else |
write_phase_r <= 0; |
end if; |
end if; |
|
end if; |
|
end process wr; |
|
re_to_dut <= not empty_from_dut and int_re_r; |
|
re : process (clk_re, rst_n) |
begin -- process re |
if rst_n = '0' then -- asynchronous reset (active low) |
data_cnt_r <= conv_std_logic_vector(0, data_width_g); |
read_phase_r <= 0; |
int_re_r <= '1'; |
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
error_out <= '0'; |
if re_to_dut = '1' then |
if data_cnt_r /= data_from_dut then |
error_out <= '1'; |
assert data_cnt_r = data_from_dut report "wrong value read: " & str(data_from_dut) & "wait: " & str(data_cnt_r) severity error; |
end if; |
if data_cnt_r /= data_cnt_r'high then |
data_cnt_r <= data_cnt_r+1; |
else |
data_cnt_r <= (others => '0'); |
end if; |
else |
data_cnt_r <= data_cnt_r; |
end if; |
|
if read_phase_r < read_phase_c then |
int_re_r <= '1'; |
read_phase_r <= read_phase_r+1; |
|
else |
if read_phase_r < read_phase_c*2 then |
int_re_r <= '0'; |
read_phase_r <= read_phase_r+1; |
else |
int_re_r <= '0'; |
read_phase_r <= 0; |
end if; |
end if; |
|
end if; |
end process re; |
|
|
end rtl; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Testbenches/tb_mixed_clk_fifo_v2.vhd
0,0 → 1,227
------------------------------------------------------------------------------- |
-- Title : Testbench for design "mixed_clk_fifo" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_mixed_clk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 14.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_1164.all; |
use work.txt_util.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_mixed_clk_fifo is |
|
end tb_mixed_clk_fifo; |
|
------------------------------------------------------------------------------- |
|
architecture rtl of tb_mixed_clk_fifo is |
|
-- component generics |
-- constant re_freq_g : integer := 1; |
-- constant we_freq_g : integer := 3; |
-- constant Period_re : time := 30 ns; |
-- constant Period_we : time := 10 ns; |
constant re_freq_g : integer := 2; |
constant we_freq_g : integer := 1; |
constant Period_re : time := 20 ns; |
constant Period_we : time := 180 ns; -- HAS TO BE EVEN due to divide |
|
constant depth_g : integer := 3; |
constant data_width_g : integer := 4; |
|
-- component ports |
signal clk_re : std_logic; |
signal clk_we : std_logic; |
signal clk_ps_re : std_logic; |
signal clk_ps_we : std_logic; |
signal rst_n : std_logic; |
signal data_to_dut : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_dut : std_logic; |
signal full_from_dut : std_logic; |
signal one_p_from_dut : std_logic; |
signal re_to_dut : std_logic; |
signal data_from_dut : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_dut : std_logic; |
signal one_d_from_dut : std_logic; |
signal data_cnt_r : std_logic_vector(data_width_g-1 downto 0); |
|
-- to create periods of not reading or not writing, |
-- full and empty cases |
constant write_phase_c : integer := 7; |
constant read_phase_c : integer := 6; |
signal read_phase_r : integer; |
signal write_phase_r : integer; |
signal int_re_r : std_logic; |
signal int_we_r : std_logic; |
|
begin -- rtl |
|
-- component instantiation |
DUT : entity work.mixed_clk_fifo |
generic map ( |
depth_g => depth_g, |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_we => clk_we, |
clk_ps_re => clk_ps_re, |
clk_ps_we => clk_ps_we, |
rst_n => rst_n, |
data_in => data_to_dut, |
we_in => we_to_dut, |
full_out => full_from_dut, |
one_p_out => one_p_from_dut, |
re_in => re_to_dut, |
data_out => data_from_dut, |
empty_out => empty_from_dut, |
one_d_out => one_d_from_dut |
); |
|
we_to_dut <= (not full_from_dut) and int_we_r; |
|
wr : process (clk_we, rst_n) |
begin -- process write |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_dut <= (others => '0'); |
write_phase_r <= 0; |
int_we_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if we_to_dut = '1' then |
if data_to_dut /= data_to_dut'high then |
data_to_dut <= data_to_dut+1; |
else |
data_to_dut <= (others => '0'); |
end if; |
else |
data_to_dut <= data_to_dut; |
end if; |
|
if write_phase_r < write_phase_c then |
write_phase_r <= write_phase_r+1; |
int_we_r <= '1'; |
|
else |
if write_phase_r < write_phase_c*2 then |
int_we_r <= '0'; |
write_phase_r <= write_phase_r+1; |
else |
write_phase_r <= 0; |
end if; |
end if; |
|
end if; |
|
end process wr; |
|
re_to_dut <= not empty_from_dut and int_re_r; |
|
re : process (clk_re, rst_n) |
begin -- process re |
if rst_n = '0' then -- asynchronous reset (active low) |
data_cnt_r <= conv_std_logic_vector(0, data_width_g); |
read_phase_r <= 0; |
int_re_r <= '1'; |
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
|
if re_to_dut = '1' then |
assert data_cnt_r = data_from_dut report "wrong value read: " & str(data_from_dut) & "wait: " & str(data_cnt_r) severity error; |
if data_cnt_r /= data_cnt_r'high then |
data_cnt_r <= data_cnt_r+1; |
else |
data_cnt_r <= (others => '0'); |
end if; |
else |
data_cnt_r <= data_cnt_r; |
end if; |
|
if read_phase_r < read_phase_c then |
int_re_r <= '1'; |
read_phase_r <= read_phase_r+1; |
|
else |
if read_phase_r < read_phase_c*2 then |
int_re_r <= '0'; |
read_phase_r <= read_phase_r+1; |
else |
int_re_r <= '0'; |
read_phase_r <= 0; |
end if; |
end if; |
|
end if; |
end process re; |
|
|
|
-- clock generation |
-- PROC |
CLOCK1 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_re <= clktmp; |
wait for Period_re/2; |
end process CLOCK1; |
|
CLOCK2 : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
clktmp := not clktmp; |
clk_we <= clktmp; |
wait for Period_we/2; |
end process CLOCK2; |
|
CLOCK3 : process -- generate clock signal for design |
begin |
clk_ps_re <= '1'; |
wait for 2 ns; |
clk_ps_re <= '0'; |
wait for (Period_re -4 ns); |
clk_ps_re <= '1'; |
wait for 2 ns; |
end process CLOCK3; |
|
CLOCK4 : process -- generate clock signal for design |
begin |
clk_ps_we <= '1'; |
wait for 2 ns; |
clk_ps_we <= '0'; |
wait for (Period_we -4 ns); |
clk_ps_we <= '1'; |
wait for 2 ns; |
end process CLOCK4; |
|
-- clk_ps_we <= clk_we; |
-- clk_ps_re <= clk_re; |
|
-- PROC |
RESET : process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*Period_re; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end rtl; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/multiclk_fifo_v3.vhd
0,0 → 1,229
------------------------------------------------------------------------------- |
-- Title : Multiclock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : multiclk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 02.01.2006 |
-- Description: Synchronous multi-clock FIFO. Note that clock frequencies MUST |
-- be realted (synchronized) in order to avoid metastability. |
-- Clocks that are asynchronous wrt. each other do not work. |
-- |
-- Note! data must be ready in the data in wrt. faster clock when writing! |
-- same applies for re and we |
-- |
-- In this implementation we really utilize both clocks, whch can be a problem |
-- in some systems (routing the another clock). |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity multiclk_fifo is |
|
generic ( |
re_freq_g : integer := 0; -- integer multiple of clk_we |
we_freq_g : integer := 0; -- or vice versa |
depth_g : integer := 0; |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; |
clk_we : in std_logic; |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end multiclk_fifo; |
|
architecture rtl of multiclk_fifo is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
constant re_per_we_c : integer := re_freq_g / we_freq_g; |
constant we_per_re_c : integer := we_freq_g / re_freq_g; |
|
-- no 0 to x-1, cuz otherwise range 0 to -1 is possible |
signal re_cnt_r : integer range 0 to re_per_we_c; |
signal we_cnt_r : integer range 0 to we_per_re_c; |
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal re_to_fifo : std_logic; |
signal data_from_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_fifo : std_logic; |
signal one_d_from_fifo : std_logic; |
signal clk_fifo : std_logic; |
signal slow_r : std_logic; -- frequncy halver for slower clock |
signal slow_was_r : std_logic; |
signal rst_cnt : std_logic; |
signal clk_slow : std_logic; |
begin -- rtl |
|
data_to_fifo <= data_in; |
full_out <= full_from_fifo; |
one_p_out <= one_p_from_fifo; |
data_out <= data_from_fifo; |
empty_out <= empty_from_fifo; |
one_d_out <= one_d_from_fifo; |
|
regular_fifo: fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_fifo, -- this is the difference |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_to_fifo, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
process (clk_slow, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
slow_r <= '0'; |
elsif clk_slow'event and clk_slow = '1' then -- rising clock edge |
slow_r <= not slow_r; |
end if; |
end process; |
|
process (clk_fifo, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
slow_was_r <= '0'; |
elsif clk_fifo'event and clk_fifo = '1' then -- rising clock edge |
slow_was_r <= slow_r; |
end if; |
end process; |
|
nullify: process (slow_r, slow_was_r) |
begin -- process nullify |
rst_cnt <= slow_was_r xor slow_r; |
end process nullify; |
|
re_gt_we : if re_freq_g >= we_freq_g generate |
clk_fifo <= clk_re; |
clk_slow <= clk_we; |
|
re_to_fifo <= re_in; |
|
equal : if re_per_we_c = 1 generate |
we_to_fifo <= we_in; |
end generate equal; |
|
greater : if re_per_we_c > 1 generate |
-- re clk is faster than we |
|
gen_we : process (re_cnt_r, we_in, rst_cnt) |
begin -- process gen_we |
if we_in = '1' then |
if re_cnt_r = re_per_we_c-2 and rst_cnt = '0' then |
we_to_fifo <= '1'; |
else |
we_to_fifo <= '0'; |
end if; |
else |
we_to_fifo <= '0'; |
end if; |
end process gen_we; |
|
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
re_cnt_r <= 0; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
if rst_cnt = '1' then |
re_cnt_r <= 0; |
else |
re_cnt_r <= re_cnt_r+1; |
end if; |
|
end if; |
end process; |
|
|
end generate greater; |
|
|
end generate re_gt_we; |
|
we_gt_re : if re_freq_g < we_freq_g generate |
|
clk_fifo <= clk_we; |
clk_slow <= clk_re; |
we_to_fifo <= we_in; |
|
-- we clk is faster than re |
gen_we : process (we_cnt_r, re_in, rst_cnt) |
begin -- process gen_we |
if re_in = '1' then |
if we_cnt_r = we_per_re_c-2 and rst_cnt = '0' then |
re_to_fifo <= '1'; |
else |
re_to_fifo <= '0'; |
end if; |
else |
re_to_fifo <= '0'; |
end if; |
end process gen_we; |
|
process (clk_we, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
we_cnt_r <= 0; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if rst_cnt = '1' then |
we_cnt_r <= 0; |
else |
we_cnt_r <= we_cnt_r+1; |
end if; |
|
end if; |
end process; |
|
|
end generate we_gt_re; |
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/multiclk_fifo_v4.vhd
0,0 → 1,256
------------------------------------------------------------------------------- |
-- Title : Multiclock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : multiclk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 16.08.2006 |
-- Description: Synchronous multi-clock FIFO. Note that clock frequencies MUST |
-- be related (synchronized) in order to avoid metastability. |
-- Clocks that are asynchronous wrt. each other do not work. |
-- |
-- Note! data must be ready in the data in wrt. faster clock when writing! |
-- same applies for re and we |
-- |
-- This one uses slow full and empty for the corresponding slower clock (i.e. |
-- reader is slower -> empty is delayed). eg. empty transition from 1->0 is |
-- delayed. |
-- |
-- In this implementation we really utilize both clocks, whch can be a problem |
-- in some systems (routing the another clock). |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity multiclk_fifo is |
|
generic ( |
re_freq_g : integer := 1; -- integer multiple of clk_we |
we_freq_g : integer := 1; -- or vice versa |
depth_g : integer := 0; |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; |
clk_we : in std_logic; |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end multiclk_fifo; |
|
architecture rtl of multiclk_fifo is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
constant re_per_we_c : integer := re_freq_g / we_freq_g; |
constant we_per_re_c : integer := we_freq_g / re_freq_g; |
|
-- no 0 to x-1, cuz otherwise range 0 to -1 is possible |
signal re_cnt_r : integer range 0 to re_per_we_c; |
signal we_cnt_r : integer range 0 to we_per_re_c; |
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal re_to_fifo : std_logic; |
signal data_from_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_fifo : std_logic; |
signal one_d_from_fifo : std_logic; |
signal empty_out_r : std_logic; |
signal full_out_r : std_logic; |
|
signal clk_fifo : std_logic; |
signal slow_r : std_logic; -- frequncy halver for slower clock |
signal slow_was_r : std_logic; |
signal rst_cnt : std_logic; |
signal clk_slow : std_logic; |
begin -- rtl |
|
data_to_fifo <= data_in; |
full_out <= full_out_r; --from_fifo; |
one_p_out <= one_p_from_fifo; |
data_out <= data_from_fifo; |
empty_out <= empty_out_r; --empty_from_fifo; |
one_d_out <= one_d_from_fifo; |
|
regular_fifo: fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_fifo, -- this is the difference |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_to_fifo, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
process (clk_slow, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
slow_r <= '0'; |
elsif clk_slow'event and clk_slow = '1' then -- rising clock edge |
slow_r <= not slow_r; |
end if; |
end process; |
|
process (clk_fifo, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
slow_was_r <= '0'; |
elsif clk_fifo'event and clk_fifo = '1' then -- rising clock edge |
slow_was_r <= slow_r; |
end if; |
end process; |
|
nullify: process (slow_r, slow_was_r) |
begin -- process nullify |
rst_cnt <= slow_was_r xor slow_r; |
end process nullify; |
|
re_gt_we : if re_freq_g >= we_freq_g generate |
clk_fifo <= clk_re; |
clk_slow <= clk_we; |
|
re_to_fifo <= re_in; |
|
equal : if re_per_we_c = 1 generate |
we_to_fifo <= we_in; |
empty_out_r <= empty_from_fifo; |
full_out_r <= full_from_fifo; |
end generate equal; |
|
greater : if re_per_we_c > 1 generate |
-- re clk is faster than we |
|
gen_we : process (re_cnt_r, we_in, rst_cnt) |
begin -- process gen_we |
if we_in = '1' then |
if re_cnt_r = re_per_we_c-2 and rst_cnt = '0' then |
we_to_fifo <= '1'; |
else |
we_to_fifo <= '0'; |
end if; |
else |
we_to_fifo <= '0'; |
end if; |
end process gen_we; |
|
empty_out_r <= empty_from_fifo; |
|
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
re_cnt_r <= 0; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
if rst_cnt = '1' then |
re_cnt_r <= 0; |
else |
re_cnt_r <= re_cnt_r+1; |
end if; |
|
if re_cnt_r = 0 then |
full_out_r <= full_from_fifo; |
else |
full_out_r <= full_out_r; |
end if; |
|
end if; |
end process; |
|
|
end generate greater; |
|
|
end generate re_gt_we; |
|
we_gt_re : if re_freq_g < we_freq_g generate |
|
clk_fifo <= clk_we; |
clk_slow <= clk_re; |
we_to_fifo <= we_in; |
|
-- we clk is faster than re |
gen_we : process (we_cnt_r, re_in, rst_cnt) |
begin -- process gen_we |
if re_in = '1' then |
if we_cnt_r = we_per_re_c-2 and rst_cnt = '0' then |
re_to_fifo <= '1'; |
else |
re_to_fifo <= '0'; |
end if; |
else |
re_to_fifo <= '0'; |
end if; |
|
end process gen_we; |
|
full_out_r <= full_from_fifo; |
|
process (clk_we, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
we_cnt_r <= 0; |
empty_out_r <= '1'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if rst_cnt = '1' then |
we_cnt_r <= 0; |
else |
we_cnt_r <= we_cnt_r+1; |
end if; |
|
if we_cnt_r = 0 then |
empty_out_r <= empty_from_fifo; |
else |
empty_out_r <= empty_out_r; |
end if; |
|
end if; |
end process; |
|
|
end generate we_gt_re; |
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/we_pulse_synchronizer.vhd
0,0 → 1,136
------------------------------------------------------------------------------- |
-- Title : Write pulse synchronizer for Mixed clock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 18.12.2006 |
-- Description: Re faster than WE |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
-- one p may be a bit suspicious if blindly trusted. should not be used. |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity we_pulse_synchronizer is |
|
generic ( |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; -- THIS IS ALWAYS THE FASTER CLOCK!!! |
clk_ps_re : in std_logic; -- phase shifted pulse |
clk_we : in std_logic; |
clk_ps_we : in std_logic; -- phase shifted pulse |
rst_n : in std_logic; |
|
-- to synchronize clk_we -> clk_re |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
-- from synchronization to clk_re, we pulse width adjusted |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
we_out : out std_logic; |
|
-- From clk_re domain FIFO |
full_in : in std_logic; |
one_p_in : in std_logic |
|
|
|
); |
end we_pulse_synchronizer; |
|
architecture rtl of we_pulse_synchronizer is |
|
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
signal we_local_r : std_logic; |
signal clk_we_was_r : std_logic; |
|
signal data_between_r : std_logic_vector (data_width_g-1 downto 0); |
signal we_between_r : std_logic; |
signal full_between_r : std_logic; |
signal one_p_between_r : std_logic; |
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal full_out_r : std_logic; |
signal clk_we_period_r : std_logic; |
|
signal derived_clk : std_logic; |
|
begin -- rtl |
|
full_out <= full_out_r; --from_fifo; |
data_out <= data_to_fifo; |
we_out <= we_to_fifo; |
one_p_from_fifo <= one_p_in; |
full_from_fifo <= full_in; |
|
refaster : process (clk_we, rst_n) |
begin -- process refaster |
if rst_n = '0' then -- asynchronous reset (active low) |
full_out_r <= '1'; |
data_between_r <= (others => '0'); |
we_between_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if full_between_r = '0' then |
data_between_r <= data_in; |
we_between_r <= we_in; |
end if; |
full_out_r <= full_between_r or one_p_between_r; |
end if; |
end process refaster; |
|
|
derived_clk <= (clk_ps_we nand clk_ps_re) and clk_we; |
|
derclk : process (derived_clk, rst_n) |
begin -- process derclk |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_fifo <= (others => '0'); |
we_local_r <= '0'; |
full_between_r <= '0'; |
one_p_between_r <= '0'; |
clk_we_period_r <= '0'; |
elsif derived_clk'event and derived_clk = '1' then -- rising clock edge |
if full_from_fifo = '0' then |
data_to_fifo <= data_between_r; |
we_local_r <= we_between_r; |
else |
we_local_r <= '0'; |
end if; |
full_between_r <= full_from_fifo; |
one_p_between_r <= one_p_from_fifo; |
clk_we_period_r <= not clk_we_period_r; |
end if; |
end process derclk; |
|
one_p_out <= one_p_between_r; -- follows one_p_between. |
we_to_fifo <= (clk_we_period_r xor clk_we_was_r) and we_local_r; |
|
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
clk_we_was_r <= '0'; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
clk_we_was_r <= clk_we_period_r; |
end if; |
end process; |
|
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/multiclk_fifo.vhd
0,0 → 1,223
------------------------------------------------------------------------------- |
-- Title : Multiclock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : multiclk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 2010-04-27 |
-- Description: Synchronous multi-clock FIFO. Note that clock frequencies MUST |
-- be realted (synchronized) in order to avoid metastability. |
-- Clocks that are asynchronous wrt. each other do not work. |
-- |
-- Note! data must be ready in the data in wrt. faster clock when writing! |
-- same applies for re and we |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- This file is part of Transaction Generator. |
-- |
-- Transaction Generator is free software: you can redistribute it and/or modify |
-- it under the terms of the Lesser GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- Transaction Generator is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- Lesser GNU General Public License for more details. |
-- |
-- You should have received a copy of the Lesser GNU General Public License |
-- along with Transaction Generator. If not, see <http://www.gnu.org/licenses/>. |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity multiclk_fifo is |
|
generic ( |
re_freq_g : integer := 0; -- integer multiple of clk_we |
we_freq_g : integer := 0; -- or vice versa |
depth_g : integer := 0; |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; |
clk_we : in std_logic; |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end multiclk_fifo; |
|
architecture rtl of multiclk_fifo is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
constant re_per_we_c : integer := re_freq_g / we_freq_g; |
constant we_per_re_c : integer := we_freq_g / re_freq_g; |
|
-- no 0 to x-1, cuz otherwise range 0 to -1 is possible |
signal re_cnt_r : integer range 0 to re_per_we_c; |
signal we_cnt_r : integer range 0 to we_per_re_c; |
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal re_to_fifo : std_logic; |
signal data_from_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_fifo : std_logic; |
signal one_d_from_fifo : std_logic; |
|
begin -- rtl |
|
data_to_fifo <= data_in; |
full_out <= full_from_fifo; |
one_p_out <= one_p_from_fifo; |
data_out <= data_from_fifo; |
empty_out <= empty_from_fifo; |
one_d_out <= one_d_from_fifo; |
|
re_gt_we : if re_freq_g >= we_freq_g generate |
|
fifo_re_gt_we : fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_re, -- this is the difference |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_to_fifo, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
re_to_fifo <= re_in; |
|
equal : if re_per_we_c = 1 generate |
we_to_fifo <= we_in; |
end generate equal; |
|
greater : if re_per_we_c > 1 generate |
-- re clk is faster than we |
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
we_to_fifo <= '0';--we_in; |
re_cnt_r <= 0; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
|
if we_in = '1' then |
if re_cnt_r = re_per_we_c-2 then |
we_to_fifo <= '1'; |
else |
we_to_fifo <= '0'; |
end if; |
|
if re_cnt_r /= re_per_we_c-1 then |
re_cnt_r <= re_cnt_r+1; |
else |
re_cnt_r <= 0; |
end if; |
|
else |
we_to_fifo <= '0'; |
re_cnt_r <= 0; |
end if; |
end if; |
end process; |
|
|
end generate greater; |
|
|
end generate re_gt_we; |
|
we_gt_re : if re_freq_g < we_freq_g generate |
|
fifo_re_gt_we : fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_we, |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_to_fifo, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
|
we_to_fifo <= we_in; |
|
-- we clk is faster than re |
process (clk_we, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
re_to_fifo <= '0';--re_in; |
we_cnt_r <= 0; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if re_in = '1' then |
if we_cnt_r = we_per_re_c-2 then |
re_to_fifo <= '1'; |
else |
re_to_fifo <= '0'; |
end if; |
if we_cnt_r /= we_per_re_c-1 then |
we_cnt_r <= we_cnt_r+1; |
else |
we_cnt_r <= 0; |
end if; |
else |
re_to_fifo <= '0'; |
we_cnt_r <= 0; |
end if; |
end if; |
end process; |
|
end generate we_gt_re; |
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/mixed_clk_fifo_v2.vhd
0,0 → 1,169
------------------------------------------------------------------------------- |
-- Title : Mixed clock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 14.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
-- Works in fpga testbench. |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity mixed_clk_fifo is |
|
generic ( |
depth_g : integer := 0; |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; |
clk_ps_re : in std_logic; -- phase shifted pulse |
clk_we : in std_logic; |
clk_ps_we : in std_logic; -- phase shifted pulse |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end mixed_clk_fifo; |
|
architecture rtl of mixed_clk_fifo is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
signal we_local_r : std_logic; |
signal clk_we_was_r : std_logic; |
|
signal data_between_r : std_logic_vector (data_width_g-1 downto 0); |
signal we_between_r : std_logic; |
signal full_between_r : std_logic; |
signal one_p_between_r : std_logic; |
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal re_to_fifo : std_logic; |
signal data_from_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_fifo : std_logic; |
signal one_d_from_fifo : std_logic; |
signal empty_out_r : std_logic; |
signal full_out_r : std_logic; |
signal clk_we_period_r : std_logic; |
|
signal derived_clk : std_logic; |
|
begin -- rtl |
|
full_out <= full_out_r; --from_fifo; |
data_out <= data_from_fifo; |
empty_out <= empty_from_fifo; |
|
regular_fifo : fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_re, |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_in, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
----------------------------------------------------------------------------- |
-- RE CLK IS FASTER |
|
process (clk_we, rst_n) |
begin -- process wefaster |
if rst_n = '0' then -- asynchronous reset (active low) |
full_out_r <= '1'; |
data_between_r <= (others => '0'); |
we_between_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
if full_between_r = '0' then |
data_between_r <= data_in; |
we_between_r <= we_in; |
end if; |
full_out_r <= full_between_r or one_p_between_r; |
end if; |
end process; |
|
|
derived_clk <= (clk_ps_we nand clk_ps_re) and clk_we; |
|
derclk : process (derived_clk, rst_n) |
begin -- process derclk |
if rst_n = '0' then -- asynchronous reset (active low) |
data_to_fifo <= (others => '0'); |
we_local_r <= '0'; |
full_between_r <= '0'; |
one_p_between_r <= '0'; |
clk_we_period_r <= '0'; |
|
elsif derived_clk'event and derived_clk = '1' then -- rising clock edge |
if full_from_fifo = '0' then |
data_to_fifo <= data_between_r; |
we_local_r <= we_between_r; |
else |
we_local_r <= '0'; |
end if; |
full_between_r <= full_from_fifo; |
one_p_between_r <= one_p_from_fifo; |
clk_we_period_r <= not clk_we_period_r; |
end if; |
end process derclk; |
|
we_to_fifo <= (clk_we_period_r xor clk_we_was_r) and we_local_r; |
|
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
clk_we_was_r <= '0'; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
clk_we_was_r <= clk_we_period_r; |
end if; |
end process; |
|
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/threeclk_fifo_v1.vhd
0,0 → 1,155
------------------------------------------------------------------------------- |
-- Title : Multiclock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : multiclk_fifo.vhd |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 16.08.2006 |
-- Description: Synchronous multi-clock FIFO. Note that clock frequencies MUST |
-- be related (synchronized) in order to avoid metastability. |
-- Clocks that are asynchronous wrt. each other do not work. |
-- |
-- Note! data must be ready in the data in wrt. faster clock when writing! |
-- same applies for re and we |
-- |
-- This one uses slow full and empty for the corresponding slower clock (i.e. |
-- reader is slower -> empty is delayed). eg. empty transition from 1->0 is |
-- delayed. |
-- |
-- In this implementation we really utilize both clocks, whch can be a problem |
-- in some systems (routing the another clock). |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity threeclk_fifo is |
|
generic ( |
re_freq_g : integer := 1; -- integer multiple of clk_we |
we_freq_g : integer := 1; -- or vice versa |
tmp_freq_g : integer := 1; -- integer multiple of both clk_re and clk_we |
depth_g : integer := 1; |
data_width_g : integer := 1 |
); |
port ( |
clk_re : in std_logic; |
clk_we : in std_logic; |
clk_tmp : in std_logic; |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end threeclk_fifo; |
|
architecture structural of threeclk_fifo is |
|
-- component multiclk_fifo |
-- generic ( |
-- re_freq_g : integer := 0; -- integer multiple of clk_we |
-- we_freq_g : integer := 0; -- or vice versa |
-- depth_g : integer := 0; |
-- data_width_g : integer := 0 |
-- ); |
-- port ( |
-- clk_re : in std_logic; |
-- clk_we : in std_logic; |
-- rst_n : in std_logic; |
|
-- data_in : in std_logic_vector (data_width_g-1 downto 0); |
-- we_in : in std_logic; |
-- full_out : out std_logic; |
-- one_p_out : out std_logic; |
|
-- re_in : in std_logic; |
-- data_out : out std_logic_vector (data_width_g-1 downto 0); |
-- empty_out : out std_logic; |
-- one_d_out : out std_logic |
-- ); |
-- end component; |
|
signal data_wef_ref : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_ref : std_logic; |
signal full_from_ref : std_logic; |
signal one_p_from_ref : std_logic; |
signal re_to_wef : std_logic; |
signal empty_from_wef : std_logic; |
|
|
begin -- structural |
|
|
|
we_fifo : entity work.multiclk_fifo |
generic map ( |
re_freq_g => tmp_freq_g, |
we_freq_g => we_freq_g, |
data_width_g => data_width_g, |
depth_g => depth_g |
) |
port map( |
clk_we => clk_we, |
clk_re => clk_tmp, |
rst_n => rst_n, |
|
data_in => data_in, |
we_in => we_in, |
full_out => full_out, |
one_p_out => one_p_out, |
|
data_out => data_wef_ref, |
re_in => re_to_wef, |
empty_out => empty_from_wef |
--one_d_out |
); |
|
|
re_to_wef <= not full_from_ref; |
we_to_ref <= not empty_from_wef; |
|
|
re_fifo : entity work.multiclk_fifo |
generic map ( |
re_freq_g => re_freq_g, |
we_freq_g => tmp_freq_g, |
data_width_g => data_width_g, |
depth_g => depth_g/2 |
) |
port map( |
clk_we => clk_tmp, |
clk_re => clk_re, |
rst_n => rst_n, |
|
data_in => data_wef_ref, |
we_in => we_to_ref, |
full_out => full_from_ref, |
one_p_out => one_p_from_ref, |
|
data_out => data_out, |
re_in => re_in, |
empty_out => empty_out, |
one_d_out => one_d_out |
); |
|
|
|
|
|
end structural; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/mixed_clk_fifo_v3.vhd
0,0 → 1,207
------------------------------------------------------------------------------- |
-- Title : Mixed clock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 18.12.2006 |
-- Description: This aims to include possibility to have the |
-- synchronization interface on both sides instead of fixed re faster scheme. |
-- |
-- NOTE! one_p may be high when full is also high |
-- one_d is high when empty is '0'. |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
-- Works in fpga testbench. |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity mixed_clk_fifo is |
|
generic ( |
re_faster_g : integer := 1; -- 0 we faster, 1 re faster. |
depth_g : integer := 0; |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; |
clk_ps_re : in std_logic; -- phase shifted pulse |
clk_we : in std_logic; |
clk_ps_we : in std_logic; -- phase shifted pulse |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
end mixed_clk_fifo; |
|
architecture rtl of mixed_clk_fifo is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
component we_pulse_synchronizer |
generic ( |
data_width_g : integer); |
port ( |
clk_re : in std_logic; |
clk_ps_re : in std_logic; |
clk_we : in std_logic; |
clk_ps_we : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
we_out : out std_logic; |
full_in : in std_logic; |
one_p_in : in std_logic); |
end component; |
|
component re_pulse_synchronizer |
generic ( |
data_width_g : integer); |
port ( |
clk_re : in std_logic; |
clk_ps_re : in std_logic; |
clk_we : in std_logic; |
clk_ps_we : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
empty_in : in std_logic; |
re_out : out std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
re_in : in std_logic; |
empty_out : out std_logic); |
end component; |
|
signal data_to_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal we_to_fifo : std_logic; |
|
signal full_from_fifo : std_logic; |
signal one_p_from_fifo : std_logic; |
signal re_to_fifo : std_logic; |
signal data_from_fifo : std_logic_vector (data_width_g-1 downto 0); |
signal empty_from_fifo : std_logic; |
signal one_d_from_fifo : std_logic; |
|
signal full_out_from_synch : std_logic; |
signal empty_out_from_synch : std_logic; |
signal one_p_from_synch : std_logic; |
|
signal clk_fifo : std_logic; |
begin -- rtl |
|
|
regular_fifo : fifo |
generic map ( |
data_width_g => data_width_g, |
depth_g => depth_g) |
port map ( |
clk => clk_fifo, |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => we_to_fifo, |
full_out => full_from_fifo, |
one_p_out => one_p_from_fifo, |
re_in => re_to_fifo, |
data_out => data_from_fifo, |
empty_out => empty_from_fifo, |
one_d_out => one_d_from_fifo |
); |
|
refaster: if re_faster_g > 0 generate |
|
we_pulse_synchronizer_1: we_pulse_synchronizer |
generic map ( |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_ps_re => clk_ps_re, |
clk_we => clk_we, |
clk_ps_we => clk_ps_we, |
rst_n => rst_n, |
-- to/from we domain |
data_in => data_in, |
we_in => we_in, |
full_out => full_out_from_synch, |
one_p_out => one_p_from_synch, |
-- to/from re domain |
data_out => data_to_fifo, |
we_out => we_to_fifo, |
full_in => full_from_fifo, |
one_p_in => one_p_from_fifo); |
|
re_to_fifo <= re_in; |
data_out <= data_from_fifo; |
empty_out <= empty_from_fifo; |
-- NOTE! this is for stupid HIBI which does not start when one_p is '1' and |
-- addres is coming |
one_p_out <= one_p_from_synch;--'0'; --not full_out_from_synch; |
full_out <= full_out_from_synch; |
one_d_out <= one_d_from_fifo; |
|
clk_fifo <= clk_re; |
end generate refaster; |
|
wefaster: if re_faster_g = 0 generate |
re_pulse_synchronizer_1: re_pulse_synchronizer |
generic map ( |
data_width_g => data_width_g) |
port map ( |
clk_re => clk_re, |
clk_ps_re => clk_ps_re, |
clk_we => clk_we, |
clk_ps_we => clk_ps_we, |
|
rst_n => rst_n, |
data_in => data_from_fifo, |
empty_in => empty_from_fifo, |
re_out => re_to_fifo, |
data_out => data_out, |
re_in => re_in, |
empty_out => empty_out_from_synch |
); |
|
we_to_fifo <= we_in; |
full_out <= full_from_fifo; |
one_p_out <= one_p_from_fifo; |
data_to_fifo <= data_in; |
|
empty_out <= empty_out_from_synch; |
one_d_out <= not empty_out_from_synch; |
clk_fifo <= clk_we; |
end generate wefaster; |
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/multi_clk/Vhdl/re_pulse_synchronizer.vhd
0,0 → 1,170
------------------------------------------------------------------------------- |
-- Title : Read pulse synchronizer for Mixed clock FIFO |
-- WE faster than re |
-- Project : |
------------------------------------------------------------------------------- |
-- File : |
-- Author : kulmala3 |
-- Created : 16.12.2005 |
-- Last update: 15.12.2006 |
-- Description: An extra FIFO slot that synchronizes the data between different |
-- clock domains |
------------------------------------------------------------------------------- |
-- Copyright (c) 2005 |
-- |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 16.12.2005 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity re_pulse_synchronizer is |
|
generic ( |
data_width_g : integer := 0 |
); |
port ( |
clk_re : in std_logic; -- THIS IS ALWAYS THE SLOWER CLOCK!!! |
clk_ps_re : in std_logic; -- phase shifted pulse |
clk_we : in std_logic; |
clk_ps_we : in std_logic; -- phase shifted pulse |
rst_n : in std_logic; |
|
-- from/to we domain |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
empty_in : in std_logic; |
re_out : out std_logic; |
|
-- from/to re domain |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
re_in : in std_logic; |
empty_out : out std_logic |
|
-- From clk_re domain FIFO |
-- full_in : in std_logic; |
-- one_p_in : in std_logic |
|
|
|
); |
end re_pulse_synchronizer; |
|
architecture rtl of re_pulse_synchronizer is |
|
signal clk_re_was_r : std_logic; |
signal clk_re_period_r : std_logic; |
|
signal derived_clk : std_logic; |
|
signal re_to_fifo : std_logic; |
-- signal re_between_r : std_logic; |
|
-- signal data_between_r : std_logic_vector(data_width_g-1 downto 0); |
signal data_out_r : std_logic_vector(data_width_g-1 downto 0); |
signal valid_r : std_logic; |
-- signal valid_between_r : std_logic; |
signal clk_was_r : std_logic; |
signal re_valid_r : std_logic; |
signal re_was_r : std_logic; |
begin -- rtl |
|
|
derived_clk <= (clk_ps_re nand clk_ps_we) and clk_re; |
|
-- read the fifo signals and read to the slot |
derclk : process (derived_clk, rst_n) |
begin -- process derclk |
if rst_n = '0' then -- asynchronous reset (active low) |
data_out_r <= (others => '0'); |
re_to_fifo <= '0'; |
valid_r <= '0'; |
clk_re_period_r <= '0'; |
|
elsif derived_clk'event and derived_clk = '1' then -- rising clock edge |
if re_valid_r = '1' or (re_was_r = '1') then |
-- by default, read invalidates data. next if will set again |
-- if new one is read instead. |
valid_r <= '0'; |
end if; |
if empty_in = '0' and (valid_r = '0' or |
(valid_r = '1' and |
(re_valid_r = '1' or |
(re_was_r = '1' and re_in = '1')))) then |
-- read data to output from fifo |
re_to_fifo <= '1'; |
data_out_r <= data_in; |
valid_r <= '1'; |
else |
re_to_fifo <= '0'; |
data_out_r <= data_out_r; |
end if; |
|
clk_re_period_r <= not clk_re_period_r; |
|
end if; |
end process derclk; |
|
empty_out <= not valid_r; |
data_out <= data_out_r; |
re_out <= re_to_fifo and (clk_re_was_r xor clk_re_period_r); |
|
re_valid_r <= (clk_was_r xnor clk_re_period_r) and re_in; |
|
process (clk_re, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
clk_was_r <= '0'; |
re_was_r <= '0'; |
|
elsif clk_re'event and clk_re = '1' then -- rising clock edge |
clk_was_r <= not clk_was_r; |
re_was_r <= re_in; |
|
end if; |
end process; |
|
-- refaster : process (clk_re, rst_n) |
-- begin -- process refaster |
-- if rst_n = '0' then -- asynchronous reset (active low) |
-- re_between_r <= '0'; |
-- valid_r <= '0'; |
-- data_out_r <= (others => '0'); |
|
-- elsif clk_re'event and clk_re = '1' then -- rising clock edge |
-- if re_in = '1' then |
-- -- by default, read invalidates data. next if will set again |
-- -- if new one is read instead. |
-- valid_r <= '0'; |
-- end if; |
-- if valid_between_r = '0' and (valid_r = '0' or |
-- (valid_r = '1' and re_in = '1')) then |
-- -- read data to output from fifo |
-- re_between_r <= '1'; |
-- data_out_r <= data_in; |
-- valid_r <= '1'; |
-- else |
-- re_between_r <= '0'; |
-- data_out_r <= data_between_r; |
-- end if; |
-- end if; |
-- end process refaster; |
|
|
-- we faster, make the pulse length equal |
process (clk_we, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
clk_re_was_r <= '0'; |
|
elsif clk_we'event and clk_we = '1' then -- rising clock edge |
clk_re_was_r <= clk_re_period_r; |
end if; |
end process; |
|
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/fifo.vhd
0,0 → 1,310
------------------------------------------------------------------------------- |
-- File : fifo.vhdl |
-- Description : General fifo buffer |
-- Author : Erno Salminen |
-- e-mail : erno.salminen@tut.fi |
-- Project : |
-- Design : |
-- Date : 29.04.2002 |
-- Modified : 30.04.2002 Vesa Lahtinen Optimized for synthesis |
-- |
-- 15.12.04 ES: names changed |
------------------------------------------------------------------------------- |
------------------------------------------------------------------------------- |
-- This file is part of Transaction Generator. |
-- |
-- Transaction Generator is free software: you can redistribute it and/or modify |
-- it under the terms of the Lesser GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- Transaction Generator is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- Lesser GNU General Public License for more details. |
-- |
-- You should have received a copy of the Lesser GNU General Public License |
-- along with Transaction Generator. If not, see <http://www.gnu.org/licenses/>. |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity fifo is |
|
generic ( |
data_width_g : integer := 32; |
depth_g : integer := 5 |
); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
|
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
full_out : out std_logic; |
one_p_out : out std_logic; |
|
re_in : in std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
empty_out : out std_logic; |
one_d_out : out std_logic |
); |
|
end fifo; |
|
architecture behavioral of fifo is |
|
|
-- Registers |
signal full_r : std_logic; |
signal empty_r : std_logic; |
signal one_d_r : std_logic; |
signal one_p_r : std_logic; |
--signal data_amount_r : std_logic_vector (depth_g-1 downto 0); |
signal data_amount_r : std_logic_vector (16-1 downto 0); |
|
signal in_ptr_r : integer range 0 to depth_g-1; |
signal out_ptr_r : integer range 0 to depth_g-1; |
|
type data_arr_type is array (depth_g-1 downto 0) of std_logic_vector (data_width_g-1 downto 0); |
signal fifo_buffer_r : data_arr_type; |
|
|
begin -- behavioral |
|
-- Continuous assignments |
-- Assigns register values to outputs |
full_out <= full_r; |
empty_out <= empty_r; |
one_d_out <= one_d_r; |
one_p_out <= one_p_r; |
data_out <= fifo_buffer_r (out_ptr_r); -- mux at output! |
-- Note! There is some old value in data output when fifo is empty. |
|
|
Main : process (clk, rst_n) |
begin -- process Main |
if rst_n = '0' then -- asynchronous reset (active low) |
|
-- Reset all registers |
-- Fifo is empty at first |
full_r <= '0'; |
empty_r <= '1'; |
one_d_r <= '0'; |
in_ptr_r <= 0; |
out_ptr_r <= 0; |
data_amount_r <= (others => '0'); |
|
if depth_g =1 then -- 30.07 |
one_p_r <= '1'; |
else |
one_p_r <= '0'; |
end if; |
|
for i in 0 to depth_g-1 loop |
fifo_buffer_r (i) <= (others => '0'); |
end loop; -- i |
|
elsif clk'event and clk = '1' then -- rising clock edge |
|
|
-- 1) Write data to fifo |
if we_in = '1' and re_in = '0' then |
|
if full_r = '0' then |
empty_r <= '0'; |
if (in_ptr_r = (depth_g-1)) then |
in_ptr_r <= 0; |
else |
in_ptr_r <= in_ptr_r + 1; |
end if; |
out_ptr_r <= out_ptr_r; |
data_amount_r <= data_amount_r +1; |
fifo_buffer_r (in_ptr_r) <= data_in; |
|
-- Check if the fifo is getting full |
if data_amount_r + 2 = depth_g then |
full_r <= '0'; |
one_p_r <= '1'; |
elsif data_amount_r +1 = depth_g then |
full_r <= '1'; |
one_p_r <= '0'; |
else |
full_r <= '0'; |
one_p_r <= '0'; |
end if; |
|
-- If fifo was empty, it has now one data |
if empty_r = '1' then |
one_d_r <= '1'; |
else |
one_d_r <= '0'; |
end if; |
|
else |
-- in_ptr_r <= in_ptr_r; |
-- out_ptr_r <= out_ptr_r; |
-- full_r <= full_r; |
-- empty_r <= empty_r; |
-- fifo_buffer_r <= fifo_buffer_r; |
-- data_amount_r <= data_amount_r; |
-- one_d_r <= one_d_r; |
-- one_p_r <= one_p_r; |
end if; |
|
|
-- 2) Read data from fifo |
elsif we_in = '0' and re_in = '1' then |
|
if empty_r = '0' then |
in_ptr_r <= in_ptr_r; |
if (out_ptr_r = (depth_g-1)) then |
out_ptr_r <= 0; |
else |
out_ptr_r <= out_ptr_r + 1; |
end if; |
full_r <= '0'; |
data_amount_r <= data_amount_r -1; |
|
-- Debug |
-- fifo_buffer_r (out_ptr_r) <= (others => '1'); |
|
-- Check if the fifo is getting empty |
if data_amount_r = 2 then |
empty_r <= '0'; |
one_d_r <= '1'; |
elsif data_amount_r = 1 then |
empty_r <= '1'; |
one_d_r <= '0'; |
else |
empty_r <= '0'; |
one_d_r <= '0'; |
end if; |
|
-- If fifo was full, it is no more |
if full_r = '1' then |
one_p_r <= '1'; |
else |
one_p_r <= '0'; |
end if; |
|
else |
-- in_ptr_r <= in_ptr_r; |
-- out_ptr_r <= out_ptr_r; |
-- full_r <= full_r; |
-- empty_r <= empty_r; |
-- fifo_buffer_r <= fifo_buffer_r; |
-- data_amount_r <= data_amount_r; |
-- one_d_r <= one_d_r; |
-- one_p_r <= one_p_r; |
end if; |
|
|
-- 3) Write and read at the same time |
elsif we_in = '1' and re_in = '1' then |
|
|
if full_r = '0' and empty_r = '0' then |
if (in_ptr_r = (depth_g-1)) then |
in_ptr_r <= 0; |
else |
in_ptr_r <= in_ptr_r + 1; |
end if; |
if (out_ptr_r = (depth_g-1)) then |
out_ptr_r <= 0; |
else |
out_ptr_r <= out_ptr_r + 1; |
end if; |
full_r <= '0'; |
empty_r <= '0'; |
data_amount_r <= data_amount_r; |
one_d_r <= one_d_r; |
one_p_r <= one_p_r; |
|
fifo_buffer_r (in_ptr_r) <= data_in; |
-- fifo_buffer_r (out_ptr_r) <= (others => '1'); --debug |
|
|
elsif full_r = '1' and empty_r = '0' then |
-- Fifo is full, only reading is possible |
in_ptr_r <= in_ptr_r; |
if (out_ptr_r = (depth_g-1)) then |
out_ptr_r <= 0; |
else |
out_ptr_r <= out_ptr_r + 1; |
end if; |
full_r <= '0'; |
one_p_r <= '1'; |
--fifo_buffer_r (out_ptr_r) <= (others => '1'); -- Debug |
data_amount_r <= data_amount_r -1; |
|
-- Check if the fifo is getting empty |
if data_amount_r = 2 then |
empty_r <= '0'; |
one_d_r <= '1'; |
elsif data_amount_r = 1 then |
empty_r <= '1'; |
one_d_r <= '0'; |
else |
empty_r <= '0'; |
one_d_r <= '0'; |
end if; |
|
|
elsif full_r = '0' and empty_r = '1' then |
-- Fifo is empty, only writing is possible |
if (in_ptr_r = (depth_g-1)) then |
in_ptr_r <= 0; |
else |
in_ptr_r <= in_ptr_r + 1; |
end if; |
out_ptr_r <= out_ptr_r; |
empty_r <= '0'; |
one_d_r <= '1'; |
fifo_buffer_r (in_ptr_r) <= data_in; |
data_amount_r <= data_amount_r +1; |
|
-- Check if the fifo is getting full |
if data_amount_r + 2 = depth_g then |
full_r <= '0'; |
one_p_r <= '1'; |
elsif data_amount_r +1 = depth_g then |
full_r <= '1'; |
one_p_r <= '0'; |
else |
full_r <= '0'; |
one_p_r <= '0'; |
end if; |
|
|
-- 4) Do nothing, fifo remains idle |
else |
|
-- in_ptr_r <= in_ptr_r; |
-- out_ptr_r <= out_ptr_r; |
-- full_r <= full_r; |
-- empty_r <= empty_r; |
-- fifo_buffer_r <= fifo_buffer_r; |
-- data_amount_r <= data_amount_r; |
-- one_d_r <= one_d_r; |
-- one_p_r <= one_p_r; |
end if; |
|
else |
-- Fifo is idle |
-- in_ptr_r <= in_ptr_r; |
-- out_ptr_r <= out_ptr_r; |
-- full_r <= full_r; |
-- empty_r <= empty_r; |
-- fifo_buffer_r <= fifo_buffer_r; |
-- data_amount_r <= data_amount_r; |
-- one_d_r <= one_d_r; |
-- one_p_r <= one_p_r; |
end if; |
|
end if; |
end process Main; |
|
end behavioral; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Testbench/tb_cdc_fifo_tester.vhd
0,0 → 1,113
------------------------------------------------------------------------------- |
-- Title : Testbench for design "cdc_fifo_tester" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : tb_cdc_fifo_tester.vhd |
-- Author : |
-- Created : 19.12.2006 |
-- Last update: 19.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2006 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 19.12.2006 1.0 AK Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all;use ieee.std_logic_1164.all; |
|
------------------------------------------------------------------------------- |
|
entity tb_cdc_fifo_tester is |
|
end tb_cdc_fifo_tester; |
|
------------------------------------------------------------------------------- |
|
architecture struct of tb_cdc_fifo_tester is |
|
component cdc_fifo_tester |
generic ( |
depth_log2_g : integer; |
dataw_g : integer); |
port ( |
rd_clk, wr_clk : in std_logic; |
rst_n : in std_logic; |
pass_out, error_out : out std_logic; |
pass_count_out : out std_logic_vector(31 downto 0)); |
end component; |
|
-- component generics |
constant depth_log2_g : integer := 3; |
constant dataw_g : integer := 30; |
|
-- component ports |
signal Clk1, Clk2 : std_logic; |
signal rst_n : std_logic; |
signal pass_out, error_out : std_logic; |
signal pass_count_out : std_logic_vector(31 downto 0); |
|
-- clock and reset |
constant Period1 : time := 100 ns; |
constant Period2 : time := 10 ns; |
|
begin -- struct |
|
assertion: process (Clk1, rst_n) |
begin -- process assertion |
if rst_n = '0' then -- asynchronous reset (active low) |
|
elsif Clk1'event and Clk1 = '1' then -- rising clock edge |
assert error_out = '0' report "Error!" severity error; |
end if; |
end process assertion; |
|
-- component instantiation |
DUT: cdc_fifo_tester |
generic map ( |
depth_log2_g => depth_log2_g, |
dataw_g => dataw_g) |
port map ( |
rd_clk => Clk1, |
wr_clk => Clk2, |
rst_n => rst_n, |
pass_out => pass_out, |
error_out => error_out, |
pass_count_out => pass_count_out); |
|
-- clock generation |
-- PROC |
CLOCK1: process -- generate clock signal for design |
variable clktmp: std_logic := '0'; |
begin |
wait for PERIOD1/2; |
clktmp := not clktmp; |
Clk1 <= clktmp; |
end process CLOCK1; |
|
-- clock generation |
-- PROC |
CLOCK2: process -- generate clock signal for design |
variable clktmp: std_logic := '0'; |
begin |
wait for PERIOD2/2; |
clktmp := not clktmp; |
Clk2 <= clktmp; |
end process CLOCK2; |
|
-- PROC |
RESET: process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*PERIOD1; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
end struct; |
|
------------------------------------------------------------------------------- |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/cdc_fifo_ctrl.vhd
0,0 → 1,206
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.gray_code.all; |
|
entity cdc_fifo_ctrl is |
|
generic ( |
READ_AHEAD_g : integer := 0; |
SYNC_CLOCKS_g : integer := 0; |
depth_log2_g : integer := 0); |
|
port ( |
rst_n : in std_logic; |
|
rd_clk : in std_logic; |
rd_en_in : in std_logic; |
rd_empty_out : out std_logic; |
rd_one_d_out : out std_logic; |
rd_addr_out : out std_logic_vector (depth_log2_g-1 downto 0); |
|
wr_clk : in std_logic; |
wr_en_in : in std_logic; |
wr_full_out : out std_logic; |
wr_one_p_out : out std_logic; |
wr_addr_out : out std_logic_vector (depth_log2_g-1 downto 0) |
); |
|
end entity cdc_fifo_ctrl; |
|
architecture rtl of cdc_fifo_ctrl is |
|
|
-- signal wr_counter_synchronized_r : unsigned (depth_log2_g-1 downto 0); |
|
|
-- (rd_clk) registers |
signal rd_counter_r : unsigned (depth_log2_g-1 downto 0); |
signal rd_counter_gray_r : std_logic_vector(depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_empty : std_logic; |
|
-- (wr_clk) registers |
signal wr_counter_r : unsigned (depth_log2_g-1 downto 0); |
signal wr_counter_gray_r : std_logic_vector(depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0); |
|
signal rd_counter_next : unsigned (depth_log2_g-1 downto 0); |
signal wr_counter_next : unsigned (depth_log2_g-1 downto 0); |
|
signal wr_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0); |
signal rd_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0); |
begin -- architecture rtl |
|
-- concurrent assignments |
wr_addr_out <= std_logic_vector(wr_counter_r); |
|
--AK TESTE CAHNGED |
-- data is available at the same clock cylce as the rd_en_in = '1' |
readahead : if READ_AHEAD_g /= 0 generate |
rd_addr_out <= std_logic_vector(rd_counter_next) when (rd_en_in = '1' and rd_empty = '0') else |
std_logic_vector(rd_counter_r); |
end generate readahead; |
|
-- data is available at the next clock cycle |
no_readahead : if READ_AHEAD_g = 0 generate |
rd_addr_out <= std_logic_vector(rd_counter_r); |
end generate no_readahead; |
|
|
-- purpose: counter logic for write address (binary counter + gray counter) |
-- type : sequential |
-- inputs : wr_clk, rst_n |
-- outputs: |
wr_counter_next <= wr_counter_r + 1; |
write_counter : process (rst_n, wr_clk) is |
begin -- process write_counter |
if (rst_n = '0') then -- asynchronous reset (active low) |
wr_counter_r <= (others => '0'); |
wr_counter_gray_r <= (others => '0'); |
wr_counter_gray_sync1_r <= (others => '0'); |
elsif rising_edge(wr_clk) then -- rising clock edge |
-- check also if becoming full |
if (wr_en_in = '1') then |
wr_counter_r <= wr_counter_next; |
wr_counter_gray_r <= gray_encode(wr_counter_next); |
end if; |
wr_counter_gray_sync1_r <= wr_counter_gray_r; |
end if; |
end process write_counter; |
|
-- purpose: counter logic for read address (binary counter & gray counter) |
-- type : sequential |
-- inputs : rd_clk, rst_n |
-- outputs: |
rd_counter_next <= rd_counter_r + 1; |
read_counter : process (rd_clk, rst_n) is |
begin -- process read_counter |
if (rst_n = '0') then -- asynchronous reset (active low) |
rd_counter_r <= (others => '0'); |
rd_counter_gray_r <= (others => '0'); |
elsif rising_edge(rd_clk) then -- rising clock edge |
-- check also if becoming empty |
if (rd_en_in = '1') then -- and (not rd_counter_gray_r = wr_counter_gray_syncd) |
rd_counter_r <= rd_counter_next; |
rd_counter_gray_r <= gray_encode(rd_counter_next); |
end if; |
end if; |
end process read_counter; |
|
|
syncd_clocks : if SYNC_CLOCKS_g /= 0 generate |
-- use only 1 synchronization register |
wr_counter_gray_syncd <= wr_counter_gray_sync1_r; |
rd_counter_gray_syncd <= rd_counter_gray_sync1_r; |
end generate syncd_clocks; |
|
no_syncd_clocks : if SYNC_CLOCKS_g = 0 generate |
-- use 2 synchronization registers |
-- wr_counter_gray_syncd <= wr_counter_gray_sync2_r; |
rd_counter_gray_syncd <= rd_counter_gray_sync2_r; |
wr_counter_gray_syncd <= wr_counter_gray_sync3_r; |
-- rd_counter_gray_syncd <= rd_counter_gray_sync3_r; |
|
end generate no_syncd_clocks; |
|
|
rd_empty_out <= rd_empty; |
|
-- purpose: determines whether the fifo is empty or not |
-- combinational inputs : rd_counter_r, wr_counter_sync2_r outputs: |
-- empty |
empty_logic : process (rd_counter_gray_r, wr_counter_gray_syncd, |
rd_counter_r) is |
begin -- process empty_logic |
if (rd_counter_gray_r = wr_counter_gray_syncd) then |
rd_empty <= '1'; |
else |
rd_empty <= '0'; |
end if; |
|
if (gray_encode(rd_counter_r+1) = wr_counter_gray_syncd) then |
rd_one_d_out <= '1'; |
else |
rd_one_d_out <= '0'; |
end if; |
end process empty_logic; |
|
|
|
full_logic : process (rd_counter_gray_syncd, wr_counter_next) is |
begin -- process full_logic |
if (rd_counter_gray_syncd = gray_encode(wr_counter_next)) then |
wr_full_out <= '1'; |
else |
wr_full_out <= '0'; |
end if; |
|
if rd_counter_gray_syncd = gray_encode(wr_counter_next+1) then |
wr_one_p_out <= '1'; |
else |
wr_one_p_out <= '0'; |
end if; |
|
end process full_logic; |
|
-- purpose: Synchronizes write counter value to read -side clock domain. |
-- type : sequential (avoids meta-stability) |
-- inputs : rd_clk, rst_n |
-- outputs: |
rd_synchronizer : process (rd_clk, rst_n) is |
begin -- process rd_synchronizer |
if rst_n = '0' then -- asynchronous reset (active low) |
-- wr_counter_gray_sync1_r <= (others => '0'); |
wr_counter_gray_sync2_r <= (others => '0'); |
wr_counter_gray_sync3_r <= (others => '0'); |
elsif rising_edge(rd_clk) then -- rising clock edge |
-- wr_counter_gray_sync1_r <= wr_counter_gray_r; |
wr_counter_gray_sync2_r <= wr_counter_gray_sync1_r; |
wr_counter_gray_sync3_r <= wr_counter_gray_sync2_r; |
end if; |
end process rd_synchronizer; |
|
-- purpose: Synchronizes read counter value to write -side clock domain. |
-- type : sequential (avoids meta-stability) |
-- inputs : wr_clk, rst_n |
-- outputs: |
wr_synchronizer : process (rst_n, wr_clk) is |
begin -- process rd_synchronizer |
if rst_n = '0' then -- asynchronous reset (active low) |
rd_counter_gray_sync1_r <= (others => '0'); |
rd_counter_gray_sync2_r <= (others => '0'); |
rd_counter_gray_sync3_r <= (others => '0'); |
elsif rising_edge(wr_clk) then -- rising clock edge |
rd_counter_gray_sync1_r <= rd_counter_gray_r; |
rd_counter_gray_sync2_r <= rd_counter_gray_sync1_r; |
rd_counter_gray_sync3_r <= rd_counter_gray_sync2_r; |
end if; |
end process wr_synchronizer; |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/async_dpram.vhd
0,0 → 1,18
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity async_dpram is |
|
generic ( |
addrw_g : integer := 0; |
dataw_g : integer := 0); |
|
port ( |
rd_clk, wr_clk : in std_logic; |
wr_en_in : in std_logic; |
data_in : in std_logic_vector(dataw_g-1 downto 0); |
data_out : out std_logic_vector(dataw_g-1 downto 0); |
rd_addr_in, wr_addr_in : in std_logic_vector (addrw_g-1 downto 0)); |
|
end entity async_dpram; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/gray.vhd
0,0 → 1,39
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
package gray_code is |
|
function gray_encode (B : unsigned) -- binary input |
return std_logic_vector; -- gray coded output |
|
function gray_decode (G : std_logic_vector) -- gray coded input |
return unsigned; -- binary output |
|
end package gray_code; |
|
package body gray_code is |
|
function gray_encode (B : unsigned) |
return std_logic_vector is |
variable G : std_logic_vector(B'range); |
begin |
G(B'left) := B(B'left); |
for i in B'left - 1 downto B'right loop |
G(i) := B(i+1) xor B(i); |
end loop; -- i |
return G; |
end gray_encode; |
|
function gray_decode (G : std_logic_vector) |
return unsigned is |
variable B : unsigned(G'range); |
begin |
B(G'left) := G(G'left); |
for i in G'left - 1 downto G'right loop |
B(i) := B(i+1) xor G(i); |
end loop; -- i |
return B; |
end gray_decode; |
|
end package body gray_code; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/cdc_fifo_tester.vhd
0,0 → 1,165
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity cdc_fifo_tester is |
|
generic ( |
depth_log2_g : integer := 2; |
dataw_g : integer := 30 |
); |
|
port ( |
rd_clk, wr_clk : in std_logic; |
rst_n : in std_logic; |
pass_out, error_out : out std_logic; |
pass_count_out : out std_logic_vector(31 downto 0)); |
|
end entity cdc_fifo_tester; |
|
architecture rtl of cdc_fifo_tester is |
|
signal input_ctr_r : unsigned(dataw_g-1 downto 0); |
signal expected_ctr_r : unsigned(dataw_g-1 downto 0); |
signal check_r : std_logic; |
signal wr_state : integer range 0 to 3 := 0; |
|
constant READ_AHEAD_co : integer := 0; |
|
signal wr_data_in : std_logic_vector(dataw_g-1 downto 0); |
signal rd_data_out : std_logic_vector(dataw_g-1 downto 0); |
signal rd_empty_out, wr_full_out : std_logic; |
signal wr_en, rd_en : std_logic; |
|
signal pass_count_r : unsigned(31 downto 0); |
|
signal wr_empty_r : std_logic; |
signal rd_full_r : std_logic; |
signal wr_empty2_r : std_logic; |
signal rd_full2_r : std_logic; |
|
signal re_to_fifo : std_logic; |
constant wr_wait_c : integer := 10; |
signal wr_wait_r : integer range 0 to wr_wait_c-1; |
signal we_wait_r : std_logic; |
begin -- architecture rtl |
|
cdc_fifo_inst : entity work.cdc_fifo |
generic map ( |
READ_AHEAD_g => READ_AHEAD_co, |
SYNC_CLOCKS_g => 0, |
depth_log2_g => depth_log2_g, |
dataw_g => dataw_g) |
port map ( |
rst_n => rst_n, |
rd_clk => rd_clk, |
rd_en_in => re_to_fifo, --rd_en, |
rd_empty_out => rd_empty_out, |
rd_data_out => rd_data_out, |
wr_clk => wr_clk, |
wr_en_in => wr_en, |
wr_full_out => wr_full_out, |
wr_data_in => wr_data_in); |
|
re_to_fifo <= '1'; |
wr_data_in <= std_logic_vector(input_ctr_r); |
pass_count_out <= std_logic_vector(pass_count_r); |
|
x : process (wr_state, wr_full_out, rd_empty_out) |
begin |
if (wr_state < 2) then |
-- write inputs as fast as possible. |
-- (i.e. write when fifo is not full) |
-- read as fast as possible. |
-- (i.e. read when fifo is not empty) |
wr_en <= not wr_full_out; |
rd_en <= not rd_empty_out; |
elsif (wr_state = 2) then |
-- write inputs "as slow as possible"! |
-- (i.e. write only when fifo is empty) |
-- read whne fifo is not empty. |
-- wr_en <= wr_empty2_r; |
-- wr_en <= not wr_full_out; |
wr_en <= we_wait_r; |
rd_en <= not rd_empty_out; |
else |
-- write inputs as fast as possible. |
-- (i.e. write when fifo is not full) |
-- read only when fifo is full |
wr_en <= not wr_full_out; |
rd_en <= not rd_empty_out; |
--rd_en <= rd_full2_r; |
end if; |
end process x; |
|
inproc : process (wr_clk, rst_n) is |
begin -- process inproc |
if rst_n = '0' then -- asynchronous reset (active low) |
input_ctr_r <= (others => '0'); |
wr_state <= 0; |
pass_out <= '0'; |
pass_count_r <= (others => '0'); |
wr_empty_r <= '0'; |
wr_empty2_r <= '0'; |
wr_wait_r <= 0; |
we_wait_r <= '0'; |
|
elsif rising_edge(wr_clk) then -- rising clock edge |
wr_empty_r <= rd_empty_out; |
wr_empty2_r <= wr_empty_r; |
|
if (wr_en = '1') then |
input_ctr_r <= input_ctr_r + 1; |
|
pass_out <= '0'; |
-- change state when pass/round done |
if (input_ctr_r = 2**dataw_g - 1) then |
wr_state <= (wr_state + 1) mod 4; |
pass_out <= '1'; |
pass_count_r <= pass_count_r + 1; |
input_ctr_r <= (others => '0'); |
end if; |
end if; |
|
if wr_state = 2 then |
if wr_wait_r < wr_wait_c-1 then |
wr_wait_r <= wr_wait_r+1; |
we_wait_r <= '0'; |
else |
we_wait_r <= '1' and (not wr_full_out); |
end if; |
else |
wr_wait_r <= 0; |
end if; |
|
end if; |
end process inproc; |
|
|
|
outchecker : process (rd_clk, rst_n) is |
begin -- process outcheker |
if rst_n = '0' then -- asynchronous reset (active low) |
expected_ctr_r <= (others => '0'); |
check_r <= '0'; |
error_out <= '0'; |
rd_full_r <= '0'; |
rd_full2_r <= '0'; |
elsif rising_edge(rd_clk) then -- rising clock edge |
check_r <= rd_en; |
rd_full_r <= wr_full_out; |
rd_full2_r <= rd_full_r; |
|
if ((check_r = '1' and READ_AHEAD_co = 0) or |
(rd_en = '1' and READ_AHEAD_co /= 0)) then |
if (std_logic_vector(expected_ctr_r) /= rd_data_out) then |
assert (false) report "test failed!" severity failure; |
error_out <= '1'; |
end if; |
expected_ctr_r <= expected_ctr_r + 1; |
end if; |
|
end if; |
end process outchecker; |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/Test_codes/async_dpram_generic_v2.vhd
0,0 → 1,34
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
architecture rtl of async_dpram is |
|
type mem_t is array (0 to 2**addrw_g - 1) of std_logic_vector(dataw_g-1 downto 0); |
|
signal memory : mem_t; |
signal wr_addr, rd_addr : integer; |
signal data_out_r : std_logic_vector(dataw_g-1 downto 0); |
begin -- architecture rtl |
|
wr_addr <= to_integer (unsigned(wr_addr_in)); |
rd_addr <= to_integer (unsigned(rd_addr_in)); |
data_out <= data_out_r; |
|
wr : process (wr_en_in, data_in) is |
begin -- process write |
-- if rising_edge(wr_clk) then -- rising clock edge |
if (wr_en_in = '1') then |
memory(wr_addr) <= data_in; |
end if; |
-- end if; |
end process wr; |
-- data_out_r <= memory(rd_addr); |
-- rd : process (rd_clk) is |
-- begin -- process rd |
-- if rising_edge(rd_clk) then |
data_out_r <= memory(rd_addr); |
-- end if; |
-- end process rd; |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/Test_codes/async_dpram_altsyncram_v2.vhd
0,0 → 1,45
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
architecture rtl of async_dpram is |
component ram2p_altsyncram_hh41 |
port ( |
address_a : in std_logic_vector (3 downto 0); |
address_b : in std_logic_vector (3 downto 0) := (others => '1'); |
clock0 : in std_logic := '1'; |
clock1 : in std_logic := '1'; |
data_a : in std_logic_vector (35 downto 0) := (others => '1'); |
q_b : out std_logic_vector (35 downto 0); |
wren_a : in std_logic := '0'); |
end component; |
|
|
signal ONE : std_logic; |
begin -- architecture rtl |
ONE <= '1'; |
-- |
ram2p_altsyncram_hh41_1: ram2p_altsyncram_hh41 |
port map ( |
address_a => '0' & wr_addr_in, |
address_b => '0' & rd_addr_in, |
clock0 => wr_clk, |
clock1 => rd_clk, |
data_a => data_in, |
q_b => data_out, |
wren_a => wr_en_in |
); |
|
|
-- generic ( |
-- addrw_g : integer := 0; |
-- dataw_g : integer := 0); |
|
-- port ( |
-- rd_clk, wr_clk : in std_logic; |
-- wr_en_in : in std_logic; |
-- data_in : in std_logic_vector(dataw_g-1 downto 0); |
-- data_out : out std_logic_vector(dataw_g-1 downto 0); |
-- rd_addr_in, wr_addr_in : in std_logic_vector (addrw_g-1 downto 0)); |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/Test_codes/cdc_fifo_ctrl_v2.vhd
0,0 → 1,202
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
use work.gray_code.all; |
|
entity cdc_fifo_ctrl is |
|
generic ( |
READ_AHEAD_g : integer := 0; |
SYNC_CLOCKS_g : integer := 0; |
depth_log2_g : integer := 0); |
|
port ( |
rst_n : in std_logic; |
|
rd_clk : in std_logic; |
rd_en_in : in std_logic; |
rd_empty_out : out std_logic; |
rd_one_d_out : out std_logic; |
rd_addr_out : out std_logic_vector (depth_log2_g-1 downto 0); |
|
wr_clk : in std_logic; |
wr_en_in : in std_logic; |
wr_full_out : out std_logic; |
wr_one_p_out : out std_logic; |
wr_addr_out : out std_logic_vector (depth_log2_g-1 downto 0) |
); |
|
end entity cdc_fifo_ctrl; |
|
architecture rtl of cdc_fifo_ctrl is |
|
|
-- signal wr_counter_synchronized_r : unsigned (depth_log2_g-1 downto 0); |
|
|
-- (rd_clk) registers |
signal rd_counter_r : unsigned (depth_log2_g-1 downto 0); |
signal rd_counter_gray_r : std_logic_vector(depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal wr_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_empty : std_logic; |
|
-- (wr_clk) registers |
signal wr_counter_r : unsigned (depth_log2_g-1 downto 0); |
signal wr_counter_gray_r : std_logic_vector(depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync1_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync2_r : std_logic_vector (depth_log2_g-1 downto 0); |
signal rd_counter_gray_sync3_r : std_logic_vector (depth_log2_g-1 downto 0); |
|
signal rd_counter_next : unsigned (depth_log2_g-1 downto 0); |
signal wr_counter_next : unsigned (depth_log2_g-1 downto 0); |
|
signal wr_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0); |
signal rd_counter_gray_syncd : std_logic_vector(depth_log2_g-1 downto 0); |
begin -- architecture rtl |
|
-- concurrent assignments |
wr_addr_out <= std_logic_vector(wr_counter_r); |
|
-- data is available at the same clock cylce as the rd_en_in = '1' |
readahead : if READ_AHEAD_g /= 0 generate |
rd_addr_out <= std_logic_vector(rd_counter_next) when (rd_en_in = '1' and rd_empty = '0') else |
std_logic_vector(rd_counter_r); |
end generate readahead; |
|
-- data is available at the next clock cycle |
no_readahead : if READ_AHEAD_g = 0 generate |
rd_addr_out <= std_logic_vector(rd_counter_r); |
end generate no_readahead; |
|
|
-- purpose: counter logic for write address (binary counter + gray counter) |
-- type : sequential |
-- inputs : wr_clk, rst_n |
-- outputs: |
wr_counter_next <= wr_counter_r + 1; |
write_counter : process (rst_n, wr_clk) is |
begin -- process write_counter |
if (rst_n = '0') then -- asynchronous reset (active low) |
wr_counter_r <= (others => '0'); |
wr_counter_gray_r <= (others => '0'); |
elsif rising_edge(wr_clk) then -- rising clock edge |
-- check also if becoming full |
if (wr_en_in = '1') then |
wr_counter_r <= wr_counter_next; |
wr_counter_gray_r <= gray_encode(wr_counter_next); |
end if; |
end if; |
end process write_counter; |
|
-- purpose: counter logic for read address (binary counter & gray counter) |
-- type : sequential |
-- inputs : rd_clk, rst_n |
-- outputs: |
rd_counter_next <= rd_counter_r + 1; |
read_counter : process (rd_clk, rst_n) is |
begin -- process read_counter |
if (rst_n = '0') then -- asynchronous reset (active low) |
rd_counter_r <= (others => '0'); |
rd_counter_gray_r <= (others => '0'); |
elsif rising_edge(rd_clk) then -- rising clock edge |
-- check also if becoming empty |
if (rd_en_in = '1') then -- and (not rd_counter_gray_r = wr_counter_gray_syncd) |
rd_counter_r <= rd_counter_next; |
rd_counter_gray_r <= gray_encode(rd_counter_next); |
end if; |
end if; |
end process read_counter; |
|
|
syncd_clocks : if SYNC_CLOCKS_g /= 0 generate |
-- use only 1 synchronization register |
wr_counter_gray_syncd <= wr_counter_gray_sync1_r; |
rd_counter_gray_syncd <= rd_counter_gray_sync1_r; |
end generate syncd_clocks; |
|
no_syncd_clocks : if SYNC_CLOCKS_g = 0 generate |
-- use 2 synchronization registers |
---- wr_counter_gray_syncd <= wr_counter_gray_sync2_r; |
rd_counter_gray_syncd <= rd_counter_gray_sync2_r; |
wr_counter_gray_syncd <= wr_counter_gray_sync3_r; |
-- rd_counter_gray_syncd <= rd_counter_gray_sync3_r; |
|
end generate no_syncd_clocks; |
|
|
rd_empty_out <= rd_empty; |
|
-- purpose: determines whether the fifo is empty or not |
-- combinational inputs : rd_counter_r, wr_counter_sync2_r outputs: |
-- empty |
empty_logic : process (rd_counter_gray_r, wr_counter_gray_syncd) is |
begin -- process empty_logic |
if (rd_counter_gray_r = wr_counter_gray_syncd) then |
rd_empty <= '1'; |
else |
rd_empty <= '0'; |
end if; |
|
if (gray_encode(rd_counter_r+1) = wr_counter_gray_syncd) then |
rd_one_d_out <= '1'; |
else |
rd_one_d_out <= '0'; |
end if; |
end process empty_logic; |
|
|
|
full_logic : process (rd_counter_gray_syncd, wr_counter_next) is |
begin -- process full_logic |
if (rd_counter_gray_syncd = gray_encode(wr_counter_next)) then |
wr_full_out <= '1'; |
else |
wr_full_out <= '0'; |
end if; |
|
if rd_counter_gray_syncd = gray_encode(wr_counter_next+1) then |
wr_one_p_out <= '1'; |
else |
wr_one_p_out <= '0'; |
end if; |
|
end process full_logic; |
|
-- purpose: Synchronizes write counter value to read -side clock domain. |
-- type : sequential (avoids meta-stability) |
-- inputs : rd_clk, rst_n |
-- outputs: |
rd_synchronizer : process (rd_clk, rst_n) is |
begin -- process rd_synchronizer |
if rst_n = '0' then -- asynchronous reset (active low) |
wr_counter_gray_sync1_r <= (others => '0'); |
wr_counter_gray_sync2_r <= (others => '0'); |
wr_counter_gray_sync3_r <= (others => '0'); |
elsif rising_edge(rd_clk) then -- rising clock edge |
wr_counter_gray_sync1_r <= wr_counter_gray_r; |
wr_counter_gray_sync2_r <= wr_counter_gray_sync1_r; |
wr_counter_gray_sync3_r <= wr_counter_gray_sync2_r; |
end if; |
end process rd_synchronizer; |
|
-- purpose: Synchronizes read counter value to write -side clock domain. |
-- type : sequential (avoids meta-stability) |
-- inputs : wr_clk, rst_n |
-- outputs: |
wr_synchronizer : process (rst_n, wr_clk) is |
begin -- process rd_synchronizer |
if rst_n = '0' then -- asynchronous reset (active low) |
rd_counter_gray_sync1_r <= (others => '0'); |
rd_counter_gray_sync2_r <= (others => '0'); |
rd_counter_gray_sync3_r <= (others => '0'); |
elsif rising_edge(wr_clk) then -- rising clock edge |
rd_counter_gray_sync1_r <= rd_counter_gray_r; |
rd_counter_gray_sync2_r <= rd_counter_gray_sync1_r; |
rd_counter_gray_sync3_r <= rd_counter_gray_sync2_r; |
end if; |
end process wr_synchronizer; |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/Test_codes/async_dpram_altsyncram.vhd
0,0 → 1,177
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
architecture rtl of async_dpram is |
|
component altsyncram |
generic |
( |
ADDRESS_ACLR_A : string := "UNUSED"; |
ADDRESS_ACLR_B : string := "NONE"; |
ADDRESS_REG_B : string := "CLOCK1"; |
BYTE_SIZE : natural := 8; |
BYTEENA_ACLR_A : string := "UNUSED"; |
BYTEENA_ACLR_B : string := "NONE"; |
BYTEENA_REG_B : string := "CLOCK1"; |
CLOCK_ENABLE_INPUT_A : string := "NORMAL"; |
CLOCK_ENABLE_INPUT_B : string := "NORMAL"; |
CLOCK_ENABLE_OUTPUT_A : string := "NORMAL"; |
CLOCK_ENABLE_OUTPUT_B : string := "NORMAL"; |
INTENDED_DEVICE_FAMILY : string := "UNUSED"; |
IMPLEMENT_IN_LES : string := "OFF"; |
INDATA_ACLR_A : string := "UNUSED"; |
INDATA_ACLR_B : string := "NONE"; |
INDATA_REG_B : string := "CLOCK1"; |
INIT_FILE : string := "UNUSED"; |
INIT_FILE_LAYOUT : string := "PORT_A"; |
MAXIMUM_DEPTH : natural := 0; |
NUMWORDS_A : natural := 0; |
NUMWORDS_B : natural := 0; |
OPERATION_MODE : string := "BIDIR_DUAL_PORT"; |
OUTDATA_ACLR_A : string := "NONE"; |
OUTDATA_ACLR_B : string := "NONE"; |
OUTDATA_REG_A : string := "UNREGISTERED"; |
OUTDATA_REG_B : string := "UNREGISTERED"; |
RAM_BLOCK_TYPE : string := "AUTO"; |
RDCONTROL_ACLR_B : string := "NONE"; |
RDCONTROL_REG_B : string := "CLOCK1"; |
READ_DURING_WRITE_MODE_MIXED_PORTS : string := "DONT_CARE"; |
WIDTH_A : natural; |
WIDTH_B : natural := 1; |
WIDTH_BYTEENA_A : natural := 1; |
WIDTH_BYTEENA_B : natural := 1; |
WIDTHAD_A : natural; |
WIDTHAD_B : natural := 1; |
WRCONTROL_ACLR_A : string := "UNUSED"; |
WRCONTROL_ACLR_B : string := "NONE"; |
WRCONTROL_WRADDRESS_REG_B : string := "CLOCK1"; |
LPM_HINT : string := "UNUSED"; |
LPM_TYPE : string := "ALTSYNCRAM" |
); |
|
port ( |
wren_a : in std_logic; |
address_a : in std_logic_vector(WIDTHAD_A-1 downto 0); |
address_b : in std_logic_vector(WIDTHAD_B-1 downto 0); |
clock0, clock1, rden_b : in std_logic; |
data_a : in std_logic_vector(WIDTH_A-1 downto 0); |
data_b : in std_logic_vector(WIDTH_B-1 downto 0); |
q_a : out std_logic_vector(WIDTH_A-1 downto 0); |
q_b : out std_logic_vector(WIDTH_B-1 downto 0) |
); |
|
end component; |
constant ADDRESS_ACLR_A : STRING := "UNUSED"; |
constant ADDRESS_ACLR_B : STRING := "NONE"; |
constant ADDRESS_REG_B : STRING := "CLOCK1"; |
constant BYTE_SIZE : NATURAL := 8; |
constant BYTEENA_ACLR_A : STRING := "UNUSED"; |
constant BYTEENA_ACLR_B : STRING := "NONE"; |
constant BYTEENA_REG_B : STRING := "CLOCK1"; |
constant CLOCK_ENABLE_INPUT_A : STRING := "NORMAL"; -- normal... |
constant CLOCK_ENABLE_INPUT_B : STRING := "NORMAL"; |
constant CLOCK_ENABLE_OUTPUT_A : STRING := "NORMAL"; |
constant CLOCK_ENABLE_OUTPUT_B : STRING := "NORMAL"; |
constant INTENDED_DEVICE_FAMILY : STRING := "UNUSED"; |
constant IMPLEMENT_IN_LES : STRING := "OFF"; |
constant INDATA_ACLR_A : STRING := "UNUSED"; |
constant INDATA_ACLR_B : STRING := "NONE"; |
constant INDATA_REG_B : STRING := "CLOCK1"; |
constant INIT_FILE : STRING := "UNUSED"; |
constant INIT_FILE_LAYOUT : STRING := "PORT_A"; |
constant MAXIMUM_DEPTH : NATURAL := 0; |
constant NUMWORDS_A : NATURAL := 2**addrw_g; |
constant NUMWORDS_B : NATURAL := 2**addrw_g; |
constant OPERATION_MODE : STRING := "DUAL_PORT"; |
constant OUTDATA_ACLR_A : STRING := "NONE"; |
constant OUTDATA_ACLR_B : STRING := "NONE"; |
constant OUTDATA_REG_A : STRING := "UNREGISTERED"; |
constant OUTDATA_REG_B : STRING := "UNREGISTERED"; |
constant RAM_BLOCK_TYPE : STRING := "AUTO"; |
constant RDCONTROL_ACLR_B : STRING := "NONE"; |
constant RDCONTROL_REG_B : STRING := "CLOCK1"; |
constant READ_DURING_WRITE_MODE_MIXED_PORTS : STRING := "DONT_CARE"; |
constant WIDTH_A : NATURAL := dataw_g; |
constant WIDTH_B : NATURAL := dataw_g; |
constant WIDTH_BYTEENA_A : NATURAL := 1; |
constant WIDTH_BYTEENA_B : NATURAL := 1; |
constant WIDTHAD_A : NATURAL := addrw_g; |
constant WIDTHAD_B : NATURAL := addrw_g; |
constant WRCONTROL_ACLR_A : STRING := "UNUSED"; |
constant WRCONTROL_ACLR_B : STRING := "NONE"; |
constant WRCONTROL_WRADDRESS_REG_B : STRING := "CLOCK1"; |
constant LPM_HINT : STRING := "UNUSED"; |
constant LPM_TYPE : STRING := "ALTSYNCRAM"; |
|
signal ONE : std_logic; |
begin -- architecture rtl |
ONE <= '1'; |
|
altsyncram_1 : altsyncram |
generic map ( |
ADDRESS_ACLR_A => ADDRESS_ACLR_A, |
ADDRESS_ACLR_B => ADDRESS_ACLR_B, |
ADDRESS_REG_B => ADDRESS_REG_B, |
BYTE_SIZE => BYTE_SIZE, |
BYTEENA_ACLR_A => BYTEENA_ACLR_A, |
BYTEENA_ACLR_B => BYTEENA_ACLR_B, |
BYTEENA_REG_B => BYTEENA_REG_B, |
CLOCK_ENABLE_INPUT_A => CLOCK_ENABLE_INPUT_A, |
CLOCK_ENABLE_INPUT_B => CLOCK_ENABLE_INPUT_B, |
CLOCK_ENABLE_OUTPUT_A => CLOCK_ENABLE_OUTPUT_A, |
CLOCK_ENABLE_OUTPUT_B => CLOCK_ENABLE_OUTPUT_B, |
INTENDED_DEVICE_FAMILY => INTENDED_DEVICE_FAMILY, |
IMPLEMENT_IN_LES => IMPLEMENT_IN_LES, |
INDATA_ACLR_A => INDATA_ACLR_A, |
INDATA_ACLR_B => INDATA_ACLR_B, |
INDATA_REG_B => INDATA_REG_B, |
INIT_FILE => INIT_FILE, |
INIT_FILE_LAYOUT => INIT_FILE_LAYOUT, |
MAXIMUM_DEPTH => MAXIMUM_DEPTH, |
NUMWORDS_A => NUMWORDS_A, |
NUMWORDS_B => NUMWORDS_B, |
OPERATION_MODE => OPERATION_MODE, |
OUTDATA_ACLR_A => OUTDATA_ACLR_A, |
OUTDATA_ACLR_B => OUTDATA_ACLR_B, |
OUTDATA_REG_A => OUTDATA_REG_A, |
OUTDATA_REG_B => OUTDATA_REG_B, |
RAM_BLOCK_TYPE => RAM_BLOCK_TYPE, |
RDCONTROL_ACLR_B => RDCONTROL_ACLR_B, |
RDCONTROL_REG_B => RDCONTROL_REG_B, |
READ_DURING_WRITE_MODE_MIXED_PORTS => READ_DURING_WRITE_MODE_MIXED_PORTS, |
WIDTH_A => WIDTH_A, |
WIDTH_B => WIDTH_B, |
WIDTH_BYTEENA_A => WIDTH_BYTEENA_A, |
WIDTH_BYTEENA_B => WIDTH_BYTEENA_B, |
WIDTHAD_A => WIDTHAD_A, |
WIDTHAD_B => WIDTHAD_B, |
WRCONTROL_ACLR_A => WRCONTROL_ACLR_A, |
WRCONTROL_ACLR_B => WRCONTROL_ACLR_B, |
WRCONTROL_WRADDRESS_REG_B => WRCONTROL_WRADDRESS_REG_B, |
LPM_HINT => LPM_HINT, |
LPM_TYPE => LPM_TYPE) |
port map ( |
wren_a => wr_en_in, |
address_a => wr_addr_in, |
address_b => rd_addr_in, |
clock0 => wr_clk, |
clock1 => rd_clk, |
rden_b => ONE, |
data_a => data_in, |
q_b => data_out |
); |
|
-- |
-- generic ( |
-- addrw_g : integer := 0; |
-- dataw_g : integer := 0); |
|
-- port ( |
-- rd_clk, wr_clk : in std_logic; |
-- wr_en_in : in std_logic; |
-- data_in : in std_logic_vector(dataw_g-1 downto 0); |
-- data_out : out std_logic_vector(dataw_g-1 downto 0); |
-- rd_addr_in, wr_addr_in : in std_logic_vector (addrw_g-1 downto 0)); |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/cdc_fifo.vhd
0,0 → 1,100
------------------------------------------------------------------------------- |
-- Title : Gray counter based mixed clock FIFO |
-- Project : |
------------------------------------------------------------------------------- |
-- File : cdc_fifo.vhd |
-- Author : |
-- Created : 19.12.2006 |
-- Last update: 19.12.2006 |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2006 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2006 1.0 Timo Alho Created |
-- 19.12.2006 Ari Kulmala Comments. header. one p and one d |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity cdc_fifo is |
|
generic ( |
READ_AHEAD_g : integer := 0; |
SYNC_CLOCKS_g : integer := 0; -- 0 two flop synch, otherwise 1 flop synch |
depth_log2_g : integer := 5; |
dataw_g : integer := 32); |
|
port ( |
rst_n : in std_logic; |
rd_clk : in std_logic; |
rd_en_in : in std_logic; |
rd_empty_out : out std_logic; |
rd_one_d_out : out std_logic; |
rd_data_out : out std_logic_vector(dataw_g-1 downto 0); |
|
|
wr_clk : in std_logic; |
wr_en_in : in std_logic; |
wr_full_out : out std_logic; |
wr_one_p_out : out std_logic; |
wr_data_in : in std_logic_vector(dataw_g-1 downto 0) |
); |
|
end entity cdc_fifo; |
|
architecture rtl of cdc_fifo is |
|
signal wr_en, rd_en : std_logic; |
signal rd_addr, wr_addr : std_logic_vector(depth_log2_g-1 downto 0); |
|
signal wr_full, rd_empty : std_logic; |
begin -- architecture rtl |
|
wr_full_out <= wr_full; |
rd_empty_out <= rd_empty; |
-- write cannot be '1' when full, |
wr_en <= wr_en_in and (not wr_full); |
-- read cannot be asserted wen empty |
rd_en <= rd_en_in and (not rd_empty); |
|
fifo_ram_storage : entity work.async_dpram |
generic map ( |
addrw_g => depth_log2_g, |
dataw_g => dataw_g) |
port map ( |
rd_clk => rd_clk, |
wr_clk => wr_clk, |
wr_en_in => wr_en, |
data_in => wr_data_in, |
data_out => rd_data_out, |
rd_addr_in => rd_addr, |
wr_addr_in => wr_addr); |
|
cdc_fifo_ctrl_2 : entity work.cdc_fifo_ctrl |
generic map ( |
READ_AHEAD_g => READ_AHEAD_g, |
SYNC_CLOCKS_g => SYNC_CLOCKS_g, |
depth_log2_g => depth_log2_g) |
port map ( |
rst_n => rst_n, |
rd_clk => rd_clk, |
rd_en_in => rd_en, |
rd_empty_out => rd_empty, |
rd_addr_out => rd_addr, |
rd_one_d_out => rd_one_d_out, |
wr_clk => wr_clk, |
wr_en_in => wr_en, |
wr_full_out => wr_full, |
wr_one_p_out => wr_one_p_out, |
wr_addr_out => wr_addr |
); |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/gray_fifo/Vhdl/async_dpram_generic.vhd
0,0 → 1,34
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
architecture rtl of async_dpram is |
|
type mem_t is array (0 to 2**addrw_g - 1) of std_logic_vector(dataw_g-1 downto 0); |
|
signal memory : mem_t; |
signal wr_addr, rd_addr : integer; |
signal data_out_r : std_logic_vector(dataw_g-1 downto 0); |
begin -- architecture rtl |
|
wr_addr <= to_integer (unsigned(wr_addr_in)); |
rd_addr <= to_integer (unsigned(rd_addr_in)); |
data_out <= data_out_r; |
|
wr : process (wr_clk) is |
begin -- process write |
if rising_edge(wr_clk) then -- rising clock edge |
if (wr_en_in = '1') then |
memory(wr_addr) <= data_in; |
end if; |
end if; |
end process wr; |
-- data_out_r <= memory(rd_addr); |
rd : process (rd_clk) is |
begin -- process rd |
if rising_edge(rd_clk) then |
data_out_r <= memory(rd_addr); |
end if; |
end process rd; |
|
end architecture rtl; |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Testbench/tb_fifo1.vhdl
0,0 → 1,316
------------------------------------------------------------------------------- |
-- File : tb_fifo1.vhdl |
-- Description : Test bench for Fifo buffer, fifo length = 1! |
-- Author : Erno Salminen |
-- Date : 29.04.2002 |
-- Modified : 02.05.2002 Vesa Lahtinen Tests added |
-- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
|
entity tb_fifo1 is |
end tb_fifo1; |
|
architecture behavioral of tb_fifo1 is |
|
|
component fifo |
|
generic ( |
width : integer := 0; |
depth : integer := 0 |
); |
|
port ( |
Clk : in std_logic; |
Rst_n : std_logic; |
Data_In : in std_logic_vector (width-1 downto 0); |
Write_Enable : in std_logic; |
One_Place_Left : out std_logic; |
Full : out std_logic; |
Data_Out : out std_logic_vector (width-1 downto 0); |
Read_Enable : in std_logic; |
Empty : out std_logic; |
One_Data_Left : out std_logic |
); |
end component; |
|
constant width : integer := 16; |
constant depth : integer := 1; -- !!! |
constant PERIOD : time := 10 ns; |
|
signal Clk : std_logic; |
signal Rst_n : std_logic; |
signal Data_In : std_logic_vector (width-1 downto 0); |
signal Data_Out : std_logic_vector (width-1 downto 0); |
signal Write_Enable : std_logic; |
signal Read_Enable : std_logic; |
signal Full : std_logic; |
signal One_Place_Left : std_logic; |
signal Empty : std_logic; |
signal One_Data_Left : std_logic; |
|
signal Read_Data : std_logic_vector (width-1 downto 0); |
|
signal Test_Phase : integer range 0 to 20; |
|
begin -- behavioral |
|
|
DUT : fifo |
generic map ( |
width => width, |
depth => depth) |
port map ( |
Clk => Clk, |
Rst_n => Rst_n, |
Data_In => Data_In, |
Write_Enable => Write_Enable, |
Full => Full, |
One_Place_Left => One_Place_Left, |
Data_Out => Data_Out, |
Read_Enable => Read_Enable, |
Empty => Empty, |
One_Data_Left => One_Data_Left ); |
|
Generate_input : process |
|
----------------------------------------------------------------------------- |
-- Two procedures for writing to and for reading the fifo |
----------------------------------------------------------------------------- |
procedure WriteToFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '0'; -- 24.05 es |
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '1' then |
assert false report "Fifo full. Cannot write" severity note; |
end if; |
wait for PERIOD; |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
wait for (wait_time)* PERIOD; |
end WriteToFifo; |
|
|
procedure ReadFifo ( |
wait_time : in integer) is |
begin --procedure |
Write_Enable <= '0'; -- 24.05 es |
Read_Enable <= '1'; |
|
if Empty = '1' then |
assert false report "Fifo empty. Cannot read." severity note; |
end if; |
wait for PERIOD; |
Read_Enable <= '0'; |
wait for (wait_time)* PERIOD; |
|
end ReadFifo; |
|
procedure WriteAndReadFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '1'; |
if Empty = '1' then |
assert false report "Fifo empty. Cannot read. Writing possible." severity note; |
end if; |
|
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '1' then |
assert false report "Fifo full. Cannot write. Reading possible." severity note; |
end if; |
|
|
wait for PERIOD; |
Read_Enable <= '0'; |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); -- 24.05 es |
wait for (wait_time)* PERIOD; |
|
end WriteAndReadFifo; |
----------------------------------------------------------------------------- |
|
|
|
begin -- process Generate_input |
-- test sequence |
-- 0 wait for reset |
-- 1 write to empty fifo and read so that it is empty again |
-- 2 write to fifo until there is only one place left |
-- 3 write to fifo so that it becomes full |
-- 4 read from full fifo and continue until there is only one data left |
-- 5 read the last data |
-- write and read the empty fifo at the same time, only write is succesful! |
-- 6 write to fifo, write and read at the same time, both should be succesful! |
-- 7 write until fifo is full |
-- 8 write and read full fifo, only reading succesful! |
-- read until fifo is empty |
-- 9 make sure fifo is empty |
|
|
-- 0 Wait for reset |
Write_Enable <= '0'; |
Read_Enable <= '0'; |
Data_In <= (others => 'Z'); |
Test_Phase <= 0; |
wait for (6+2)*PERIOD; |
wait for PERIOD/2; |
wait for PERIOD/3; |
|
|
-- At the beginning |
-- Full = 0 |
-- Empty = 1 |
-- One_Place_Left = 1 |
-- One_Data_Left = 0 |
-- NOTE! Empty = One_Place_Left and Full = One_Data_Left |
assert Full = '0' report "0: Full not correct" severity error; |
assert Empty = '1' report "0: Empty not correct" severity error; |
assert One_Data_Left = '0' report "0: One_Data_Left not correct" severity error; |
assert One_Place_Left = '1' report "0: One_Place_Left not correct" severity error; |
|
-- 1) Write to empty fifo |
Test_Phase <= Test_Phase +1; |
WriteToFifo (5, 1); |
assert Full = '1' report "1: Full not correct" severity error; |
assert Empty = '0' report "1: Empty not correct" severity error; |
assert One_Data_Left = '1' report "1: One_Data_Left not correct" severity error; |
assert One_Place_Left = '0' report "1: One_Place_Left not correct" severity error; |
assert Data_Out = conv_std_logic_vector (5, width) report "1: data not stored correctly" severity error; |
|
-- 2 )write to full fifo |
Test_Phase <=Test_Phase +1; |
WriteToFifo (10, 1); |
WriteToFifo (11, 1); |
WriteToFifo (12, 1); |
WriteToFifo (13, 1); |
assert Full = '1' report "2: Full not correct" severity error; |
assert Empty = '0' report "2: Empty not correct" severity error; |
assert One_Data_Left = '1' report "2: One_Data_Left not correct" severity error; |
assert One_Place_Left = '0' report "2: One_Place_Left not correct" severity error; |
assert Data_Out = conv_std_logic_vector (5, width) report "2: data not stored correctly" severity error; |
|
|
-- 3) write and read full fifo |
-- only read succesful |
Test_Phase <= Test_Phase +1; |
WriteAndReadFifo (14,2); |
assert Full = '0' report "3: Full not correct" severity error; |
assert Empty = '1' report "3: Empty not correct" severity error; |
assert One_Data_Left = '0' report "3: One_Data_Left not correct" severity error; |
assert One_Place_Left = '1' report "3: One_Place_Left not correct" severity error; |
|
|
-- 4 read empty fifo |
Test_Phase <= Test_Phase +1; |
ReadFifo (1); |
ReadFifo (1); |
ReadFifo (1); |
assert Full = '0' report "4: Full not correct" severity error; |
assert Empty = '1' report "4: Empty not correct" severity error; |
assert One_Data_Left = '0' report "4: One_Data_Left not correct" severity error; |
assert One_Place_Left = '1' report "4: One_Place_Left not correct" severity error; |
|
-- 5 write and read empty fifo |
Test_Phase <= Test_Phase +1; |
WriteAndReadFifo (15,2); |
assert Full = '1' report "5: Full not correct" severity error; |
assert Empty = '0' report "5: Empty not correct" severity error; |
assert One_Data_Left = '1' report "5: One_Data_Left not correct" severity error; |
assert One_Place_Left = '0' report "5: One_Place_Left not correct" severity error; |
assert Data_Out = conv_std_logic_vector (15, width) report "5: data not stored correctly" severity error; |
|
-- 6 read full fifo |
Test_Phase <= Test_Phase +1; |
ReadFifo (2); |
assert Full = '0' report "6: Full not correct" severity error; |
assert Empty = '1' report "6: Empty not correct" severity error; |
assert One_Data_Left = '0' report "6: One_Data_Left not correct" severity error; |
assert One_Place_Left = '1' report "6: One_Place_Left not correct" severity error; |
|
-- 7 other shit |
-- ReadFifo (2); |
-- WriteToFifo (52, 1); |
-- ReadFifo (2); |
|
-- WriteToFifo (14, 1); |
-- WriteToFifo (15, 1); |
-- WriteToFifo (16, 1); |
|
-- WriteToFifo (17, 1); |
-- ReadFifo (1); |
-- ReadFifo (1); |
-- ReadFifo (4); |
|
-- WriteAndReadFifo (67,2); |
-- wait for 5*PERIOD; |
-- ReadFifo (1); |
|
-- Test completed |
Test_Phase <= 0; |
wait; |
end process Generate_input; |
|
|
|
Read_Data_from_fifo : process (Clk, Rst_n) |
begin -- process Read_Data_from_fifo |
if Rst_n = '0' then -- asynchronous reset (active low) |
Read_Data <= (others => '0'); |
elsif Clk'event and Clk = '1' then -- rising clock edge |
if Read_Enable = '1' then |
Read_Data <= Data_Out; |
else |
Read_Data <= Read_Data; |
end if; |
end if; |
end process Read_Data_from_fifo; |
|
|
|
|
CLOCK1: process -- generate clock signal for design |
variable clktmp: std_logic := '0'; |
begin |
wait for PERIOD/2; |
clktmp := not clktmp; |
Clk <= clktmp; |
end process CLOCK1; |
|
RESET: process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*PERIOD; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end behavioral; |
|
|
|
|
|
configuration basic_cfg of tb_fifo1 is |
|
for behavioral |
for all : fifo |
--use entity work.fifo (inout_mux); |
use entity work.fifo (in_mux); |
--use entity work.fifo (shift_reg); |
end for; |
|
end for; |
|
|
end basic_cfg; |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Testbench/tb_fifo_stratix.vhd
0,0 → 1,188
------------------------------------------------------------------------------- |
-- title : tb_fifo_stratix |
-- project : |
------------------------------------------------------------------------------- |
-- file : tb_fifo_stratix.vhdl |
-- author : kulmala3 |
-- created : 08.09.2004 |
-- last update: 31.05.2005 |
-- description: tests that fifo_stratix works in fpga. synthesizable test bench |
------------------------------------------------------------------------------- |
-- revisions : |
-- date version author description |
-- 08.09.2004 1.0 ak created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_unsigned.all; |
|
entity tb_fifo_stratix is |
|
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
led_state_out : out std_logic_vector(3 downto 0); |
led_error_out : out std_logic_vector(3 downto 0) |
); |
|
end tb_fifo_stratix; |
|
architecture rtl of tb_fifo_stratix is |
|
component fifo |
generic ( |
data_width_g : integer; |
depth_g : integer); |
port ( |
clk : in std_logic; |
rst_n : in std_logic; |
data_in : in std_logic_vector (data_width_g-1 downto 0); |
we_in : in std_logic; |
one_p_out : out std_logic; |
full_out : out std_logic; |
data_out : out std_logic_vector (data_width_g-1 downto 0); |
re_in : in std_logic; |
empty_out : out std_logic; |
one_d_out : out std_logic); |
end component; |
|
type ctrl_state is (initial, write_fifo, read_fifo); |
|
signal control_r : ctrl_state; |
signal write_counter_r : integer range 0 to 2**16-1; |
signal read_counter_r : integer range 0 to 2**16-1; |
signal read_data_r : integer range 0 to 2**16-1; |
signal error_counter_r : integer range 0 to 2**16-1; |
|
constant initial_c : std_logic_vector := "0001"; |
constant write_c : std_logic_vector := "0010"; |
constant read_c : std_logic_vector := "0100"; |
|
|
constant width : integer := 16; |
constant depth : integer := 5; |
|
signal data_to_fifo : std_logic_vector (width-1 downto 0); |
signal write_enable : std_logic; |
signal one_place_left_r : std_logic; |
signal full_r : std_logic; |
signal data_from_fifo : std_logic_vector (width-1 downto 0); |
signal read_enable : std_logic; |
signal empty_r : std_logic; |
signal one_data_left_r : std_logic; |
|
signal ef_r : std_logic_vector(1 downto 0); |
signal temp : std_logic; |
begin -- rtl |
|
data_to_fifo <= conv_std_logic_vector(write_counter_r, width); |
read_data_r <= conv_integer(data_from_fifo); |
ef_r <= empty_r & full_r; |
led_error_out <= conv_std_logic_vector(error_counter_r, 4); |
temp <= one_data_left_r and one_place_left_r; |
|
fifo_1 : fifo |
generic map ( |
data_width_g => width, |
depth_g => depth) |
port map ( |
clk => clk, |
rst_n => rst_n, |
data_in => data_to_fifo, |
we_in => write_enable, |
one_p_out => one_place_left_r, |
full_out => full_r, |
data_out => data_from_fifo, |
re_in => read_enable, |
empty_out => empty_r, |
one_d_out => one_data_left_r); |
|
process (clk, rst_n) |
begin -- process |
if rst_n = '0' then -- asynchronous reset (active low) |
control_r <= initial; |
write_enable <= '0'; |
read_enable <= '0'; |
write_counter_r <= 0; |
read_counter_r <= 1; |
-- just to use one_data_left_r and one_place_left_r |
led_state_out <= temp & temp & temp & temp; |
error_counter_r <= 0; |
|
elsif clk'event and clk = '1' then -- rising clock edge |
|
case control_r is |
when initial => |
case ef_r is |
when "00" | "01" => -- not empty, not full or full-> read |
control_r <= read_fifo; |
write_enable <= '0'; |
read_enable <= '0'; |
when "10" => -- empty, write |
control_r <= write_fifo; |
write_enable <= '0'; |
read_enable <= '0'; |
when others => null; --empty and full, not possible... |
end case; |
led_state_out <= initial_c; |
|
when write_fifo => |
read_enable <= '0'; |
if full_r = '0' then -- not yet full |
write_enable <= '1'; |
write_counter_r <= write_counter_r+1; |
control_r <= write_fifo; |
else |
-- fifo full |
write_enable <= '0'; |
-- write_counter_r+1 always written, so we do -1 here. |
write_counter_r <= write_counter_r-1; |
control_r <= read_fifo; |
end if; |
led_state_out <= write_c; |
|
when read_fifo => |
write_enable <= '0'; |
if empty_r = '0' then |
read_enable <= '1'; |
if read_enable = '1' then |
if read_data_r /= read_counter_r then |
-- error! |
assert false report "fifo read error, wrong data" severity error; |
if error_counter_r >= 2**4-1 then |
error_counter_r <= 0; |
else |
error_counter_r <= error_counter_r +1; |
end if; |
-- if something was missing, start from the new data value |
read_counter_r <= read_data_r+1; |
else |
error_counter_r <= error_counter_r; |
read_counter_r <= read_counter_r+1; |
end if; |
control_r <= read_fifo; |
end if; |
else |
-- empty |
read_enable <= '0'; |
read_counter_r <= read_counter_r; |
error_counter_r <= error_counter_r; |
control_r <= initial; |
end if; |
|
led_state_out <= read_c; |
|
|
when others => null; |
|
|
end case; |
|
|
end if; |
end process; |
|
|
end rtl; |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Testbench/tb_fifo2.vhdl
0,0 → 1,338
------------------------------------------------------------------------------- |
-- File : tb_fifo2.vhdl |
-- Description : Testbench for a Fifo buffer |
-- Author : Erno Salminen |
-- Date : 29.04.2002 |
-- Modified : 02.05.2002 Vesa Lahtinen More tests added |
-- 18.06.2003 AK - direction for Rst_n signal |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
|
entity tb_fifo2 is |
end tb_fifo2; |
|
architecture behavioral of tb_fifo2 is |
|
component fifo |
|
generic ( |
width : integer := 0; |
depth : integer := 0 |
); |
|
port ( |
Clk : in std_logic; |
Rst_n : in std_logic; |
Data_In : in std_logic_vector (width-1 downto 0); |
Write_Enable : in std_logic; |
One_Place_Left : out std_logic; |
Full : out std_logic; |
Data_Out : out std_logic_vector (width-1 downto 0); |
Read_Enable : in std_logic; |
Empty : out std_logic; |
One_Data_Left : out std_logic |
); |
|
|
end component; |
|
|
constant width : integer := 16; |
constant depth : integer := 5; |
constant PERIOD : time := 10 ns; |
|
signal Clk : std_logic; |
signal Rst_n : std_logic; |
signal Data_In : std_logic_vector (width-1 downto 0); |
signal Data_Out : std_logic_vector (width-1 downto 0); |
signal Write_Enable : std_logic; |
signal Read_Enable : std_logic; |
signal Full : std_logic; |
signal One_Place_Left : std_logic; |
signal Empty : std_logic; |
signal One_Data_Left : std_logic; |
|
signal Read_Data : std_logic_vector (width-1 downto 0); |
signal Test_Phase : integer range 0 to 20; |
|
begin -- behavioral |
|
|
DUT : fifo |
generic map ( |
width => width, |
depth => depth) |
port map ( |
Clk => Clk, |
Rst_n => Rst_n, |
Data_In => Data_In, |
Write_Enable => Write_Enable, |
Full => Full, |
One_Place_Left => One_Place_Left, |
Data_Out => Data_Out, |
Read_Enable => Read_Enable, |
Empty => Empty, |
One_Data_Left => One_Data_Left ); |
|
Generate_input : process |
|
----------------------------------------------------------------------------- |
-- Two procedures for writing to and for reading the fifo |
----------------------------------------------------------------------------- |
procedure WriteToFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '1' then |
--assert false report "Fifo full. Cannot write" severity note; |
end if; |
wait for PERIOD; |
--if wait_time > 0 then |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
wait for (wait_time)* PERIOD; |
--end if; |
|
end WriteToFifo; |
|
|
procedure ReadFifo ( |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '1'; |
if Empty = '1' then |
--assert false report "Fifo empty. Cannot read" severity note; |
end if; |
wait for PERIOD; |
--if wait_time > 0 then |
Read_Enable <= '0'; |
wait for (wait_time)* PERIOD; |
--end if; |
|
|
end ReadFifo; |
|
|
procedure WriteAndReadFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '1'; |
if Empty = '1' then |
--assert false report "Fifo empty. Cannot read" severity note; |
end if; |
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '0' then |
--assert false report "Fifo full. Cannot write" severity note; |
end if; |
|
|
wait for PERIOD; |
--if wait_time > 0 then |
Read_Enable <= '0'; |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
wait for (wait_time)* PERIOD; |
--end if; |
|
|
end WriteAndReadFifo; |
----------------------------------------------------------------------------- |
|
|
|
begin -- process Generate_input |
|
-- test sequence |
-- 0 wait for reset |
-- 1 write to empty fifo and read so that it is empty again |
-- 2 write to fifo until there is only one place left |
-- 3 write to fifo so that it becomes full |
-- 4 read from full fifo and continue until there is only one data left |
-- 5 read the last data |
-- write and read the empty fifo at the same time, only write is succesful! |
-- 6 write to fifo, write and read at the same time, both should be succesful! |
-- 7 write until fifo is full |
-- 8 write and read full fifo, only reading succesful! |
-- read until fifo is empty |
-- 9 make sure fifo is empty |
|
-- Wait for reset |
Write_Enable <= '0'; |
Read_Enable <= '0'; |
Data_In <= (others => 'Z'); |
Test_Phase <= 0; |
wait for (6+2)*PERIOD; |
wait for PERIOD/2; |
wait for PERIOD/3; |
|
-- 0) At the beginning |
-- One_Place_Left = 0 |
-- Empty = 1 |
-- Full = 0 |
-- One_Data_Left = 0 |
assert One_Data_Left = '0' report "0: One_Place_Left does not work" severity error; |
assert Empty = '1' report "0: Empty does not work" severity error; |
assert Full = '0' report "0: Full does not work" severity error; |
assert One_Data_Left = '0' report "0: One_Place_Left does not work" severity error; |
|
-- 1) Write one data to empty fifo |
-- Data_Out = 5 |
-- One_Data_Left = 1 |
-- Empty = 0 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (5, 1); |
assert Data_Out = conv_std_logic_vector (5, width) report "1: data not stored correctly" severity error; |
assert One_Data_Left = '1' report "1: One_Place_Left does not work" severity error; |
assert Empty = '0' report "1: Empty does not work" severity error; |
|
ReadFifo (2); |
WriteToFifo (52, 1); |
ReadFifo (2); |
|
-- 2) Fill up the empty fifo until there is only one place left |
-- One_Place_Left = 1 |
-- Full = 0 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (10, 1); --to empty fifo |
assert Data_Out = conv_std_logic_vector (10, width) report "2: data not stored correctly" severity error; |
WriteToFifo (11, 0); |
WriteToFifo (12, 0); |
WriteToFifo (13, 0); |
assert One_Place_Left = '1' report "2: One_Place_Left does not work" severity error; |
assert Full = '0' report "2: Full does not work" severity error; |
|
--3) One data more => fifo becomes full |
-- Try to write two data (15 & 16) to full fifo |
-- One_Place_Left = 0 |
-- Full = 1 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (14, 0); |
assert One_Place_Left = '0' report "3: One_Place_Left does not work" severity error; |
assert Full = '1' report "3: Full does not work" severity error; |
|
WriteToFifo (15, 0); |
WriteToFifo (16, 0); |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
|
-- 4) Read one data from full fifo |
Test_Phase <= Test_Phase +1; |
ReadFifo (1); -- fifo out: 10 => 11 |
assert One_Place_Left = '1' report "4: One_Place_Left does not work" severity error; |
assert Full = '0' report "4: Full does not work" severity error; |
assert Data_Out = conv_std_logic_vector (11, width) report "4: data not stored correctly" severity error; |
|
ReadFifo (1); -- fifo out: 11 => 12 |
ReadFifo (1); -- fifo out: 12 => 13 |
WriteToFifo (17, 1); |
ReadFifo (1); -- fifo out: 13 => 14 |
ReadFifo (1); -- fifo out: 14 => 17 |
|
-- 5) Read the last data |
-- write one to empty fifo and read empty fifo at the same time |
Test_Phase <= Test_Phase +1; |
assert Data_Out = conv_std_logic_vector (17, width) report "5: data not stored correctly" severity error; |
ReadFifo (4); -- fifo out: 14 => empty (11) |
WriteAndReadFifo (67,2); |
wait for 5*PERIOD; |
ReadFifo (1);-- fifo out: 67 => empty |
|
-- 6) Fill up the fifo with two (1 & 2) data |
-- Start reading fifo at the same as the latter data (2) is written |
Test_Phase <= Test_Phase +1; |
WriteToFifo (1, 0); |
WriteAndReadFifo (2,0); |
assert Data_Out = conv_std_logic_vector (2, width) report "6: data not stored correctly" severity error; |
|
-- 7) Fill up the fifo |
Test_Phase <= Test_Phase +1; |
WriteToFifo (3, 0); |
WriteToFifo (4, 0); |
WriteToFifo (5, 0); |
WriteToFifo (6, 0); |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
-- Fifo now full |
assert Full = '1' report "8: Full does not work" severity error; |
|
-- 8) Empty the fifo |
-- At first try to write one data (88) to full fifo and read fifo at the same |
-- time. Data 88 should not go to fifo |
Test_Phase <= Test_Phase +1; |
WriteAndReadFifo(88,0); |
ReadFifo(0); |
ReadFifo(0); |
ReadFifo(0); |
ReadFifo(0); |
assert Data_Out /= conv_std_logic_vector (88, width) report "8: data not stored correctly" severity error; |
|
-- 9) Fifo should be empty |
Test_Phase <= 9; |
assert Empty = '1' report "9: Empty does not work" severity error; |
|
-- Test completd |
Test_Phase <= 0; |
wait; |
end process Generate_input; |
|
|
|
Read_Data_from_fifo : process (Clk, Rst_n) |
begin -- process Read_Data_from_fifo |
if Rst_n = '0' then -- asynchronous reset (active low) |
Read_Data <= (others => '0'); |
elsif Clk'event and Clk = '1' then -- rising clock edge |
if Read_Enable = '1' and Empty = '0'then |
Read_Data <= Data_Out; |
else |
Read_Data <= Read_Data; |
end if; |
end if; |
end process Read_Data_from_fifo; |
|
|
|
|
|
CLOCK1: process -- generate clock signal for design |
variable clktmp: std_logic := '0'; |
begin |
wait for PERIOD/2; |
clktmp := not clktmp; |
Clk <= clktmp; |
end process CLOCK1; |
|
|
|
RESET: process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*PERIOD; -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end behavioral; |
|
|
configuration basic_cfg of tb_fifo2 is |
|
for behavioral |
for all : fifo |
--use entity work.fifo (inout_mux); |
--use entity work.fifo (in_mux); |
use entity work.fifo (shift_reg); |
end for; |
|
end for; |
|
end basic_cfg; |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Testbench/tb_fifo_mixed_clocks2.vhdl
0,0 → 1,354
------------------------------------------------------------------------------- |
-- File : tb_fifo_mixed_clocks2.vhdl |
-- Description : Testbench for a mixed clock Fifo buffer |
-- Author : Ari Kulmala |
-- Date : 19.06.2003 |
-- Modified : |
-- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
|
entity tb_fifo_mixed_clocks2 is |
end tb_fifo_mixed_clocks2; |
|
architecture behavioral of tb_fifo_mixed_clocks2 is |
|
component mixed_clocks_fifo |
|
generic ( |
width : integer := 0; |
depth : integer := 0); |
|
port ( |
Clk_In : in std_logic; |
Clk_Out : in std_logic; |
Rst_n : in std_logic; -- Active low |
Data_In : in std_logic_vector (width-1 downto 0); |
Write_Enable : in std_logic; |
-- One_Place_Left : out std_logic; |
Full : out std_logic; |
Data_Out : out std_logic_vector (width-1 downto 0); |
Read_Enable : in std_logic; |
Empty : out std_logic |
-- One_Data_Left : out std_logic |
); |
|
end component; |
|
|
constant width : integer := 16; |
constant depth : integer := 5; |
constant PERIOD_IN : time := 10 ns; |
constant PERIOD_OUT : time := 4 ns; |
|
signal Clk_In : std_logic; |
signal Clk_Out : std_logic; |
signal Rst_n : std_logic; |
signal Data_In : std_logic_vector (width-1 downto 0); |
signal Data_Out : std_logic_vector (width-1 downto 0); |
signal Write_Enable : std_logic; |
signal Read_Enable : std_logic; |
signal Full : std_logic; |
--signal One_Place_Left : std_logic; |
signal Empty : std_logic; |
--signal One_Data_Left : std_logic; |
|
signal Read_Data : std_logic_vector (width-1 downto 0); |
signal Test_Phase : integer range 0 to 20; |
|
begin -- behavioral |
|
|
DUT : mixed_clocks_fifo |
generic map ( |
width => width, |
depth => depth) |
port map ( |
Clk_In => Clk_In, |
Clk_Out => Clk_Out, |
Rst_n => Rst_n, |
Data_In => Data_In, |
Write_Enable => Write_Enable, |
Full => Full, |
-- One_Place_Left => One_Place_Left, |
Data_Out => Data_Out, |
Read_Enable => Read_Enable, |
Empty => Empty); |
-- One_Data_Left => One_Data_Left ); |
|
Generate_input : process |
|
----------------------------------------------------------------------------- |
-- Two procedures for writing to and for reading the fifo |
----------------------------------------------------------------------------- |
procedure WriteToFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '1' then |
--assert false report "Fifo full. Cannot write" severity note; |
end if; |
wait for PERIOD_IN; |
--if wait_time > 0 then |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
wait for (wait_time)* PERIOD_IN; |
--end if; |
|
end WriteToFifo; |
|
|
procedure ReadFifo ( |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '1'; |
if Empty = '1' then |
--assert false report "Fifo empty. Cannot read" severity note; |
end if; |
wait for PERIOD_OUT+1ns; |
--if wait_time > 0 then |
Read_Enable <= '0'; |
wait for (wait_time)* PERIOD_OUT; |
--end if; |
|
|
end ReadFifo; |
|
|
procedure WriteAndReadFifo ( |
Data_To_Fifo : in integer; |
wait_time : in integer) is |
begin --procedure |
Read_Enable <= '1'; |
if Empty = '1' then |
--assert false report "Fifo empty. Cannot read" severity note; |
end if; |
Data_In <= conv_std_logic_vector (Data_To_Fifo, width); |
Write_Enable <= '1'; |
if Full = '0' then |
--assert false report "Fifo full. Cannot write" severity note; |
end if; |
|
|
wait for PERIOD_IN; |
--if wait_time > 0 then |
Read_Enable <= '0'; |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
wait for (wait_time)* (PERIOD_IN); |
--end if; |
|
|
end WriteAndReadFifo; |
----------------------------------------------------------------------------- |
|
|
|
begin -- process Generate_input |
|
-- test sequence |
-- 0 wait for reset |
-- 1 write to empty fifo and read so that it is empty again |
-- 2 write to fifo until there is only one place left |
-- 3 write to fifo so that it becomes full |
-- 4 read from full fifo and continue until there is only one data left |
-- 5 read the last data |
-- write and read the empty fifo at the same time, only write is succesful! |
-- 6 write to fifo, write and read at the same time, both should be succesful! |
-- 7 write until fifo is full |
-- 8 write and read full fifo, only reading succesful! |
-- read until fifo is empty |
-- 9 make sure fifo is empty |
|
-- Wait for reset |
Write_Enable <= '0'; |
Read_Enable <= '0'; |
Data_In <= (others => 'Z'); |
Test_Phase <= 0; |
wait for (6+2)*PERIOD_IN; |
wait for PERIOD_IN/2; |
wait for PERIOD_IN/3; |
|
-- 0) At the beginning |
-- One_Place_Left = 0 |
-- Empty = 1 |
-- Full = 0 |
-- One_Data_Left = 0 |
-- assert One_Data_Left = '0' report "0: One_Place_Left does not work" severity error; |
assert Empty = '1' report "0 : Empty does not work" severity error; |
assert Full = '0' report "0 : Full does not work" severity error; |
-- assert One_Data_Left = '0' report "0: One_Place_Left does not work" severity error; |
|
-- 1) Write one data to empty fifo |
-- Data_Out = 5 |
-- One_Data_Left = 1 |
-- Empty = 0 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (5, 1); |
assert Data_Out = conv_std_logic_vector (5, width) report "1 : data not stored correctly" severity error; |
-- assert One_Data_Left = '1' report "1: One_Place_Left does not work" severity error; |
assert Empty = '0' report "1 : Empty does not work" severity error; |
|
ReadFifo (2); |
WriteToFifo (52, 1); |
ReadFifo (2); |
|
-- 2) Fill up the empty fifo until there is only one place left |
-- One_Place_Left = 1 |
-- Full = 0 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (10, 1); --to empty fifo |
assert Data_Out = conv_std_logic_vector (10, width) report "2 : data not stored correctly" severity error; |
WriteToFifo (11, 0); |
WriteToFifo (12, 0); |
WriteToFifo (13, 0); |
-- assert One_Place_Left = '1' report "2: One_Place_Left does not work" severity error; |
assert Full = '0' report "2 : Full does not work" severity error; |
|
--3) One data more => fifo becomes full |
-- Try to write two data (15 & 16) to full fifo |
-- One_Place_Left = 0 |
-- Full = 1 |
Test_Phase <= Test_Phase +1; |
WriteToFifo (14, 0); |
-- assert One_Place_Left = '0' report "3: One_Place_Left does not work" severity error; |
assert Full = '1' report "3 : Full does not work" severity error; |
|
WriteToFifo (15, 0); |
WriteToFifo (16, 0); |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
|
-- 4) Read one data from full fifo |
Test_Phase <= Test_Phase +1; |
ReadFifo (1); -- fifo out: 10 => 11 |
-- assert One_Place_Left = '1' report "4: One_Place_Left does not work" severity error; |
assert Full = '0' report "4 : Full does not work" severity error; |
assert Data_Out = conv_std_logic_vector (11, width) report "4 : data not stored correctly" severity error; |
|
ReadFifo (1); -- fifo out: 11 => 12 |
ReadFifo (1); -- fifo out: 12 => 13 |
WriteToFifo (17, 1); |
ReadFifo (1); -- fifo out: 13 => 14 |
ReadFifo (1); -- fifo out: 14 => 17 |
|
-- 5) Read the last data |
-- write one to empty fifo and read empty fifo at the same time |
Test_Phase <= Test_Phase +1; |
assert Data_Out = conv_std_logic_vector (17, width) report "5 : data not stored correctly" severity error; |
ReadFifo (4); -- fifo out: 14 => empty (11) |
WriteAndReadFifo (67, 2); |
wait for 5*PERIOD_IN; |
ReadFifo (1); -- fifo out: 67 => empty |
|
-- 6) Fill up the fifo with two (1 & 2) data |
-- Start reading fifo at the same as the latter data (2) is written |
Test_Phase <= Test_Phase +1; |
WriteToFifo (1, 0); |
WriteAndReadFifo (2, 0); |
assert Data_Out = conv_std_logic_vector (2, width) report "6 : data not stored correctly" severity error; |
|
-- 7) Fill up the fifo |
Test_Phase <= Test_Phase +1; |
WriteToFifo (3, 0); |
WriteToFifo (4, 0); |
WriteToFifo (5, 0); |
WriteToFifo (6, 0); |
Write_Enable <= '0'; |
Data_In <= (others => 'Z'); |
-- Fifo now full |
assert Full = '1' report "8 : Full does not work" severity error; |
|
-- 8) Empty the fifo |
-- At first try to write one data (88) to full fifo and read fifo at the same |
-- time. Data 88 should not go to fifo |
Test_Phase <= Test_Phase +1; |
WriteAndReadFifo(88, 0); |
ReadFifo(0); |
ReadFifo(0); |
ReadFifo(0); |
ReadFifo(0); |
assert Data_Out /= conv_std_logic_vector (88, width) report "8 : data not stored correctly" severity error; |
|
-- 9) Fifo should be empty |
Test_Phase <= 9; |
assert Empty = '1' report "9 : Empty does not work" severity error; |
|
-- Test completed |
Test_Phase <= 0; |
wait; |
end process Generate_input; |
|
|
|
Read_Data_from_fifo : process (Clk_In, Rst_n) |
begin -- process Read_Data_from_fifo |
if Rst_n = '0' then -- asynchronous reset (active low) |
Read_Data <= (others => '0'); |
elsif Clk_In'event and Clk_In = '1' then -- rising clock edge |
if Read_Enable = '1' and Empty = '0'then |
Read_Data <= Data_Out; |
else |
Read_Data <= Read_Data; |
end if; |
end if; |
end process Read_Data_from_fifo; |
|
|
|
|
|
CLOCK_IN : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
wait for PERIOD_IN/2; |
clktmp := not clktmp; |
Clk_In <= clktmp; |
end process CLOCK_IN; |
|
CLOCK_OUT : process -- generate clock signal for design |
variable clktmp : std_logic := '0'; |
begin |
wait for PERIOD_OUT/2; |
clktmp := not clktmp; |
Clk_Out <= clktmp; |
end process CLOCK_OUT; |
|
|
|
RESET : process |
begin |
Rst_n <= '0'; -- Reset the testsystem |
wait for 6*(PERIOD_IN); -- Wait |
Rst_n <= '1'; -- de-assert reset |
wait; |
end process RESET; |
|
|
|
end behavioral; |
|
|
configuration basic_cfg of tb_fifo_mixed_clocks2 is |
|
for behavioral |
for all : mixed_clocks_fifo |
--use entity work.fifo (inout_mux); |
--use entity work.fifo (in_mux); |
--use entity work.fifo (shift_reg); |
use entity work.mixed_clocks_fifo (mixed_clocks); |
end for; |
|
end for; |
|
end basic_cfg; |
|
|
|
|
|
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/mixed_fifos_wave.do
0,0 → 1,29
onerror {resume} |
quietly WaveActivateNextPane {} 0 |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/clk_in |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/clk_out |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/rst_n |
add wave -noupdate -format Literal -radix decimal /tb_fifo_mixed_clocks2/dut/data_in |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/write_enable |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/full |
add wave -noupdate -format Literal -radix decimal /tb_fifo_mixed_clocks2/dut/data_out |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/read_enable |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/empty |
add wave -noupdate -format Literal -radix decimal /tb_fifo_mixed_clocks2/dut/input_buffer |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/full_reg |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/empty_reg |
add wave -noupdate -format Literal -radix decimal /tb_fifo_mixed_clocks2/dut/write_token |
add wave -noupdate -format Literal -radix decimal /tb_fifo_mixed_clocks2/dut/read_token |
add wave -noupdate -format Logic -radix decimal /tb_fifo_mixed_clocks2/dut/write_turned |
TreeUpdate [SetDefaultTree] |
WaveRestoreCursors {92 ns} |
WaveRestoreZoom {0 ns} {257 ns} |
configure wave -namecolwidth 211 |
configure wave -valuecolwidth 39 |
configure wave -justifyvalue left |
configure wave -signalnamewidth 0 |
configure wave -snapdistance 10 |
configure wave -datasetprefix 0 |
configure wave -rowmargin 4 |
configure wave -childrowmargin 2 |
run 700 |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/create_makefile
0,0 → 1,51
# |
# Skripti kaantaa kaikki vhdl-tiedostot ja tekee niista makefilen |
# Ymparistomuuttjat |
# CODEC_DATA_DIR kertoo mihin hakemistoon kaannetyt fiilut laitetaan. |
# CODEC_WORK_DIR kertoo tyohakemiston (mm. Makefile.vhdl on siella) |
# |
|
clear |
#Poistetaan vanha codelib ja tehdaan ja mapataan uusi |
echo "Removing old vhdl library" |
rm -rf $CODEC_DATA_DIR/codelib |
echo; echo "Creating a new library at" |
echo $CODEC_DATA_DIR; echo |
|
vlib $CODEC_DATA_DIR/codelib |
vmap work $CODEC_DATA_DIR/codelib |
|
# Hibi-koodit v2 |
echo; echo "Compiling vhdl codes"; echo |
|
vcom Vhdl/shift_slot.vhdl |
|
vcom Vhdl/fifo_iom.vhdl |
vcom Vhdl/fifo_im.vhdl |
vcom Vhdl/fifo_shift.vhdl |
vcom Vhdl/fifo_shift_slotted.vhdl |
#vcom Vhdl/fifo_casev3.vhdl |
#vcom Vhdl/fifo_im_case.vhdl |
vcom Vhdl/fifo_casev5.vhdl |
vcom Vhdl/fifo_casev4.vhdl |
vcom Vhdl/fifo_mixed_clocks.vhdl |
|
# Testipenkit |
echo; echo "Compiling vhdl testbenches";echo |
|
vcom Testbench/tb_fifo1.vhdl |
vcom Testbench/tb_fifo2.vhdl |
vcom Testbench/tb_fifo_mixed_clocks2.vhdl |
|
|
|
|
# Poistetaan vanha makefile ja tehdaan uusi |
echo;echo "Creating a new makefile" |
rm -f $CODEC_WORK_DIR/Makefile.vhdl |
vmake $CODEC_DATA_DIR/codelib > $CODEC_WORK_DIR/Makefile |
|
echo " --------Create_Makefile done-------------" |
|
|
|
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/wave.do
0,0 → 1,26
onerror {resume} |
quietly WaveActivateNextPane {} 0 |
add wave -noupdate -format Logic /tb_fifo2/clk |
add wave -noupdate -format Logic /tb_fifo2/rst_n |
add wave -noupdate -format Literal -radix unsigned /tb_fifo2/data_in |
add wave -noupdate -format Literal -radix unsigned /tb_fifo2/data_out |
add wave -noupdate -format Logic /tb_fifo2/write_enable |
add wave -noupdate -format Logic /tb_fifo2/read_enable |
add wave -noupdate -format Logic /tb_fifo2/full |
add wave -noupdate -format Logic /tb_fifo2/one_place_left |
add wave -noupdate -format Logic /tb_fifo2/empty |
add wave -noupdate -format Logic /tb_fifo2/one_data_left |
add wave -noupdate -format Literal -radix unsigned /tb_fifo2/read_data |
add wave -noupdate -format Literal /tb_fifo2/test_phase |
add wave -noupdate -format Literal -radix unsigned /tb_fifo2/dut/fifo_buffer |
TreeUpdate [SetDefaultTree] |
WaveRestoreCursors {0 ns} |
WaveRestoreZoom {0 ns} {1 us} |
configure wave -namecolwidth 150 |
configure wave -valuecolwidth 100 |
configure wave -justifyvalue left |
configure wave -signalnamewidth 0 |
configure wave -snapdistance 10 |
configure wave -datasetprefix 0 |
configure wave -rowmargin 4 |
configure wave -childrowmargin 2 |
/trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/fifo_Comparison.ppt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/fifo_Comparison.ppt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison_fpga.m
===================================================================
--- trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison_fpga.m (nonexistent)
+++ trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison_fpga.m (revision 18)
@@ -0,0 +1,91 @@
+% SYNTHESIS FOR FPGA
+% used Mentor Graphics Precision RTL Synthesis 2003a.29
+% Synthesized for Altera Excalibur ARM, frequency 20 MHz
+%
+% Uses double_fifo_muxed_read components
+% which include two FIFOs and a read multiplexer
+% FIFOs are 3b wide
+
+close all
+clear all
+
+% Vertailussa kaytetyt fifojen pituudet
+length = [3 30 80]
+
+
+% Max clock frequency
+% (library set up time 0.17 ns is left out of these results)
+delay_casev3 = [113.3 62.4 46.3]
+delay_casev4 = [113.3 59.0 40.7]
+delay_im_case = [ 88.0 81.1 71.0]
+delay_im = [ 84.4 71.2 59.7]
+
+% Areas [IOs]
+%io_casev3 = [ 32 32 32]
+%io_casev4 = [ 32 32 32]
+%io_im_case = [ 32 32 32]
+
+% Areas [LCs]
+area_casev3 = [ 90 858 2370]
+area_casev4 = [ 90 864 2394]
+area_im_case = [ 94 1098 2744]
+area_im = [ 126 1090 2730]
+
+% Areas total
+%area_casev3 = io_casev3 +lc_casev3
+%area_casev4 = io_casev4 +lc_casev4
+%area_im_case = io_im_case +lc_im_case
+
+
+
+% Plot figures
+% Delay figure
+%figure
+%plot ( length, delay_im, 'r-o')
+%hold on
+%plot ( length, delay_iom, '-<')
+%hold on
+%plot ( length, delay_shift, 'k-*')
+%hold on
+%plot ( length, delay_slotted_shift, 'bo-')
+%hold on
+plot ( length, delay_casev3, 'k-o')
+hold on
+plot ( length, delay_casev4, 'r-*')
+hold on
+plot ( length, delay_im_case, '-<')
+hold on
+plot ( length, delay_im, '-*')
+hold on
+
+legend ('casev3', 'casev4', 'in-mux-case', 'in-mux', 0)
+title (['Max frequency (MHz) of 3-bit double-FIFO'])
+xlabel ('Depth of FIFOs')
+ylabel ('Max Frequency [MHz]')
+axis ([0 82 0 120])
+
+% Area figure
+figure
+%plot ( length, area_im, 'r-o')
+%hold on
+%plot ( length, area_iom, '-<')
+%hold on
+%plot ( length, area_shift, 'k-*')
+%hold on
+%plot ( length, area_slotted_shift, 'bs-')
+%hold on
+plot ( length, area_casev3, 'k-o')
+hold on
+plot ( length, area_casev4, 'r-*')
+hold on
+plot ( length, area_im_case, '-<')
+hold on
+plot ( length, area_im_case, '-*')
+hold on
+legend ('casev3', 'casev4', 'in-mux-case', 'in-mux', 0)
+
+title (['Area (LC) of 3-bit double-FIFO'])
+xlabel ('Depth of FIFOs')
+ylabel ('Area [LC]')
+axis ([0 82 0 3000])
+
Index: trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison.m
===================================================================
--- trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison.m (nonexistent)
+++ trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/plot_comparison.m (revision 18)
@@ -0,0 +1,108 @@
+% Prints the synthesis results of FIFO comparison @ 0.18 um
+% Uses double_fifo_muxed_read components
+% which include two FIFOs and a read multiplexer
+% FIFOs are 3b wide
+% _im = in-mux (triagle in figures)
+% _iom = inout-mux (circle in figures)
+% shift = shift register (star in figures)
+
+close all
+clear all
+
+% Vertailussa kaytetyt fifojen pituudet
+length = [3 30 80]
+
+
+% Delay [ns] = data arrival time
+% (library set up time 0.17 ns is left out of these results)
+delay_im = [1.99 3.06 3.82]
+delay_iom = [2.25 3.63 4.62]
+delay_shift = [1.33 2.15 2.81]
+delay_slotted_shift = [1.56 1.99 1.81]
+% delay_casev3 = [1.05 2.16 3.43]
+delay_casev4 = [1.48 2.36 3.64]
+delay_casev4a = [1.69 2.52 3.34]
+delay_casev5 = [1.72 2.52 3.75]
+delay_casev6 = [1.86 2.66 3.55]
+delay_im_case = [1.57 2.54 3.92]
+
+
+% Areas [um2]
+area_im = [11214 55672 161906]
+area_iom = [12955 62296 140750]
+area_slotted_shift = [ 7688 43724 110645]
+area_shift = [ 7696 45350 114765]
+% area_casev3 = [ 6602 50802 129232]
+area_casev4 = [10014 54546 133443]
+area_casev4a = [11051 63721 159215]
+area_casev5 = [10264 55255 132984]
+area_casev6 = [10088 64253 158724]
+area_im_case = [ 8978 53493 160079]
+
+% Plot figures
+% Delay figure
+figure
+%plot ( length, delay_shift, 'k-*')
+%hold on
+%plot ( length, delay_slotted_shift, 'bo-')
+%hold on
+plot ( length, delay_im, 'k-o')
+hold on
+plot ( length, delay_iom, '-<')
+hold on
+plot ( length, delay_casev4, 'r-o')
+hold on
+plot ( length, delay_casev4a, 'r-*')
+hold on
+plot ( length, delay_casev5, 'r-+')
+hold on
+plot ( length, delay_casev6, 'c-+')
+hold on
+plot ( length, delay_im_case, 'k-<')
+hold on
+
+%title (['Delay of 3-bit double-FIFO (blue triangle=inout-mux, red' ...
+% ' o= in-mux, black *=shift, black square= slotted shift, red * =
+%casev4, red triangle = im-case, black o= casev3)'])
+
+title ('Delay of 3-bit double-FIFO')
+legend('in-mux', 'inout-mux', 'casev4', 'casev4a','casev5','casev6', 'in-mux-case',0)
+
+xlabel ('Depth of FIFOs')
+ylabel ('Delay [ns]')
+axis ([0 82 0 5])
+
+% Area figure
+figure
+%plot ( length, area_shift, 'k-*')
+%hold on
+%plot ( length, area_slotted_shift, 'bs-')
+%hold on
+plot ( length, area_im, 'k-o')
+hold on
+plot ( length, area_iom, '-<')
+hold on
+plot ( length, area_casev4, 'r-o')
+hold on
+plot ( length, area_casev4a, 'r-*')
+hold on
+plot ( length, area_casev5, 'r-+')
+hold on
+plot ( length, area_casev6, 'c-+')
+hold on
+plot ( length, area_im_case, 'k-<')
+hold on
+
+
+%title (['Area of 3-bit double-FIFO (blue triangle=inout-mux, red' ...
+% ' o= in-mux, black *=shift, black square= slotted shift, red * =
+%casev4, red triangle = im-case, black o = casev3)'])
+
+title ('Area of 3-bit double-FIFO')
+legend('in-mux', 'inout-mux', 'casev4', 'casev4a', 'casev5','casev6','in-mux-case',0)
+
+xlabel ('Depth of FIFOs')
+ylabel ('Area [um2]')
+axis ([0 82 0 18e4])
+
+
Index: trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/fifo_Comparison.pdf
===================================================================
--- trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/fifo_Comparison.pdf (nonexistent)
+++ trunk/TUT/ip.hwp.storage/fifos/synch_fifos/Doc/fifo_Comparison.pdf (revision 18)
@@ -0,0 +1,2469 @@
+%PDF-1.3
+%âãÏÓ
+33 0 obj
+<<
+/Linearized 1
+/O 35
+/H [ 1120 353 ]
+/L 243892
+/E 63664
+/N 7
+/T 243114
+>>
+endobj
+ xref
+33 34
+0000000016 00000 n
+0000001027 00000 n
+0000001473 00000 n
+0000001680 00000 n
+0000001839 00000 n
+0000002065 00000 n
+0000002623 00000 n
+0000002845 00000 n
+0000003297 00000 n
+0000003336 00000 n
+0000003357 00000 n
+0000004012 00000 n
+0000004033 00000 n
+0000004504 00000 n
+0000004525 00000 n
+0000004989 00000 n
+0000005010 00000 n
+0000005554 00000 n
+0000005575 00000 n
+0000006119 00000 n
+0000006140 00000 n
+0000006728 00000 n
+0000007123 00000 n
+0000007336 00000 n
+0000007357 00000 n
+0000007833 00000 n
+0000007854 00000 n
+0000008430 00000 n
+0000008508 00000 n
+0000033608 00000 n
+0000051442 00000 n
+0000060836 00000 n
+0000001120 00000 n
+0000001452 00000 n
+trailer
+<<
+/Size 67
+/Info 31 0 R
+/Root 34 0 R
+/Prev 243104
+/ID[<5ab2ce6d23797f07660c2e8ad696cfc3><5b35cbeb57638c642f899e30b20e117a>]
+>>
+startxref
+0
+%%EOF
+
+34 0 obj
+<<
+/Type /Catalog
+/Pages 30 0 R
+/Metadata 32 0 R
+/PageLabels 29 0 R
+>>
+endobj
+65 0 obj
+<< /S 168 /L 265 /Filter /FlateDecode /Length 66 0 R >>
+stream
+H‰b```f``I``e``ߊĀ B@16Ž@VË´'00pÊ2¼m8´ÃÐ"™gʉpµ†M¢.7K—Ý0œ•zሄblæ´Ã ¥Ë¢xÜçwº<ì]v'õ"³ä²X¶ŒŽ ÉÑÁÀ¤ÑÑÀ d300Še@‚èÖåĘ}%´«€meàg,aÒ`ËPœ ©}€èÎ/|æ Œ¬
+,b‚;Ä$€Š¹aÏù÷D†L^4ƒ!±±†±aÁ6k×0OÈ00¯ý¤™€Ø À ‰›A
+endstream
+endobj
+66 0 obj
+240
+endobj
+35 0 obj
+<<
+/Type /Page
+/Parent 30 0 R
+/Resources 36 0 R
+/Contents [ 43 0 R 45 0 R 47 0 R 49 0 R 51 0 R 53 0 R 57 0 R 59 0 R ]
+/MediaBox [ 0 0 612 792 ]
+/CropBox [ 0 0 612 792 ]
+/Rotate 0
+>>
+endobj
+36 0 obj
+<<
+/ProcSet [ /PDF /Text ]
+/Font << /TT2 38 0 R /TT4 40 0 R /TT6 54 0 R >>
+/ExtGState << /GS1 60 0 R >>
+/ColorSpace << /Cs6 41 0 R >>
+>>
+endobj
+37 0 obj
+<<
+/Type /FontDescriptor
+/Ascent 905
+/CapHeight 0
+/Descent -211
+/Flags 32
+/FontBBox [ -628 -376 2034 1010 ]
+/FontName /EIDOEC+Arial,Bold
+/ItalicAngle 0
+/StemV 144
+/XHeight 515
+/FontFile2 62 0 R
+>>
+endobj
+38 0 obj
+<<
+/Type /Font
+/Subtype /TrueType
+/FirstChar 32
+/LastChar 150
+/Widths [ 278 278 355 0 0 0 0 191 333 333 389 584 278 333 278 278 556 556 556
+556 556 556 556 556 556 556 278 0 0 0 0 0 0 667 667 722 722 667
+611 778 722 278 0 0 556 833 722 778 667 0 722 667 611 722 0 0 0
+0 0 0 0 0 0 556 0 556 556 500 556 556 278 556 556 222 0 500 222
+833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 350 556 ]
+/Encoding /WinAnsiEncoding
+/BaseFont /EIDOCC+Arial
+/FontDescriptor 39 0 R
+>>
+endobj
+39 0 obj
+<<
+/Type /FontDescriptor
+/Ascent 905
+/CapHeight 718
+/Descent -211
+/Flags 32
+/FontBBox [ -665 -325 2028 1006 ]
+/FontName /EIDOCC+Arial
+/ItalicAngle 0
+/StemV 94
+/XHeight 515
+/FontFile2 61 0 R
+>>
+endobj
+40 0 obj
+<<
+/Type /Font
+/Subtype /TrueType
+/FirstChar 32
+/LastChar 122
+/Widths [ 278 0 0 0 0 0 0 0 0 0 389 584 0 0 278 0 0 0 556 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 722 0 722 722 0 611 778 722 278 0 0 611 833 0 0 667 0
+0 667 0 0 0 0 0 0 0 333 0 333 0 556 0 556 611 556 611 556 333 611
+611 278 0 0 278 889 611 611 0 611 389 556 333 611 556 778 556 556
+500 ]
+/Encoding /WinAnsiEncoding
+/BaseFont /EIDOEC+Arial,Bold
+/FontDescriptor 37 0 R
+>>
+endobj
+41 0 obj
+[
+/ICCBased 64 0 R
+]
+endobj
+42 0 obj
+577
+endobj
+43 0 obj
+<< /Filter /FlateDecode /Length 42 0 R >>
+stream
+H‰tTËnÛ0¼ë+öH´á›òµnS4@[ƒ‘ƒ!S±¿*)õ—´ßÛ%i«NëB µ‚É™á¬ï惃f ™ž¡Ùwž‡BVà½ë”Þ:èCÑïêâ®®mÛBj
+=¹²~†R2èÔ»B¤ß"¦€º‰Ë©`’×/ŇºøC(•7³hh' T^LdÒM©RÆ`Ün+•oYJBPÛ‘+V2Þºÿ
+Íaw\õÝpØGzjwV]§JZ‡ªfÄxØE˜Œ8‹8Kö“—N6ç
+=KxÖ]Û†>ìGH4Ýî¸
+;ú\Ýa?ð§úäe&2Í›H#šL£+]MÎ,ٯוe=+Ò×*-¶P¿Oí ÏÑ^j6p–CXgÒ›
+³³D5)×
+5:Vs†mú`Õ7›nÍøÚ‡Û‚¬ñèÍ5^Jö_ɳ¬Ü£O=J~„~µZ‡èö0v·ˆ²h5ç6õm¯
+Ž¼T¤ÿt¸ÂmaØtíHYzî†1ôÐí^’lË%ÎØëúl¥ñ;屃E£¦(ž“ø4qNæÈi[̿Ъ^@Æ\ž@
+øË'눂¦" Š¬MY¥P.½nQ|û+ýÚÅÛù'ü4i&Oš¿LA*”$‘^â<TÑŽ«5YeÔUÂyE6áE¶´tÛŽt*œ•ÒqrKiã+uqõ·ð_DÜýÖ€ä¥Õ H»‹¸@ü-À ¬ã
+endstream
+endobj
+44 0 obj
+393
+endobj
+45 0 obj
+<< /Filter /FlateDecode /Length 44 0 R >>
+stream
+H‰œ”=OÃ0†wÿŠÛJ=|vœµÀÒ…lˆ…ÒNm‘øü|ÎNSÒ’E‘b_üÞùü¼VÜlâf«Ð3x{Ê„‰0Dà(Ø4çËêËbëîFˆã„a„ãûfî.š†Á$+§Š(쫬Œêw0ä=zï\Í£÷bë7µ)©@ón[l§¯OS‚ÍÛGÙäºH¿½¼qÚ†ÕJ°q”"²Kãµcµ>úq¥=ýÚ=LA~J/¥ý¶¬^kŒ¥d@Î)ÞÂ\Q°ê…•ì”¥˜¡<Ä`â\JP@r˜qÔHÍUKL¾ˆ…–åZ[x\Ž‰1~%בHÔ’ëHÕ¾%Ó‘ÜÇ;Òþ$¹Â#q!סª©àé@vaf\”ÃäÉ.åh:ævÎYs†PÀh»UŒµqikjmx^ºUï$&ɺ2X`ë³oÝITÌ,5þt»Ï·E%Ø¢>Ø"vsû¶Õ±E%ìmQú¶ˆV}[¤P?e‹Ø/á?¶ÀüS€ ªê>
+endstream
+endobj
+46 0 obj
+386
+endobj
+47 0 obj
+<< /Filter /FlateDecode /Length 46 0 R >>
+stream
+H‰Œ“=k1†wÿ
+¹F–ü¹ºdím¥K¡-—.)äïW¶Î÷Å¥”£G~eûµÎÚê/£ÆH&è«Ä>q<(¢<çK<æ†)_ã1ÿ¢¬>i0ôW
+¤1D©NÙ ŽX„%a™½ Xæ3M“m*Œ—£zê•3€ø«Ed)[¶ê¯
+@ôº?+Ðý]½nµÆ>;oÒáÒYº·þ¤ž{Vû²Øb¼¿ÙH,K££²(#Xð0±wƧÊa—g}Þ0UætÕ³/«ËW6n—ʽÕuÎPª×›ÞKȯãIÄãÊ ªÞœSg9ŠsŠ´à¡1A’“SÌ{<ënêåf2í8§Àžr·Ü×C‚,ÿDL«x%»¬à{Èîo·ÈÇ.§A/n‘”™‡‰¹õ´hã.Oz„M½¶;nøua·h¡Á @òІu<‹òøÍ þÏmëms×z3òÔËÑÝ–g=¦Þ=îmu;ööW€ ÉÞ¸
+endstream
+endobj
+48 0 obj
+466
+endobj
+49 0 obj
+<< /Filter /FlateDecode /Length 48 0 R >>
+stream
+H‰tSËnÜ0¼ë+x´¬@Rïk€šk|k{h‚,’À›ÍÉç—”´¶7ØÀ€Áœ‘—l]†Ù(pXl¬u<«7¢²N€¯ª»+ƒpÏ€61¼ƒ¡€““áC«C®RJiåµî