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

Ready for review. But not verified.

parent 82db8eff
Branches
No related tags found
1 merge request!243Resolve L2SDP-707
Pipeline #29178 failed
......@@ -266,7 +266,8 @@ BEGIN
g_rd_fifo_uw_w => c_rd_fifo_uw_w,
g_max_adr => c_nof_adr,
g_burstsize => g_burstsize,
g_last_burstsize => c_last_burstsize
g_last_burstsize => c_last_burstsize,
g_adr_per_b => c_adr_per_b
)
PORT MAP(
clk => clk,
......
......@@ -40,16 +40,17 @@ ENTITY ddrctrl_controller IS
GENERIC (
g_tech_ddr : t_c_tech_ddr;
g_stop_percentage : NATURAL := 50;
g_nof_streams : NATURAL;
g_out_data_w : NATURAL;
g_wr_data_w : NATURAL;
g_rd_fifo_depth : NATURAL;
g_rd_data_w : NATURAL;
g_block_size : NATURAL;
g_rd_fifo_uw_w : NATURAL;
g_max_adr : NATURAL;
g_burstsize : NATURAL;
g_last_burstsize : NATURAL
g_nof_streams : NATURAL; -- 12
g_out_data_w : NATURAL; -- 14
g_wr_data_w : NATURAL; -- 168
g_rd_fifo_depth : NATURAL; -- 256
g_rd_data_w : NATURAL; -- 256
g_block_size : NATURAL; -- 1024
g_rd_fifo_uw_w : NATURAL; -- 8
g_max_adr : NATURAL; -- 16128
g_burstsize : NATURAL; -- 64
g_last_burstsize : NATURAL; -- 18
g_adr_per_b : NATURAL -- 299
);
PORT (
clk : IN STD_LOGIC;
......@@ -81,18 +82,23 @@ END ddrctrl_controller;
ARCHITECTURE rtl OF ddrctrl_controller IS
CONSTANT c_bitshift_adr : NATURAL := ceil_log2(g_burstsize); -- bitshift to make sure there is only a burst start at a interval of c_burstsize.
CONSTANT c_bitshift_w : NATURAL := ceil_log2(g_burstsize); -- bitshift to make sure there is only a burst start at a interval of 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_pof_ma : NATURAL := (g_max_adr*(100-g_stop_percentage))/100;
CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_adr-1 DOWNTO 0) := (OTHERS => '0');
CONSTANT c_pof_ma : NATURAL := (((g_max_adr*(100-g_stop_percentage))/100)/g_adr_per_b)*g_adr_per_b;
CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_w-1 DOWNTO 0) := (OTHERS => '0');
-- constant for reading
CONSTANT c_rd_data_w : NATURAL := g_nof_streams*g_out_data_w; -- 168
CONSTANT c_rest : NATURAL := c_rd_data_w-(g_wr_data_w mod c_rd_data_w); -- 96
CONSTANT c_max_read_cnt : NATURAL := (g_max_adr+1)/g_burstsize; -- 256
CONSTANT c_io_ddr_data_w : NATURAL := func_tech_ddr_ctlr_data_w(g_tech_ddr); -- 576
CONSTANT c_proportion : NATURAL := (c_io_ddr_data_w/c_rd_data_w)+1;
-- type for statemachine
TYPE t_state IS (RESET, WRITING, SET_STOP, STOP_WRITING, START_READING, READING, STOP_READING, IDLE);
TYPE t_state IS (RESET, WRITING, SET_STOP, STOP_WRITING, LAST_WRITE_BURST, START_READING, READING, STOP_READING, IDLE);
-- record for readability
TYPE t_reg IS RECORD
......@@ -101,7 +107,10 @@ ARCHITECTURE rtl OF ddrctrl_controller IS
started : STD_LOGIC;
-- stopping signals
ready_for_stop : STD_LOGIC;
stop_adr : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
last_adr_to_write_to : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
stop_burstsize : NATURAL;
stopped : STD_LOGIC;
rst_ddrctrl_input : STD_LOGIC;
cooling_down : NATURAL;
......@@ -120,7 +129,7 @@ ARCHITECTURE rtl OF ddrctrl_controller IS
wr_sosi : t_dp_sosi;
END RECORD;
CONSTANT c_t_reg_init : t_reg := (RESET, '0', TO_UVEC(g_max_adr, c_adr_w), '1', '1', 8, '0', 0, (OTHERS => '0'), 0, '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init);
CONSTANT c_t_reg_init : t_reg := (RESET, '0', '0', TO_UVEC(g_max_adr, c_adr_w), (OTHERS => '0'), 0, '1', '1', c_proportion, '0', 0, (OTHERS => '0'), 0, '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init);
-- signals for readability
......@@ -153,7 +162,7 @@ BEGIN
WHEN WRITING =>
-- if adr mod g_burstsize = 0
-- this makes sure that only ones every 64 writes a writeburst is started.
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
v.need_burst := '1';
END IF;
IF dvr_miso.done = '1' AND q_reg.need_burst = '1' THEN
......@@ -164,7 +173,7 @@ BEGIN
v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length);
ELSE
v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length);
v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length);
END IF;
ELSE
......@@ -178,17 +187,21 @@ BEGIN
WHEN SET_STOP =>
--setting a stop address dependend on the g_stop_percentage
IF inp_adr+c_pof_ma >= g_max_adr THEN
v.stop_adr(c_adr_w-1 DOWNTO c_bitshift_adr) := TO_UVEC(inp_adr-c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO c_bitshift_adr);
v.stop_adr(c_adr_w-1 DOWNTO 0) := TO_UVEC(inp_adr-c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO 0);
ELSE
v.stop_adr(c_adr_w-1 DOWNTO c_bitshift_adr) := TO_UVEC(inp_adr+c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO c_bitshift_adr);
v.stop_adr(c_adr_w-1 DOWNTO 0) := TO_UVEC(inp_adr+c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO 0);
END IF;
v.stop_adr(c_bitshift_adr-1 DOWNTO 0) := c_zeros;
v.cooling_down := 8;
v.ready_for_stop := '0';
v.cooling_down := c_proportion;
v.last_adr_to_write_to(c_adr_w-1 DOWNTO c_bitshift_w) := v.stop_adr(c_adr_w-1 DOWNTO c_bitshift_w);
v.last_adr_to_write_to(c_bitshift_w-1 DOWNTO 0) := (OTHERS => '0');
v.stop_burstsize := TO_UINT(v.stop_adr(c_adr_w-1 DOWNTO 0))-TO_UINT(v.last_adr_to_write_to);
-- still a write cyle
-- if adr mod g_burstsize = 0
-- this makes sure that only ones every 64 writes a writeburst is started.
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
v.need_burst := '1';
END IF;
IF dvr_miso.done = '1' AND q_reg.need_burst = '1' THEN
......@@ -199,7 +212,7 @@ BEGIN
v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length);
ELSE
v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length);
v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length);
END IF;
ELSE
......@@ -211,23 +224,26 @@ BEGIN
WHEN STOP_WRITING =>
v.dvr_mosi.burstbegin := '0';
v.stopped := '1';
-- wait until the write burst is finished
IF NOT (q_reg.cooling_down = 0) THEN
v.cooling_down := q_reg.cooling_down-1;
v.state := STOP_WRITING;
ELSIF dvr_miso.done = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN
v.stopped := '1';
ELSIF dvr_miso.done = '1' AND q_reg.need_burst = '0' THEN
v.wr_sosi.valid := '0';
v.state := START_READING;
v.state := LAST_WRITE_BURST;
ELSE
v.state := STOP_WRITING;
END IF;
IF inp_sosi.valid = '1' THEN
v.cooling_down := c_proportion;
END IF;
-- still receiving write data.
-- if adr mod g_burstsize = 0
-- this makes sure that only ones every 64 writes a writeburst is started.
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN
v.need_burst := '1';
END IF;
IF dvr_miso.done = '1' AND q_reg.need_burst = '1' THEN
......@@ -238,7 +254,7 @@ BEGIN
v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length);
ELSE
v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length);
v.dvr_mosi.address(c_bitshift_adr-1 DOWNTO 0) := c_zeros(c_bitshift_adr-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize
v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length);
END IF;
ELSE
......@@ -249,11 +265,27 @@ BEGIN
v.wr_sosi := inp_sosi;
WHEN LAST_WRITE_BURST =>
IF dvr_miso.done = '1' THEN
v.dvr_mosi.burstbegin := '1';
v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := q_reg.last_adr_to_write_to(c_adr_w-1 DOWNTO 0);
v.dvr_mosi.burstsize := TO_UVEC(q_reg.stop_burstsize, dvr_mosi.burstsize'length);
v.state := START_READING;
ELSE
v.dvr_mosi.burstbegin := '0';
v.state := LAST_WRITE_BURST;
END IF;
v.dvr_mosi.wr := '1';
v.dvr_mosi.rd := '0';
WHEN START_READING =>
v.dvr_mosi.burstbegin := '0';
v.rd_burst_en := '1';
v.dvr_mosi.wr := '0';
v.dvr_mosi.rd := '1';
v.outp_ds := inp_ds;
v.read_cnt := 0;
FOR I IN 0 TO inp_bsn_adr+(g_max_adr-TO_UINT(q_reg.stop_adr)) LOOP -- takes a while WRONG, wil be fixed after L2SDP-705, 706 and 70
IF v.outp_ds-c_rest <= 0 THEN
......@@ -269,6 +301,11 @@ BEGIN
WHEN READING =>
-- rd_fifo needs a refil after rd_fifo_usedw <= 10 because of delays, if you wait until rd_fifo_usedw = 0 then you get an empty fifo which results in your outputs sosi.valid not being constatly valid.
IF TO_UINT(rd_fifo_usedw) <= 10 AND dvr_miso.done = '1' AND q_reg.rd_burst_en = '1' AND dvr_miso.done = '1' THEN
v.dvr_mosi.burstbegin := '0';
v.dvr_mosi.burstsize(dvr_mosi.burstsize'length-1 DOWNTO 0) := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length);
v.dvr_mosi.wr := '0';
v.dvr_mosi.rd := '1';
v.outp_ds := inp_ds;
IF TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+g_burstsize*q_reg.read_cnt >= g_max_adr THEN
v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+g_burstsize*q_reg.read_cnt)-g_max_adr-1, c_adr_w);
ELSE
......@@ -319,8 +356,10 @@ BEGIN
IF q_reg.state = RESET OR q_reg.state = WRITING OR q_reg.state = SET_STOP OR q_reg.state = IDLE THEN
IF stop_in = '1' THEN
v.ready_for_stop := '1';
ELSIF q_reg.ready_for_stop = '1' AND inp_sosi.eop = '1' THEN
v.state := SET_STOP;
ELSIF v.stop_adr = TO_UVEC(inp_adr, c_adr_w) AND v.stop_adr(c_bitshift_adr-1 DOWNTO 0) = c_zeros(c_bitshift_adr-1 DOWNTO 0) AND q_reg.stopped = '0' THEN
ELSIF v.stop_adr = TO_UVEC(inp_adr, c_adr_w) AND q_reg.stopped = '0' THEN
v.state := STOP_WRITING;
ELSIF v.stopped = '0' AND inp_sosi.valid = '1' AND q_reg.started = '1' THEN
v.state := WRITING;
......
......@@ -163,7 +163,6 @@ BEGIN
v.out_ready := '0';
v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0);
v.dd_fresh := '0';
v.a_of := in_ds+2+((5)*14); -- will be fixed after in_ds is fixed in ddrctrl_controller.
v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v(g_out_data_w+v.a_of-1 DOWNTO v.a_of);
v.out_sosi.valid := '1';
v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := in_bsn(c_dp_stream_bsn_w-1 DOWNTO 0);
......@@ -242,14 +241,11 @@ BEGIN
v.out_ready := '1';
v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0);
IF in_sosi.valid = '1' THEN
v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0);
v.dd_fresh := '1';
END IF;
IF in_sosi.valid = '1' THEN
v.state := FIRST_READ;
v.delay_data(g_in_data_w-1 DOWNTO 0) := in_sosi.data(g_in_data_w-1 DOWNTO 0);
v.dd_fresh := '1';
ELSE
v.state := OFF;
END IF;
......
......@@ -40,7 +40,6 @@ ENTITY tb_ddrctrl IS
g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m; -- type of memory
g_nof_streams : POSITIVE := 12; -- number of input streams
g_data_w : NATURAL := 14; -- data with of input data vectors
g_sim_length : NATURAL := 16500; -- close to the amount of word that gets put into the memory
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;
......@@ -67,7 +66,6 @@ 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; -- mm clock frequency in MHz
CONSTANT c_mm_clk_period : TIME := (10**6/c_mm_clk_freq)*1 ps; -- mm clock period, 10 ns
CONSTANT c_sim_length : NATURAL := (g_sim_length*c_ctrl_data_w)/c_in_data_w; -- amount of input words that get put into the DUT
-- constant for checking output data
CONSTANT c_adr_w : NATURAL := func_tech_ddr_ctlr_address_w(c_tech_ddr); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27
......@@ -116,6 +114,8 @@ ARCHITECTURE tb OF tb_ddrctrl IS
-- constant for running the test
CONSTANT c_total_vector : STD_LOGIC_VECTOR(g_data_w*g_nof_streams*c_bim*g_block_size-1 DOWNTO 0) := c_total_vector_init; -- vector which contains all input data vectors to make it easy to fill ctr_vector
SIGNAL c_total_vector_length : NATURAL := c_total_vector'length;
CONSTANT c_check : NATURAL := 32;
CONSTANT c_check_bottom : NATURAL := 5;
CONSTANT c_ones : STD_LOGIC_VECTOR(c_check-c_check_bottom-1 DOWNTO 0) := (OTHERS => '1');
......@@ -176,7 +176,7 @@ BEGIN
-- wr fifo has delay of 4 clockcylces after reset
-- filling the input data vectors with the corresponding numbers
run_multiple_times : FOR K in 0 TO 4 LOOP
run_multiple_times : FOR K in 0 TO 3 LOOP
make_data : FOR J IN 0 TO c_bim*g_block_size-1 LOOP
in_data_cnt <= in_data_cnt+1;
fill_in_sosi_arr : FOR I IN 0 TO g_nof_streams-1 LOOP
......@@ -202,7 +202,7 @@ BEGIN
END LOOP;
END IF;
END LOOP;
IF K = 2 AND J = c_bim*g_block_size-1 THEN
IF K = 1 AND J = c_bim*g_block_size-1 THEN
stop_in <= '1';
ELSE
stop_in <= '0';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment