URL
https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk
Subversion Repositories funbase_ip_library
[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.accelerator/] [dct_to_hibi/] [1.0/] [hdl/] [dct_to_hibi_v2.vhd] - Rev 145
Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- Title : DCT to Hibi. Connects dctQidct block to HIBI Wrapper -- Project : ------------------------------------------------------------------------------- -- File : dct_to_hibi_v2.vhd -- Author : rasmusa -- Created : 01.07.2006 -- Last update: 2006-08-22 -- -- Input: -- 1. Two address to send the results to (one for quant, one for idct) -- 2. Control word for the current macroblock -- Control word structure: bit 6: chroma(1)/luma(0), 5: intra(1)/inter(0), -- 4..0: quantizer parameter (QP) -- 3. Then the DCT data ( 8x8x6 x 16-bit values = 384 x 16 bit ) -- -- Chroma/luma: 4 luma, 2 chroma -- -- Outputs: -- Outputs are 16-bit words which are packed up to hibi. If hibi width is -- 32b, then 2 16-bit words are combined into one hibi word. -- 01. quant results: 1. 8*8 x 16bit values to quant result address -- 02. idct results: 1. 8*8 x 16bit values to idct result address -- 03. quant results: 2. 8*8 x 16bit values to quant result address -- 04. idct results: 2. 8*8 x 16bit values to idct result address -- 05. quant results: 3. 8*8 x 16bit values to quant result address -- 06. idct results: 3. 8*8 x 16bit values to idct result address -- 07. quant results: 4. 8*8 x 16bit values to quant result address -- 08. idct results: 4. 8*8 x 16bit values to idct result address -- 09. quant results: 5. 8*8 x 16bit values to quant result address -- 10. idct results: 5. 8*8 x 16bit values to idct result address -- 11. quant results: 6. 8*8 x 16bit values to quant result address -- 12. quant results: 1 word with bits 5..0 determing if 8x8 quant blocks(1-6) -- has all values zeros (except dc-component in intra) -- 13. idct results: 6. 8*8 x 16bit values to idct result address ------------------------------------------------------------------------------- -- Total amount of 16-bit values is: 384 per result address + 1 hibi word to -- quantization result address. -- -- With default parameter: -- Total of 193 words of data to quant address (if data_width_g = 32) -- Total of 192 words of data to idct address (if data_width_g = 32) ------------------------------------------------------------------------------- -- Copyright (c) 2005 ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 01.07.2005 1.0 AK Created -- 11.08.2005 1.1 AK all-zero quant result given -- 16.05.2005 1.11 AK chroma/luma bit -- 17.07.2007 1.12i AR Major rewrite, IF changed to R4, ... ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_misc.all; -- For or_reduce use ieee.std_logic_misc.all; entity dct_to_hibi is generic ( data_width_g : integer := 32; comm_width_g : integer := 5; dct_width_g : integer; -- Incoming data width(9b) quant_width_g : integer; -- Quantizated data width(8b) idct_width_g : integer; -- Data width after IDCT(9b) use_self_rel_g : integer; -- Does it release itself from RTM? own_address_g : integer; -- Used for self-release rtm_address_g : integer; -- Used for self-release debug_w_g : integer := 1 ); port ( clk : in std_logic; rst_n : in std_logic; -- HIBI signals hibi_av_out : out std_logic; hibi_data_out : out std_logic_vector (data_width_g-1 downto 0); hibi_comm_out : out std_logic_vector (comm_width_g-1 downto 0); hibi_we_out : out std_logic; hibi_full_in : in std_logic; hibi_re_out : out std_logic; hibi_av_in : in std_logic; hibi_data_in : in std_logic_vector (data_width_g-1 downto 0); hibi_comm_in : in std_logic_vector (comm_width_g-1 downto 0); hibi_empty_in : in std_logic; -- DCT signals wr_dct_out : out std_logic; quant_ready4col_out : out std_logic; idct_ready4col_out : out std_logic; data_dct_out : out std_logic_vector(dct_width_g-1 downto 0); intra_out : out std_logic; loadQP_out : out std_logic; QP_out : out std_logic_vector (4 downto 0); chroma_out : out std_logic; data_idct_in : in std_logic_vector(idct_width_g-1 downto 0); data_quant_in : in std_logic_vector(quant_width_g-1 downto 0); dct_ready4col_in : in std_logic; wr_idct_in : in std_logic; wr_quant_in : in std_logic; debug_out : out std_logic_vector(debug_w_g-1 downto 0) ); end dct_to_hibi; architecture rtl of dct_to_hibi is -- How many 8x8 blocks are sent after a request -- (4 x luma + 2 x chroma = a 16x16 macroblock ) constant n_blocks_per_req_c : integer := 6; -- Incoming value width constant dct_word_width_in_bus_c : integer := 16; -- Result value width constant output_word_width_c : integer := 16; constant rx_elements_c : integer := 8*8*n_blocks_per_req_c; -- How many 16-bit values in a hibi word constant tx_fifo_value_sel_max_c : integer := data_width_g/output_word_width_c; -- Because dctQidct pushes out 8 values at a time, fifo must be: constant tx_fifo_depth_c : integer := 8/tx_fifo_value_sel_max_c; -- /tx_fifo_value_sel_max_c because multiple values in a word constant n_values_in_block_c : integer := 8*8/tx_fifo_value_sel_max_c; -- Input data (received from the dct's point of view ) signal rx_counter_r : integer range 0 to rx_elements_c-1; -- tx from the dct's point of view ( actually results ) -- Signals for quant result fifo signal tx_q_fifo_full : std_logic; signal tx_q_fifo_empty : std_logic; signal tx_q_fifo_re : std_logic; signal tx_q_fifo_we : std_logic; signal tx_q_fifo_data_from : std_logic_vector(data_width_g-1 downto 0); signal tx_q_fifo_data_to_r : std_logic_vector(data_width_g-1 downto 0); signal tx_q_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1; -- Signals for idct result fifo signal tx_i_fifo_full : std_logic; signal tx_i_fifo_empty : std_logic; signal tx_i_fifo_re : std_logic; signal tx_i_fifo_we : std_logic; signal tx_i_fifo_data_from : std_logic_vector(data_width_g-1 downto 0); signal tx_i_fifo_data_to_r : std_logic_vector(data_width_g-1 downto 0); signal tx_i_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1; -- Signals for tx fifo (muxed to either to q or i fifo) signal tx_fifo_full : std_logic; signal tx_fifo_empty : std_logic; signal tx_fifo_re : std_logic; signal tx_fifo_re_r : std_logic; signal tx_fifo_data_from : std_logic_vector(data_width_g-1 downto 0); signal tx_data_counter_r : integer range 0 to n_values_in_block_c-1; -- n_blocks_per_req_c result blocks of a kind (quant and idct). Sum is 2*n_blocks_per_req_c constant result_block_count_c : integer := n_blocks_per_req_c*2; signal result_block_counter_r : integer range 0 to result_block_count_c-1; component fifo generic ( data_width_g : integer; depth_g : integer); port ( clk : in std_logic; rst_n : in std_logic; data_in : in std_logic_vector (data_width_g-1 downto 0); we_in : in std_logic; one_p_out : out std_logic; full_out : out std_logic; data_out : out std_logic_vector (data_width_g-1 downto 0); re_in : in std_logic; empty_out : out std_logic; one_d_out : out std_logic); end component; -- Originally Ari's counter which tells if current block is luma or chroma. component cl_cnt generic ( n_luma_g : integer; n_chroma_g : integer); port ( clk : in std_logic; rst_n : in std_logic; ena_in : in std_logic; cl_out : out std_logic); end component; type main_state_type is (idle, wait_quant_addr, wait_idct_addr, wait_control, wait_data, write_data); type result_send_type is (idle, send_av, send_data, send_last, send_rel_av, send_rel); -- States (results is quant is kind of state too ) signal main_state : main_state_type; signal result_send_state : result_send_type; signal result_is_quant_r : std_logic; -- Signals related to control word signal control_word_r : std_logic_vector(data_width_g-1 downto 0); alias intra_r : std_logic is control_word_r(5); alias quant_param_r : std_logic_vector(4 downto 0) is control_word_r(4 downto 0); signal loadQP_r : std_logic; -- Some internal hibi signals signal hibi_re_i : std_logic; signal hibi_re_r : std_logic; signal hibi_we_i : std_logic; signal hibi_we_r : std_logic; signal hibi_av_r : std_logic; signal hibi_data_r : std_logic_vector(data_width_g-1 downto 0); -- Signals to handle sending self release to rtm signal send_release_r : std_logic; signal release_sent_r : std_logic; -- Signals releated to fifos which store the result addresses signal addr_fifos_re_r : std_logic; signal addr_fifo_q_we : std_logic; signal addr_fifo_i_we : std_logic; signal addr_ret_for_quant : std_logic_vector(data_width_g-1 downto 0); signal addr_ret_for_idct : std_logic_vector(data_width_g-1 downto 0); signal addr_ret : std_logic_vector(data_width_g-1 downto 0); -- For determing if a 8x8 block has only zeros ( skip 1st value of intra block ) signal first_of_a_block_r : std_logic; signal quant_or_r : std_logic_vector(n_blocks_per_req_c-1 downto 0); signal intra_old_r : std_logic; signal send_or_value_r : std_logic; -- For signalling dctQidct if we are ready to receive results or not signal ready_for_q_col_r : std_logic; signal ready_for_i_col_r : std_logic; begin -- rtl ----------------------------------------------------------------------------- intra_out <= intra_r; QP_out <= quant_param_r; loadQP_out <= loadQP_r; ----------------------------------------------------------------------------- cl_cnt_1 : cl_cnt generic map ( n_luma_g => 4, n_chroma_g => 2) port map ( clk => clk, rst_n => rst_n, ena_in => loadQP_r, cl_out => chroma_out ); ----------------------------------------------------------------------------- fifo_tx_i : fifo generic map ( data_width_g => data_width_g, depth_g => tx_fifo_depth_c ) port map ( clk => clk, rst_n => rst_n, data_in => tx_i_fifo_data_to_r, we_in => tx_i_fifo_we, full_out => tx_i_fifo_full, data_out => tx_i_fifo_data_from, re_in => tx_i_fifo_re, empty_out => tx_i_fifo_empty ); ----------------------------------------------------------------------------- fifo_tx_q : fifo generic map ( data_width_g => data_width_g, depth_g => tx_fifo_depth_c ) port map ( clk => clk, rst_n => rst_n, data_in => tx_q_fifo_data_to_r, we_in => tx_q_fifo_we, full_out => tx_q_fifo_full, data_out => tx_q_fifo_data_from, re_in => tx_q_fifo_re, empty_out => tx_q_fifo_empty ); addr_fifo_q : fifo generic map ( data_width_g => data_width_g, depth_g => 2 -- two addresses in mem (new and current) ) port map ( clk => clk, rst_n => rst_n, data_in => hibi_data_in, we_in => addr_fifo_q_we, -- full_out => tx_q_fifo_full, data_out => addr_ret_for_quant, re_in => addr_fifos_re_r -- empty_out => tx_q_fifo_empty ); addr_fifo_i : fifo generic map ( data_width_g => data_width_g, depth_g => 2 -- two addresses in mem (new and current) ) port map ( clk => clk, rst_n => rst_n, data_in => hibi_data_in, we_in => addr_fifo_i_we, -- full_out => tx_q_fifo_full, data_out => addr_ret_for_idct, re_in => addr_fifos_re_r -- empty_out => tx_q_fifo_empty ); ----------------------------------------------------------------------------- quant_ready4col_out <= ready_for_q_col_r; --2.8. idct_ready4col_out <= ready_for_i_col_r; --2.8. addr_fifo_q_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_quant_addr else '0'; addr_fifo_i_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_idct_addr else '0'; ----------------------------------------------------------------------------- -- This process handles the incoming requests and stores the data to fifo -- for the dct main : process (clk, rst_n) variable value_sel_v : integer range 0 to data_width_g/dct_word_width_in_bus_c-1; begin -- process main if rst_n = '0' then -- asynchronous reset (active low) control_word_r <= (others => '0'); wr_dct_out <= '0'; hibi_re_r <= '0'; data_dct_out <= (others => '0'); loadQP_r <= '0'; main_state <= idle; send_release_r <= '0'; rx_counter_r <= 0; elsif clk'event and clk = '1' then -- rising clock edge loadQP_r <= '0'; if release_sent_r = '1' then send_release_r <= '0'; end if; case main_state is when idle => wr_dct_out <= '0'; hibi_re_r <= '1'; if hibi_empty_in = '0' and hibi_av_in = '1' then main_state <= wait_quant_addr; end if; when wait_quant_addr => if hibi_empty_in = '0' and hibi_av_in = '0' then main_state <= wait_idct_addr; end if; when wait_idct_addr => if hibi_empty_in = '0' and hibi_av_in = '0' then main_state <= wait_control; end if; when wait_control => if hibi_empty_in = '0' and hibi_av_in = '0' then control_word_r <= hibi_data_in; hibi_re_r <= '0'; main_state <= wait_data; end if; when wait_data => wr_dct_out <= '0'; hibi_re_r <= '0'; if dct_ready4col_in = '1' then main_state <= write_data; end if; when write_data => wr_dct_out <= '0'; hibi_re_r <= '0'; value_sel_v := rx_counter_r mod (data_width_g/dct_word_width_in_bus_c); if hibi_empty_in = '0' and hibi_av_in = '1' and hibi_re_r = '0' then hibi_re_r <= '1'; end if; if hibi_empty_in = '0' and hibi_av_in = '0' and (value_sel_v /= data_width_g/dct_word_width_in_bus_c-1 or hibi_re_i = '1') then wr_dct_out <= '1'; for i in 0 to data_width_g/dct_word_width_in_bus_c-1 loop if i = value_sel_v then data_dct_out <= hibi_data_in(i*dct_word_width_in_bus_c+dct_width_g-1 downto i*dct_word_width_in_bus_c); end if; end loop; if data_width_g/dct_word_width_in_bus_c = 1 then hibi_re_r <= '1'; else if value_sel_v = data_width_g/dct_word_width_in_bus_c-1-1 then hibi_re_r <= '1'; end if; end if; if rx_counter_r mod 8 = 7 then main_state <= wait_data; end if; if rx_counter_r mod 64 = 63 then loadQP_r <= '1'; end if; if rx_counter_r = rx_elements_c-1 then rx_counter_r <= 0; send_release_r <= '1'; main_state <= idle; else rx_counter_r <= rx_counter_r + 1; end if; -- else -- hibi_re_r <= '1'; end if; end case; end if; end process main; ----------------------------------------------------------------------------- hibi_re_i <= hibi_re_r and (not hibi_empty_in); hibi_re_out <= hibi_re_i; ----------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Process which handles the result idct data writing to corresponding tx fifo ------------------------------------------------------------------------------- output_to_fifo_i : process (clk, rst_n) begin -- process dct_to_fifo if rst_n = '0' then -- asynchronous reset (active low) tx_i_fifo_value_sel_r <= 0; tx_i_fifo_data_to_r <= (others => '0'); tx_i_fifo_we <= '0'; elsif clk'event and clk = '1' then -- rising clock edge tx_i_fifo_we <= '0'; if wr_idct_in = '1' then tx_i_fifo_we <= '0'; assert tx_i_fifo_full = '0' report "TX I FIFO FULL!" severity failure; for i in 0 to tx_fifo_value_sel_max_c-1 loop if i = tx_i_fifo_value_sel_r then tx_i_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_idct_in), output_word_width_c)); end if; end loop; if tx_i_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then tx_i_fifo_value_sel_r <= 0; tx_i_fifo_we <= '1'; else tx_i_fifo_value_sel_r <= tx_i_fifo_value_sel_r + 1; end if; end if; end if; end process output_to_fifo_i; ------------------------------------------------------------------------------- -- Process which handles the result quant data writing to corresponding tx fifo ------------------------------------------------------------------------------- output_to_fifo_q : process (clk, rst_n) variable intra_v : std_logic; begin -- process dct_to_fifo if rst_n = '0' then -- asynchronous reset (active low) tx_q_fifo_value_sel_r <= 0; tx_q_fifo_data_to_r <= (others => '0'); tx_q_fifo_we <= '0'; elsif clk'event and clk = '1' then -- rising clock edge tx_q_fifo_we <= '0'; if wr_quant_in = '1' then tx_q_fifo_we <= '0'; assert tx_q_fifo_full = '0' report "TX Q FIFO FULL!" severity failure; -- The following if statement is also in the zero check process if result_block_counter_r = 0 then intra_v := intra_r; -- Commented out intra_old <= intra_r assignment because -- it is in the zero check process else intra_v := intra_old_r; end if; for i in 0 to tx_fifo_value_sel_max_c-1 loop if i = tx_q_fifo_value_sel_r then -- Lets treat the first coeff of an intra block as a unsigned -- (1-254 according to the quant specs found in IQuant.vhd) if (first_of_a_block_r = '1' and intra_v = '1') then tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(unsigned(data_quant_in), output_word_width_c)); else tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_quant_in), output_word_width_c)); end if; end if; end loop; if tx_q_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then tx_q_fifo_value_sel_r <= 0; tx_q_fifo_we <= '1'; else tx_q_fifo_value_sel_r <= tx_q_fifo_value_sel_r + 1; end if; end if; end if; end process output_to_fifo_q; ----------------------------------------------------------------------------- -- Depending on the result_is_quant_r signal, tx_fifo signals are connected -- to either of the two transmit fifos (quant or idct) ----------------------------------------------------------------------------- q_i_fifo_mux_demux : process (tx_i_fifo_full, tx_q_fifo_full, tx_q_fifo_empty, tx_i_fifo_empty, tx_fifo_re, tx_q_fifo_data_from, tx_i_fifo_data_from, result_is_quant_r, addr_ret_for_idct, addr_ret_for_quant) begin -- process q_i_fifo_mux tx_q_fifo_re <= '0'; tx_i_fifo_re <= '0'; if result_is_quant_r = '1' then tx_q_fifo_re <= tx_fifo_re; tx_fifo_full <= tx_q_fifo_full; tx_fifo_empty <= tx_q_fifo_empty; tx_fifo_data_from <= tx_q_fifo_data_from; addr_ret <= addr_ret_for_quant; else tx_i_fifo_re <= tx_fifo_re; tx_fifo_data_from <= tx_i_fifo_data_from; tx_fifo_full <= tx_i_fifo_full; tx_fifo_empty <= tx_i_fifo_empty; addr_ret <= addr_ret_for_idct; end if; end process q_i_fifo_mux_demux; ----------------------------------------------------------------------------- hibi_we_i <= hibi_we_r and (not hibi_full_in) and ((not tx_fifo_empty) or release_sent_r or send_or_value_r); hibi_we_out <= hibi_we_i; hibi_av_out <= hibi_av_r; tx_fifo_re <= tx_fifo_re_r and (not hibi_full_in) and (not tx_fifo_empty); -- Choose hibi_data_out depending on the state and hibi_av_out (_r) tx_fifo_read : process (result_send_state, hibi_data_r, tx_fifo_data_from, hibi_av_r) begin -- process tx_fifo_i_read if (result_send_state = send_data) and hibi_av_r = '0' then hibi_data_out <= tx_fifo_data_from; else hibi_data_out <= hibi_data_r; end if; end process tx_fifo_read; ----------------------------------------------------------------------------- -- ZERO CHECK PROCESS -- Determine if incoming quant data has only zeros or not ----------------------------------------------------------------------------- zero_check : process (clk, rst_n) variable intra_v : std_logic; begin -- process zero_check if rst_n = '0' then -- asynchronous reset (active low) quant_or_r <= (others => '0'); first_of_a_block_r <= '1'; intra_old_r <= '0'; elsif clk'event and clk = '1' then -- rising clock edge intra_v := '0'; if wr_quant_in = '1' then -- These same if-statements are also in quant result write process if result_block_counter_r = 0 then intra_v := intra_r; intra_old_r <= intra_r; else intra_v := intra_old_r; end if; if not (first_of_a_block_r = '1' and intra_v = '1') then quant_or_r(0) <= quant_or_r(0) or or_reduce(data_quant_in); end if; if first_of_a_block_r = '1' then first_of_a_block_r <= '0'; end if; end if; if result_send_state = send_last and result_is_quant_r = '1' then first_of_a_block_r <= '1'; quant_or_r <= quant_or_r(n_blocks_per_req_c-2 downto 0) & '0'; end if; end if; end process zero_check; ----------------------------------------------------------------------------- -- SEND RESULTS OVER HIBI ----------------------------------------------------------------------------- hibi_send_proc : process (clk, rst_n) begin -- process hibi_send_proc if rst_n = '0' then -- asynchronous reset (active low) hibi_data_r <= (others => '0'); hibi_comm_out <= std_logic_vector(to_unsigned(0, comm_width_g)); hibi_we_r <= '0'; hibi_av_r <= '0'; tx_fifo_re_r <= '0'; tx_data_counter_r <= 0; release_sent_r <= '0'; result_is_quant_r <= '1'; addr_fifos_re_r <= '0'; send_or_value_r <= '0'; result_send_state <= idle; result_block_counter_r <= 0; ready_for_q_col_r <= '1'; ready_for_i_col_r <= '1'; elsif clk'event and clk = '1' then -- rising clock edge addr_fifos_re_r <= '0'; -- If incoming data from dctQidct, let's set the ready signals low if wr_quant_in = '1' then ready_for_q_col_r <= '0'; end if; if wr_idct_in = '1' then ready_for_i_col_r <= '0'; end if; case result_send_state is -- Do nothing unless there is something in transmit fifo or release is -- requested when idle => if tx_fifo_empty = '0' then result_send_state <= send_av; end if; if send_release_r = '1' and use_self_rel_g /= 0 then result_send_state <= send_rel_av; end if; -- Send self release address valid (+2 for release to rtm) when send_rel_av => release_sent_r <= '1'; hibi_av_r <= '1'; hibi_we_r <= '1'; hibi_comm_out <= std_logic_vector(to_unsigned(3, comm_width_g)); hibi_data_r <= std_logic_vector(to_unsigned(rtm_address_g+2, data_width_g)); result_send_state <= send_rel; -- Send self release data (own address) when send_rel => if hibi_we_i = '1' then hibi_av_r <= '0'; hibi_data_r <= std_logic_vector(to_unsigned(own_address_g, data_width_g)); if hibi_av_r = '0' then hibi_data_r <= (others => '0'); hibi_we_r <= '0'; hibi_comm_out <= (others => '0'); release_sent_r <= '0'; result_send_state <= idle; end if; end if; -- Send address valid in the beginning of every 8x8 block when send_av => hibi_av_r <= '1'; hibi_we_r <= '1'; hibi_comm_out <= std_logic_vector(to_unsigned(2, comm_width_g)); hibi_data_r <= addr_ret; result_send_state <= send_data; when send_data => -- If last sending was ok. if hibi_we_i = '1' then tx_fifo_re_r <= '1'; hibi_av_r <= '0'; -- If address is sent if hibi_av_r = '0' then -- If 8x8 block sending is ready if tx_data_counter_r = n_values_in_block_c-1 then -- 0..31 tx_data_counter_r <= 0; -- If we are finished sending the last 8x8 block (idct in fact) if result_block_counter_r = result_block_count_c-1 then --0..11 result_block_counter_r <= 0; addr_fifos_re_r <= '1'; else result_block_counter_r <= result_block_counter_r + 1; end if; hibi_av_r <= '0'; hibi_comm_out <= (others => '0'); hibi_we_r <= '0'; hibi_data_r <= (others => '0'); tx_fifo_re_r <= '0'; send_or_value_r <= '0'; -- If we are finished sending the last QUANT block, -- let's send the OR-value which determines if QUANT blocks -- has zeros. if result_block_counter_r = result_block_count_c-2 then hibi_we_r <= '1'; send_or_value_r <= '1'; hibi_data_r(n_blocks_per_req_c-1 downto 0) <= quant_or_r; hibi_comm_out <= std_logic_vector(to_unsigned(2, comm_width_g)); end if; result_send_state <= send_last; else tx_data_counter_r <= tx_data_counter_r + 1; end if; -- After every 8 values, we set the ready signal back on if tx_data_counter_r mod (8/tx_fifo_value_sel_max_c) = (8/tx_fifo_value_sel_max_c)-1 then if result_is_quant_r = '1' then ready_for_q_col_r <= '1'; else ready_for_i_col_r <= '1'; end if; end if; end if; end if; -- In this state, the or word is being sent, if send_or_value_r is high. when send_last => if send_or_value_r = '0' or hibi_we_i = '1' then send_or_value_r <= '0'; hibi_we_r <= '0'; hibi_data_r <= (others => '0'); hibi_comm_out <= (others => '0'); result_is_quant_r <= not result_is_quant_r; result_send_state <= idle; end if; end case; end if; end process hibi_send_proc; end rtl;