Files
2d_display_engine-new/tb/wb_mem_bridge_tb.vhd
Matthias Blankertz 1807fb99b5 - Replaced cache with simpler wishbone-memory bridge
- Redesign wishbone interconnect
- Changed wb_ddr_ctrl_wb_sc to allow easier addition of ports
2013-06-04 23:18:16 +02:00

362 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-04
-- 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;
use work.intercon_package.all;
-------------------------------------------------------------------------------
entity wb_mem_bridge_tb is
end wb_mem_bridge_tb;
-------------------------------------------------------------------------------
architecture testbench of wb_mem_bridge_tb is
-- component generics
constant burst_length : integer := 8;
constant burst_length_ln2 : integer := 3;
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 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 wbs_i : mem_bridge_wbs_i_type;
signal wbs_o : mem_bridge_wbs_o_type;
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);
begin -- testbench
-- component instantiation
DUT: entity work.wb_mem_bridge
generic map (
burst_length => burst_length,
burst_length_ln2 => burst_length_ln2,
dontcare => dontcare
)
port map (
clk_i => clk_i,
rst_i => rst_i,
wbs_i => wbs_i,
wbs_o => wbs_o,
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
);
mem_ctrl_inst: entity work.wb_ddr_ctrl_wb_sc
generic map (
burst_length => burst_length,
burst_length_ln2 => burst_length_ln2,
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,
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';
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait for 50 ns;
wait until rising_edge(clk_i);
rst_i <= '0';
wait until rising_edge(clk_i);
-- Read miss (on clean buffer)
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '0';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000002#, 24));
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
assert wbs_o.dat_o = x"00000001" report "Incorrect read data (WB)" severity error;
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait until rising_edge(clk_i);
-- Write hit
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '1';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000000#, 24));
wbs_i.dat_i <= x"DEADBEEF";
wbs_i.sel_i <= "1111";
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait until rising_edge(clk_i);
-- Read hit
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '0';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000000#, 24));
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
assert wbs_o.dat_o = x"DEADBEEF" report "Incorrect read data (WB)" severity error;
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait until rising_edge(clk_i);
-- Read miss (on dirty buffer)
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '0';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000020#, 24));
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
assert wbs_o.dat_o = x"00000010" report "Incorrect read data (WB)" severity error;
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait until rising_edge(clk_i);
-- Write miss (on clean buffer)
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '1';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000033#, 24));
wbs_i.dat_i <= x"DEADBEEF";
wbs_i.sel_i <= "1111";
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
wbs_i.stb_i <= '0';
wbs_i.cyc_i <= '0';
wait until rising_edge(clk_i);
-- Write miss (on dirty buffer)
wbs_i.stb_i <= '1';
wbs_i.cyc_i <= '1';
wbs_i.we_i <= '1';
wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000044#, 24));
wbs_i.dat_i <= x"DEADBEEF";
wbs_i.sel_i <= "1111";
wait until rising_edge(clk_i);
while wbs_o.ack_o = '0' loop
wait until rising_edge(clk_i);
end loop;
wbs_i.stb_i <= '0';
wbs_i.cyc_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;
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;
-------------------------------------------------------------------------------