rle.vhd

来自「Pure hardware JPEG Encoder design. Packa」· VHDL 代码 · 共 312 行

VHD
312
字号
----------------------------------------------------------------------------------                                                                            ----                          V H D L    F I L E                                ----                          COPYRIGHT (C) 2009                                ----                                                                            ------------------------------------------------------------------------------------                                                                            ---- Title       : RLE                                                          ---- Design      : MDCT CORE                                                    ---- Author      : Michal Krepa                                                 ----                                                                            ------------------------------------------------------------------------------------                                                                            ---- File        : RLE.VHD                                                      ---- Created     : Wed Mar 04 2009                                              ----                                                                            ------------------------------------------------------------------------------------                                                                            ----  Description : Run Length Encoder                                          ----                Baseline Entropy Coding                                     ------------------------------------------------------------------------------------------------------------------------------------------------------------------library IEEE;  use IEEE.STD_LOGIC_1164.All;  use IEEE.NUMERIC_STD.all;  library work;  use work.JPEG_PKG.all;  entity rle is  generic     (       RAMADDR_W     : INTEGER := 6;      RAMDATA_W     : INTEGER := 12    );   port    (      rst        : in  STD_LOGIC;      clk        : in  STD_LOGIC;      di         : in  STD_LOGIC_VECTOR(RAMDATA_W-1 downto 0);      start_pb   : in  std_logic;      sof        : in  std_logic;      rle_sm_settings : in T_SM_SETTINGS;            runlength  : out STD_LOGIC_VECTOR(3 downto 0);      size       : out STD_LOGIC_VECTOR(3 downto 0);      amplitude  : out STD_LOGIC_VECTOR(RAMDATA_W-1 downto 0);      dovalid    : out STD_LOGIC;      rd_addr    : out STD_LOGIC_VECTOR(5 downto 0)    );end rle;architecture rtl of rle is      constant SIZE_REG_C      : INTEGER := 4;  constant ZEROS_32_C      : UNSIGNED(31 downto 0) := (others => '0');    signal prev_dc_reg_0   : SIGNED(RAMDATA_W-1 downto 0);  signal prev_dc_reg_1   : SIGNED(RAMDATA_W-1 downto 0);  signal prev_dc_reg_2   : SIGNED(RAMDATA_W-1 downto 0);  signal acc_reg         : SIGNED(RAMDATA_W downto 0);  signal size_reg        : UNSIGNED(SIZE_REG_C-1 downto 0);   signal ampli_vli_reg   : SIGNED(RAMDATA_W downto 0);  signal runlength_reg   : UNSIGNED(3 downto 0);     signal dovalid_reg     : STD_LOGIC;  signal zero_cnt        : unsigned(5 downto 0);  signal wr_cnt_d1       : unsigned(5 downto 0);  signal wr_cnt          : unsigned(5 downto 0);    signal rd_cnt         : unsigned(5 downto 0);  signal rd_en          : std_logic;    signal divalid        : STD_LOGIC;  signal zrl_proc       : std_logic;  signal zrl_proc_d1    : std_logic;  signal zrl_di         : STD_LOGIC_VECTOR(RAMDATA_W-1 downto 0);begin  size      <= STD_LOGIC_VECTOR(size_reg);  amplitude <= STD_LOGIC_VECTOR(ampli_vli_reg(11 downto 0));    rd_addr <= STD_LOGIC_VECTOR(rd_cnt);  -------------------------------------------  -- Counter1  -------------------------------------------  process(clk,rst)  begin    if rst = '1' then      rd_en           <= '0';      rd_cnt          <= (others => '0');    elsif clk = '1' and clk'event then      if start_pb = '1' then        rd_cnt <= (others => '0');        rd_en <= '1';             end if;            -- input read enable      if rd_en = '1' and zrl_proc = '0' then        if rd_cnt = 64-1 then          rd_cnt <= (others => '0');          rd_en  <= '0';        else          rd_cnt <= rd_cnt + 1;        end if;      end if;    end if;  end process;    -------------------------------------------  -- MAIN PROCESSING  -------------------------------------------  process(clk,rst)  begin    if rst = '1' then      wr_cnt_d1       <= (others => '0');      prev_dc_reg_0   <= (others => '0');      prev_dc_reg_1   <= (others => '0');      prev_dc_reg_2   <= (others => '0');      dovalid_reg     <= '0';      acc_reg         <= (others => '0');      runlength_reg   <= (others => '0');      runlength       <= (others => '0');      dovalid         <= '0';      zero_cnt        <= (others => '0');      zrl_proc        <= '0';      zrl_proc_d1     <= '0';    elsif clk = '1' and clk'event then      dovalid_reg     <= '0';      runlength_reg   <= (others => '0');      wr_cnt_d1       <= wr_cnt;      runlength       <= std_logic_vector(runlength_reg);      dovalid         <= dovalid_reg;      divalid         <= rd_en;      zrl_proc_d1     <= zrl_proc;      -- input data valid      if divalid = '1' and zrl_proc_d1 = '0' then        wr_cnt <= wr_cnt + 1;              -- first DCT coefficient received, DC data        if wr_cnt = 0 then          -- differental coding of DC data per component          case rle_sm_settings.cmp_idx is            when "00" =>              acc_reg <= RESIZE(SIGNED(di),RAMDATA_W+1) - RESIZE(prev_dc_reg_0,RAMDATA_W+1);              prev_dc_reg_0 <= SIGNED(di);            when "01" =>              acc_reg <= RESIZE(SIGNED(di),RAMDATA_W+1) - RESIZE(prev_dc_reg_1,RAMDATA_W+1);              prev_dc_reg_1 <= SIGNED(di);            when "10" =>              acc_reg <= RESIZE(SIGNED(di),RAMDATA_W+1) - RESIZE(prev_dc_reg_2,RAMDATA_W+1);              prev_dc_reg_2 <= SIGNED(di);            when others =>              null;          end case;          runlength_reg    <= (others => '0');          dovalid_reg      <= '1';        -- AC coefficient        else          -- zero AC          if signed(di) = 0 then            -- EOB            if wr_cnt = 63 then              acc_reg          <= (others => '0');              runlength_reg    <= (others => '0');              dovalid_reg      <= '1';            -- no EOB            else              zero_cnt <= zero_cnt + 1;            end if;          -- non-zero AC          else            -- normal RLE case            if zero_cnt <= 15 then              acc_reg        <= RESIZE(SIGNED(di),RAMDATA_W+1);              runlength_reg  <= zero_cnt(3 downto 0);              zero_cnt       <= (others => '0');              dovalid_reg    <= '1';            -- zero_cnt > 15            else              -- generate ZRL              acc_reg        <= (others => '0');              runlength_reg  <= X"F";              zero_cnt       <= zero_cnt - 16;              dovalid_reg    <= '1';              -- stall input until ZRL is handled              zrl_proc       <= '1';              zrl_di         <= di;            end if;          end if;        end if;      end if;            -- ZRL processing      if zrl_proc = '1' then        if zero_cnt <= 15 then          acc_reg        <= RESIZE(SIGNED(zrl_di),RAMDATA_W+1);          runlength_reg  <= zero_cnt(3 downto 0);          zero_cnt       <= (others => '0');          dovalid_reg    <= '1';          -- continue input handling          zrl_proc <= '0';        -- zero_cnt > 15        else          -- generate ZRL          acc_reg        <= (others => '0');          runlength_reg  <= X"F";          zero_cnt       <= zero_cnt - 16;          dovalid_reg    <= '1';        end if;           end if;            -- start of 8x8 block processing      if start_pb = '1' then        zero_cnt <= (others => '0');        wr_cnt   <= (others => '0');      end if;            if sof = '1' then        prev_dc_reg_0 <= (others => '0');        prev_dc_reg_1 <= (others => '0');        prev_dc_reg_2 <= (others => '0');      end if;    end if;  end process;       -------------------------------------------------------------------  -- Entropy Coder  -------------------------------------------------------------------  p_entropy_coder : process(CLK, RST)  begin    if RST = '1' then      ampli_vli_reg <= (others => '0');      size_reg      <= (others => '0');    elsif CLK'event and CLK = '1' then      -- perform VLI (variable length integer) encoding for Symbol-2 (Amplitude)      -- positive input      if acc_reg >= 0 then        ampli_vli_reg <= acc_reg;      else        ampli_vli_reg <= acc_reg - TO_SIGNED(1,RAMDATA_W+1);      end if;            -- compute Symbol-1 Size      if acc_reg = TO_SIGNED(-1,RAMDATA_W+1) then        size_reg <= TO_UNSIGNED(1,SIZE_REG_C);      elsif (acc_reg < TO_SIGNED(-1,RAMDATA_W+1) and acc_reg > TO_SIGNED(-4,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(2,SIZE_REG_C);      elsif (acc_reg < TO_SIGNED(-3,RAMDATA_W+1) and acc_reg > TO_SIGNED(-8,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(3,SIZE_REG_C);      elsif (acc_reg < TO_SIGNED(-7,RAMDATA_W+1) and acc_reg > TO_SIGNED(-16,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(4,SIZE_REG_C);       elsif (acc_reg < TO_SIGNED(-15,RAMDATA_W+1) and acc_reg > TO_SIGNED(-32,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(5,SIZE_REG_C);        elsif (acc_reg < TO_SIGNED(-31,RAMDATA_W+1) and acc_reg > TO_SIGNED(-64,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(6,SIZE_REG_C);      elsif (acc_reg < TO_SIGNED(-63,RAMDATA_W+1) and acc_reg > TO_SIGNED(-128,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(7,SIZE_REG_C);       elsif (acc_reg < TO_SIGNED(-127,RAMDATA_W+1) and acc_reg > TO_SIGNED(-256,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(8,SIZE_REG_C);       elsif (acc_reg < TO_SIGNED(-255,RAMDATA_W+1) and acc_reg > TO_SIGNED(-512,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(9,SIZE_REG_C);        elsif (acc_reg < TO_SIGNED(-511,RAMDATA_W+1) and acc_reg > TO_SIGNED(-1024,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(10,SIZE_REG_C);        elsif (acc_reg < TO_SIGNED(-1023,RAMDATA_W+1) and acc_reg > TO_SIGNED(-2048,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(11,SIZE_REG_C);      end if;        -- compute Symbol-1 Size      -- positive input      if acc_reg = TO_SIGNED(1,RAMDATA_W+1) then        size_reg <= TO_UNSIGNED(1,SIZE_REG_C);      elsif (acc_reg > TO_SIGNED(1,RAMDATA_W+1) and acc_reg < TO_SIGNED(4,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(2,SIZE_REG_C);      elsif (acc_reg > TO_SIGNED(3,RAMDATA_W+1) and acc_reg < TO_SIGNED(8,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(3,SIZE_REG_C);      elsif (acc_reg > TO_SIGNED(7,RAMDATA_W+1) and acc_reg < TO_SIGNED(16,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(4,SIZE_REG_C);       elsif (acc_reg > TO_SIGNED(15,RAMDATA_W+1) and acc_reg < TO_SIGNED(32,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(5,SIZE_REG_C);          elsif (acc_reg > TO_SIGNED(31,RAMDATA_W+1) and acc_reg < TO_SIGNED(64,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(6,SIZE_REG_C);        elsif (acc_reg > TO_SIGNED(63,RAMDATA_W+1) and acc_reg < TO_SIGNED(128,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(7,SIZE_REG_C);        elsif (acc_reg > TO_SIGNED(127,RAMDATA_W+1) and acc_reg < TO_SIGNED(256,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(8,SIZE_REG_C);        elsif (acc_reg > TO_SIGNED(255,RAMDATA_W+1) and acc_reg < TO_SIGNED(512,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(9,SIZE_REG_C);        elsif (acc_reg > TO_SIGNED(511,RAMDATA_W+1) and acc_reg < TO_SIGNED(1024,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(10,SIZE_REG_C);         elsif (acc_reg > TO_SIGNED(1023,RAMDATA_W+1) and acc_reg < TO_SIGNED(2048,RAMDATA_W+1)) then        size_reg <= TO_UNSIGNED(11,SIZE_REG_C);        end if;             -- DC coefficient amplitude=0 case OR EOB      if acc_reg = 0 then         size_reg <= TO_UNSIGNED(0,SIZE_REG_C);      end if;    end if;  end process;        end rtl;  --------------------------------------------------------------------------------

⌨️ 快捷键说明

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