📄 huffman.vhd
字号:
-- 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 + -