Skip to content
Snippets Groups Projects
Commit 867537af authored by David Brouwer's avatar David Brouwer
Browse files

Created new testbenches based on the architecture of...

Created new testbenches based on the architecture of tb_common_paged_ram_crw_crw.vhd, as common_paged_ram_cr_cw and common_paged_ram_rw_rw no longer uses underlying common_paged_ram_crw_crw.
parent 60795a74
No related branches found
No related tags found
1 merge request!363Porting ram for Intel Agilex 7
-- -----------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- -----------------------------------------------------------------------------
--
-- Author:
-- D.F. Brouwer
-- Purpose:
-- Test bench for common_paged_ram_cr_cw
-- Reference:
-- Based on tb_common_paged_ram_crw_crw.vhd
-- Description:
-- Features:
-- . Use c_gap_sz = 0 to try writing and reading multiple page without idle
-- cycles
-- . Most applications use c_nof_pages = 2, but use > 2 is supported too.
-- Usage:
-- > as 10
-- > run -all
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.common_pkg.all;
use work.tb_common_pkg.all;
entity tb_common_paged_ram_cr_cw is
end tb_common_paged_ram_cr_cw;
architecture tb of tb_common_paged_ram_cr_cw is
constant clk_period : time := 10 ns;
constant c_data_w : natural := 8;
constant c_nof_pages : natural := 2; -- >= 2
constant c_page_sz : natural := 8;
constant c_wr_start_page : natural := 0;
constant c_rd_start_page : natural := 1;
constant c_gap_sz : natural := 0; -- >= 0
constant c_rl : natural := 1;
signal rst : std_logic;
signal clk : std_logic := '1';
signal tb_end : std_logic := '0';
-- DUT
signal next_page : std_logic;
signal wr_next_page : std_logic;
signal wr_adr : std_logic_vector(ceil_log2(c_page_sz) - 1 downto 0) := (others => '0');
signal wr_en : std_logic;
signal wr_dat : std_logic_vector(c_data_w - 1 downto 0) := (others => '0');
signal rd_next_page : std_logic;
signal rd_adr : std_logic_vector(ceil_log2(c_page_sz) - 1 downto 0) := (others => '0');
signal rd_en : std_logic := '0';
signal mux_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
signal mux_rd_val : std_logic;
signal adr_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
signal adr_rd_val : std_logic;
signal ofs_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
signal ofs_rd_val : std_logic;
-- Verify
signal verify_en : std_logic;
signal ready : std_logic := '1';
signal prev_mux_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
signal prev_adr_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
signal prev_ofs_rd_dat : std_logic_vector(c_data_w - 1 downto 0);
begin
clk <= not clk and not tb_end after clk_period / 2;
rst <= '1', '0' after clk_period * 7;
verify_en <= '0', '1' after clk_period * (15 + (c_nof_pages - 1) * c_page_sz);
-- Apply stimuli via port 'a', do write 'a' and read 'b', and derive the 'b' stimuli from the 'a' stimuli with 1 clock cycle latency
wr_next_page <= next_page;
rd_next_page <= next_page when rising_edge(clk);
wr_dat <= INCR_UVEC( wr_dat, 1) when rising_edge(clk) and wr_en = '1';
wr_adr <= INCR_UVEC( wr_adr, 1) when rising_edge(clk) and wr_en = '1';
rd_adr <= wr_adr when rising_edge(clk);
rd_en <= wr_en when rising_edge(clk);
p_stimuli : process
begin
next_page <= '0';
wr_en <= '0';
proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 3);
-- Access the pages several times
for I in 0 to c_nof_pages * 3 loop
wr_en <= '1';
proc_common_wait_some_cycles(clk, c_page_sz - 1);
next_page <= '1';
proc_common_wait_some_cycles(clk, 1);
next_page <= '0';
wr_en <= '0';
proc_common_wait_some_cycles(clk, c_gap_sz); -- optinal gap between the pages
end loop;
wr_en <= '0';
proc_common_wait_some_cycles(clk, c_page_sz);
tb_end <= '1';
wait;
end process;
u_dut_mux : entity work.common_paged_ram_cr_cw
generic map (
g_str => "use_mux",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_wr_start_page => c_wr_start_page,
g_rd_start_page => c_rd_start_page
)
port map (
-- Write port clock domain
wr_rst => rst,
wr_clk => clk,
wr_clken => '1',
wr_next_page => wr_next_page,
wr_adr => wr_adr,
wr_en => wr_en,
wr_dat => wr_dat,
-- Read port clock domain
rd_rst => rst,
rd_clk => clk,
rd_clken => '1',
rd_next_page => rd_next_page,
rd_adr => rd_adr,
rd_en => rd_en,
rd_dat => mux_rd_dat,
rd_val => mux_rd_val
);
u_dut_adr : entity work.common_paged_ram_cr_cw
generic map (
g_str => "use_adr",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_wr_start_page => c_wr_start_page,
g_rd_start_page => c_rd_start_page
)
port map (
-- Write port clock domain
wr_rst => rst,
wr_clk => clk,
wr_clken => '1',
wr_next_page => wr_next_page,
wr_adr => wr_adr,
wr_en => wr_en,
wr_dat => wr_dat,
-- Read port clock domain
rd_rst => rst,
rd_clk => clk,
rd_clken => '1',
rd_next_page => rd_next_page,
rd_adr => rd_adr,
rd_en => rd_en,
rd_dat => adr_rd_dat,
rd_val => adr_rd_val
);
u_dut_ofs : entity work.common_paged_ram_cr_cw
generic map (
g_str => "use_ofs",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_wr_start_page => c_wr_start_page,
g_rd_start_page => c_rd_start_page
)
port map (
-- Write port clock domain
wr_rst => rst,
wr_clk => clk,
wr_clken => '1',
wr_next_page => wr_next_page,
wr_adr => wr_adr,
wr_en => wr_en,
wr_dat => wr_dat,
-- Read port clock domain
rd_rst => rst,
rd_clk => clk,
rd_clken => '1',
rd_next_page => rd_next_page,
rd_adr => rd_adr,
rd_en => rd_en,
rd_dat => ofs_rd_dat,
rd_val => ofs_rd_val
);
-- Verify that the read data is incrementing data
proc_common_verify_data(c_rl, clk, verify_en, ready, mux_rd_val, mux_rd_dat, prev_mux_rd_dat);
proc_common_verify_data(c_rl, clk, verify_en, ready, adr_rd_val, adr_rd_dat, prev_adr_rd_dat);
proc_common_verify_data(c_rl, clk, verify_en, ready, ofs_rd_val, ofs_rd_dat, prev_ofs_rd_dat);
-- Verify that the read data is the same for all three DUT variants
p_verify_equal : process(clk)
begin
if rising_edge(clk) then
if unsigned(mux_rd_dat) /= unsigned(adr_rd_dat) or unsigned(mux_rd_dat) /= unsigned(ofs_rd_dat) then
report "DUT : read data differs between two implementations" severity ERROR;
end if;
if mux_rd_val /= adr_rd_val or mux_rd_val /= ofs_rd_val then
report "DUT : read valid differs between two implementations" severity ERROR;
end if;
end if;
end process;
end tb;
-- -----------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- -----------------------------------------------------------------------------
--
-- Author:
-- D.F. Brouwer
-- Purpose:
-- Test bench for common_paged_ram_rw_rw
-- Reference:
-- Based on tb_common_paged_ram_crw_crw.vhd
-- Description:
-- Features:
-- . Use c_gap_sz = 0 to try writing and reading multiple page without idle
-- cycles
-- . Most applications use c_nof_pages = 2, but use > 2 is supported too.
-- Usage:
-- > as 10
-- > run -all
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.common_pkg.all;
use work.tb_common_pkg.all;
entity tb_common_paged_ram_rw_rw is
end tb_common_paged_ram_rw_rw;
architecture tb of tb_common_paged_ram_rw_rw is
constant clk_period : time := 10 ns;
constant c_data_w : natural := 8;
constant c_nof_pages : natural := 2; -- >= 2
constant c_page_sz : natural := 8;
constant c_start_page_a : natural := 0;
constant c_start_page_b : natural := 1;
constant c_gap_sz : natural := 0; -- >= 0
constant c_rl : natural := 1;
signal rst : std_logic;
signal clk : std_logic := '1';
signal tb_end : std_logic := '0';
-- DUT
signal next_page : std_logic;
signal next_page_a : std_logic;
signal adr_a : std_logic_vector(ceil_log2(c_page_sz) - 1 downto 0) := (others => '0');
signal wr_en_a : std_logic;
signal wr_dat_a : std_logic_vector(c_data_w - 1 downto 0) := (others => '0');
signal next_page_b : std_logic;
signal adr_b : std_logic_vector(ceil_log2(c_page_sz) - 1 downto 0) := (others => '0');
signal rd_en_b : std_logic := '0';
signal mux_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
signal mux_rd_val_b : std_logic;
signal adr_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
signal adr_rd_val_b : std_logic;
signal ofs_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
signal ofs_rd_val_b : std_logic;
-- Verify
signal verify_en : std_logic;
signal ready : std_logic := '1';
signal prev_mux_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
signal prev_adr_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
signal prev_ofs_rd_dat_b : std_logic_vector(c_data_w - 1 downto 0);
begin
clk <= not clk and not tb_end after clk_period / 2;
rst <= '1', '0' after clk_period * 7;
verify_en <= '0', '1' after clk_period * (15 + (c_nof_pages - 1) * c_page_sz);
-- Apply stimuli via port 'a', do write 'a' and read 'b', and derive the 'b' stimuli from the 'a' stimuli with 1 clock cycle latency
next_page_a <= next_page;
next_page_b <= next_page when rising_edge(clk);
wr_dat_a <= INCR_UVEC(wr_dat_a, 1) when rising_edge(clk) and wr_en_a = '1';
adr_a <= INCR_UVEC( adr_a, 1) when rising_edge(clk) and wr_en_a = '1';
adr_b <= adr_a when rising_edge(clk);
rd_en_b <= wr_en_a when rising_edge(clk);
p_stimuli : process
begin
next_page <= '0';
wr_en_a <= '0';
proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 3);
-- Access the pages several times
for I in 0 to c_nof_pages * 3 loop
wr_en_a <= '1';
proc_common_wait_some_cycles(clk, c_page_sz - 1);
next_page <= '1';
proc_common_wait_some_cycles(clk, 1);
next_page <= '0';
wr_en_a <= '0';
proc_common_wait_some_cycles(clk, c_gap_sz); -- optinal gap between the pages
end loop;
wr_en_a <= '0';
proc_common_wait_some_cycles(clk, c_page_sz);
tb_end <= '1';
wait;
end process;
u_dut_mux : entity work.common_paged_ram_rw_rw
generic map (
g_str => "use_mux",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_start_page_a => c_start_page_a,
g_start_page_b => c_start_page_b
)
port map (
rst => rst,
clk => clk,
clken => '1',
next_page_a => next_page_a,
adr_a => adr_a,
wr_en_a => wr_en_a,
wr_dat_a => wr_dat_a,
rd_en_a => '0',
rd_dat_a => OPEN,
rd_val_a => OPEN,
next_page_b => next_page_b,
adr_b => adr_b,
wr_en_b => '0',
wr_dat_b => (others => '0'),
rd_en_b => rd_en_b,
rd_dat_b => mux_rd_dat_b,
rd_val_b => mux_rd_val_b
);
u_dut_adr : entity work.common_paged_ram_rw_rw
generic map (
g_str => "use_adr",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_start_page_a => c_start_page_a,
g_start_page_b => c_start_page_b
)
port map (
rst => rst,
clk => clk,
clken => '1',
next_page_a => next_page_a,
adr_a => adr_a,
wr_en_a => wr_en_a,
wr_dat_a => wr_dat_a,
rd_en_a => '0',
rd_dat_a => OPEN,
rd_val_a => OPEN,
next_page_b => next_page_b,
adr_b => adr_b,
wr_en_b => '0',
wr_dat_b => (others => '0'),
rd_en_b => rd_en_b,
rd_dat_b => adr_rd_dat_b,
rd_val_b => adr_rd_val_b
);
u_dut_ofs : entity work.common_paged_ram_rw_rw
generic map (
g_str => "use_ofs",
g_data_w => c_data_w,
g_nof_pages => c_nof_pages,
g_page_sz => c_page_sz,
g_start_page_a => c_start_page_a,
g_start_page_b => c_start_page_b
)
port map (
rst => rst,
clk => clk,
clken => '1',
next_page_a => next_page_a,
adr_a => adr_a,
wr_en_a => wr_en_a,
wr_dat_a => wr_dat_a,
rd_en_a => '0',
rd_dat_a => OPEN,
rd_val_a => OPEN,
next_page_b => next_page_b,
adr_b => adr_b,
wr_en_b => '0',
wr_dat_b => (others => '0'),
rd_en_b => rd_en_b,
rd_dat_b => ofs_rd_dat_b,
rd_val_b => ofs_rd_val_b
);
-- Verify that the read data is incrementing data
proc_common_verify_data(c_rl, clk, verify_en, ready, mux_rd_val_b, mux_rd_dat_b, prev_mux_rd_dat_b);
proc_common_verify_data(c_rl, clk, verify_en, ready, adr_rd_val_b, adr_rd_dat_b, prev_adr_rd_dat_b);
proc_common_verify_data(c_rl, clk, verify_en, ready, ofs_rd_val_b, ofs_rd_dat_b, prev_ofs_rd_dat_b);
-- Verify that the read data is the same for all three DUT variants
p_verify_equal : process(clk)
begin
if rising_edge(clk) then
if unsigned(mux_rd_dat_b) /= unsigned(adr_rd_dat_b) or unsigned(mux_rd_dat_b) /= unsigned(ofs_rd_dat_b) then
report "DUT : read data differs between two implementations" severity ERROR;
end if;
if mux_rd_val_b /= adr_rd_val_b or mux_rd_val_b /= ofs_rd_val_b then
report "DUT : read valid differs between two implementations" severity ERROR;
end if;
end if;
end process;
end tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment