Skip to content
Snippets Groups Projects
Commit f7170178 authored by Job van Wee's avatar Job van Wee
Browse files

Seeing data in the memory map!

parent 910c8d71
No related branches found
No related tags found
1 merge request!228Resolve L2SDP-666
......@@ -57,8 +57,13 @@ ENTITY ddrctrl IS
PORT (
clk : IN STD_LOGIC := '0';
rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC := '0';
mm_rst : IN STD_LOGIC := '0';
in_sosi_arr : IN t_dp_sosi_arr; -- input data
wr_not_rd : IN STD_LOGIC := '0';
out_of : OUT NATURAL; -- amount of internal overflow this output
out_adr : OUT NATURAL;
term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol;
term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst;
......@@ -83,12 +88,11 @@ ARCHITECTURE str OF ddrctrl IS
CONSTANT c_io_ddr_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr );
-- signals for connecting the components
SIGNAL data : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0);
SIGNAL sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL adr : NATURAL := 0;
SIGNAL a_of : NATURAL := 0;
SIGNAL ctrl_clk : STD_LOGIC := '0';
SIGNAL ctrl_rst : STD_LOGIC := '0';
SIGNAL ctrl_clk : STD_LOGIC;
SIGNAL ctrl_rst : STD_LOGIC;
SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL wr_siso : t_dp_siso;
SIGNAL rd_siso : t_dp_siso;
......@@ -97,50 +101,24 @@ ARCHITECTURE str OF ddrctrl IS
BEGIN
dvr_mosi.address <= TO_UVEC(adr, dvr_mosi.address'length);
-- makes one data vector out of all the data from the t_dp_sosi_arr
u_pack : ENTITY work.ddrctrl_pack
GENERIC MAP(
g_nof_streams => g_nof_streams, -- number of input streams
g_data_w => g_data_w -- data with of input data vectors
)
PORT MAP(
in_sosi_arr => in_sosi_arr, -- input data
out_data => data -- output data
);
-- resizes the input data vector so that the output data vector can be stored into the ddr memory
u_repack : ENTITY work.ddrctrl_repack
GENERIC MAP(
g_tech_ddr => g_tech_ddr, -- type of memory
g_in_data_w => c_out_data_w -- the input data with
)
PORT MAP(
clk => clk,
rst => rst,
in_data => data, -- input data
out_of => a_of, -- amount of internal overflow
out_sosi => sosi -- output data
);
-- creates address by counting input valids
u_address_counter : ENTITY work.ddrctrl_address_counter
dvr_mosi.burstbegin <= wr_sosi.valid;
dvr_mosi.wr <= wr_not_rd;
dvr_mosi.rd <= NOT wr_not_rd;
-- input to io_ddr
u_ddrctrl_input : ENTITY work.ddrctrl_input
GENERIC MAP(
g_tech_ddr => g_tech_ddr, -- type of memory
g_sim_model => g_sim_model -- determens if this is a simulation
g_tech_ddr => g_tech_ddr,
g_sim_model => g_sim_model,
g_nof_streams => g_nof_streams,
g_data_w => g_data_w
)
PORT MAP(
clk => clk,
rst => rst,
in_sosi => sosi, -- input data
in_of => a_of,
out_sosi => wr_sosi, -- output data
in_sosi_arr => in_sosi_arr,
out_of => out_of,
out_adr => adr
out_sosi => wr_sosi,
out_adr => out_adr
);
-- functions as a fifo buffer for input data into the sdram stick. also manages input to sdram stick.
......@@ -173,8 +151,8 @@ BEGIN
ctlr_rst_in => ctrl_rst,
-- MM clock + reset
mm_rst => rst,
mm_clk => clk,
mm_rst => mm_rst,
mm_clk => mm_clk,
-- MM interface
reg_io_ddr_mosi => open,
......
-------------------------------------------------------------------------------
--
-- Copyright 2022
-- 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: Job van Wee
-- Purpose: Folding a stream of data into a mm data configuration so it can be
-- stored in a DDR RAM-stick.
--
-- Description:
-- First the data from the sosi array gets collected into one data vector.
-- After that this data vector gets resized to the right size data vector in
-- order to make it storable in a DDR RAM-stick.
-- After that a address gets assigned to the data so the data can be found back.
--
-- Remark:
-- Use VHDL coding template from:
-- https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding
-- The maximum value of the address is determend by g_tech_ddr.
LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE technology_lib.technology_pkg.ALL;
USE tech_ddr_lib.tech_ddr_pkg.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY ddrctrl_input IS
GENERIC (
g_tech_ddr : t_c_tech_ddr; -- type of memory
g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation
g_nof_streams : NATURAL := 12; -- number of input streams
g_data_w : NATURAL := 14 -- data with of input data vectors
);
PORT (
clk : IN STD_LOGIC := '0';
rst : IN STD_LOGIC;
in_sosi_arr : IN t_dp_sosi_arr; -- input data
out_of : OUT NATURAL; -- amount of internal overflow this output
out_sosi : OUT t_dp_sosi; -- output data
out_adr : OUT NATURAL
);
END ddrctrl_input;
ARCHITECTURE str OF ddrctrl_input IS
-- constant for readability
CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data with for ddrctrl_repack
-- signals for connecting the components
SIGNAL data : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0);
SIGNAL sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL a_of : NATURAL := 0;
BEGIN
-- makes one data vector out of all the data from the t_dp_sosi_arr
u_pack : ENTITY work.ddrctrl_pack
GENERIC MAP(
g_nof_streams => g_nof_streams, -- number of input streams
g_data_w => g_data_w -- data with of input data vectors
)
PORT MAP(
in_sosi_arr => in_sosi_arr, -- input data
out_data => data -- output data
);
-- resizes the input data vector so that the output data vector can be stored into the ddr memory
u_repack : ENTITY work.ddrctrl_repack
GENERIC MAP(
g_tech_ddr => g_tech_ddr, -- type of memory
g_in_data_w => c_out_data_w -- the input data with
)
PORT MAP(
clk => clk,
rst => rst,
in_data => data, -- input data
out_of => a_of, -- amount of internal overflow
out_sosi => sosi -- output data
);
-- creates address by counting input valids
u_address_counter : ENTITY work.ddrctrl_address_counter
GENERIC MAP(
g_tech_ddr => g_tech_ddr, -- type of memory
g_sim_model => g_sim_model -- determens if this is a simulation
)
PORT MAP(
clk => clk,
rst => rst,
in_sosi => sosi, -- input data
in_of => a_of,
out_sosi => out_sosi, -- output data
out_of => out_of,
out_adr => out_adr
);
END str;
......@@ -31,6 +31,7 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_pkg.ALL;
USE technology_lib.technology_select_pkg.ALL;
ENTITY tb_ddrctrl IS
GENERIC (
......@@ -39,10 +40,10 @@ ENTITY tb_ddrctrl IS
g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation
g_nof_streams : POSITIVE := 12; -- number of input streams
g_data_w : NATURAL := 14; -- data with of input data vectors
g_sim_length : NATURAL := 52
g_sim_length : NATURAL := 1052;
g_technology : NATURAL := c_tech_select_default;
g_wr_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO, >=16 and independent of wr burst size, default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
g_rd_fifo_depth : NATURAL := 256 -- defined at DDR side of the FIFO, >=16 AND > max number of rd burst sizes (so > c_rd_fifo_af_margin), default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master;
g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m
);
END tb_ddrctrl;
......@@ -51,6 +52,16 @@ ARCHITECTURE tb OF tb_ddrctrl IS
-- constants for testbench
CONSTANT c_clk_freq : NATURAL := 200; -- clock frequency in MHz
CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps; -- clock priod, 5 ns
CONSTANT c_mm_clk_freq : NATURAL := 100;
CONSTANT c_mm_clk_period : TIME := (10**6 / c_mm_clk_freq) * 1 ps;
-- Select DDR3 or DDR4 dependent on the technology and sim model
CONSTANT c_mem_ddr : t_c_tech_ddr := func_tech_sel_ddr(g_technology, g_tech_ddr3, g_tech_ddr4);
CONSTANT c_sim_ddr : t_c_tech_ddr := func_tech_sel_ddr(g_technology, c_tech_ddr3_sim_16k, c_tech_ddr4_sim_16k);
CONSTANT c_tech_ddr : t_c_tech_ddr := func_tech_sel_ddr(g_sim_model, c_sim_ddr, c_mem_ddr);
CONSTANT c_wr_fifo_depth : NATURAL := 16; -- defined at DDR side of the FIFO
CONSTANT c_rd_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO
-- constants for readability
CONSTANT c_in_data_w : NATURAL := g_nof_streams * g_data_w; -- output data with, 168
......@@ -75,13 +86,16 @@ ARCHITECTURE tb OF tb_ddrctrl IS
-- input signals for ddrctrl.vhd
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '0';
SIGNAL mm_clk : STD_LOGIC := '0';
SIGNAL mm_rst : STD_LOGIC := '0';
SIGNAL q_rst : STD_LOGIC := '0';
SIGNAL q_q_rst : STD_LOGIC := '0';
SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- input data signal for ddrctrl_pack.vhd
SIGNAL wr_not_rd : STD_LOGIC;
-- output singals from ddrctrl.vhd
SIGNAL out_of : NATURAL := 0; -- output signal from ddrctrl_repack to determen how high the overflow is
SIGNAL out_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; -- output signal from ddrctrl_pack.vhd
SIGNAL out_adr : NATURAL := 0;
-- testbench signal
SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off
......@@ -96,10 +110,17 @@ ARCHITECTURE tb OF tb_ddrctrl IS
SIGNAL lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest
SIGNAL q_lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest with a delay of 1 clockcycle
-- PHY
SIGNAL phy3_io : t_tech_ddr3_phy_io;
SIGNAL phy3_ou : t_tech_ddr3_phy_ou;
SIGNAL phy4_io : t_tech_ddr4_phy_io;
SIGNAL phy4_ou : t_tech_ddr4_phy_ou;
BEGIN
-- generating clock
clk <= NOT clk OR tb_end AFTER c_clk_period/2;
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
-- excecuting test
p_test : PROCESS
......@@ -110,9 +131,12 @@ BEGIN
WAIT UNTIL rising_edge(clk); -- align to rising edge
WAIT FOR c_clk_period*4;
rst <= '1';
mm_rst <= '1';
WAIT FOR c_clk_period*1;
rst <= '0';
mm_rst <= '0';
test_running <= '1';
wr_not_rd <= '1';
-- filling the input data vectors with the corresponding numbers
make_data : FOR J IN 0 TO g_sim_length-1 LOOP
......@@ -123,14 +147,15 @@ BEGIN
WAIT FOR c_clk_period*1;
END LOOP;
test_running <= '0';
wr_not_rd <= '0';
-- testing reset
FOR I IN 0 TO g_sim_length-1 LOOP
rst <= '1';
WAIT FOR c_clk_period*1;
rst <= '0';
WAIT FOR c_clk_period*((((c_out_data_w/c_in_data_w)+1)*c_adr_size)+4);
END LOOP;
-- FOR I IN 0 TO g_sim_length-1 LOOP
-- rst <= '1';
-- WAIT FOR c_clk_period*1;
-- rst <= '0';
-- WAIT FOR c_clk_period*((((c_out_data_w/c_in_data_w)+1)*c_adr_size)+4);
-- END LOOP;
-- stopping the testbench
......@@ -139,75 +164,49 @@ BEGIN
ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE;
END PROCESS;
-- generating compare data for out_mosi
p_out_mosi : PROCESS
BEGIN
WAIT UNTIL rising_edge(clk);
if rising_edge(clk) THEN
q_q_rst <= q_rst;
q_lag_due_reset <= lag_due_reset;
q_rst <= rst;
END IF;
IF q_rst = '1' THEN
IF lag_due_reset + TO_UINT(out_mosi.address) >= c_adr_size THEN
lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address)-c_adr_size;
ELSE
lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address);
END IF;
END IF;
END PROCESS;
-- verifying if the address is correct by keeping track of the address
p_verify_address : PROCESS
BEGIN
FOR I IN 0 TO c_adr_size-1 LOOP
IF I >= q_lag_due_reset THEN
ASSERT I-q_lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR;
ELSE
ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR;
END IF;
WAIT UNTIL out_mosi.wr = '1';
IF q_q_rst = '1' THEN
WAIT UNTIL out_mosi.wr = '1';
END IF;
END LOOP;
END PROCESS;
-- verification by checking if the input vectors are correctly put into the output vector and the amount of overflow is as expected
p_verify : PROCESS
VARIABLE ctr_of : NATURAL := 0;
VARIABLE out_data_cnt : NATURAL := 0;
BEGIN
WAIT UNTIL rising_edge(clk);
IF q_q_test_running = '1' AND out_mosi.wr = '1' THEN
out_data_cnt := out_data_cnt+1;
IF out_data_cnt mod 2 = 0 THEN
ctr_of := c_in_data_w*(q_q_in_data_cnt)-c_out_data_w*out_data_cnt;
ASSERT ctr_of = out_of REPORT "The amount of overflow does not match, ctr_of = " & NATURAL'image(ctr_of) & ", out_of = " & NATURAL'image(out_of) SEVERITY ERROR;
END IF;
ASSERT out_mosi.wrdata(c_out_data_w-1 DOWNTO 0) = c_total_vector(c_out_data_w*out_data_cnt-1 DOWNTO c_out_data_w*(out_data_cnt-1)) REPORT "Data does not match, out_data_cnt = " & NATURAL'image(out_data_cnt) SEVERITY ERROR;
END IF;
END PROCESS;
-- DUT
u_ddrctrl : ENTITY work.ddrctrl
GENERIC MAP (
g_tech_ddr => g_tech_ddr,
g_tech_ddr => c_tech_ddr,
g_sim_model => g_sim_model,
g_technology => g_technology,
g_nof_streams => g_nof_streams,
g_data_w => g_data_w,
g_wr_fifo_depth => g_wr_fifo_depth,
g_rd_fifo_depth => g_rd_fifo_depth
g_wr_fifo_depth => c_wr_fifo_depth,
g_rd_fifo_depth => c_rd_fifo_depth
)
PORT MAP (
clk => clk,
rst => rst,
mm_clk => mm_clk,
mm_rst => mm_rst,
in_sosi_arr => in_sosi_arr,
wr_not_rd => wr_not_rd,
out_of => out_of,
out_adr => out_adr,
--PHY
phy3_io => phy3_io,
phy3_ou => phy3_ou,
phy4_io => phy4_io,
phy4_ou => phy4_ou
);
u_tech_ddr_memory_model : ENTITY tech_ddr_lib.tech_ddr_memory_model
GENERIC MAP (
g_tech_ddr => c_tech_ddr
)
PORT MAP (
-- DDR3 PHY interface
mem3_in => phy3_ou,
mem3_io => phy3_io,
-- DDR4 PHY interface
mem4_in => phy4_ou,
mem4_io => phy4_io
);
END tb;
-------------------------------------------------------------------------------
--
-- Copyright 2022
-- 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: Job van Wee
-- Purpose: Self checking and self-stopping tb for ddrctrl_input.vhd
-- Usage:
-- > run -a
LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.MATH_REAL.ALL;
USE technology_lib.technology_pkg.ALL;
USE tech_ddr_lib.tech_ddr_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_pkg.ALL;
ENTITY tb_ddrctrl_input IS
GENERIC (
g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m; -- type of memory
g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation
g_nof_streams : POSITIVE := 12; -- number of input streams
g_data_w : NATURAL := 14; -- data with of input data vectors
g_sim_length : NATURAL := 52
);
END tb_ddrctrl_input;
ARCHITECTURE tb OF tb_ddrctrl_input IS
-- constants for testbench
CONSTANT c_clk_freq : NATURAL := 200; -- clock frequency in MHz
CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps; -- clock priod, 5 ns
-- constants for readability
CONSTANT c_in_data_w : NATURAL := g_nof_streams * g_data_w; -- output data with, 168
CONSTANT c_out_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- output data vector with, 576
CONSTANT c_adr_w : NATURAL := 4; -- address with in simulation
CONSTANT c_adr_size : NATURAL := 2**c_adr_w; -- address size in simulation
-- function for making total data vector
FUNCTION c_total_vector_init RETURN STD_LOGIC_VECTOR IS
VARIABLE temp : STD_LOGIC_VECTOR(c_in_data_w*g_sim_length-1 DOWNTO 0);
BEGIN
FOR I IN 0 TO g_sim_length*g_nof_streams-1 LOOP
temp(g_data_w*(I+1)-1 DOWNTO g_data_w*I) := TO_UVEC(I, g_data_w);
END LOOP;
RETURN temp;
END FUNCTION c_total_vector_init;
-- constant for running the test
CONSTANT c_total_vector : STD_LOGIC_VECTOR(c_in_data_w*g_sim_length-1 DOWNTO 0) := c_total_vector_init; -- vector which contains all input data vectors to make it easy to fill ctr_vector
-- input signals for ddrctrl_input.vhd
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '0';
SIGNAL q_rst : STD_LOGIC := '0';
SIGNAL q_q_rst : STD_LOGIC := '0';
SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init); -- input data signal for ddrctrl_pack.vhd
-- output singals from ddrctrl_input.vhd
SIGNAL out_of : NATURAL := 0; -- output signal from ddrctrl_repack to determen how high the overflow is
SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; -- output signal from ddrctrl_pack.vhd
SIGNAL out_adr : NATURAL := 0;
-- testbench signal
SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off
-- signals for running test
SIGNAL in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd
SIGNAL q_in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd with a delay of 1 clockcycle
SIGNAL q_q_in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd with a delay of 2 clockcycles
SIGNAL test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started
SIGNAL q_test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started with a delay of 1 clockcycle
SIGNAL q_q_test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started with a delay of 2 clockcycles
SIGNAL lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest
SIGNAL q_lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest with a delay of 1 clockcycle
BEGIN
-- generating clock
clk <= NOT clk OR tb_end AFTER c_clk_period/2;
-- excecuting test
p_test : PROCESS
BEGIN
-- start the test
tb_end <= '0';
WAIT UNTIL rising_edge(clk); -- align to rising edge
WAIT FOR c_clk_period*4;
rst <= '1';
WAIT FOR c_clk_period*1;
rst <= '0';
test_running <= '1';
-- filling the input data vectors with the corresponding numbers
make_data : FOR J IN 0 TO g_sim_length-1 LOOP
in_data_cnt <= in_data_cnt+1;
fill_in_sosi_arr_rest : FOR I IN 0 TO g_nof_streams-1 LOOP
in_sosi_arr(I).data(g_data_w-1 DOWNTO 0) <= c_total_vector(g_data_w*(I+1)+J*c_in_data_w-1 DOWNTO g_data_w*I+J*c_in_data_w);
END LOOP;
WAIT FOR c_clk_period*1;
END LOOP;
test_running <= '0';
-- testing reset
FOR I IN 0 TO g_sim_length-1 LOOP
rst <= '1';
WAIT FOR c_clk_period*1;
rst <= '0';
WAIT FOR c_clk_period*((((c_out_data_w/c_in_data_w)+1)*c_adr_size)+4);
END LOOP;
-- stopping the testbench
WAIT FOR c_clk_period*4;
tb_end <= '1';
ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE;
END PROCESS;
-- generating compare data for out_sosi
p_out_sosi : PROCESS
BEGIN
WAIT UNTIL rising_edge(clk);
if rising_edge(clk) THEN
q_q_rst <= q_rst;
q_lag_due_reset <= lag_due_reset;
q_rst <= rst;
END IF;
IF q_rst = '1' THEN
IF lag_due_reset + out_adr >= c_adr_size THEN
lag_due_reset <= lag_due_reset+out_adr-c_adr_size;
ELSE
lag_due_reset <= lag_due_reset+out_adr;
END IF;
END IF;
END PROCESS;
-- verifying if the address is correct by keeping track of the address
p_verify_address : PROCESS
BEGIN
FOR I IN 0 TO c_adr_size-1 LOOP
IF I >= q_lag_due_reset THEN
ASSERT I-q_lag_due_reset = out_adr REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR;
ELSE
ASSERT (I-q_lag_due_reset)+c_adr_size = out_adr REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR;
END IF;
WAIT UNTIL out_sosi.valid = '1';
IF q_q_rst = '1' THEN
WAIT UNTIL out_sosi.valid = '1';
END IF;
END LOOP;
END PROCESS;
-- verification by checking if the input vectors are correctly put into the output vector and the amount of overflow is as expected
p_verify : PROCESS
VARIABLE ctr_of : NATURAL := 0;
VARIABLE out_data_cnt : NATURAL := 0;
BEGIN
WAIT UNTIL rising_edge(clk);
IF q_q_test_running = '1' AND out_sosi.valid = '1' THEN
out_data_cnt := out_data_cnt+1;
IF out_data_cnt mod 2 = 0 THEN
ctr_of := c_in_data_w*(q_q_in_data_cnt)-c_out_data_w*out_data_cnt;
ASSERT ctr_of = out_of REPORT "The amount of overflow does not match, ctr_of = " & NATURAL'image(ctr_of) & ", out_of = " & NATURAL'image(out_of) SEVERITY ERROR;
END IF;
ASSERT out_sosi.data(c_out_data_w-1 DOWNTO 0) = c_total_vector(c_out_data_w*out_data_cnt-1 DOWNTO c_out_data_w*(out_data_cnt-1)) REPORT "Data does not match, out_data_cnt = " & NATURAL'image(out_data_cnt) SEVERITY ERROR;
END IF;
END PROCESS;
-- DUT
u_ddrctrl_input : ENTITY work.ddrctrl_input
GENERIC MAP (
g_tech_ddr => g_tech_ddr,
g_sim_model => g_sim_model,
g_nof_streams => g_nof_streams,
g_data_w => g_data_w
)
PORT MAP (
clk => clk,
rst => rst,
in_sosi_arr => in_sosi_arr,
out_of => out_of,
out_sosi => out_sosi,
out_adr => out_adr
);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment