-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- File Name : Huffman.vhd
|
-- File Name : Huffman.vhd
|
--
|
--
|
-- Project : JPEG_ENC
|
-- Project : JPEG_ENC
|
--
|
--
|
-- Module : Huffman
|
-- Module : Huffman
|
--
|
--
|
-- Content : Huffman Encoder
|
-- Content : Huffman Encoder
|
--
|
--
|
-- Description : Huffman encoder core
|
-- Description : Huffman encoder core
|
--
|
--
|
-- Spec. :
|
-- Spec. :
|
--
|
--
|
-- Author : Michal Krepa
|
-- Author : Michal Krepa
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- History :
|
-- History :
|
-- 20090228: (MK): Initial Creation.
|
-- 20090228: (MK): Initial Creation.
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
----------------------------------- LIBRARY/PACKAGE ---------------------------
|
----------------------------------- LIBRARY/PACKAGE ---------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- generic packages/libraries:
|
-- generic packages/libraries:
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- user packages/libraries:
|
-- user packages/libraries:
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
library work;
|
library work;
|
use work.JPEG_PKG.all;
|
use work.JPEG_PKG.all;
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
----------------------------------- ENTITY ------------------------------------
|
----------------------------------- ENTITY ------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
entity Huffman is
|
entity Huffman is
|
port
|
port
|
(
|
(
|
CLK : in std_logic;
|
CLK : in std_logic;
|
RST : in std_logic;
|
RST : in std_logic;
|
-- CTRL
|
-- CTRL
|
start_pb : in std_logic;
|
start_pb : in std_logic;
|
ready_pb : out std_logic;
|
ready_pb : out std_logic;
|
huf_sm_settings : in T_SM_SETTINGS;
|
huf_sm_settings : in T_SM_SETTINGS;
|
|
|
-- HOST IF
|
-- HOST IF
|
sof : in std_logic;
|
sof : in std_logic;
|
img_size_x : in std_logic_vector(15 downto 0);
|
img_size_x : in std_logic_vector(15 downto 0);
|
img_size_y : in std_logic_vector(15 downto 0);
|
img_size_y : in std_logic_vector(15 downto 0);
|
cmp_max : in std_logic_vector(1 downto 0);
|
cmp_max : in std_logic_vector(1 downto 0);
|
|
|
-- RLE
|
-- RLE
|
rle_buf_sel : out std_logic;
|
rle_buf_sel : out std_logic;
|
rd_en : out std_logic;
|
rd_en : out std_logic;
|
runlength : in std_logic_vector(3 downto 0);
|
runlength : in std_logic_vector(3 downto 0);
|
VLI_size : in std_logic_vector(3 downto 0);
|
VLI_size : in std_logic_vector(3 downto 0);
|
VLI : in std_logic_vector(11 downto 0);
|
VLI : in std_logic_vector(11 downto 0);
|
d_val : in std_logic;
|
d_val : in std_logic;
|
rle_fifo_empty : in std_logic;
|
rle_fifo_empty : in std_logic;
|
|
|
-- Byte Stuffer
|
-- Byte Stuffer
|
bs_buf_sel : in std_logic;
|
bs_buf_sel : in std_logic;
|
bs_fifo_empty : out std_logic;
|
bs_fifo_empty : out std_logic;
|
bs_rd_req : in std_logic;
|
bs_rd_req : in std_logic;
|
bs_packed_byte : out std_logic_vector(7 downto 0)
|
bs_packed_byte : out std_logic_vector(7 downto 0)
|
);
|
);
|
end entity Huffman;
|
end entity Huffman;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
----------------------------------- ARCHITECTURE ------------------------------
|
----------------------------------- ARCHITECTURE ------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
architecture RTL of Huffman is
|
architecture RTL of Huffman is
|
|
|
type T_STATE is (IDLE, RUN_VLC, RUN_VLI, PAD);
|
type T_STATE is (IDLE, RUN_VLC, RUN_VLI, PAD);
|
|
|
constant C_M : integer := 23;
|
constant C_M : integer := 23;
|
constant BLK_SIZE : integer := 64;
|
constant BLK_SIZE : integer := 64;
|
|
|
signal state : T_STATE;
|
signal state : T_STATE;
|
signal rle_buf_sel_s : std_logic;
|
signal rle_buf_sel_s : std_logic;
|
signal first_rle_word : std_logic;
|
signal first_rle_word : std_logic;
|
signal word_reg : unsigned(C_M-1 downto 0);
|
signal word_reg : unsigned(C_M-1 downto 0);
|
signal bit_ptr : unsigned(4 downto 0);
|
signal bit_ptr : unsigned(4 downto 0);
|
signal num_fifo_wrs : unsigned(1 downto 0);
|
signal num_fifo_wrs : unsigned(1 downto 0);
|
signal VLI_ext : unsigned(15 downto 0);
|
signal VLI_ext : unsigned(15 downto 0);
|
signal VLI_ext_size : unsigned(4 downto 0);
|
signal VLI_ext_size : unsigned(4 downto 0);
|
signal ready_HFW : std_logic;
|
signal ready_HFW : std_logic;
|
signal fifo_wbyte : std_logic_vector(7 downto 0);
|
signal fifo_wbyte : std_logic_vector(7 downto 0);
|
signal fifo_wrt_cnt : unsigned(1 downto 0);
|
signal fifo_wrt_cnt : unsigned(1 downto 0);
|
signal fifo_wren : std_logic;
|
signal fifo_wren : std_logic;
|
signal last_block : std_logic;
|
signal last_block : std_logic;
|
signal image_area_size : unsigned(33 downto 0);
|
signal image_area_size : unsigned(33 downto 0);
|
signal block_cnt : unsigned(27 downto 0);
|
signal block_cnt : unsigned(27 downto 0);
|
signal VLC_size : unsigned(4 downto 0);
|
signal VLC_size : unsigned(4 downto 0);
|
signal VLC : unsigned(15 downto 0);
|
signal VLC : unsigned(15 downto 0);
|
signal VLC_DC_size : std_logic_vector(3 downto 0);
|
signal VLC_DC_size : std_logic_vector(3 downto 0);
|
signal VLC_DC : unsigned(8 downto 0);
|
signal VLC_DC : unsigned(8 downto 0);
|
signal VLC_AC_size : unsigned(4 downto 0);
|
signal VLC_AC_size : unsigned(4 downto 0);
|
signal VLC_AC : unsigned(15 downto 0);
|
signal VLC_AC : unsigned(15 downto 0);
|
signal vlc_vld : std_logic;
|
signal vlc_vld : std_logic;
|
signal d_val_d1 : std_logic;
|
signal d_val_d1 : std_logic;
|
signal d_val_d2 : std_logic;
|
signal d_val_d2 : std_logic;
|
signal d_val_d3 : std_logic;
|
signal d_val_d3 : std_logic;
|
signal d_val_d4 : std_logic;
|
signal d_val_d4 : std_logic;
|
signal VLI_size_d : std_logic_vector(3 downto 0);
|
signal VLI_size_d : std_logic_vector(3 downto 0);
|
signal VLI_d : std_logic_vector(11 downto 0);
|
signal VLI_d : std_logic_vector(11 downto 0);
|
signal VLI_size_d1 : std_logic_vector(3 downto 0);
|
signal VLI_size_d1 : std_logic_vector(3 downto 0);
|
signal VLI_d1 : std_logic_vector(11 downto 0);
|
signal VLI_d1 : std_logic_vector(11 downto 0);
|
signal HFW_running : std_logic;
|
signal HFW_running : std_logic;
|
signal runlength_r : std_logic_vector(3 downto 0);
|
signal runlength_r : std_logic_vector(3 downto 0);
|
signal VLI_size_r : std_logic_vector(3 downto 0);
|
signal VLI_size_r : std_logic_vector(3 downto 0);
|
signal VLI_r : std_logic_vector(11 downto 0);
|
signal VLI_r : std_logic_vector(11 downto 0);
|
signal rd_en_s : std_logic;
|
signal rd_en_s : std_logic;
|
signal pad_byte : std_logic_vector(7 downto 0);
|
signal pad_byte : std_logic_vector(7 downto 0);
|
signal pad_reg : std_logic;
|
signal pad_reg : std_logic;
|
signal VLC_CR_DC_size : std_logic_vector(3 downto 0);
|
signal VLC_CR_DC_size : std_logic_vector(3 downto 0);
|
signal VLC_CR_DC : unsigned(10 downto 0);
|
signal VLC_CR_DC : unsigned(10 downto 0);
|
signal VLC_CR_AC_size : unsigned(4 downto 0);
|
signal VLC_CR_AC_size : unsigned(4 downto 0);
|
signal VLC_CR_AC : unsigned(15 downto 0);
|
signal VLC_CR_AC : unsigned(15 downto 0);
|
signal start_pb_d1 : std_logic;
|
signal start_pb_d1 : std_logic;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture: begin
|
-- Architecture: begin
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
begin
|
begin
|
|
|
rle_buf_sel <= rle_buf_sel_s;
|
rle_buf_sel <= rle_buf_sel_s;
|
|
|
rd_en <= rd_en_s;
|
rd_en <= rd_en_s;
|
vlc_vld <= rd_en_s;
|
vlc_vld <= rd_en_s;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- latch FIFO Q
|
-- latch FIFO Q
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_latch_fifo : process(CLK, RST)
|
p_latch_fifo : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
VLI_size_r <= (others => '0');
|
VLI_size_r <= (others => '0');
|
VLI_r <= (others => '0');
|
VLI_r <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
if d_val = '1' then
|
if d_val = '1' then
|
VLI_size_r <= VLI_size;
|
VLI_size_r <= VLI_size;
|
VLI_r <= VLI;
|
VLI_r <= VLI;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- DC_ROM Luminance
|
-- DC_ROM Luminance
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_DC_ROM : entity work.DC_ROM
|
U_DC_ROM : entity work.DC_ROM
|
port map
|
port map
|
(
|
(
|
CLK => CLK,
|
CLK => CLK,
|
RST => RST,
|
RST => RST,
|
VLI_size => VLI_size,
|
VLI_size => VLI_size,
|
|
|
VLC_DC_size => VLC_DC_size,
|
VLC_DC_size => VLC_DC_size,
|
VLC_DC => VLC_DC
|
VLC_DC => VLC_DC
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- AC_ROM Luminance
|
-- AC_ROM Luminance
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_AC_ROM : entity work.AC_ROM
|
U_AC_ROM : entity work.AC_ROM
|
port map
|
port map
|
(
|
(
|
CLK => CLK,
|
CLK => CLK,
|
RST => RST,
|
RST => RST,
|
runlength => runlength,
|
runlength => runlength,
|
VLI_size => VLI_size,
|
VLI_size => VLI_size,
|
|
|
VLC_AC_size => VLC_AC_size,
|
VLC_AC_size => VLC_AC_size,
|
VLC_AC => VLC_AC
|
VLC_AC => VLC_AC
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- DC_ROM Chrominance
|
-- DC_ROM Chrominance
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_DC_CR_ROM : entity work.DC_CR_ROM
|
U_DC_CR_ROM : entity work.DC_CR_ROM
|
port map
|
port map
|
(
|
(
|
CLK => CLK,
|
CLK => CLK,
|
RST => RST,
|
RST => RST,
|
VLI_size => VLI_size,
|
VLI_size => VLI_size,
|
|
|
VLC_DC_size => VLC_CR_DC_size,
|
VLC_DC_size => VLC_CR_DC_size,
|
VLC_DC => VLC_CR_DC
|
VLC_DC => VLC_CR_DC
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- AC_ROM Chrominance
|
-- AC_ROM Chrominance
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_AC_CR_ROM : entity work.AC_CR_ROM
|
U_AC_CR_ROM : entity work.AC_CR_ROM
|
port map
|
port map
|
(
|
(
|
CLK => CLK,
|
CLK => CLK,
|
RST => RST,
|
RST => RST,
|
runlength => runlength,
|
runlength => runlength,
|
VLI_size => VLI_size,
|
VLI_size => VLI_size,
|
|
|
VLC_AC_size => VLC_CR_AC_size,
|
VLC_AC_size => VLC_CR_AC_size,
|
VLC_AC => VLC_CR_AC
|
VLC_AC => VLC_CR_AC
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Double Fifo
|
-- Double Fifo
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_DoubleFifo : entity work.DoubleFifo
|
U_DoubleFifo : entity work.DoubleFifo
|
port map
|
port map
|
(
|
(
|
CLK => CLK,
|
CLK => CLK,
|
RST => RST,
|
RST => RST,
|
-- HUFFMAN
|
-- HUFFMAN
|
data_in => fifo_wbyte,
|
data_in => fifo_wbyte,
|
wren => fifo_wren,
|
wren => fifo_wren,
|
-- BYTE STUFFER
|
-- BYTE STUFFER
|
buf_sel => bs_buf_sel,
|
buf_sel => bs_buf_sel,
|
rd_req => bs_rd_req,
|
rd_req => bs_rd_req,
|
fifo_empty => bs_fifo_empty,
|
fifo_empty => bs_fifo_empty,
|
data_out => bs_packed_byte
|
data_out => bs_packed_byte
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- RLE buf_sel
|
-- RLE buf_sel
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_rle_buf_sel : process(CLK, RST)
|
p_rle_buf_sel : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
rle_buf_sel_s <= '0';
|
rle_buf_sel_s <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
if start_pb = '1' then
|
if start_pb = '1' then
|
rle_buf_sel_s <= not rle_buf_sel_s;
|
rle_buf_sel_s <= not rle_buf_sel_s;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- mux for DC/AC ROM Luminance/Chrominance
|
-- mux for DC/AC ROM Luminance/Chrominance
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux : process(CLK, RST)
|
p_mux : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
VLC_size <= (others => '0');
|
VLC_size <= (others => '0');
|
VLC <= (others => '0');
|
VLC <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
-- DC
|
-- DC
|
if first_rle_word = '1' then
|
if first_rle_word = '1' then
|
-- luminance
|
-- luminance
|
if huf_sm_settings.cmp_idx = 0 then
|
if huf_sm_settings.cmp_idx = 0 then
|
VLC_size <= unsigned('0' & VLC_DC_size);
|
VLC_size <= unsigned('0' & VLC_DC_size);
|
VLC <= resize(VLC_DC, VLC'length);
|
VLC <= resize(VLC_DC, VLC'length);
|
-- chrominance
|
-- chrominance
|
else
|
else
|
VLC_size <= unsigned('0' & VLC_CR_DC_size);
|
VLC_size <= unsigned('0' & VLC_CR_DC_size);
|
VLC <= resize(VLC_CR_DC, VLC'length);
|
VLC <= resize(VLC_CR_DC, VLC'length);
|
end if;
|
end if;
|
-- AC
|
-- AC
|
else
|
else
|
-- luminance
|
-- luminance
|
if huf_sm_settings.cmp_idx = 0 then
|
if huf_sm_settings.cmp_idx = 0 then
|
VLC_size <= VLC_AC_size;
|
VLC_size <= VLC_AC_size;
|
VLC <= VLC_AC;
|
VLC <= VLC_AC;
|
-- chrominance
|
-- chrominance
|
else
|
else
|
VLC_size <= VLC_CR_AC_size;
|
VLC_size <= VLC_CR_AC_size;
|
VLC <= VLC_CR_AC;
|
VLC <= VLC_CR_AC;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Block Counter / Last Block detector
|
-- Block Counter / Last Block detector
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_blk_cnt : process(CLK, RST)
|
p_blk_cnt : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
image_area_size <= (others => '0');
|
image_area_size <= (others => '0');
|
last_block <= '0';
|
last_block <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
image_area_size <= unsigned(cmp_max)*
|
image_area_size <= unsigned(cmp_max)*
|
unsigned(img_size_x)*unsigned(img_size_y);
|
unsigned(img_size_x)*unsigned(img_size_y);
|
|
|
if sof = '1' then
|
if sof = '1' then
|
block_cnt <= (others => '0');
|
block_cnt <= (others => '0');
|
elsif start_pb = '1' then
|
elsif start_pb = '1' then
|
block_cnt <= block_cnt + 1;
|
block_cnt <= block_cnt + 1;
|
end if;
|
end if;
|
|
|
if block_cnt = image_area_size(33 downto 6) then
|
if block_cnt = image_area_size(33 downto 6) then
|
last_block <= '1';
|
last_block <= '1';
|
else
|
else
|
last_block <= '0';
|
last_block <= '0';
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
VLI_ext <= unsigned("0000" & VLI_d1);
|
VLI_ext <= unsigned("0000" & VLI_d1);
|
VLI_ext_size <= unsigned('0' & VLI_size_d1);
|
VLI_ext_size <= unsigned('0' & VLI_size_d1);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- delay line
|
-- delay line
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_vli_dly : process(CLK, RST)
|
p_vli_dly : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
VLI_d <= (others => '0');
|
VLI_d <= (others => '0');
|
VLI_size_d <= (others => '0');
|
VLI_size_d <= (others => '0');
|
VLI_d1 <= (others => '0');
|
VLI_d1 <= (others => '0');
|
VLI_size_d1 <= (others => '0');
|
VLI_size_d1 <= (others => '0');
|
d_val_d1 <= '0';
|
d_val_d1 <= '0';
|
d_val_d2 <= '0';
|
d_val_d2 <= '0';
|
d_val_d3 <= '0';
|
d_val_d3 <= '0';
|
d_val_d4 <= '0';
|
d_val_d4 <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
VLI_d1 <= VLI_r;
|
VLI_d1 <= VLI_r;
|
VLI_size_d1 <= VLI_size_r;
|
VLI_size_d1 <= VLI_size_r;
|
|
|
VLI_d <= VLI_d1;
|
VLI_d <= VLI_d1;
|
VLI_size_d <= VLI_size_d1;
|
VLI_size_d <= VLI_size_d1;
|
|
|
d_val_d1 <= d_val;
|
d_val_d1 <= d_val;
|
d_val_d2 <= d_val_d1;
|
d_val_d2 <= d_val_d1;
|
d_val_d3 <= d_val_d2;
|
d_val_d3 <= d_val_d2;
|
d_val_d4 <= d_val_d3;
|
d_val_d4 <= d_val_d3;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- HandleFifoWrites
|
-- HandleFifoWrites
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_HandleFifoWrites : process(CLK, RST)
|
p_HandleFifoWrites : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
ready_HFW <= '0';
|
ready_HFW <= '0';
|
fifo_wrt_cnt <= (others => '0');
|
fifo_wrt_cnt <= (others => '0');
|
fifo_wren <= '0';
|
fifo_wren <= '0';
|
fifo_wbyte <= (others => '0');
|
fifo_wbyte <= (others => '0');
|
rd_en_s <= '0';
|
rd_en_s <= '0';
|
start_pb_d1 <= '0';
|
start_pb_d1 <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
fifo_wren <= '0';
|
fifo_wren <= '0';
|
ready_HFW <= '0';
|
ready_HFW <= '0';
|
rd_en_s <= '0';
|
rd_en_s <= '0';
|
start_pb_d1 <= start_pb;
|
start_pb_d1 <= start_pb;
|
|
|
if start_pb_d1 = '1' then
|
if start_pb_d1 = '1' then
|
rd_en_s <= '1' and not rle_fifo_empty;
|
rd_en_s <= '1' and not rle_fifo_empty;
|
end if;
|
end if;
|
|
|
if HFW_running = '1' and ready_HFW = '0' then
|
if HFW_running = '1' and ready_HFW = '0' then
|
-- there is no at least one integer byte to write this time
|
-- there is no at least one integer byte to write this time
|
if num_fifo_wrs = 0 then
|
if num_fifo_wrs = 0 then
|
ready_HFW <= '1';
|
ready_HFW <= '1';
|
if state = RUN_VLI then
|
if state = RUN_VLI then
|
rd_en_s <= '1' and not rle_fifo_empty;
|
rd_en_s <= '1' and not rle_fifo_empty;
|
end if;
|
end if;
|
-- single byte write to FIFO
|
-- single byte write to FIFO
|
else
|
else
|
fifo_wrt_cnt <= fifo_wrt_cnt + 1;
|
fifo_wrt_cnt <= fifo_wrt_cnt + 1;
|
fifo_wren <= '1';
|
fifo_wren <= '1';
|
-- last byte write
|
-- last byte write
|
if fifo_wrt_cnt + 1 = num_fifo_wrs then
|
if fifo_wrt_cnt + 1 = num_fifo_wrs then
|
ready_HFW <= '1';
|
ready_HFW <= '1';
|
if state = RUN_VLI then
|
if state = RUN_VLI then
|
rd_en_s <= '1' and not rle_fifo_empty;
|
rd_en_s <= '1' and not rle_fifo_empty;
|
end if;
|
end if;
|
fifo_wrt_cnt <= (others => '0');
|
fifo_wrt_cnt <= (others => '0');
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
case fifo_wrt_cnt is
|
case fifo_wrt_cnt is
|
when "00" =>
|
when "00" =>
|
fifo_wbyte <= std_logic_vector(word_reg(C_M-1 downto C_M-8));
|
fifo_wbyte <= std_logic_vector(word_reg(C_M-1 downto C_M-8));
|
when "01" =>
|
when "01" =>
|
fifo_wbyte <= std_logic_vector(word_reg(C_M-8-1 downto C_M-16));
|
fifo_wbyte <= std_logic_vector(word_reg(C_M-8-1 downto C_M-16));
|
when others =>
|
when others =>
|
fifo_wbyte <= (others => '0');
|
fifo_wbyte <= (others => '0');
|
end case;
|
end case;
|
if pad_reg = '1' then
|
if pad_reg = '1' then
|
fifo_wbyte <= pad_byte;
|
fifo_wbyte <= pad_byte;
|
end if;
|
end if;
|
|
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- divide by 8
|
-- divide by 8
|
num_fifo_wrs <= bit_ptr(4 downto 3);
|
num_fifo_wrs <= bit_ptr(4 downto 3);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Variable Length Processor FSM
|
-- Variable Length Processor FSM
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_vlp : process(CLK, RST)
|
p_vlp : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
ready_pb <= '0';
|
ready_pb <= '0';
|
first_rle_word <= '0';
|
first_rle_word <= '0';
|
state <= IDLE;
|
state <= IDLE;
|
word_reg <= (others => '0');
|
word_reg <= (others => '0');
|
bit_ptr <= (others => '0');
|
bit_ptr <= (others => '0');
|
HFW_running <= '0';
|
HFW_running <= '0';
|
pad_reg <= '0';
|
pad_reg <= '0';
|
pad_byte <= (others => '0');
|
pad_byte <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
ready_pb <= '0';
|
ready_pb <= '0';
|
|
|
case state is
|
case state is
|
|
|
when IDLE =>
|
when IDLE =>
|
if start_pb = '1' then
|
if start_pb = '1' then
|
first_rle_word <= '1';
|
first_rle_word <= '1';
|
state <= RUN_VLC;
|
state <= RUN_VLC;
|
end if;
|
end if;
|
|
|
when RUN_VLC =>
|
when RUN_VLC =>
|
-- data valid DC or data valid AC
|
-- data valid DC or data valid AC
|
if (d_val_d1 = '1' and first_rle_word = '1') or
|
if (d_val_d1 = '1' and first_rle_word = '1') or
|
(d_val = '1' and first_rle_word = '0') then
|
(d_val = '1' and first_rle_word = '0') then
|
for i in 0 to C_M-1 loop
|
for i in 0 to C_M-1 loop
|
if i < to_integer(VLC_size) then
|
if i < to_integer(VLC_size) then
|
word_reg(C_M-1-to_integer(bit_ptr)-i) <= VLC(to_integer(VLC_size)-1-i);
|
word_reg(C_M-1-to_integer(bit_ptr)-i) <= VLC(to_integer(VLC_size)-1-i);
|
end if;
|
end if;
|
end loop;
|
end loop;
|
bit_ptr <= bit_ptr + resize(VLC_size,bit_ptr'length);
|
bit_ptr <= bit_ptr + resize(VLC_size,bit_ptr'length);
|
|
|
-- HandleFifoWrites
|
-- HandleFifoWrites
|
HFW_running <= '1';
|
HFW_running <= '1';
|
-- HandleFifoWrites completed
|
-- HandleFifoWrites completed
|
elsif HFW_running = '1' and
|
elsif HFW_running = '1' and
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
-- shift word reg left to skip bytes already written to FIFO
|
-- shift word reg left to skip bytes already written to FIFO
|
word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
|
word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
|
-- adjust bit pointer after some bytes were written to FIFO
|
-- adjust bit pointer after some bytes were written to FIFO
|
-- modulo 8 operation
|
-- modulo 8 operation
|
bit_ptr <= bit_ptr - (num_fifo_wrs & "000");
|
bit_ptr <= bit_ptr - (num_fifo_wrs & "000");
|
HFW_running <= '0';
|
HFW_running <= '0';
|
first_rle_word <= '0';
|
first_rle_word <= '0';
|
state <= RUN_VLI;
|
state <= RUN_VLI;
|
end if;
|
end if;
|
|
|
when RUN_VLI =>
|
when RUN_VLI =>
|
if HFW_running = '0' then
|
if HFW_running = '0' then
|
|
|
for i in 0 to C_M-1 loop
|
for i in 0 to C_M-1 loop
|
if i < to_integer(VLI_ext_size) then
|
if i < to_integer(VLI_ext_size) then
|
word_reg(C_M-1-to_integer(bit_ptr)-i)
|
word_reg(C_M-1-to_integer(bit_ptr)-i)
|
<= VLI_ext(to_integer(VLI_ext_size)-1-i);
|
<= VLI_ext(to_integer(VLI_ext_size)-1-i);
|
end if;
|
end if;
|
end loop;
|
end loop;
|
|
|
bit_ptr <= bit_ptr + resize(VLI_ext_size,bit_ptr'length);
|
bit_ptr <= bit_ptr + resize(VLI_ext_size,bit_ptr'length);
|
|
|
-- HandleFifoWrites
|
-- HandleFifoWrites
|
HFW_running <= '1';
|
HFW_running <= '1';
|
-- HandleFifoWrites completed
|
-- HandleFifoWrites completed
|
elsif HFW_running = '1' and
|
elsif HFW_running = '1' and
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
-- shift word reg left to skip bytes already written to FIFO
|
-- shift word reg left to skip bytes already written to FIFO
|
word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
|
word_reg <= shift_left(word_reg, to_integer(num_fifo_wrs & "000"));
|
-- adjust bit pointer after some bytes were written to FIFO
|
-- adjust bit pointer after some bytes were written to FIFO
|
-- modulo 8 operation
|
-- modulo 8 operation
|
bit_ptr <= bit_ptr - (num_fifo_wrs & "000");
|
bit_ptr <= bit_ptr - (num_fifo_wrs & "000");
|
HFW_running <= '0';
|
HFW_running <= '0';
|
|
|
-- end of block
|
-- end of block
|
if rle_fifo_empty = '1' then
|
if rle_fifo_empty = '1' then
|
-- end of segment
|
-- end of segment
|
if bit_ptr - (num_fifo_wrs & "000") /= 0 and last_block = '1' then
|
if bit_ptr - (num_fifo_wrs & "000") /= 0 and last_block = '1' then
|
state <= PAD;
|
state <= PAD;
|
else
|
else
|
ready_pb <= '1';
|
ready_pb <= '1';
|
state <= IDLE;
|
state <= IDLE;
|
end if;
|
end if;
|
else
|
else
|
state <= RUN_VLC;
|
state <= RUN_VLC;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- end of segment which requires bit padding
|
-- end of segment which requires bit padding
|
when PAD =>
|
when PAD =>
|
if HFW_running = '0' then
|
if HFW_running = '0' then
|
-- 1's bit padding to integer number of bytes
|
-- 1's bit padding to integer number of bytes
|
for i in 0 to 7 loop
|
for i in 0 to 7 loop
|
if i < bit_ptr then
|
if i < bit_ptr then
|
pad_byte(7-i) <= word_reg(C_M-1-i);
|
pad_byte(7-i) <= word_reg(C_M-1-i);
|
else
|
else
|
pad_byte(7-i) <= '1';
|
pad_byte(7-i) <= '1';
|
end if;
|
end if;
|
end loop;
|
end loop;
|
pad_reg <= '1';
|
pad_reg <= '1';
|
|
|
bit_ptr <= to_unsigned(8, bit_ptr'length);
|
bit_ptr <= to_unsigned(8, bit_ptr'length);
|
|
|
-- HandleFifoWrites
|
-- HandleFifoWrites
|
HFW_running <= '1';
|
HFW_running <= '1';
|
elsif HFW_running = '1' and
|
elsif HFW_running = '1' and
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
(num_fifo_wrs = 0 or fifo_wrt_cnt + 1 = num_fifo_wrs) then
|
bit_ptr <= (others => '0');
|
bit_ptr <= (others => '0');
|
HFW_running <= '0';
|
HFW_running <= '0';
|
pad_reg <= '0';
|
pad_reg <= '0';
|
|
|
ready_pb <= '1';
|
ready_pb <= '1';
|
state <= IDLE;
|
state <= IDLE;
|
end if;
|
end if;
|
|
|
when others =>
|
when others =>
|
|
|
end case;
|
end case;
|
|
|
if sof = '1' then
|
if sof = '1' then
|
bit_ptr <= (others => '0');
|
bit_ptr <= (others => '0');
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
end architecture RTL;
|
end architecture RTL;
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture: end
|
-- Architecture: end
|
|
|