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

Ready for Review.

parent f7170178
No related branches found
No related tags found
1 merge request!228Resolve L2SDP-666
......@@ -50,10 +50,8 @@ ENTITY ddrctrl IS
g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation
g_technology : NATURAL := c_tech_select_default;
g_nof_streams : NATURAL := 12; -- number of input streams
g_data_w : NATURAL := 14; -- data with of input data vectors
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_data_w : NATURAL := 14 -- data with of input data vectors
);
PORT (
clk : IN STD_LOGIC := '0';
rst : IN STD_LOGIC;
......@@ -67,12 +65,12 @@ ENTITY ddrctrl IS
term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol;
term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst;
-- DDR3 PHY external interface
phy3_in : IN t_tech_ddr3_phy_in := c_tech_ddr3_phy_in_x;
phy3_io : INOUT t_tech_ddr3_phy_io;
phy3_ou : OUT t_tech_ddr3_phy_ou;
-- DDR4 PHY external interface
phy4_in : IN t_tech_ddr4_phy_in := c_tech_ddr4_phy_in_x;
phy4_io : INOUT t_tech_ddr4_phy_io;
......@@ -84,11 +82,17 @@ END ddrctrl;
ARCHITECTURE str OF ddrctrl IS
-- constant for readability
CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data width for ddrctrl_repack 168
CONSTANT c_io_ddr_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr );
CONSTANT c_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data width for ddrctrl_repack 168
CONSTANT c_io_ddr_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr );
CONSTANT c_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
CONSTANT c_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
CONSTANT c_burstsize : NATURAL := 64; -- max burstsize for max troughput
CONSTANT c_bitshift_adr : NATURAL := ceil_log2(c_burstsize);
CONSTANT c_adr_w : NATURAL := 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
CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_adr-1 DOWNTO 0) := (OTHERS => '0');
-- signals for connecting the components
SIGNAL sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL adr : NATURAL := 0;
SIGNAL a_of : NATURAL := 0;
SIGNAL ctrl_clk : STD_LOGIC;
......@@ -97,13 +101,29 @@ ARCHITECTURE str OF ddrctrl IS
SIGNAL wr_siso : t_dp_siso;
SIGNAL rd_siso : t_dp_siso;
SIGNAL dvr_mosi : t_mem_ctlr_mosi;
SIGNAL dvr_miso : t_mem_ctlr_miso;
BEGIN
dvr_mosi.address <= TO_UVEC(adr, dvr_mosi.address'length);
dvr_mosi.burstbegin <= wr_sosi.valid;
p_burst : PROCESS(adr)
BEGIN
IF TO_UVEC(adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN
dvr_mosi.burstbegin <= '1';
IF adr = 0 THEN
dvr_mosi.address <= TO_UVEC(c_max_adr-c_burstsize, dvr_mosi.address'length);
ELSE
dvr_mosi.address <= TO_UVEC(adr-c_burstsize, dvr_mosi.address'length);
END IF;
ELSE
dvr_mosi.burstbegin <= '0';
END IF;
END PROCESS;
dvr_mosi.burstsize <= TO_UVEC(c_burstsize, dvr_mosi.burstsize'length);
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(
......@@ -118,7 +138,7 @@ BEGIN
in_sosi_arr => in_sosi_arr,
out_of => out_of,
out_sosi => wr_sosi,
out_adr => out_adr
out_adr => adr
);
-- functions as a fifo buffer for input data into the sdram stick. also manages input to sdram stick.
......@@ -129,8 +149,8 @@ BEGIN
g_tech_ddr => g_tech_ddr,
g_cross_domain_dvr_ctlr => FALSE,
g_wr_data_w => c_io_ddr_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,
g_rd_data_w => c_io_ddr_data_w,
g_wr_flush_mode => "VAL",
g_wr_flush_use_channel => FALSE,
......@@ -162,7 +182,7 @@ BEGIN
dvr_clk => clk,
dvr_rst => rst,
dvr_miso => open,
dvr_miso => dvr_miso,
dvr_mosi => dvr_mosi,
-- Write FIFO clock domain
......
......@@ -60,7 +60,7 @@ ARCHITECTURE rtl OF ddrctrl_address_counter IS
-- 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_adr_w : NATURAL := 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
-- type for statemachine
......@@ -103,7 +103,7 @@ BEGIN
CASE q_reg.state IS
WHEN RESET =>
v.s_adr := 0;
v.s_adr := c_max_adr-1;
WHEN COUNTING =>
v.s_adr := q_reg.s_adr+1;
......
......@@ -40,7 +40,7 @@ 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 := 1052;
g_sim_length : NATURAL := 16500;
g_technology : NATURAL := c_tech_select_default;
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
......@@ -54,6 +54,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS
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;
CONSTANT c_sim_length : NATURAL := (g_sim_length*576)/168;
-- 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);
......@@ -71,16 +72,16 @@ ARCHITECTURE tb OF tb_ddrctrl IS
-- 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);
VARIABLE temp : STD_LOGIC_VECTOR(c_in_data_w*c_sim_length-1 DOWNTO 0);
BEGIN
FOR I IN 0 TO g_sim_length*g_nof_streams-1 LOOP
FOR I IN 0 TO c_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
CONSTANT c_total_vector : STD_LOGIC_VECTOR(c_in_data_w*c_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.vhd
......@@ -137,9 +138,18 @@ BEGIN
mm_rst <= '0';
test_running <= '1';
wr_not_rd <= '1';
WAIT FOR c_clk_period*1;
make_data_0 : FOR J IN 1 TO 40-1 LOOP
in_data_cnt <= in_data_cnt+1;
fill_in_sosi_arr_rest_0 : 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;
-- filling the input data vectors with the corresponding numbers
make_data : FOR J IN 0 TO g_sim_length-1 LOOP
make_data : FOR J IN 40 TO c_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);
......@@ -150,7 +160,7 @@ BEGIN
wr_not_rd <= '0';
-- testing reset
-- FOR I IN 0 TO g_sim_length-1 LOOP
-- FOR I IN 0 TO c_sim_length-1 LOOP
-- rst <= '1';
-- WAIT FOR c_clk_period*1;
-- rst <= '0';
......@@ -174,9 +184,7 @@ BEGIN
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 => c_wr_fifo_depth,
g_rd_fifo_depth => c_rd_fifo_depth
g_data_w => g_data_w
)
PORT MAP (
clk => clk,
......@@ -195,18 +203,4 @@ BEGIN
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;
......@@ -48,10 +48,9 @@ ARCHITECTURE tb OF tb_ddrctrl_address_counter IS
-- 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_w : NATURAL := func_tech_ddr_ctlr_address_w( g_tech_ddr ); -- address with in simulation
CONSTANT c_adr_size : NATURAL := 2**c_adr_w; -- address size in simulation
-- input signals for ddrctrl_address_counter.vhd
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '0';
......@@ -96,6 +95,10 @@ BEGIN
in_data <= (OTHERS => '0');
in_data_enable <= '0';
WAIT UNTIL rising_edge(clk);
WAIT FOR c_clk_period*4;
rst <= '1';
WAIT FOR c_clk_period*1;
rst <= '0';
-- changing inputs to start the address counting
FOR I IN 0 TO g_sim_length-1 LOOP
......@@ -160,17 +163,27 @@ BEGIN
-- verifying if the address is correct by keeping track of the address
p_verify_address : PROCESS
VARIABLE v_adr : NATURAL range 0 to c_adr_size-1 := c_adr_size-1;
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;
WAIT UNTIL rst = '1';
WAIT UNTIL rst = '0';
FOR I IN 0 TO g_sim_length-1 LOOP
IF v_adr >= q_lag_due_reset THEN
ASSERT v_adr-q_lag_due_reset = out_adr REPORT "Wrong address, 1, v_adr = " & NATURAL'image(v_adr-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;
ASSERT (v_adr-q_lag_due_reset)+c_adr_size = out_adr REPORT "Wrong address, 2, v_adr = " & NATURAL'image((v_adr-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;
IF v_adr = c_adr_size-1 THEN
v_adr := 0;
ELSE
v_adr := v_adr+1;
END IF;
END LOOP;
END PROCESS;
......
......@@ -53,7 +53,7 @@ ARCHITECTURE tb OF tb_ddrctrl_input IS
-- 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_w : NATURAL := func_tech_ddr_ctlr_address_w( g_tech_ddr ) ; -- address with in simulation
CONSTANT c_adr_size : NATURAL := 2**c_adr_w; -- address size in simulation
-- function for making total data vector
......@@ -124,12 +124,12 @@ BEGIN
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;
--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
......@@ -148,28 +148,39 @@ BEGIN
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;
IF lag_due_reset+out_adr+2 >= c_adr_size THEN
lag_due_reset <= lag_due_reset+out_adr+2-c_adr_size;
ELSE
lag_due_reset <= lag_due_reset+out_adr;
lag_due_reset <= lag_due_reset+out_adr+2;
END IF;
END IF;
END PROCESS;
-- verifying if the address is correct by keeping track of the address
p_verify_address : PROCESS
VARIABLE v_adr : NATURAL range 0 to c_adr_size-1 := c_adr_size-2;
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;
WAIT UNTIL rst = '1';
WAIT UNTIL rst = '0';
FOR I IN 0 TO g_sim_length-1 LOOP
IF v_adr >= q_lag_due_reset THEN
ASSERT v_adr-q_lag_due_reset = out_adr REPORT "Wrong address, 1, v_adr = " & NATURAL'image(v_adr-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;
ASSERT (v_adr-q_lag_due_reset)+c_adr_size = out_adr REPORT "Wrong address, 2, v_adr = " & NATURAL'image((v_adr-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(out_adr) SEVERITY ERROR;
END IF;
WAIT UNTIL out_sosi.valid = '1';
WAIT UNTIL out_sosi.valid = '1';
IF q_q_rst = '1' THEN
WAIT UNTIL out_sosi.valid = '1';
END IF;
IF v_adr = c_adr_size-1 THEN
v_adr := 0;
ELSE
v_adr := v_adr+1;
END IF;
END LOOP;
WAIT;
END PROCESS;
-- verification by checking if the input vectors are correctly put into the output vector and the amount of overflow is as expected
......
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