- Added ZPU processor - Optimized wb_ddr_ctrl_wb_dc* to meet timing - Added cache frontend
443 lines
16 KiB
VHDL
Executable File
443 lines
16 KiB
VHDL
Executable File
-------------------------------------------------------------------------------
|
|
-- Title : Testbench for design "wb_ddr_ctrl"
|
|
-- Project :
|
|
-------------------------------------------------------------------------------
|
|
-- File : wb_ddr_ctrl_tb.vhd
|
|
-- Author : Matthias Blankertz <matthias@blankertz.org>
|
|
-- Company :
|
|
-- Created : 2013-02-26
|
|
-- Last update: 2013-03-03
|
|
-- Platform :
|
|
-- Standard : VHDL'93
|
|
-------------------------------------------------------------------------------
|
|
-- Description:
|
|
-------------------------------------------------------------------------------
|
|
-- Copyright (c) 2013
|
|
-------------------------------------------------------------------------------
|
|
-- Revisions :
|
|
-- Date Version Author Description
|
|
-- 2013-02-26 1.0 Matthias Created
|
|
-------------------------------------------------------------------------------
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
use work.intercon_package.all;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
entity wb_ddr_ctrl_tb is
|
|
|
|
end wb_ddr_ctrl_tb;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
architecture testbench of wb_ddr_ctrl_tb is
|
|
|
|
component wb_ddr_ctrl
|
|
port (
|
|
ddr2_clock : in std_ulogic;
|
|
ddr2_reset : in std_ulogic;
|
|
ddr2_dq : inout std_logic_vector(15 downto 0);
|
|
ddr2_a : out std_logic_vector(12 downto 0);
|
|
ddr2_ba : out std_logic_vector(1 downto 0);
|
|
ddr2_cke : out std_logic;
|
|
ddr2_cs_n : out std_logic;
|
|
ddr2_ras_n : out std_logic;
|
|
ddr2_cas_n : out std_logic;
|
|
ddr2_we_n : out std_logic;
|
|
ddr2_odt : out std_logic;
|
|
ddr2_dm : out std_logic_vector(1 downto 0);
|
|
rst_dqs_div_in : in std_logic;
|
|
rst_dqs_div_out : out std_logic;
|
|
ddr2_dqs : inout std_logic_vector(1 downto 0);
|
|
ddr2_dqs_n : inout std_logic_vector(1 downto 0);
|
|
ddr2_ck : out std_logic_vector(0 downto 0);
|
|
ddr2_ck_n : out std_logic_vector(0 downto 0);
|
|
clk_i : in std_ulogic;
|
|
rst_i : in std_ulogic;
|
|
wbs_i : in sdram_ctrl_wbs_i_type;
|
|
wbs_o : out sdram_ctrl_wbs_o_type);
|
|
end component;
|
|
|
|
component ddr2_model
|
|
port (
|
|
ck : in std_logic;
|
|
ck_n : in std_logic;
|
|
cke : in std_logic;
|
|
cs_n : in std_logic;
|
|
ras_n : in std_logic;
|
|
cas_n : in std_logic;
|
|
we_n : in std_logic;
|
|
dm_rdqs : inout std_logic_vector(1 downto 0);
|
|
ba : in std_logic_vector(1 downto 0);
|
|
addr : in std_logic_vector(12 downto 0);
|
|
dq : inout std_logic_vector(15 downto 0);
|
|
dqs : inout std_logic_vector(1 downto 0);
|
|
dqs_n : inout std_logic_vector(1 downto 0);
|
|
rdqs_n : out std_logic_vector(1 downto 0);
|
|
odt : in std_logic
|
|
);
|
|
end component;
|
|
|
|
-- component ports
|
|
signal ddr2_clock : std_ulogic := '0';
|
|
signal ddr2_reset : std_ulogic;
|
|
signal ddr2_dq : std_logic_vector(15 downto 0);
|
|
signal ddr2_a : std_logic_vector(12 downto 0);
|
|
signal ddr2_ba : std_logic_vector(1 downto 0);
|
|
signal ddr2_cke : std_logic;
|
|
signal ddr2_cs_n : std_logic;
|
|
signal ddr2_ras_n : std_logic;
|
|
signal ddr2_cas_n : std_logic;
|
|
signal ddr2_we_n : std_logic;
|
|
signal ddr2_odt : std_logic;
|
|
signal ddr2_dm : std_logic_vector(1 downto 0);
|
|
signal rst_dqs_div_in : std_logic;
|
|
signal rst_dqs_div_out : std_logic;
|
|
signal ddr2_dqs : std_logic_vector(1 downto 0);
|
|
signal ddr2_dqs_n : std_logic_vector(1 downto 0);
|
|
signal ddr2_ck : std_logic_vector(0 downto 0);
|
|
signal ddr2_ck_n : std_logic_vector(0 downto 0);
|
|
signal clk_i : std_ulogic := '0';
|
|
signal rst_i : std_ulogic;
|
|
signal dat_i : std_logic_vector(31 downto 0) := (others => '-');
|
|
signal dat_o : std_logic_vector(31 downto 0);
|
|
signal ack_o : std_ulogic;
|
|
signal adr_i : std_logic_vector(25 downto 2) := (others => '-');
|
|
signal cyc_i : std_ulogic := '0';
|
|
signal sel_i : std_logic_vector(3 downto 0) := (others => '0');
|
|
signal stb_i : std_ulogic := '0';
|
|
signal we_i : std_ulogic := '0';
|
|
signal cti_i : std_logic_vector(2 downto 0) := (others => '0');
|
|
signal bte_i : std_logic_vector(1 downto 0) := (others => '0');
|
|
|
|
begin -- testbench
|
|
|
|
-- component instantiation
|
|
DUT: wb_ddr_ctrl
|
|
port map (
|
|
ddr2_clock => ddr2_clock,
|
|
ddr2_reset => ddr2_reset,
|
|
ddr2_dq => ddr2_dq,
|
|
ddr2_a => ddr2_a,
|
|
ddr2_ba => ddr2_ba,
|
|
ddr2_cke => ddr2_cke,
|
|
ddr2_cs_n => ddr2_cs_n,
|
|
ddr2_ras_n => ddr2_ras_n,
|
|
ddr2_cas_n => ddr2_cas_n,
|
|
ddr2_we_n => ddr2_we_n,
|
|
ddr2_odt => ddr2_odt,
|
|
ddr2_dm => ddr2_dm,
|
|
rst_dqs_div_in => rst_dqs_div_in,
|
|
rst_dqs_div_out => rst_dqs_div_out,
|
|
ddr2_dqs => ddr2_dqs,
|
|
ddr2_dqs_n => ddr2_dqs_n,
|
|
ddr2_ck => ddr2_ck,
|
|
ddr2_ck_n => ddr2_ck_n,
|
|
clk_i => clk_i,
|
|
rst_i => rst_i,
|
|
wbs_i.dat_i => dat_i,
|
|
wbs_i.adr_i => adr_i,
|
|
wbs_i.cyc_i => cyc_i,
|
|
wbs_i.sel_i => sel_i,
|
|
wbs_i.stb_i => stb_i,
|
|
wbs_i.we_i => we_i,
|
|
wbs_i.cti_i => cti_i,
|
|
wbs_i.bte_i => bte_i,
|
|
wbs_o.dat_o => dat_o,
|
|
wbs_o.ack_o => ack_o);
|
|
|
|
rst_dqs_div_in <= rst_dqs_div_out after 100 ps;
|
|
|
|
ddr2_model_inst : ddr2_model port map (
|
|
ck => ddr2_ck(0),
|
|
ck_n => ddr2_ck_n(0),
|
|
cke => ddr2_cke,
|
|
cs_n => ddr2_cs_n,
|
|
ras_n => ddr2_ras_n,
|
|
cas_n => ddr2_cas_n,
|
|
we_n => ddr2_we_n,
|
|
dm_rdqs => ddr2_dm,
|
|
ba => ddr2_ba,
|
|
addr => ddr2_a,
|
|
dq => ddr2_dq,
|
|
dqs => ddr2_dqs,
|
|
dqs_n => ddr2_dqs_n,
|
|
rdqs_n => open,
|
|
odt => ddr2_odt);
|
|
|
|
|
|
-- clock generation
|
|
ddr2_clock <= not ddr2_clock after 3.7594 ns;
|
|
clk_i <= not clk_i after 10 ns;
|
|
|
|
-- waveform generation
|
|
WaveGen_Proc: process
|
|
variable expected_data : std_logic_vector(31 downto 0);
|
|
begin
|
|
-- insert signal assignments here
|
|
ddr2_reset <= '1';
|
|
rst_i <= '1';
|
|
wait for 60 ns;
|
|
wait until rising_edge(ddr2_clock);
|
|
ddr2_reset <= '0' after 1 ns;
|
|
wait until rising_edge(clk_i);
|
|
rst_i <= '0' after 2 ns;
|
|
|
|
-- simple write cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '1' after 2 ns;
|
|
sel_i <= "1111" after 2 ns;
|
|
adr_i <= x"000010" after 2 ns;
|
|
dat_i <= x"deadbeef" after 2 ns;
|
|
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- simple read cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
adr_i <= x"000010" after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
assert dat_o = x"deadbeef" report "Read failed: unexpected data (expected 0xdeadbeef)" severity warning;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- simple write cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '1' after 2 ns;
|
|
sel_i <= "1111" after 2 ns;
|
|
adr_i <= x"000011" after 2 ns;
|
|
dat_i <= x"12345678" after 2 ns;
|
|
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- simple read cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
adr_i <= x"000010" after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
assert dat_o = x"deadbeef" report "Read failed: unexpected data (expected 0xdeadbeef)" severity warning;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- simple read cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
adr_i <= x"000011" after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
assert dat_o = x"12345678" report "Read failed: unexpected data (expected 0x12345678)" severity warning;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- burst write cycle
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '1' after 2 ns;
|
|
dat_i <= x"d000000d" after 2 ns;
|
|
for i in 0 to 7 loop
|
|
adr_i <= std_logic_vector(to_unsigned(256+i,24)) after 2 ns;
|
|
dat_i(23 downto 16) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
dat_i(15 downto 8) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
sel_i <= "1111" after 2 ns;
|
|
if i = 7 then -- EOB
|
|
cti_i <= "111" after 2 ns;
|
|
end if;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
end loop; -- i
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- unaligned burst write cycle
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '1' after 2 ns;
|
|
dat_i <= x"d000000d" after 2 ns;
|
|
for i in 7 to 31 loop
|
|
adr_i <= std_logic_vector(to_unsigned(256+i,24)) after 2 ns;
|
|
dat_i(23 downto 16) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
dat_i(15 downto 8) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
sel_i <= "1111" after 2 ns;
|
|
if i = 15 then -- EOB
|
|
cti_i <= "111" after 2 ns;
|
|
end if;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
end loop; -- i
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- simple read cycle
|
|
wait until rising_edge(clk_i);
|
|
stb_i <= '1' after 2 ns;
|
|
cti_i <= "000" after 2 ns; -- classic cycle
|
|
we_i <= '0' after 2 ns;
|
|
adr_i <= x"000105" after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
assert dat_o = x"d005050d" report "Read failed: unexpected data (expected 0xd005050d)" severity warning;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- burst read cycle
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
for i in 0 to 15 loop
|
|
adr_i <= std_logic_vector(to_unsigned(256+i,24)) after 2 ns;
|
|
expected_data(31 downto 24) := x"d0";
|
|
expected_data(23 downto 16) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(15 downto 8) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(7 downto 0) := x"0d";
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
assert dat_o = expected_data report "Read failed: unexpected_data" severity warning;
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- burst read cycle
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
for i in 16 to 31 loop
|
|
adr_i <= std_logic_vector(to_unsigned(256+i,24)) after 2 ns;
|
|
expected_data(31 downto 24) := x"d0";
|
|
expected_data(23 downto 16) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(15 downto 8) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(7 downto 0) := x"0d";
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
assert dat_o = expected_data report "Read failed: unexpected_data" severity warning;
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- unaligned burst read cycle
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
for i in 15 to 30 loop
|
|
adr_i <= std_logic_vector(to_unsigned(256+i,24)) after 2 ns;
|
|
expected_data(31 downto 24) := x"d0";
|
|
expected_data(23 downto 16) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(15 downto 8) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(7 downto 0) := x"0d";
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
assert dat_o = expected_data report "Read failed: unexpected_data" severity warning;
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- burst write cycle crossing row boundary
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '1' after 2 ns;
|
|
dat_i <= x"d000000d" after 2 ns;
|
|
for i in 0 to 15 loop
|
|
adr_i <= std_logic_vector(to_unsigned(4088+i,24)) after 2 ns;
|
|
dat_i(23 downto 16) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
dat_i(15 downto 8) <= std_logic_vector(to_unsigned(i,8)) after 2 ns;
|
|
sel_i <= "1111" after 2 ns;
|
|
if i = 15 then -- EOB
|
|
cti_i <= "111" after 2 ns;
|
|
end if;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
end loop; -- i
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- burst read cycle crossing row boundary
|
|
wait until rising_edge(clk_i);
|
|
cti_i <= "010" after 2 ns; -- incrementing burst
|
|
bte_i <= "00" after 2 ns; -- linear
|
|
stb_i <= '1' after 2 ns;
|
|
we_i <= '0' after 2 ns;
|
|
for i in 0 to 15 loop
|
|
adr_i <= std_logic_vector(to_unsigned(4088+i,24)) after 2 ns;
|
|
expected_data(31 downto 24) := x"d0";
|
|
expected_data(23 downto 16) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(15 downto 8) := std_logic_vector(to_unsigned(i,8));
|
|
expected_data(7 downto 0) := x"0d";
|
|
if i = 15 then -- EOB
|
|
cti_i <= "111" after 2 ns;
|
|
end if;
|
|
wait until rising_edge(clk_i);
|
|
while ack_o = '0' loop
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
assert dat_o = expected_data report "Read failed: unexpected_data" severity warning;
|
|
end loop;
|
|
stb_i <= '0' after 2 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
assert false report "Test complete" severity failure;
|
|
|
|
wait;
|
|
end process WaveGen_Proc;
|
|
|
|
end testbench;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
configuration wb_ddr_ctrl_tb_testbench_cfg of wb_ddr_ctrl_tb is
|
|
for testbench
|
|
end for;
|
|
end wb_ddr_ctrl_tb_testbench_cfg;
|
|
|
|
-------------------------------------------------------------------------------
|