- WIP: New cache for CPU - Memory controller now supports modulu bursts and different burst lengths - WIP: Timing problems...
345 lines
11 KiB
VHDL
345 lines
11 KiB
VHDL
-------------------------------------------------------------------------------
|
|
-- Title : Testbench for design "wb_ddr_ctrl_wb_sc"
|
|
-- Project :
|
|
-------------------------------------------------------------------------------
|
|
-- File : wb_ddr_ctrl_wb_sc_tb.vhd
|
|
-- Author : <Matthias@MATTHIAS-PC>
|
|
-- Company :
|
|
-- Created : 2013-03-08
|
|
-- Last update: 2013-06-08
|
|
-- Platform :
|
|
-- Standard : VHDL'87
|
|
-------------------------------------------------------------------------------
|
|
-- Description:
|
|
-------------------------------------------------------------------------------
|
|
-- Copyright (c) 2013
|
|
-------------------------------------------------------------------------------
|
|
-- Revisions :
|
|
-- Date Version Author Description
|
|
-- 2013-03-08 1.0 Matthias Created
|
|
-------------------------------------------------------------------------------
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library ieee_proposed;
|
|
use ieee_proposed.std_logic_1164_additions.all;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
entity wb_ddr_ctrl_wb_sc_tb is
|
|
|
|
end wb_ddr_ctrl_wb_sc_tb;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
architecture testbench of wb_ddr_ctrl_wb_sc_tb is
|
|
|
|
-- component generics
|
|
constant dontcare : std_logic := '0';
|
|
|
|
-- component ports
|
|
signal clk_i : std_ulogic := '0';
|
|
signal rst_i : std_ulogic := '1';
|
|
signal vga_mem_rdrq : std_logic := '0';
|
|
signal vga_mem_adr : std_logic_vector(19 downto 0);
|
|
signal vga_mem_ack : std_logic;
|
|
signal vga_mem_dat_i : std_logic_vector(63 downto 0);
|
|
signal wb_mem_rdrq : std_logic := '0';
|
|
signal wb_mem_wrrq : std_logic := '0';
|
|
signal wb_mem_adr : std_logic_vector(19 downto 0);
|
|
signal wb_mem_dat_o : std_logic_vector(63 downto 0);
|
|
signal wb_mem_sel : std_logic_vector(7 downto 0);
|
|
signal wb_mem_ack : std_logic;
|
|
signal wb_mem_dat_i : std_logic_vector(63 downto 0);
|
|
signal cpu_mem_rdrq : std_logic := '0';
|
|
signal cpu_mem_wrrq : std_logic := '0';
|
|
signal cpu_mem_adr : std_logic_vector(22 downto 0);
|
|
signal cpu_mem_dat_o : std_logic_vector(63 downto 0);
|
|
signal cpu_mem_sel : std_logic_vector(7 downto 0);
|
|
signal cpu_mem_ack : std_logic;
|
|
signal cpu_mem_dat_i : std_logic_vector(63 downto 0);
|
|
signal ddr_din : std_logic_vector(63 downto 0);
|
|
signal ddr_dout : std_logic_vector(63 downto 0);
|
|
signal ddr_adr : std_logic_vector(22 downto 0);
|
|
signal ddr_we : std_ulogic;
|
|
signal ddr_be : std_logic_vector(7 downto 0);
|
|
signal fifo_to_ddr_write : std_ulogic;
|
|
signal fifo_from_ddr_read : std_ulogic;
|
|
signal fifo_to_ddr_full : std_ulogic := '0';
|
|
signal fifo_from_ddr_empty : std_ulogic := '1';
|
|
|
|
signal sim_done : boolean := false;
|
|
constant maxdelay : integer := 8;
|
|
signal delay : integer range 0 to maxdelay := 2;
|
|
signal readrate : integer := 1;
|
|
|
|
type fifo_a is array(0 to 127) of std_logic_vector(22 downto 0);
|
|
signal fifo : fifo_a := (others => (others => '0'));
|
|
signal fifo_rdptr, fifo_wrptr : integer range 0 to 127;
|
|
|
|
type wrptr_dly_a is array(maxdelay downto 0) of integer range 0 to 127;
|
|
signal wrptr_dly : wrptr_dly_a := (others => 0);
|
|
|
|
constant burst_length : integer := 8;
|
|
|
|
begin -- testbench
|
|
|
|
-- component instantiation
|
|
DUT: entity work.wb_ddr_ctrl_wb_sc
|
|
generic map (
|
|
dontcare => dontcare)
|
|
port map (
|
|
clk_i => clk_i,
|
|
rst_i => rst_i,
|
|
vga_mem_rdrq => vga_mem_rdrq,
|
|
vga_mem_adr => vga_mem_adr,
|
|
vga_mem_ack => vga_mem_ack,
|
|
vga_mem_dat_i => vga_mem_dat_i,
|
|
wb_mem_rdrq => wb_mem_rdrq,
|
|
wb_mem_wrrq => wb_mem_wrrq,
|
|
wb_mem_adr => wb_mem_adr,
|
|
wb_mem_dat_o => wb_mem_dat_o,
|
|
wb_mem_sel => wb_mem_sel,
|
|
wb_mem_ack => wb_mem_ack,
|
|
wb_mem_dat_i => wb_mem_dat_i,
|
|
cpu_mem_rdrq => cpu_mem_rdrq,
|
|
cpu_mem_wrrq => cpu_mem_wrrq,
|
|
cpu_mem_adr => cpu_mem_adr,
|
|
cpu_mem_dat_o => cpu_mem_dat_o,
|
|
cpu_mem_sel => cpu_mem_sel,
|
|
cpu_mem_ack => cpu_mem_ack,
|
|
cpu_mem_dat_i => cpu_mem_dat_i,
|
|
ddr_din => ddr_din,
|
|
ddr_dout => ddr_dout,
|
|
ddr_adr => ddr_adr,
|
|
ddr_we => ddr_we,
|
|
ddr_be => ddr_be,
|
|
fifo_to_ddr_write => fifo_to_ddr_write,
|
|
fifo_from_ddr_read => fifo_from_ddr_read,
|
|
fifo_to_ddr_full => fifo_to_ddr_full,
|
|
fifo_from_ddr_empty => fifo_from_ddr_empty);
|
|
|
|
-- clock generation
|
|
clk_i <= not clk_i after 10 ns when not sim_done else
|
|
'0';
|
|
|
|
-- waveform generation
|
|
WaveGen_Proc: process
|
|
variable ctr : integer;
|
|
variable expected_data : std_logic_vector(63 downto 0);
|
|
begin
|
|
-- insert signal assignments here
|
|
rst_i <= '1';
|
|
|
|
wait for 50 ns;
|
|
wait until rising_edge(clk_i);
|
|
|
|
rst_i <= '0';
|
|
wait until rising_edge(clk_i);
|
|
|
|
-- Test VGA read port
|
|
|
|
vga_mem_rdrq <= '1';
|
|
vga_mem_adr <= x"00010";
|
|
wait until rising_edge(clk_i);
|
|
vga_mem_rdrq <= '0';
|
|
|
|
ctr := 0;
|
|
while ctr < burst_length loop
|
|
if vga_mem_ack = '1' then
|
|
expected_data := (others => '0');
|
|
expected_data(22 downto 3) := x"00010";
|
|
expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3));
|
|
assert vga_mem_dat_i = expected_data report "Incorrect read data (VGA)" severity failure;
|
|
ctr := ctr + 1;
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
|
|
vga_mem_rdrq <= '1';
|
|
vga_mem_adr <= x"10010";
|
|
wait until rising_edge(clk_i);
|
|
vga_mem_rdrq <= '0';
|
|
|
|
ctr := 0;
|
|
while ctr < burst_length loop
|
|
if vga_mem_ack = '1' then
|
|
expected_data := (others => '0');
|
|
expected_data(22 downto 3) := x"10010";
|
|
expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3));
|
|
assert vga_mem_dat_i = expected_data report "Incorrect read data (VGA)" severity failure;
|
|
ctr := ctr + 1;
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
|
|
-- Test wb read port
|
|
|
|
wb_mem_rdrq <= '1';
|
|
wb_mem_adr <= x"00010";
|
|
wait until rising_edge(clk_i);
|
|
wb_mem_rdrq <= '0';
|
|
|
|
ctr := 0;
|
|
while ctr < burst_length loop
|
|
if wb_mem_ack = '1' then
|
|
expected_data := (others => '0');
|
|
expected_data(22 downto 3) := x"00010";
|
|
expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3));
|
|
assert wb_mem_dat_i = expected_data report "Incorrect read data (WB)" severity failure;
|
|
ctr := ctr + 1;
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
|
|
wb_mem_rdrq <= '1';
|
|
wb_mem_adr <= x"10010";
|
|
wait until rising_edge(clk_i);
|
|
wb_mem_rdrq <= '0';
|
|
|
|
ctr := 0;
|
|
while ctr < burst_length loop
|
|
if wb_mem_ack = '1' then
|
|
expected_data := (others => '0');
|
|
expected_data(22 downto 3) := x"10010";
|
|
expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3));
|
|
assert wb_mem_dat_i = expected_data report "Incorrect read data (WB)" severity failure;
|
|
ctr := ctr + 1;
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
|
|
-- Test wb write port
|
|
wb_mem_wrrq <= '1';
|
|
wb_mem_adr <= x"10010";
|
|
wb_mem_dat_o <= x"de00ad00be00ef00";
|
|
--wait until rising_edge(clk_i);
|
|
|
|
|
|
ctr := 0;
|
|
while ctr < burst_length loop
|
|
if wb_mem_ack = '1' then
|
|
ctr := ctr + 1;
|
|
wb_mem_dat_o(7 downto 0) <= std_logic_vector(to_unsigned(ctr, 8));
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
wb_mem_wrrq <= '0';
|
|
end loop;
|
|
|
|
-- Test cpu read port
|
|
|
|
cpu_mem_rdrq <= '1';
|
|
cpu_mem_adr <= x"00010" & "001";
|
|
wait until rising_edge(clk_i);
|
|
cpu_mem_rdrq <= '0';
|
|
|
|
ctr := 0;
|
|
while ctr < 4 loop
|
|
if cpu_mem_ack = '1' then
|
|
expected_data := (others => '0');
|
|
expected_data(22 downto 2) := x"00010" & "0";
|
|
expected_data(1 downto 0) := std_logic_vector(to_unsigned(ctr, 2)+1);
|
|
assert cpu_mem_dat_i = expected_data report "Incorrect read data (CPU)" severity failure;
|
|
ctr := ctr + 1;
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
end loop;
|
|
|
|
-- Test cpu write port
|
|
cpu_mem_wrrq <= '1';
|
|
cpu_mem_adr <= x"10010" & "111" ;
|
|
cpu_mem_dat_o <= x"de00ad00be00ef00";
|
|
--wait until rising_edge(clk_i);
|
|
|
|
|
|
ctr := 0;
|
|
while ctr < 4 loop
|
|
if cpu_mem_ack = '1' then
|
|
ctr := ctr + 1;
|
|
cpu_mem_dat_o(7 downto 0) <= std_logic_vector(to_unsigned(ctr, 8));
|
|
end if;
|
|
|
|
wait until rising_edge(clk_i);
|
|
cpu_mem_wrrq <= '0';
|
|
end loop;
|
|
|
|
sim_done <= true;
|
|
wait;
|
|
end process WaveGen_Proc;
|
|
|
|
emul_fifo_to_ddr : process
|
|
constant max_fill : integer := 2;
|
|
variable fill : integer := 0;
|
|
variable ctr : integer := 0;
|
|
begin
|
|
wait until rst_i = '0';
|
|
while true loop
|
|
wait until rising_edge(clk_i);
|
|
if fifo_to_ddr_write = '1' then
|
|
assert fill < max_fill report "DUT->DDR FIFO overflow" severity failure;
|
|
if ddr_we = '0' then
|
|
fifo(fifo_wrptr) <= ddr_adr;
|
|
fifo_wrptr <= (fifo_wrptr + 1) mod 128;
|
|
end if;
|
|
fill := fill + 1;
|
|
end if;
|
|
if ctr >= readrate then
|
|
if fill > 0 then
|
|
fill := fill - 1;
|
|
end if;
|
|
ctr := 0;
|
|
else
|
|
ctr := ctr + 1;
|
|
end if;
|
|
if fill >= max_fill then
|
|
fifo_to_ddr_full <= '1';
|
|
else
|
|
fifo_to_ddr_full <= '0';
|
|
end if;
|
|
end loop;
|
|
end process emul_fifo_to_ddr;
|
|
|
|
emul_fifo_from_ddr : process
|
|
|
|
variable rdptr_next : integer range 0 to 127;
|
|
begin
|
|
wait until rst_i = '0';
|
|
while true loop
|
|
wait until rising_edge(clk_i);
|
|
wrptr_dly <= wrptr_dly(maxdelay-1 downto 0) & fifo_wrptr;
|
|
|
|
rdptr_next := fifo_rdptr;
|
|
if fifo_from_ddr_read = '1' then
|
|
assert wrptr_dly(delay) /= fifo_rdptr report "DDR->DUT FIFO underflow" severity failure;
|
|
ddr_dout(63 downto 23) <= (others => '0');
|
|
ddr_dout(22 downto 0) <= fifo(fifo_rdptr);
|
|
rdptr_next := (fifo_rdptr + 1) mod 128;
|
|
end if;
|
|
if wrptr_dly(delay) = rdptr_next then
|
|
fifo_from_ddr_empty <= '1';
|
|
else
|
|
fifo_from_ddr_empty <= '0';
|
|
end if;
|
|
fifo_rdptr <= rdptr_next;
|
|
end loop;
|
|
end process emul_fifo_from_ddr;
|
|
|
|
end testbench;
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
configuration wb_ddr_ctrl_wb_sc_tb_testbench_cfg of wb_ddr_ctrl_wb_sc_tb is
|
|
for testbench
|
|
end for;
|
|
end wb_ddr_ctrl_wb_sc_tb_testbench_cfg;
|
|
|
|
-------------------------------------------------------------------------------
|