diff --git a/applications/lofar2/designs/lofar2_unb2c_ddrctrl/src/vhdl/lofar2_unb2c_ddrctrl.vhd b/applications/lofar2/designs/lofar2_unb2c_ddrctrl/src/vhdl/lofar2_unb2c_ddrctrl.vhd index 4348e204ab73f7af8ae8ad9326c45cc5a894c26c..3e949f5ab8ea2b043fc172d77a16a9d6f5238a59 100644 --- a/applications/lofar2/designs/lofar2_unb2c_ddrctrl/src/vhdl/lofar2_unb2c_ddrctrl.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_ddrctrl/src/vhdl/lofar2_unb2c_ddrctrl.vhd @@ -51,6 +51,7 @@ ENTITY lofar2_unb2c_ddrctrl IS PORT ( -- GENERAL CLK : IN STD_LOGIC; -- System Clock + tb_clk : IN STD_LOGIC; PPS : IN STD_LOGIC; -- System Sync WDI : OUT STD_LOGIC; -- Watchdog Clear INTA : INOUT STD_LOGIC; -- FPGA interconnect line @@ -106,6 +107,7 @@ ARCHITECTURE str OF lofar2_unb2c_ddrctrl IS SIGNAL xo_ethclk : STD_LOGIC; SIGNAL xo_rst : STD_LOGIC; SIGNAL xo_rst_n : STD_LOGIC; + SIGNAL not_mm_clk : STD_LOGIC; SIGNAL mm_clk : STD_LOGIC; SIGNAL mm_rst : STD_LOGIC := '0'; SIGNAL st_pps : STD_LOGIC; @@ -198,7 +200,7 @@ ARCHITECTURE str OF lofar2_unb2c_ddrctrl IS -- ddrctrl SIGNAL st_sosi_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0); - SIGNAL out_siso : t_dp_siso; + SIGNAL out_siso : t_dp_siso := c_dp_siso_rst; SIGNAL out_sosi_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); SIGNAL phy3_io : t_tech_ddr3_phy_io; SIGNAL phy3_ou : t_tech_ddr3_phy_ou; @@ -228,8 +230,9 @@ ARCHITECTURE str OF lofar2_unb2c_ddrctrl IS BEGIN + mm_clk <= tb_clk; - out_siso.ready <= vector_or(NOT out_wr_data_done_arr) OR vector_or(NOT out_wr_bsn_done_arr); + out_siso.ready <= vector_and(NOT out_wr_data_done_arr) AND vector_and(NOT out_wr_bsn_done_arr); store_bsn_in_re : FOR I IN 0 TO c_nof_streams-1 GENERATE @@ -295,7 +298,7 @@ BEGIN -- Basic WG parameters, see diag_wg.vhd for their meaning g_buf_dat_w => c_wg_buf_dat_w, g_buf_addr_w => c_wg_buf_addr_w, - g_calc_support => FALSE, + g_calc_support => TRUE, g_calc_gain_w => 1, g_calc_dat_w => c_sdp_W_adc ) @@ -418,7 +421,7 @@ BEGIN -- DB settings g_data_type => c_bsn_type, - g_data_w => t_dp_sosi.bsn'length, + g_data_w => c_dp_stream_bsn_w, g_buf_nof_data => c_buf_nof_words, g_buf_use_sync => FALSE, g_use_steps => FALSE, @@ -458,7 +461,7 @@ BEGIN g_stamp_time => g_stamp_time, g_revision_id => g_revision_id, g_fw_version => c_fw_version, - g_mm_clk_freq => c_mm_clk_freq, + g_mm_clk_freq => SEL_A_B(g_sim, 10**10, c_mm_clk_freq), g_eth_clk_freq => c_unb2c_board_eth_clk_freq_125M, g_aux => c_unb2c_board_aux, g_factory_image => g_factory_image, @@ -471,7 +474,7 @@ BEGIN xo_rst => xo_rst, xo_rst_n => xo_rst_n, - mm_clk => mm_clk, + mm_clk => not_mm_clk, mm_rst => mm_rst, dp_rst => st_rst, @@ -571,7 +574,7 @@ BEGIN ) PORT MAP( mm_rst => mm_rst, - mm_clk => mm_clk, + mm_clk => mm_clk, -- PIOs pout_wdi => pout_wdi, diff --git a/applications/lofar2/designs/lofar2_unb2c_ddrctrl/tb/vhdl/tb_lofar2_unb2c_ddrctrl.vhd b/applications/lofar2/designs/lofar2_unb2c_ddrctrl/tb/vhdl/tb_lofar2_unb2c_ddrctrl.vhd index 07cd68479c98163cfcc5e1945c0198f373779fc6..5e2cfb3acbd2645d6c1b80f366df7b047cc79793 100644 --- a/applications/lofar2/designs/lofar2_unb2c_ddrctrl/tb/vhdl/tb_lofar2_unb2c_ddrctrl.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_ddrctrl/tb/vhdl/tb_lofar2_unb2c_ddrctrl.vhd @@ -118,9 +118,10 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_ddrctrl IS -- WG CONSTANT c_wg_phase : REAL := 0.0; -- WG phase in degrees CONSTANT c_wg_freq : REAL := 160.0; -- WG freq - CONSTANT c_wg_ampl : NATURAL := NATURAL(0.125*REAL(c_sdp_FS_adc)); -- in number of lsb + CONSTANT c_wg_ampl : NATURAL := NATURAL(1.0*REAL(c_sdp_FS_adc)); -- in number of lsb CONSTANT c_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values - + CONSTANT c_subband : REAL := 1.0; + -- DUT SIGNAL st_clk : STD_LOGIC := '0'; SIGNAL tb_clk : STD_LOGIC := '0'; @@ -131,6 +132,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_ddrctrl IS SIGNAL rd_data : STD_LOGIC_VECTOR(c_rd_data_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL sosi_out_data : STD_LOGIC_VECTOR(c_rd_data_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL sosi_out_bsn : STD_LOGIC_VECTOR(c_rd_data_w-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL sosi_out_data_sin : STD_LOGIC_VECTOR( c_data_w-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL sosi_out_not_bsn : STD_LOGIC_VECTOR(c_rd_data_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL WDI : STD_LOGIC; SIGNAL INTA : STD_LOGIC; @@ -186,6 +189,7 @@ BEGIN PORT MAP ( -- GENERAL CLK => st_clk, + tb_clk => tb_clk, PPS => pps, WDI => WDI, INTA => INTA, @@ -246,7 +250,7 @@ BEGIN FOR I IN 0 TO c_nof_streams-1 LOOP mmf_mm_bus_wr(c_mm_file_reg_diag_wg_wideband_arr, (I*4)+0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc mmf_mm_bus_wr(c_mm_file_reg_diag_wg_wideband_arr, (I*4)+1, INTEGER(c_wg_phase), tb_clk); -- phase offset in degrees - mmf_mm_bus_wr(c_mm_file_reg_diag_wg_wideband_arr, (I*4)+2, INTEGER(c_wg_freq), tb_clk); -- freq + mmf_mm_bus_wr(c_mm_file_reg_diag_wg_wideband_arr, (I*4)+2, INTEGER(REAL(c_subband)*c_sdp_wg_subband_freq_unit), tb_clk); -- freq mmf_mm_bus_wr(c_mm_file_reg_diag_wg_wideband_arr, (I*4)+3, INTEGER(REAL(c_wg_ampl)*c_sdp_wg_ampl_lsb), tb_clk); -- ampl END LOOP; mmf_mm_bus_wr(c_mm_file_reg_stop_in, 0, 0, tb_clk); @@ -262,22 +266,20 @@ BEGIN mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1 - WAIT FOR c_mm_clk_period*26000; + WAIT FOR c_mm_clk_period*24000; mmf_mm_bus_wr(c_mm_file_reg_stop_in, 0, 1, tb_clk); WAIT FOR c_mm_clk_period*16; mmf_mm_bus_wr(c_mm_file_reg_stop_in, 0, 0, tb_clk); - WAIT FOR c_mm_clk_period*30000; + WAIT FOR c_mm_clk_period*50000; FOR I IN 0 TO c_bim-1 LOOP - -- mmf_mm_bus_rd(c_mm_file_reg_data_buf, 0, sosi_out_data(c_rd_data_w-1 DOWNTO 0), tb_clk); - -- mmf_mm_bus_rd( c_mm_file_reg_bsn_buf, 0, sosi_out_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); FOR J IN 0 TO c_nof_streams-1 LOOP FOR K IN 0 TO c_block_size-1 LOOP - mmf_mm_bus_rd(c_mm_file_ram_data_buf, (J*c_block_size)+K , sosi_out_data(c_rd_data_w-1 DOWNTO 0), tb_clk); - sosi_out_data(c_rd_data_w-1 DOWNTO c_data_w) <= (OTHERS => sosi_out_data(c_data_w-1)); - mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, (J*c_block_size)+(k*2) , sosi_out_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); - -- mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, (J*c_block_size)+(k*2)+1, sosi_out_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); + mmf_mm_bus_rd(c_mm_file_ram_data_buf, (J*c_block_size)+K , sosi_out_data(c_rd_data_w-1 DOWNTO 0), tb_clk); + sosi_out_data_sin(c_data_w-1 DOWNTO 0) <= sosi_out_data(c_data_w-1 DOWNTO 0); + mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, ((J*c_block_size)+k)*2 , sosi_out_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); + mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, ((J*c_block_size)+k)*2+1, sosi_out_not_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); END LOOP; END LOOP; WAIT FOR c_st_clk_period*1024; @@ -286,6 +288,28 @@ BEGIN WAIT FOR c_mm_clk_period*3000; + WAIT FOR c_mm_clk_period*2400; + mmf_mm_bus_wr(c_mm_file_reg_stop_in, 0, 1, tb_clk); + WAIT FOR c_mm_clk_period*30; + mmf_mm_bus_wr(c_mm_file_reg_stop_in, 0, 0, tb_clk); + WAIT FOR c_mm_clk_period*55000; + + + FOR I IN 0 TO c_bim-1 LOOP + FOR J IN 0 TO c_nof_streams-1 LOOP + FOR K IN 0 TO c_block_size-1 LOOP + mmf_mm_bus_rd(c_mm_file_ram_data_buf, (J*c_block_size)+K , sosi_out_data(c_rd_data_w-1 DOWNTO 0), tb_clk); + sosi_out_data_sin(c_data_w-1 DOWNTO 0) <= sosi_out_data(c_data_w-1 DOWNTO 0); + mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, ((J*c_block_size)+k)*2 , sosi_out_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); + mmf_mm_bus_rd( c_mm_file_ram_bsn_buf, ((J*c_block_size)+k)*2+1, sosi_out_not_bsn(c_rd_data_w-1 DOWNTO 0), tb_clk); + END LOOP; + END LOOP; + WAIT FOR c_st_clk_period*2024; + WAIT FOR c_st_clk_period*9; + END LOOP; + + WAIT FOR c_mm_clk_period*3000; + tb_end <= '1'; ASSERT FALSE REPORT "Test: OK" SEVERITY FAILURE; WAIT; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd index 37a5457749df80c735034f43a1883076e4d52de1..0517a0d49176aea7646bd7a6bd1dbb5a0464c6f5 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd @@ -235,6 +235,7 @@ BEGIN -- reading ddr memory u_ddrctrl_output : ENTITY work.ddrctrl_output GENERIC MAP( + g_technology => g_technology, g_tech_ddr => g_tech_ddr, g_sim_model => g_sim_model, g_in_data_w => c_io_ddr_data_w, diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index bf0f59d644ee316e563df54c4d5ca868d9acb3f1..e11ca04a0ece82e967e53ea6639f7ce199318f7a 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -86,7 +86,7 @@ ARCHITECTURE rtl OF ddrctrl_controller IS 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)/g_adr_per_b)*g_adr_per_b; + CONSTANT c_pof_ma : NATURAL := (((g_max_adr*(100-g_stop_percentage))/100)/g_adr_per_b)*g_adr_per_b; --percentage of max address. CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_w-1 DOWNTO 0) := (OTHERS => '0'); @@ -233,10 +233,10 @@ BEGIN WHEN SET_STOP => -- this state sets a stop address dependend on the g_stop_percentage. - IF inp_adr+c_pof_ma >= g_max_adr THEN + IF inp_adr-c_pof_ma >= 0 THEN 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 0) := TO_UVEC(inp_adr+c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO 0); + v.stop_adr(c_adr_w-1 DOWNTO 0) := TO_UVEC(inp_adr+g_max_adr-c_pof_ma, c_adr_w)(c_adr_w-1 DOWNTO 0); END IF; v.ready_for_set_stop := '0'; 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); diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd index 829126807ac2a515209a5934341a7b26bb6f67e5..4992fcc141926bda32f9525f6887cc4951cb37aa 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd @@ -41,6 +41,7 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY ddrctrl_output IS GENERIC ( + g_technology : NATURAL; g_tech_ddr : t_c_tech_ddr; -- type of memory g_sim_model : BOOLEAN := TRUE; -- determens if this is a simulation g_in_data_w : NATURAL := 576; @@ -64,10 +65,23 @@ END ddrctrl_output; ARCHITECTURE str OF ddrctrl_output 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_out_data_w : NATURAL := g_nof_streams*g_data_w; -- the input data width for ddrctrl_repack 168 + + -- fifo + CONSTANT c_fifo_size : NATURAL := 2; + -- signals for connecting the components - SIGNAL sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; +-- SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; +-- SIGNAL fifo_snk_in_sosi : t_dp_sosi := c_dp_sosi_init; + SIGNAL q_out_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL q_q_out_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL unpack_state_off : STD_LOGIC := '0'; +-- SIGNAL siso : t_dp_siso := c_dp_siso_rst; +-- SIGNAL fifo_src_out_sosi : t_dp_sosi := c_dp_sosi_init; +-- SIGNAL fifo_usedw : STD_LOGIC_VECTOR(ceil_log2(c_fifo_size)-1 DOWNTO 0) := (OTHERS => '0'); BEGIN @@ -83,11 +97,12 @@ BEGIN PORT MAP( clk => clk, rst => rst, - in_sosi => in_sosi, -- input data + in_sosi => in_sosi, -- input data in_bsn => in_bsn, out_siso => out_siso, - out_sosi => sosi, -- output data - out_ready => out_ready + out_sosi => out_sosi, -- output data + out_ready => out_ready, + state_off => unpack_state_off ); -- resizes the input data vector so that the output data vector can be stored into the ddr memory @@ -101,4 +116,57 @@ BEGIN out_sosi_arr => out_sosi_arr ); + +-- u_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths +-- GENERIC MAP ( +-- g_technology => g_technology, +-- g_wr_data_w => c_out_data_w, +-- g_rd_data_w => c_out_data_w, +-- g_use_ctrl => FALSE, +-- g_wr_fifo_size => c_fifo_size, +-- g_wr_fifo_af_margin => 0, +-- g_rd_fifo_rl => 0 +-- ) +-- PORT MAP ( +-- wr_rst => rst, +-- wr_clk => clk, +-- rd_rst => rst, +-- rd_clk => clk, +-- +-- snk_out => OPEN, +-- snk_in => fifo_snk_in_sosi, +-- +-- wr_ful => OPEN, +-- wr_usedw => fifo_usedw, +-- rd_usedw => OPEN, +-- rd_emp => OPEN, +-- +-- src_in => siso, +-- src_out => fifo_src_out_sosi +-- ); + + sosi.sop <= sosi.valid AND sosi.sop; + sosi.eop <= sosi.valid AND sosi.eop; + + p_out_siso_ready : PROCESS(out_siso, clk, out_sosi, q_out_siso) + + BEGIN + + IF out_siso.ready = '0' AND NOT (q_out_siso.ready = out_siso.ready) THEN + sosi <= out_sosi; + sosi.valid <= '0'; + -- assert false report "sosi.valid = '0'" severity note; + ELSIF q_out_siso.ready = '1' AND NOT (q_q_out_siso.ready = q_out_siso.ready) AND unpack_state_off = '0' THEN + sosi <= out_sosi; + sosi.valid <= '1'; + -- assert false report "sosi.valid = '1'" severity note; + ELSE + sosi <= out_sosi; + END IF; + IF rising_edge(clk) THEN + q_q_out_siso <= q_out_siso; + q_out_siso <= out_siso; + END IF; + END PROCESS; + END str; diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd index 5e0700011d131d88169168535d6d3eb3f62d428e..d49c47a082d2a9ab29159ca12447af8aafc7a88d 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd @@ -52,7 +52,8 @@ ENTITY ddrctrl_output_unpack IS in_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); out_siso : IN t_dp_siso; out_sosi : OUT t_dp_sosi := c_dp_sosi_init; - out_ready : OUT STD_LOGIC := '0' + out_ready : OUT STD_LOGIC := '0'; + state_off : OUT STD_LOGIC := '0' ); END ddrctrl_output_unpack; @@ -76,9 +77,10 @@ ARCHITECTURE rtl OF ddrctrl_output_unpack IS bsn_cnt : NATURAL; out_sosi : t_dp_sosi; out_ready : STD_LOGIC; + state_off : STD_LOGIC; END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, 0, 0, (OTHERS => '0'), '0', '0', (OTHERS => '0'), 0, c_dp_sosi_init, '0'); + CONSTANT c_t_reg_init : t_reg := (RESET, 0, 0, (OTHERS => '0'), '0', '0', (OTHERS => '0'), 0, c_dp_sosi_init, '0', '0'); -- signals for readability SIGNAL d_reg : t_reg := c_t_reg_init; @@ -89,241 +91,300 @@ BEGIN q_reg <= d_reg WHEN rising_edge(clk); -- put the input data into c_v and fill the output vector from c_v - p_state : PROCESS(q_reg, rst, in_sosi, out_siso) + p_state : PROCESS(q_reg, rst, in_bsn, in_sosi, out_siso) VARIABLE v : t_reg; BEGIN v := q_reg; + IF out_siso.ready = '1' OR q_reg.state = OFF OR q_reg.state = IDLE OR q_reg.state = RESET OR rst = '1' THEN - CASE q_reg.state IS - WHEN READING => - -- generating output from the data already present in c_v - v.out_ready := '0'; - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - v.op_data_cnt := q_reg.op_data_cnt+1; - - IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN - -- put the delay data into the second half of c_v beceause these are now zeros - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.valid_data := '1'; - END IF; - 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 (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1') AND out_siso.ready = '1' THEN - v.state := OVER_HALF; - ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' AND v.valid_data = '0' THEN - v.state := IDLE; - ELSIF out_siso.ready = '1' THEN - v.state := READING; - ELSE - v.state := IDLE; - END IF; - - - IF q_reg.out_sosi.eop = '1' THEN - v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); - v.out_sosi.eop := '0'; - v.out_sosi.sop := '1'; - v.bsn_cnt := 0; - ELSIF q_reg.out_sosi.sop = '1' THEN - v.out_sosi.sop := '0'; - END IF; - - IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN - v.state := BSN; - v.out_ready := '1'; - ELSIF q_reg.bsn_cnt = g_block_size-3 THEN - v.state := IDLE; - END IF; - - - - WHEN OVER_HALF => - -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added - IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN - v.out_ready := '1'; - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - -- put the delay data into the first half of c_v - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; - v.op_data_cnt := 0; - ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN - v.out_ready := '1'; - -- generate output from the middle of c_v + CASE q_reg.state IS + WHEN READING => + -- generating output from the data already present in c_v + v.out_ready := '0'; v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - -- put zeros into the second half of c_v beceause dd_fresh is '0' - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); - v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; - v.op_data_cnt := 0; - v.valid_data := '0'; - ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + v.op_data_cnt := q_reg.op_data_cnt+1; + + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; + 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 (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1') AND out_siso.ready = '1' THEN + v.state := OVER_HALF; + ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '0' AND v.valid_data = '0' THEN + v.state := IDLE; + ELSIF out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; + + + IF q_reg.out_sosi.eop = '1' THEN + v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := INCR_UVEC(q_reg.out_sosi.bsn, 1); + v.out_sosi.eop := '0'; + v.out_sosi.sop := '1'; + v.bsn_cnt := 0; + ELSIF q_reg.out_sosi.sop = '1' THEN + v.out_sosi.sop := '0'; + END IF; + + IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN + v.state := BSN; + v.out_ready := '1'; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := IDLE; + END IF; + + + + WHEN OVER_HALF => + -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN + v.out_ready := '1'; + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put the delay data into the first half of c_v + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN + v.out_ready := '1'; + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put zeros into the second half of c_v beceause dd_fresh is '0' + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; + v.valid_data := '0'; + ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + v.out_ready := '1'; + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + v.dd_fresh := '0'; + v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; + v.op_data_cnt := 0; + END IF; + + + + + 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 (g_out_data_w*(v.op_data_cnt+1))+v.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1') AND out_siso.ready = '1' THEN + v.state := OVER_HALF; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' THEN + v.state := IDLE; + ELSIF out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; + + IF q_reg.out_sosi.sop = '1' THEN + v.out_sosi.sop := '0'; + END IF; + + IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN + v.state := BSN; + v.dd_fresh := '1'; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := IDLE; + END IF; + + + WHEN FIRST_READ => + -- fills the first half of c_v and generates output from it. v.out_ready := '1'; - -- put the delay data into the second half of c_v beceause these are now zeros - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - v.dd_fresh := '0'; - v.a_of := ((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of)-g_in_data_w; - v.op_data_cnt := 0; - END IF; - - - - - 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 (g_out_data_w*(v.op_data_cnt+1))+v.a_of >= g_in_data_w AND (v.dd_fresh = '1' OR v.valid_data = '1') AND out_siso.ready = '1' THEN - v.state := OVER_HALF; - ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' THEN - v.state := IDLE; - ELSIF out_siso.ready = '1' THEN - v.state := READING; - ELSE - v.state := IDLE; - END IF; - - IF q_reg.out_sosi.sop = '1' THEN - v.out_sosi.sop := '0'; - END IF; - - IF q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '1' THEN - v.state := BSN; - v.dd_fresh := '1'; - ELSIF q_reg.bsn_cnt = g_block_size-3 THEN - v.state := IDLE; - END IF; - - - WHEN FIRST_READ => - -- fills the first half of c_v and generates output from it. - v.out_ready := '1'; - v.c_v(c_v_w-1 DOWNTO 0) := (OTHERS => '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.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); - v.out_sosi.sop := '1'; - v.out_sosi.eop := '0'; - v.bsn_cnt := 0; - v.op_data_cnt := q_reg.op_data_cnt+1; - - 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 out_siso.ready = '1' THEN - v.state := READING; - ELSE - v.state := IDLE; - END IF; - - WHEN BSN => - -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added also increases the bsn output - v.out_sosi.valid := '0'; - IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - -- put the delay data into the first half of c_v - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.op_data_cnt := 0; - ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - -- put zeros into the second half of c_v beceause dd_fresh is '0' - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); - v.op_data_cnt := 0; - v.valid_data := '0'; - ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN - -- put the delay data into the second half of c_v beceause these are now zeros - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); - -- put the second half of c_v into the first half of c_v - v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); - v.out_sosi.valid := '1'; - v.bsn_cnt := q_reg.bsn_cnt+1; + v.c_v(c_v_w-1 DOWNTO 0) := (OTHERS => '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.op_data_cnt := 0; - ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' AND (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of < g_in_data_w THEN - -- generate output from the middle of c_v - v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + 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.bsn_cnt := q_reg.bsn_cnt+1; - END IF; - - v.out_ready := '0'; - v.out_sosi.eop := '1'; - v.a_of := 0; - v.bsn_cnt := q_reg.bsn_cnt+1; - - IF v.dd_fresh = '1' AND v.valid_data = '0' THEN - -- put the delay data into the second half of c_v beceause these are now zeros - v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); - v.dd_fresh := '0'; - v.valid_data := '1'; - END IF; - 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 g_bim+TO_UINT(in_bsn)-1 = TO_UINT(v.out_sosi.bsn) THEN - v.state := OFF; - ELSIF out_siso.ready = '1' THEN - v.state := READING; - ELSE - v.state := IDLE; - END IF; - - WHEN RESET => - v := c_t_reg_init; - - 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; - v.state := OFF; - - - WHEN IDLE => - -- the statemachine goes to Idle when its finished or when its waiting on other components. + v.out_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0) := in_bsn(c_dp_stream_bsn_w-1 DOWNTO 0); + v.out_sosi.sop := '1'; + v.out_sosi.eop := '0'; + v.bsn_cnt := 0; + v.op_data_cnt := q_reg.op_data_cnt+1; + + 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 out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; + + WHEN BSN => + -- generating output data from c_v but past the halfway point of c_v so there needs to be new data added also increases the bsn output + v.out_sosi.valid := '0'; + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '1' THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put the delay data into the first half of c_v + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '1' THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + -- put zeros into the second half of c_v beceause dd_fresh is '0' + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := (OTHERS => '0'); + v.op_data_cnt := 0; + v.valid_data := '0'; + ELSIF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := v.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + -- put the second half of c_v into the first half of c_v + v.c_v(g_in_data_w-1 DOWNTO 0) := q_reg.c_v(c_v_w-1 DOWNTO g_in_data_w); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + v.dd_fresh := '0'; + v.op_data_cnt := 0; + ELSIF q_reg.dd_fresh = '0' AND q_reg.valid_data = '0' AND (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of < g_in_data_w THEN + -- generate output from the middle of c_v + v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := q_reg.c_v((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of); + v.out_sosi.valid := '1'; + v.bsn_cnt := q_reg.bsn_cnt+1; + END IF; + + v.out_ready := '0'; + v.out_sosi.eop := '1'; + v.a_of := 0; + v.bsn_cnt := q_reg.bsn_cnt+1; + + IF v.dd_fresh = '1' AND v.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; + 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 g_bim+TO_UINT(in_bsn)-1 = TO_UINT(v.out_sosi.bsn) THEN + v.state := RESET; + ELSIF out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; + + WHEN RESET => + v := c_t_reg_init; + + 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; + v.state := OFF; + + + WHEN IDLE => + -- the statemachine goes to Idle when its finished or when its waiting on other components. + IF q_reg.dd_fresh = '0' THEN + v.out_ready := '1'; + ELSE + v.out_ready := '0'; + END IF; + v.out_sosi.valid := '0'; + + IF q_reg.dd_fresh = '1' AND q_reg.valid_data = '0' THEN + -- put the delay data into the second half of c_v beceause these are now zeros + v.c_v(c_v_w-1 DOWNTO g_in_data_w) := q_reg.delay_data(g_in_data_w-1 DOWNTO 0); + v.dd_fresh := '0'; + v.valid_data := '1'; + END IF; + 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 q_reg.bsn_cnt = g_block_size-3 AND out_siso.ready = '0' THEN + v.state := IDLE; + ELSIF q_reg.bsn_cnt = g_block_size-3 THEN + v.state := BSN; + ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of >= g_in_data_w AND v.dd_fresh = '1' AND out_siso.ready = '1' AND out_siso.ready = '1' THEN + v.state := OVER_HALF; + ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of < g_in_data_w AND out_siso.ready = '1' THEN + v.state := READING; + ELSE + v.state := IDLE; + END IF; + + + + WHEN OFF => + -- the stamachine has a state off so it knows when to go to first read, it can't go to first read from IDLE + v.out_sosi := c_dp_sosi_init; + v.bsn_cnt := 0; + v.state_off := '1'; + + IF in_sosi.valid = '1' AND q_reg.dd_fresh = '0' 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'; + v.out_ready := '0'; + v.state_off := '0'; + v.state := FIRST_READ; + ELSIF q_reg.dd_fresh = '1' THEN + v.out_ready := '0'; + v.state := OFF; + ELSIF out_siso.ready = '1' THEN + v.out_ready := '1'; + v.state := OFF; + ELSE + v.state := OFF; + END IF; + + + END CASE; + ELSE IF q_reg.dd_fresh = '0' THEN v.out_ready := '1'; ELSE @@ -352,32 +413,9 @@ BEGIN ELSIF (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of < g_in_data_w AND out_siso.ready = '1' THEN v.state := READING; ELSE - v.state := IDLE; + v.state := IDLE; END IF; - - - - WHEN OFF => - -- the stamachine has a state off so it knows when to go to first read, it can't go to first read from IDLE - v.out_sosi := c_dp_sosi_init; - - IF in_sosi.valid = '1' AND q_reg.dd_fresh = '0' 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'; - v.out_ready := '0'; - v.state := FIRST_READ; - ELSIF q_reg.dd_fresh = '1' THEN - v.out_ready := '0'; - v.state := OFF; - ELSIF out_siso.ready = '1' THEN - v.out_ready := '1'; - v.state := OFF; - ELSE - v.state := OFF; - END IF; - - - END CASE; + END IF; IF rst = '1' THEN v.state := RESET; @@ -386,8 +424,9 @@ BEGIN END PROCESS; -- fill outputs - out_sosi <= q_reg.out_sosi; + out_sosi <= q_reg.out_sosi; out_ready <= q_reg.out_ready; + state_off <= q_reg.state_off; END rtl; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 7d4ba2a51ca0324fcc9e1fd2504a0374d7a328fb..8bf84ded9db142cb0fc8f57b8c2175cc7a724602 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -156,17 +156,17 @@ 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; - out_siso.ready <= '1'; out_siso.xon <= '1'; -- excecuting test p_test : PROCESS - + VARIABLE out_siso_ready : NATURAL := 0; BEGIN -- start the test + out_siso.ready <= '1'; tb_end <= '0'; in_sosi_arr(0).valid <= '0'; WAIT UNTIL rising_edge(clk); -- align to rising edge @@ -205,11 +205,29 @@ BEGIN 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); in_sosi_arr(I).valid <= '1'; END LOOP; + IF K = 0 AND J = c_bim*g_block_size-1 THEN stop_in <= '1'; ELSE stop_in <= '0'; END IF; + + FOR L IN 0 TO 30 LOOP + IF k = 1 AND J = c_bim*g_block_size*85/100+60+L THEN + out_siso_ready := out_siso_ready+1; + END IF; + IF k = 1 AND J = c_bim*g_block_size*85/100+160+L THEN + out_siso_ready := out_siso_ready+1; + END IF; + END LOOP; + + IF out_siso_ready = 0 THEN + out_siso.ready <= '1'; + ELSE + out_siso.ready <= '0'; + out_siso_ready := 0; + END IF; + WAIT FOR c_clk_period*1; END LOOP; END LOOP; diff --git a/libraries/base/diag/src/vhdl/diag_data_buffer_dev.vhd b/libraries/base/diag/src/vhdl/diag_data_buffer_dev.vhd index be0e2c1c0029f7f3d50986f06a5a29f8826c54fe..2b10ed7d116199d44093a8ac9cf840850decd12b 100644 --- a/libraries/base/diag/src/vhdl/diag_data_buffer_dev.vhd +++ b/libraries/base/diag/src/vhdl/diag_data_buffer_dev.vhd @@ -169,7 +169,7 @@ BEGIN ASSERT c_mm_factor=2**true_log2(c_mm_factor) REPORT "Only support mixed width data that uses a power of 2 multiple." SEVERITY FAILURE; - out_wr_done <= wr_done; + out_wr_done <= nxt_wr_done; ram_mm_miso <= i_ram_mm_miso;