⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffman.vhd

📁 Pure hardware JPEG Encoder design. Package includes vhdl source code, test bench, detail design docu
💻 VHD
📖 第 1 页 / 共 2 页
字号:
      -- AC
      else
        -- luminance
        if huf_sm_settings.cmp_idx = 0 then
          VLC_size <= VLC_AC_size;
          VLC      <= VLC_AC;
        -- chrominance
        else
          VLC_size <= VLC_CR_AC_size;
          VLC      <= VLC_CR_AC;
        end if;
      end if;
    end if;
  end process;
  
  -------------------------------------------------------------------
  -- Block Counter / Last Block detector
  -------------------------------------------------------------------
  p_blk_cnt : process(CLK, RST)
  begin
    if RST = '1' then
      image_area_size <= (others => '0');
      last_block      <= '0';
    elsif CLK'event and CLK = '1' then
      image_area_size <= unsigned(cmp_max)*
                         unsigned(img_size_x)*unsigned(img_size_y);
      
      if sof = '1' then
        block_cnt <= (others => '0');
      elsif start_pb = '1' then
        block_cnt <= block_cnt + 1;
      end if;
      
      if block_cnt = image_area_size(33 downto 6) then
        last_block <= '1';
      else
        last_block <= '0';
      end if;
      
    end if;
  end process;
  
  VLI_ext      <= unsigned("0000" & VLI_d1);
  VLI_ext_size <= unsigned('0' & VLI_size_d1);
  
  -------------------------------------------------------------------
  -- delay line
  -------------------------------------------------------------------
  p_vli_dly : process(CLK, RST)
  begin
    if RST = '1' then
      VLI_d       <= (others => '0');
      VLI_size_d  <= (others => '0');
      VLI_d1      <= (others => '0');
      VLI_size_d1 <= (others => '0');
      d_val_d1    <= '0';
      d_val_d2    <= '0';
      d_val_d3    <= '0';
      d_val_d4    <= '0';
    elsif CLK'event and CLK = '1' then
      VLI_d1      <= VLI_r;
      VLI_size_d1 <= VLI_size_r;
      
      VLI_d       <= VLI_d1;
      VLI_size_d  <= VLI_size_d1;
      
      d_val_d1   <= d_val;
      d_val_d2   <= d_val_d1;
      d_val_d3   <= d_val_d2;
      d_val_d4   <= d_val_d3;
    end if;
  end process;
  
  -------------------------------------------------------------------
  -- HandleFifoWrites
  -------------------------------------------------------------------
  p_HandleFifoWrites : process(CLK, RST)
  begin
    if RST = '1' then
      ready_HFW    <= '0';
      fifo_wrt_cnt <= (others => '0');
      fifo_wren    <= '0';
      fifo_wbyte   <= (others => '0');
      rd_en_s      <= '0';
    elsif CLK'event and CLK = '1' then
      fifo_wren <= '0';
      ready_HFW <= '0';
      rd_en_s   <= '0';
      
      if start_pb = '1' then
        rd_en_s     <= '1';
      end if;
    
      if HFW_running = '1' and ready_HFW = '0' then
        -- there is no at least one integer byte to write this time
        if num_fifo_wrs = 0 then
          ready_HFW    <= '1';
          if state = RUN_VLI then
            rd_en_s      <= '1';
          end if;
        -- single byte write to FIFO
        else
          fifo_wrt_cnt <= fifo_wrt_cnt + 1;
          fifo_wren    <= '1';
          -- last byte write
          if fifo_wrt_cnt + 1 = num_fifo_wrs then
            ready_HFW    <= '1';
            if state = RUN_VLI then
              rd_en_s      <= '1';
            end if;
            fifo_wrt_cnt <= (others => '0');
          end if;
        end if;
      end if;
      
      case fifo_wrt_cnt is 
        when "00" =>
          fifo_wbyte <= std_logic_vector(word_reg(C_M-1 downto C_M-8));
        when "01" =>
          fifo_wbyte <= std_logic_vector(word_reg(C_M-8-1 downto C_M-16));            
        when others =>
          fifo_wbyte <= (others => '0');
      end case;
      if pad_reg = '1' then
        fifo_wbyte <= pad_byte;
      end if;

          
    end if;
  end process;
  
  -- divide by 8
  num_fifo_wrs <= bit_ptr(4 downto 3);
  
  -------------------------------------------------------------------
  -- Variable Length Processor FSM
  -------------------------------------------------------------------
  p_vlp : process(CLK, RST)
  begin
    if RST = '1' then
      ready_pb     <= '0';
      first_rle_word <= '0';
      state        <= IDLE;
      word_reg     <= (others => '0');
      bit_ptr      <= (others => '0');
      HFW_running  <= '0';
      pad_reg      <= '0';
      pad_byte     <= (others => '0');
    elsif CLK'event and CLK = '1' then
      ready_pb  <= '0';
    
      case state is
      
        when IDLE =>
          if start_pb = '1' then
            first_rle_word <= '1';
            state       <= RUN_VLC;
          end if;
        
        when RUN_VLC =>
          -- data valid DC or data valid AC
          if (d_val_d2 = '1' and first_rle_word = '1') or 
             (d_val = '1' and first_rle_word = '0') then
            for i in 0 to C_M-1 loop
              if i < to_integer(VLC_size) then
                word_reg(C_M-1-to_integer(bit_ptr)-i) <= VLC(to_integer(VLC_size)-1-i);
              end if;
            end loop;
            bit_ptr <= bit_ptr + resize(VLC_size,bit_ptr'length);
            
            -- HandleFifoWrites
            HFW_running  <= '1';
          -- HandleFifoWrites completed
          elsif HFW_running = '1' and 
                (num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
            -- shift word reg left to skip bytes already written to FIFO
            word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
            -- adjust bit pointer after some bytes were written to FIFO
            -- modulo 8 operation
            bit_ptr <= bit_ptr - (num_fifo_wrs & "000"); 
            HFW_running     <= '0';
            first_rle_word  <= '0';
            state           <= RUN_VLI;
          end if;
        
        when RUN_VLI =>
          if HFW_running = '0' then
            
            for i in 0 to C_M-1 loop
              if i < to_integer(VLI_ext_size) then
                word_reg(C_M-1-to_integer(bit_ptr)-i)
                  <= VLI_ext(to_integer(VLI_ext_size)-1-i);
              end if;
            end loop;
              
            bit_ptr <= bit_ptr + resize(VLI_ext_size,bit_ptr'length);
            
            -- HandleFifoWrites
            HFW_running <= '1';
          -- HandleFifoWrites completed
          elsif HFW_running = '1' and 
                (num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
            -- shift word reg left to skip bytes already written to FIFO
            word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
            -- adjust bit pointer after some bytes were written to FIFO
            -- modulo 8 operation
            bit_ptr <= bit_ptr - (num_fifo_wrs & "000"); 
            HFW_running <= '0';
            
            -- end of block
            if rle_fifo_empty = '1' then
              -- end of segment
              if bit_ptr - (num_fifo_wrs & "000") /= 0 and last_block = '1' then
                state <= PAD;  
              else
                ready_pb <= '1';
                state    <= IDLE;
              end if;
            else
              state          <= RUN_VLC;
            end if;
          end if;
          
        -- end of segment which requires bit padding
        when PAD =>
          if HFW_running = '0' then
            -- 1's bit padding to integer number of bytes
            for i in 0 to 7 loop
              if i < bit_ptr then
                pad_byte(7-i) <= word_reg(C_M-1-i);
              else
                pad_byte(7-i) <= '1';
              end if;
            end loop;
            pad_reg <= '1';
            
            bit_ptr <= to_unsigned(8, bit_ptr'length);         

            -- HandleFifoWrites
            HFW_running <= '1';
         elsif HFW_running = '1' and 
                (num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
           bit_ptr      <= (others => '0');
           HFW_running  <= '0';
           pad_reg      <= '0';

           ready_pb <= '1';
           state <= IDLE;
         end if;
        
        when others =>
        
      end case;
      
      if sof = '1' then
        bit_ptr <= (others => '0');
      end if;
      
    end if;
  end process;


end architecture RTL;
-------------------------------------------------------------------------------
-- Architecture: end
-------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -