-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- File Name : BUF_FIFO.vhd
|
-- File Name : BUF_FIFO.vhd
|
--
|
--
|
-- Project : JPEG_ENC
|
-- Project : JPEG_ENC
|
--
|
--
|
-- Module : BUF_FIFO
|
-- Module : BUF_FIFO
|
--
|
--
|
-- Content : Input FIFO Buffer
|
-- Content : Input FIFO Buffer
|
--
|
--
|
-- Description :
|
-- Description :
|
--
|
--
|
-- Spec. :
|
-- Spec. :
|
--
|
--
|
-- Author : Michal Krepa
|
-- Author : Michal Krepa
|
--
|
--
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- History :
|
-- History :
|
-- 20090311: (MK): Initial Creation.
|
-- 20090311: (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 BUF_FIFO is
|
entity BUF_FIFO is
|
port
|
port
|
(
|
(
|
CLK : in std_logic;
|
CLK : in std_logic;
|
RST : in std_logic;
|
RST : in std_logic;
|
-- HOST PROG
|
-- HOST PROG
|
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);
|
sof : in std_logic;
|
sof : in std_logic;
|
|
|
-- HOST DATA
|
-- HOST DATA
|
iram_wren : in std_logic;
|
iram_wren : in std_logic;
|
iram_wdata : in std_logic_vector(C_PIXEL_BITS-1 downto 0);
|
iram_wdata : in std_logic_vector(C_PIXEL_BITS-1 downto 0);
|
fifo_almost_full : out std_logic;
|
fifo_almost_full : out std_logic;
|
|
|
-- FDCT
|
-- FDCT
|
fdct_fifo_rd : in std_logic;
|
fdct_fifo_rd : in std_logic;
|
fdct_fifo_q : out std_logic_vector(23 downto 0);
|
fdct_fifo_q : out std_logic_vector(23 downto 0);
|
fdct_fifo_hf_full : out std_logic
|
fdct_fifo_hf_full : out std_logic
|
);
|
);
|
end entity BUF_FIFO;
|
end entity BUF_FIFO;
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
----------------------------------- ARCHITECTURE ------------------------------
|
----------------------------------- ARCHITECTURE ------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
architecture RTL of BUF_FIFO is
|
architecture RTL of BUF_FIFO is
|
|
|
|
|
constant C_NUM_LINES : integer := 8 + C_EXTRA_LINES;
|
constant C_NUM_LINES : integer := 8 + C_EXTRA_LINES;
|
|
|
signal pixel_cnt : unsigned(15 downto 0);
|
signal pixel_cnt : unsigned(15 downto 0);
|
signal line_cnt : unsigned(15 downto 0);
|
signal line_cnt : unsigned(15 downto 0);
|
|
|
signal ramq : STD_LOGIC_VECTOR(C_PIXEL_BITS-1 downto 0);
|
signal ramq : STD_LOGIC_VECTOR(C_PIXEL_BITS-1 downto 0);
|
signal ramd : STD_LOGIC_VECTOR(C_PIXEL_BITS-1 downto 0);
|
signal ramd : STD_LOGIC_VECTOR(C_PIXEL_BITS-1 downto 0);
|
signal ramwaddr : unsigned(log2(C_MAX_LINE_WIDTH*C_NUM_LINES)-1 downto 0);
|
signal ramwaddr : unsigned(log2(C_MAX_LINE_WIDTH*C_NUM_LINES)-1 downto 0);
|
signal ramenw : STD_LOGIC;
|
signal ramenw : STD_LOGIC;
|
signal ramraddr : unsigned(log2(C_MAX_LINE_WIDTH*C_NUM_LINES)-1 downto 0);
|
signal ramraddr : unsigned(log2(C_MAX_LINE_WIDTH*C_NUM_LINES)-1 downto 0);
|
|
|
signal pix_inblk_cnt : unsigned(2 downto 0);
|
signal pix_inblk_cnt : unsigned(3 downto 0);
|
signal pix_inblk_cnt_d1 : unsigned(2 downto 0);
|
signal pix_inblk_cnt_d1 : unsigned(3 downto 0);
|
signal line_inblk_cnt : unsigned(2 downto 0);
|
signal line_inblk_cnt : unsigned(2 downto 0);
|
|
|
signal read_block_cnt : unsigned(12 downto 0);
|
signal read_block_cnt : unsigned(12 downto 0);
|
signal read_block_cnt_d1 : unsigned(12 downto 0);
|
signal read_block_cnt_d1 : unsigned(12 downto 0);
|
signal write_block_cnt : unsigned(12 downto 0);
|
signal write_block_cnt : unsigned(12 downto 0);
|
|
|
signal ramraddr_int : unsigned(16+log2(C_NUM_LINES)-1 downto 0);
|
signal ramraddr_int : unsigned(16+log2(C_NUM_LINES)-1 downto 0);
|
signal raddr_base_line : unsigned(16+log2(C_NUM_LINES)-1 downto 0);
|
signal raddr_base_line : unsigned(16+log2(C_NUM_LINES)-1 downto 0);
|
signal raddr_tmp : unsigned(15 downto 0);
|
signal raddr_tmp : unsigned(15 downto 0);
|
signal ramwaddr_d1 : unsigned(ramwaddr'range);
|
signal ramwaddr_d1 : unsigned(ramwaddr'range);
|
|
|
signal line_lock : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
signal line_lock : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
|
|
signal memwr_line_cnt : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
signal memwr_line_cnt : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
|
|
signal memrd_offs_cnt : unsigned(log2(C_NUM_LINES)-1+1 downto 0);
|
signal memrd_offs_cnt : unsigned(log2(C_NUM_LINES)-1+1 downto 0);
|
signal memrd_line : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
signal memrd_line : unsigned(log2(C_NUM_LINES)-1 downto 0);
|
|
|
signal wr_line_idx : unsigned(15 downto 0);
|
signal wr_line_idx : unsigned(15 downto 0);
|
signal rd_line_idx : unsigned(15 downto 0);
|
signal rd_line_idx : unsigned(15 downto 0);
|
|
|
signal image_write_end : std_logic;
|
signal image_write_end : std_logic;
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture: begin
|
-- Architecture: begin
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
begin
|
begin
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- RAM for SUB_FIFOs
|
-- RAM for SUB_FIFOs
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
U_SUB_RAMZ : entity work.SUB_RAMZ
|
U_SUB_RAMZ : entity work.SUB_RAMZ
|
generic map
|
generic map
|
(
|
(
|
RAMADDR_W => log2( C_MAX_LINE_WIDTH*C_NUM_LINES ),
|
RAMADDR_W => log2( C_MAX_LINE_WIDTH*C_NUM_LINES ),
|
RAMDATA_W => C_PIXEL_BITS
|
RAMDATA_W => C_PIXEL_BITS
|
)
|
)
|
port map
|
port map
|
(
|
(
|
d => ramd,
|
d => ramd,
|
waddr => std_logic_vector(ramwaddr_d1),
|
waddr => std_logic_vector(ramwaddr_d1),
|
raddr => std_logic_vector(ramraddr),
|
raddr => std_logic_vector(ramraddr),
|
we => ramenw,
|
we => ramenw,
|
clk => clk,
|
clk => clk,
|
|
|
q => ramq
|
q => ramq
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- register RAM data input
|
-- register RAM data input
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux1 : process(CLK, RST)
|
p_mux1 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
ramenw <= '0';
|
ramenw <= '0';
|
ramd <= (others => '0');
|
ramd <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
ramd <= iram_wdata;
|
ramd <= iram_wdata;
|
ramenw <= iram_wren;
|
ramenw <= iram_wren;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- resolve RAM write address
|
-- resolve RAM write address
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_pixel_cnt : process(CLK, RST)
|
p_pixel_cnt : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
pixel_cnt <= (others => '0');
|
pixel_cnt <= (others => '0');
|
memwr_line_cnt <= (others => '0');
|
memwr_line_cnt <= (others => '0');
|
wr_line_idx <= (others => '0');
|
wr_line_idx <= (others => '0');
|
ramwaddr <= (others => '0');
|
ramwaddr <= (others => '0');
|
ramwaddr_d1 <= (others => '0');
|
ramwaddr_d1 <= (others => '0');
|
image_write_end <= '0';
|
image_write_end <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
ramwaddr_d1 <= ramwaddr;
|
ramwaddr_d1 <= ramwaddr;
|
|
|
if iram_wren = '1' then
|
if iram_wren = '1' then
|
-- end of line
|
-- end of line
|
if pixel_cnt = unsigned(img_size_x)-1 then
|
if pixel_cnt = unsigned(img_size_x)-1 then
|
pixel_cnt <= (others => '0');
|
pixel_cnt <= (others => '0');
|
-- absolute write line index
|
-- absolute write line index
|
wr_line_idx <= wr_line_idx + 1;
|
wr_line_idx <= wr_line_idx + 1;
|
|
|
if wr_line_idx = unsigned(img_size_y)-1 then
|
if wr_line_idx = unsigned(img_size_y)-1 then
|
image_write_end <= '1';
|
image_write_end <= '1';
|
end if;
|
end if;
|
|
|
-- memory line index
|
-- memory line index
|
if memwr_line_cnt = C_NUM_LINES-1 then
|
if memwr_line_cnt = C_NUM_LINES-1 then
|
memwr_line_cnt <= (others => '0');
|
memwr_line_cnt <= (others => '0');
|
ramwaddr <= (others => '0');
|
ramwaddr <= (others => '0');
|
else
|
else
|
memwr_line_cnt <= memwr_line_cnt + 1;
|
memwr_line_cnt <= memwr_line_cnt + 1;
|
ramwaddr <= ramwaddr + 1;
|
ramwaddr <= ramwaddr + 1;
|
end if;
|
end if;
|
else
|
else
|
pixel_cnt <= pixel_cnt + 1;
|
pixel_cnt <= pixel_cnt + 1;
|
ramwaddr <= ramwaddr + 1;
|
ramwaddr <= ramwaddr + 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if sof = '1' then
|
if sof = '1' then
|
pixel_cnt <= (others => '0');
|
pixel_cnt <= (others => '0');
|
ramwaddr <= (others => '0');
|
ramwaddr <= (others => '0');
|
memwr_line_cnt <= (others => '0');
|
memwr_line_cnt <= (others => '0');
|
wr_line_idx <= (others => '0');
|
wr_line_idx <= (others => '0');
|
image_write_end <= '0';
|
image_write_end <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- FIFO half full / almost full flag generation
|
-- FIFO half full / almost full flag generation
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux3 : process(CLK, RST)
|
p_mux3 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
fdct_fifo_hf_full <= '0';
|
fdct_fifo_hf_full <= '0';
|
fifo_almost_full <= '0';
|
fifo_almost_full <= '0';
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
|
|
if rd_line_idx + 8 <= wr_line_idx then
|
if rd_line_idx + 8 <= wr_line_idx then
|
fdct_fifo_hf_full <= '1';
|
fdct_fifo_hf_full <= '1';
|
else
|
else
|
fdct_fifo_hf_full <= '0';
|
fdct_fifo_hf_full <= '0';
|
end if;
|
end if;
|
|
|
fifo_almost_full <= '0';
|
fifo_almost_full <= '0';
|
if C_EXTRA_LINES = 0 then
|
|
if wr_line_idx = rd_line_idx + C_NUM_LINES-1 then
|
if wr_line_idx = rd_line_idx + C_NUM_LINES-1 then
|
if pixel_cnt >= unsigned(img_size_x)-1-1 then
|
if pixel_cnt >= unsigned(img_size_x)-1-1 then
|
fifo_almost_full <= '1';
|
fifo_almost_full <= '1';
|
end if;
|
end if;
|
elsif wr_line_idx > rd_line_idx + C_NUM_LINES-1 then
|
elsif wr_line_idx > rd_line_idx + C_NUM_LINES-1 then
|
fifo_almost_full <= '1';
|
fifo_almost_full <= '1';
|
end if;
|
end if;
|
else
|
|
if wr_line_idx > rd_line_idx + C_NUM_LINES-1 then
|
|
fifo_almost_full <= '1';
|
|
end if;
|
|
end if;
|
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- read side
|
-- read side
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux5 : process(CLK, RST)
|
p_mux5 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
memrd_offs_cnt <= (others => '0');
|
memrd_offs_cnt <= (others => '0');
|
read_block_cnt <= (others => '0');
|
read_block_cnt <= (others => '0');
|
pix_inblk_cnt <= (others => '0');
|
pix_inblk_cnt <= (others => '0');
|
line_inblk_cnt <= (others => '0');
|
line_inblk_cnt <= (others => '0');
|
rd_line_idx <= (others => '0');
|
rd_line_idx <= (others => '0');
|
pix_inblk_cnt_d1 <= (others => '0');
|
pix_inblk_cnt_d1 <= (others => '0');
|
read_block_cnt_d1 <= (others => '0');
|
read_block_cnt_d1 <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
pix_inblk_cnt_d1 <= pix_inblk_cnt;
|
pix_inblk_cnt_d1 <= pix_inblk_cnt;
|
read_block_cnt_d1 <= read_block_cnt;
|
read_block_cnt_d1 <= read_block_cnt;
|
|
|
-- BUF FIFO read
|
-- BUF FIFO read
|
if fdct_fifo_rd = '1' then
|
if fdct_fifo_rd = '1' then
|
-- last pixel in block
|
-- last pixel in block
|
if pix_inblk_cnt = 8-1 then
|
if pix_inblk_cnt = 8-1 then
|
pix_inblk_cnt <= (others => '0');
|
pix_inblk_cnt <= (others => '0');
|
|
|
-- last line in 8
|
-- last line in 8
|
if line_inblk_cnt = 8-1 then
|
if line_inblk_cnt = 8-1 then
|
line_inblk_cnt <= (others => '0');
|
line_inblk_cnt <= (others => '0');
|
|
|
-- last block in last line
|
-- last block in last line
|
if read_block_cnt = unsigned(img_size_x(15 downto 3))-1 then
|
if read_block_cnt = unsigned(img_size_x(15 downto 3))-1 then
|
read_block_cnt <= (others => '0');
|
read_block_cnt <= (others => '0');
|
rd_line_idx <= rd_line_idx + 8;
|
rd_line_idx <= rd_line_idx + 8;
|
if memrd_offs_cnt + 8 > C_NUM_LINES-1 then
|
if memrd_offs_cnt + 8 > C_NUM_LINES-1 then
|
memrd_offs_cnt <= memrd_offs_cnt + 8 - C_NUM_LINES;
|
memrd_offs_cnt <= memrd_offs_cnt + 8 - C_NUM_LINES;
|
else
|
else
|
memrd_offs_cnt <= memrd_offs_cnt + 8;
|
memrd_offs_cnt <= memrd_offs_cnt + 8;
|
end if;
|
end if;
|
else
|
else
|
read_block_cnt <= read_block_cnt + 1;
|
read_block_cnt <= read_block_cnt + 1;
|
end if;
|
end if;
|
else
|
else
|
line_inblk_cnt <= line_inblk_cnt + 1;
|
line_inblk_cnt <= line_inblk_cnt + 1;
|
end if;
|
end if;
|
|
|
else
|
else
|
pix_inblk_cnt <= pix_inblk_cnt + 1;
|
pix_inblk_cnt <= pix_inblk_cnt + 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if memrd_offs_cnt + (line_inblk_cnt) > C_NUM_LINES-1 then
|
if memrd_offs_cnt + (line_inblk_cnt) > C_NUM_LINES-1 then
|
memrd_line <= memrd_offs_cnt(memrd_line'range) + (line_inblk_cnt) - (C_NUM_LINES);
|
memrd_line <= memrd_offs_cnt(memrd_line'range) + (line_inblk_cnt) - (C_NUM_LINES);
|
else
|
else
|
memrd_line <= memrd_offs_cnt(memrd_line'range) + (line_inblk_cnt);
|
memrd_line <= memrd_offs_cnt(memrd_line'range) + (line_inblk_cnt);
|
end if;
|
end if;
|
|
|
if sof = '1' then
|
if sof = '1' then
|
memrd_line <= (others => '0');
|
memrd_line <= (others => '0');
|
memrd_offs_cnt <= (others => '0');
|
memrd_offs_cnt <= (others => '0');
|
read_block_cnt <= (others => '0');
|
read_block_cnt <= (others => '0');
|
pix_inblk_cnt <= (others => '0');
|
pix_inblk_cnt <= (others => '0');
|
line_inblk_cnt <= (others => '0');
|
line_inblk_cnt <= (others => '0');
|
rd_line_idx <= (others => '0');
|
rd_line_idx <= (others => '0');
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- generate RAM data output based on 16 or 24 bit mode selection
|
-- generate RAM data output based on 16 or 24 bit mode selection
|
fdct_fifo_q <= (ramq(15 downto 11) & "000" &
|
fdct_fifo_q <= (ramq(15 downto 11) & "000" &
|
ramq(10 downto 5) & "00" &
|
ramq(10 downto 5) & "00" &
|
ramq(4 downto 0) & "000") when C_PIXEL_BITS = 16 else
|
ramq(4 downto 0) & "000") when C_PIXEL_BITS = 16 else
|
std_logic_vector(resize(unsigned(ramq), 24));
|
std_logic_vector(resize(unsigned(ramq), 24));
|
|
|
|
|
ramraddr <= ramraddr_int(ramraddr'range);
|
ramraddr <= ramraddr_int(ramraddr'range);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- resolve RAM read address
|
-- resolve RAM read address
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux4 : process(CLK, RST)
|
p_mux4 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
ramraddr_int <= (others => '0');
|
ramraddr_int <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
raddr_base_line <= (memrd_line) * unsigned(img_size_x);
|
raddr_base_line <= (memrd_line) * unsigned(img_size_x);
|
raddr_tmp <= (read_block_cnt_d1 & "000") + pix_inblk_cnt_d1;
|
raddr_tmp <= (read_block_cnt_d1 & "000") + pix_inblk_cnt_d1;
|
|
|
ramraddr_int <= raddr_tmp + raddr_base_line;
|
ramraddr_int <= raddr_tmp + raddr_base_line;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end architecture RTL;
|
end architecture RTL;
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture: end
|
-- Architecture: end
|
|
|