diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd index f0cf079b5a95b9cd9682181815e94d3592ab825f..f8d6c54ed0d3a7142a25958812991925c68c01f7 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd @@ -18,7 +18,7 @@ -- ------------------------------------------------------------------------------- -- Author: Job van Wee --- Purpose: Create address by counting input valids +-- Purpose: Creates address by counting input valids -- -- Description: -- The counter starts on the first valid = '1' clockcylce, the counter stops @@ -41,43 +41,44 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY ddrctrl_address_counter IS GENERIC ( - g_tech_ddr : t_c_tech_ddr; - g_sim_model : BOOLEAN := TRUE + g_tech_ddr : t_c_tech_ddr; -- type of memory + g_sim_model : BOOLEAN := TRUE -- determens if this is a simulation ); PORT ( - clk : IN STD_LOGIC; rst : IN STD_LOGIC; - in_sosi : IN t_dp_sosi; - out_mosi : OUT t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst + in_sosi : IN t_dp_sosi; -- input data + out_mosi : OUT t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst -- output data ); END ddrctrl_address_counter; ARCHITECTURE rtl OF ddrctrl_address_counter IS - CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); --576 - CONSTANT c_adr_w : NATURAL := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); --27; - CONSTANT c_max_adr : NATURAL := 2**(c_adr_w) - 1; + -- constants for readability + CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- the with of the input data and output data, 576 + CONSTANT c_adr_w : NATURAL := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27 + CONSTANT c_max_adr : NATURAL := 2**(c_adr_w) - 1; -- the maximal address that is possible within the vector length of the address - SIGNAL s_adr : NATURAL range 0 to 2**(c_adr_w)-1 := 0; + -- signal for storing address + SIGNAL s_adr : NATURAL range 0 to 2**(c_adr_w)-1 := 0; -- a signal that contains the address BEGIN + -- The data is directly put through. out_mosi.wrdata(c_data_w - 1 DOWNTO 0) <= in_sosi.data(c_data_w - 1 DOWNTO 0); out_mosi.wr <= in_sosi.valid; out_mosi.address(c_adr_w -1 DOWNTO 0) <= TO_UVEC(s_adr, c_adr_w); - p_clk : PROCESS(clk) + -- Increments the address each time in_sosi.valid = '1', if address = c_max_adr the address is reset to 0. + p_adr : PROCESS(rst, in_sosi.valid) BEGIN - IF rising_edge(clk) THEN - IF rst = '1' THEN + IF rst = '1' THEN + s_adr <= 0; + ELSIF rising_edge(in_sosi.valid) THEN + IF s_adr = c_max_adr THEN s_adr <= 0; - ELSIF in_sosi.valid = '1' THEN - IF (s_adr = c_max_adr) THEN - s_adr <= 0; - ELSE - s_adr <= s_adr + 1; - END IF; + ELSE + s_adr <= s_adr + 1; END IF; END IF; END PROCESS; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd index 3a000800679663e31c860cca2791bfd4e01d3bbb..0f3e4d414a0f5f513b4fdfc341698fc4dd164bf5 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd @@ -33,75 +33,60 @@ USE common_lib.common_pkg.ALL; ENTITY tb_ddrctrl_address_counter IS GENERIC ( - g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m; - g_sim_model : BOOLEAN := TRUE + 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_sim_length : NATURAL := 52 -- determens the length of the duration of the test ); END tb_ddrctrl_address_counter; ARCHITECTURE tb OF tb_ddrctrl_address_counter IS - CONSTANT c_clk_freq : NATURAL := 200; -- MHz - CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps; + -- constants for running the testbench + CONSTANT c_clk_freq : NATURAL := 200; -- clock frequency in MHz + CONSTANT c_clk_period : TIME := (10**6/c_clk_freq)*1 ps; -- clock period, 5 ns - CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- 576 - CONSTANT c_adr_w : NATURAL := 4; - CONSTANT c_max_adr : NATURAL := 2**c_adr_w; + -- constants for running the test + CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- in and 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 - SIGNAL tb_end : STD_LOGIC := '0'; + -- input signals for ddrctrl_address_counter.vhd SIGNAL clk : STD_LOGIC := '1'; - SIGNAL rst : STD_LOGIC; + SIGNAL rst : STD_LOGIC := '0'; + SIGNAL in_sosi : t_dp_sosi := c_dp_sosi_init; -- signal which is the input for ddrctrl_address_counter.vhd - SIGNAL in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); - SIGNAL in_data_enable : STD_LOGIC; - SIGNAL in_sosi : t_dp_sosi := c_dp_sosi_init; + -- output signal from ddrctrl_address_counter.vhd + SIGNAL out_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; -- signal which is the output from ddrctrl_address_counter.vhd - SIGNAL out_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; + -- testbench signals + SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off + SIGNAL in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); -- signal which contains the data that is set as input + SIGNAL in_data_enable : STD_LOGIC; -- signal to determen if in_data is ready for reading + SIGNAL lag_due_reset : NATURAL := 0; -- signal to hold the address lag after a rest BEGIN - -- if these ASSERT's get uncommented u can see that modelsim does take a few itteration before the warning gets asserted. These asserts are also present in p_verify - - --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) = out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata" SEVERITY ERROR; -- gives error if in_sosi and out_mosi do not match - --ASSERT in_sosi.valid = out_mosi.wr REPORT "in_sosi.valid does not match out_mosi.wr" SEVERITY ERROR; - --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) /= out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does match out_mosi.wrdata" SEVERITY WARNING; -- gives warning if in_sosi and out_mosi do match - --ASSERT in_sosi.valid /= out_mosi.wr REPORT "in_sosi.valid does match out_mosi.wr" SEVERITY WARNING; - - in_sosi.data(c_data_w - 1 DOWNTO 0) <= in_data(c_data_w - 1 DOWNTO 0); - in_sosi.valid <= in_data_enable; + -- wiring the input signals to the inputs of the testbench + in_sosi.data(c_data_w-1 DOWNTO 0) <= in_data(c_data_w-1 DOWNTO 0); + in_sosi.valid <= in_data_enable; + -- generating clock clk <= NOT clk OR tb_end AFTER c_clk_period/2; - p_mm : PROCESS + -- excecuting the test + p_test : PROCESS BEGIN - rst <= '1', '0' AFTER c_clk_period/10; - + -- initialize inputs tb_end <= '0'; in_data <= (OTHERS => '0'); in_data_enable <= '0'; + WAIT UNTIL rising_edge(clk); - WAIT UNTIL rising_edge(clk); -- align to rising edge - WAIT FOR c_clk_period*10; - - FOR I IN 0 TO 6 LOOP - in_data_enable <= '1'; - in_data <= NOT in_data; - ASSERT I = TO_UINT(out_mosi.address) REPORT "Wrong address, I = " & NATURAL'image(I) SEVERITY ERROR; - WAIT FOR c_clk_period*1; - in_data_enable <= '0'; - WAIT FOR c_clk_period*2; - END LOOP; - - WAIT FOR c_clk_period*1; - rst <= '1'; -- reset - WAIT FOR c_clk_period*1; - rst <= '0'; - WAIT FOR c_clk_period*1; - - FOR I IN 0 TO 20 LOOP - ASSERT I = TO_UINT(out_mosi.address) OR I - c_max_adr = TO_UINT(out_mosi.address) REPORT "Wrong address, I = " & NATURAL'image(I) SEVERITY ERROR; + -- changing inputs to start the address counting + FOR I IN 0 TO g_sim_length-1 LOOP in_data_enable <= '1'; in_data <= NOT in_data; WAIT FOR c_clk_period*1; @@ -109,41 +94,64 @@ BEGIN WAIT FOR c_clk_period*2; END LOOP; - WAIT FOR c_clk_period*20; - + -- stopping the test + WAIT FOR c_clk_period*4; tb_end <= '1'; - WAIT; - + ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; END PROCESS; - p_verify : PROCESS + -- verifying if the data is correct and if valid is correct + p_verify_data_valid : PROCESS BEGIN WAIT UNTIL rising_edge(clk); IF rising_edge(clk) THEN - ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) = out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata" SEVERITY ERROR; -- gives error if in_sosi and out_mosi do not match - ASSERT in_sosi.valid = out_mosi.wr REPORT "in_sosi.valid does not match out_mosi.wr" SEVERITY ERROR; - --ASSERT in_sosi.data(c_data_w - 1 DOWNTO 0) /= out_mosi.wrdata(c_data_w - 1 DOWNTO 0) REPORT "in_sosi.data does match out_mosi.wrdata" SEVERITY WARNING; -- gives warning if in_sosi and out_mosi do match - --ASSERT in_sosi.valid /= out_mosi.wr REPORT "in_sosi.valid does match out_mosi.wr" SEVERITY WARNING; + ASSERT in_sosi.data(c_data_w-1 DOWNTO 0) = out_mosi.wrdata(c_data_w-1 DOWNTO 0) REPORT "in_sosi.data does not match out_mosi.wrdata" SEVERITY ERROR; + ASSERT in_sosi.valid = out_mosi.wr REPORT "in_sosi.valid does not match out_mosi.wr" SEVERITY ERROR; END IF; END PROCESS; + -- excecuting the reset test + p_test_reset : PROCESS + BEGIN + rst <= '0'; + WAIT FOR c_clk_period*(c_adr_size+3); + 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; + rst <= '1'; + WAIT FOR c_clk_period*1; + END PROCESS; + + -- verifying if the address is correct by keeping trach of the address + p_verify_address : PROCESS + BEGIN + FOR I IN 0 TO c_adr_size-1 LOOP + WAIT UNTIL out_mosi.wr = '1'; + IF rst = '1' THEN + WAIT UNTIL out_mosi.wr = '1'; + END IF; + IF I >= lag_due_reset THEN + ASSERT I-lag_due_reset = TO_UINT(out_mosi.address) REPORT "Wrong address, 1, I = " & NATURAL'image(I-lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + ELSE + ASSERT (I-lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address) REPORT "Wrong address, 2, I = " & NATURAL'image((I-lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR; + END IF; + END LOOP; + END PROCESS; + + + -- DUT u_ddrctrl_address_counter : ENTITY work.ddrctrl_address_counter GENERIC MAP ( g_tech_ddr => g_tech_ddr, g_sim_model => g_sim_model ) PORT MAP ( - clk => clk, rst => rst, in_sosi => in_sosi, out_mosi => out_mosi - ); END tb; - - - - -