Line 55... |
Line 55... |
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_block_cnt : in std_logic_vector(12 downto 0);
|
|
fdct_fifo_rd : in std_logic;
|
fdct_fifo_rd : in std_logic;
|
fdct_fifo_empty : out 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;
|
|
|
Line 70... |
Line 68... |
----------------------------------- ARCHITECTURE ------------------------------
|
----------------------------------- ARCHITECTURE ------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
architecture RTL of BUF_FIFO is
|
architecture RTL of BUF_FIFO is
|
|
|
constant C_NUM_SUBF : integer := C_MAX_LINE_WIDTH/8;
|
|
|
|
constant C_SUBF_ADDRW : integer := 7-C_MEMORY_OPTIMIZED;
|
|
--constant C_LOG2_NUM_SUBF : integer := integer(log2(real(C_NUM_SUBF)));
|
|
|
|
type T_DATA_ARR is array (0 to C_NUM_SUBF-1) of std_logic_vector(23 downto 0);
|
|
type T_CNT_ARR is array (0 to C_NUM_SUBF-1) of
|
|
std_logic_vector(C_SUBF_ADDRW downto 0);
|
|
|
|
type T_FIFO_RAMADDR is array (0 to C_NUM_SUBF-1) of
|
|
STD_LOGIC_VECTOR(C_SUBF_ADDRW-1 downto 0);
|
|
|
|
signal fifo_rd : std_logic_vector(C_NUM_SUBF-1 downto 0);
|
|
signal fifo_wr : std_logic_vector(C_NUM_SUBF-1 downto 0);
|
|
signal fifo_data : std_logic_vector(C_PIXEL_BITS-1 downto 0);
|
|
signal fifo_data_d1 : std_logic_vector(C_PIXEL_BITS-1 downto 0);
|
|
signal fifo_full : std_logic_vector(C_NUM_SUBF-1 downto 0);
|
|
signal fifo_empty : std_logic_vector(C_NUM_SUBF-1 downto 0);
|
|
signal fifo_half_full : std_logic_vector(C_NUM_SUBF-1 downto 0);
|
|
signal fifo_count : T_CNT_ARR;
|
|
|
|
signal pixel_cnt : unsigned(15 downto 0);
|
signal pixel_cnt : unsigned(15 downto 0);
|
signal wblock_cnt : unsigned(12 downto 0);
|
signal line_cnt : unsigned(15 downto 0);
|
signal last_idx : unsigned(12 downto 0);
|
|
signal idx_reg : unsigned(log2(C_NUM_SUBF)-1 downto 0);
|
|
signal wr_idx_reg : unsigned(log2(C_NUM_SUBF)-1 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 : STD_LOGIC_VECTOR
|
signal ramwaddr : unsigned(log2(C_MAX_LINE_WIDTH*8)-1 downto 0);
|
(log2(C_NUM_SUBF)+C_SUBF_ADDRW-1 downto 0);
|
|
signal ramwaddr_offset : unsigned(C_SUBF_ADDRW-1 downto 0);
|
|
signal ramwaddr_base : unsigned(log2(C_NUM_SUBF)+C_SUBF_ADDRW downto 0);
|
|
signal ramenw : STD_LOGIC;
|
signal ramenw : STD_LOGIC;
|
signal ramenw_m1 : STD_LOGIC;
|
signal ramraddr : unsigned(log2(C_MAX_LINE_WIDTH*8)-1 downto 0);
|
signal ramenw_m2 : STD_LOGIC;
|
|
signal ramraddr : STD_LOGIC_VECTOR
|
signal pix_inblk_cnt : unsigned(7 downto 0);
|
(log2(C_NUM_SUBF)+C_SUBF_ADDRW-1 downto 0);
|
signal line_inblk_cnt : unsigned(7 downto 0);
|
signal ramraddr_base : unsigned(log2(C_NUM_SUBF)+C_SUBF_ADDRW downto 0);
|
|
signal ramraddr_offset : unsigned(C_SUBF_ADDRW-1 downto 0);
|
signal read_block_cnt : unsigned(12 downto 0);
|
signal ramenr : STD_LOGIC;
|
signal write_block_cnt : unsigned(12 downto 0);
|
|
|
signal fifo_ramwaddr : T_FIFO_RAMADDR;
|
signal ramraddr_int : unsigned(23 downto 0);
|
signal fifo_ramenw : STD_LOGIC_VECTOR(C_NUM_SUBF-1 downto 0);
|
signal raddr_base_line : unsigned(23 downto 0);
|
signal fifo_ramraddr : T_FIFO_RAMADDR;
|
signal raddr_tmp : unsigned(15 downto 0);
|
signal fifo_ramenr : STD_LOGIC_VECTOR(C_NUM_SUBF-1 downto 0);
|
signal ramwaddr_d1 : unsigned(log2(C_MAX_LINE_WIDTH*8)-1 downto 0);
|
|
|
|
signal block_lock : unsigned(C_MAX_LINE_WIDTH/8-1 downto 0);
|
|
|
signal offset_ramwaddr : STD_LOGIC_VECTOR(C_SUBF_ADDRW-1 downto 0);
|
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
-- Architecture: begin
|
-- Architecture: begin
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
begin
|
begin
|
|
|
-------------------------------------------------------------------
|
|
-- SUB_FIFOs
|
|
-------------------------------------------------------------------
|
|
G_SUB_FIFO : for i in 0 to C_NUM_SUBF-1 generate
|
|
|
|
U_SUB_FIFO : entity work.SUB_FIFO
|
|
generic map
|
|
(
|
|
DATA_WIDTH => C_PIXEL_BITS,
|
|
ADDR_WIDTH => C_SUBF_ADDRW
|
|
)
|
|
port map
|
|
(
|
|
rst => RST,
|
|
clk => CLK,
|
|
rinc => fifo_rd(i),
|
|
winc => fifo_wr(i),
|
|
|
|
fullo => fifo_full(i),
|
|
emptyo => fifo_empty(i),
|
|
count => fifo_count(i),
|
|
|
|
ramwaddr => fifo_ramwaddr(i),
|
|
ramenw => fifo_ramenw(i),
|
|
ramraddr => fifo_ramraddr(i),
|
|
ramenr => fifo_ramenr(i)
|
|
);
|
|
end generate G_SUB_FIFO;
|
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- 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_NUM_SUBF)+C_SUBF_ADDRW,
|
RAMADDR_W => log2(C_MAX_LINE_WIDTH*8),
|
RAMDATA_W => C_PIXEL_BITS
|
RAMDATA_W => C_PIXEL_BITS
|
)
|
)
|
port map
|
port map
|
(
|
(
|
d => ramd,
|
d => ramd,
|
waddr => ramwaddr,
|
waddr => std_logic_vector(ramwaddr_d1),
|
raddr => ramraddr,
|
raddr => std_logic_vector(ramraddr),
|
we => ramenw,
|
we => ramenw,
|
clk => clk,
|
clk => clk,
|
|
|
q => ramq
|
q => ramq
|
);
|
);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- FIFO almost full
|
-- register RAM data input
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_fifo_almost_full : process(CLK, RST)
|
p_mux1 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
fifo_almost_full <= '1';
|
ramenw <= '0';
|
last_idx <= (others => '0');
|
ramd <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
if img_size_x = (img_size_x'range => '0') then
|
ramd <= iram_wdata;
|
last_idx <= (others => '0');
|
ramenw <= iram_wren;
|
else
|
|
last_idx <= unsigned(img_size_x(15 downto 3))-1;
|
|
end if;
|
|
|
|
if C_MEMORY_OPTIMIZED = 0 then
|
|
if unsigned(fifo_count(to_integer(wblock_cnt))) > to_unsigned(128-2*8,8) then
|
|
fifo_almost_full <= '1';
|
|
else
|
|
fifo_almost_full <= '0';
|
|
end if;
|
|
else
|
|
if unsigned(fifo_count(to_integer(wblock_cnt))) >= to_unsigned(62,8) then
|
|
fifo_almost_full <= '1';
|
|
-- due to FIFO full latency next subFIFO is in danger of being
|
|
-- overwritten thus its fifo full must be checked ahead
|
|
else
|
|
-- next=0 when current is last
|
|
if wblock_cnt = last_idx then
|
|
-- latency from FIFO full till it is recognized by Host is 2T (64-2)=62
|
|
if unsigned(fifo_count(0)) >= to_unsigned(62,8) then
|
|
fifo_almost_full <= '1';
|
|
else
|
|
fifo_almost_full <= '0';
|
|
end if;
|
|
-- next is just current+1
|
|
else
|
|
-- latency from FIFO full till it is recognized by Host is 2T (64-2)=62
|
|
if unsigned(fifo_count(to_integer(wblock_cnt)+1)) >= to_unsigned(62,8) then
|
|
fifo_almost_full <= '1';
|
|
else
|
|
fifo_almost_full <= '0';
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
end if;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- pixel_cnt
|
-- 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');
|
|
line_cnt <= (others => '0');
|
|
ramwaddr <= (others => '0');
|
|
ramwaddr_d1 <= (others => '0');
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
|
ramwaddr_d1 <= ramwaddr;
|
|
|
if iram_wren = '1' then
|
if iram_wren = '1' then
|
|
-- pixel index in 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');
|
|
-- line counter
|
|
line_cnt <= line_cnt + 1;
|
|
-- RAM is only 8 lines buffer
|
|
if line_cnt(2 downto 0) = 8-1 then
|
|
ramwaddr <= (others => '0');
|
|
else
|
|
ramwaddr <= ramwaddr + 1;
|
|
end if;
|
else
|
else
|
pixel_cnt <= pixel_cnt + 1;
|
pixel_cnt <= pixel_cnt + 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');
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
wblock_cnt <= pixel_cnt(pixel_cnt'high downto 3);
|
write_block_cnt <= pixel_cnt(15 downto 3);
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- FIFO half full
|
-- lock written blocks, unlock after read
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_half_full : process(CLK, RST)
|
p_mux6 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
for i in 0 to C_NUM_SUBF-1 loop
|
block_lock <= (others => '0');
|
fifo_half_full(i) <= '0';
|
|
end loop;
|
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
for i in 0 to C_NUM_SUBF-1 loop
|
if pixel_cnt(2 downto 0) = 8-1 then
|
if C_MEMORY_OPTIMIZED = 0 then
|
if line_cnt(2 downto 0) = 8-1 then
|
if unsigned(fifo_count(i)) >= 64 then
|
block_lock(to_integer(write_block_cnt)) <= '1';
|
fifo_half_full(i) <= '1';
|
end if;
|
else
|
end if;
|
fifo_half_full(i) <= '0';
|
|
|
if pix_inblk_cnt = 8-1 then
|
|
if line_inblk_cnt = 8-1 then
|
|
block_lock(to_integer(read_block_cnt)) <= '0';
|
end if;
|
end if;
|
else
|
|
fifo_half_full(i) <= fifo_full(i);
|
|
end if;
|
end if;
|
end loop;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Mux1
|
-- FIFO half full / almost full flag generation
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux1 : process(CLK, RST)
|
p_mux3 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
for i in 0 to C_NUM_SUBF-1 loop
|
fdct_fifo_hf_full <= '0';
|
fifo_wr(i) <= '0';
|
fifo_almost_full <= '0';
|
end loop;
|
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
for i in 0 to C_NUM_SUBF-1 loop
|
|
if wblock_cnt(log2(C_NUM_SUBF)-1 downto 0) = i then
|
if block_lock(to_integer(read_block_cnt)) = '1' then
|
fifo_wr(i) <= iram_wren;
|
fdct_fifo_hf_full <= '1';
|
|
else
|
|
fdct_fifo_hf_full <= '0';
|
|
end if;
|
|
|
|
if write_block_cnt = unsigned(img_size_x(15 downto 3))-1 then
|
|
if block_lock(0) = '1' then
|
|
fifo_almost_full <= '1';
|
else
|
else
|
fifo_wr(i) <= '0';
|
fifo_almost_full <= '0';
|
|
end if;
|
|
elsif block_lock(to_integer(write_block_cnt+1)) = '1' then
|
|
fifo_almost_full <= '1';
|
|
else
|
|
fifo_almost_full <= '0';
|
end if;
|
end if;
|
end loop;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Mux2
|
-- read side
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
p_mux2 : process(CLK, RST)
|
p_mux5 : process(CLK, RST)
|
begin
|
begin
|
if RST = '1' then
|
if RST = '1' then
|
for i in 0 to C_NUM_SUBF-1 loop
|
read_block_cnt <= (others => '0');
|
fifo_rd(i) <= '0';
|
pix_inblk_cnt <= (others => '0');
|
end loop;
|
line_inblk_cnt <= (others => '0');
|
fdct_fifo_empty <= '0';
|
|
fdct_fifo_hf_full <= '0';
|
|
idx_reg <= (others => '0');
|
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
idx_reg <= unsigned(fdct_block_cnt(log2(C_NUM_SUBF)-1 downto 0));
|
if fdct_fifo_rd = '1' then
|
|
if pix_inblk_cnt = 8-1 then
|
for i in 0 to C_NUM_SUBF-1 loop
|
pix_inblk_cnt <= (others => '0');
|
if idx_reg = i then
|
if line_inblk_cnt = 8-1 then
|
fifo_rd(i) <= fdct_fifo_rd;
|
line_inblk_cnt <= (others => '0');
|
|
if read_block_cnt = unsigned(img_size_x(15 downto 3))-1 then
|
|
read_block_cnt <= (others => '0');
|
|
else
|
|
read_block_cnt <= read_block_cnt + 1;
|
|
end if;
|
|
else
|
|
line_inblk_cnt <= line_inblk_cnt + 1;
|
|
end if;
|
else
|
else
|
fifo_rd(i) <= '0';
|
pix_inblk_cnt <= pix_inblk_cnt + 1;
|
|
end if;
|
end if;
|
end if;
|
end loop;
|
|
|
|
fdct_fifo_empty <= fifo_empty(to_integer(idx_reg));
|
if sof = '1' then
|
fdct_fifo_hf_full <= fifo_half_full(to_integer(idx_reg));
|
read_block_cnt <= (others => '0');
|
|
pix_inblk_cnt <= (others => '0');
|
|
line_inblk_cnt <= (others => '0');
|
end if;
|
end if;
|
end process;
|
|
|
|
|
end if;
|
|
end process;
|
|
|
|
-- 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));
|
|
|
-------------------------------------------------------------------
|
|
-- Mux3
|
|
-------------------------------------------------------------------
|
|
p_mux3 : process(CLK, RST)
|
|
begin
|
|
if RST = '1' then
|
|
ramwaddr <= (others => '0');
|
|
ramwaddr_offset <= (others => '0');
|
|
ramwaddr_base <= (others => '0');
|
|
ramenw <= '0';
|
|
ramenw_m1 <= '0';
|
|
wr_idx_reg <= (others => '0');
|
|
ramd <= (others => '0');
|
|
fifo_data <= (others => '0');
|
|
fifo_data_d1 <= (others => '0');
|
|
elsif CLK'event and CLK = '1' then
|
|
wr_idx_reg <= unsigned(wblock_cnt(log2(C_NUM_SUBF)-1 downto 0));
|
|
|
|
fifo_data <= iram_wdata;
|
ramraddr <= ramraddr_int(ramraddr'range);
|
fifo_data_d1 <= fifo_data;
|
|
ramd <= fifo_data_d1;
|
|
|
|
ramenw_m1 <= fifo_ramenw(to_integer(wr_idx_reg));
|
|
ramenw <= ramenw_m1;
|
|
|
|
ramwaddr_offset <= unsigned(fifo_ramwaddr(to_integer(wr_idx_reg)));
|
|
ramwaddr_base <= to_unsigned(2**C_SUBF_ADDRW, C_SUBF_ADDRW+1) *
|
|
wr_idx_reg;
|
|
ramwaddr <= std_logic_vector(ramwaddr_base(ramwaddr'range) +
|
|
resize(ramwaddr_offset, ramwaddr'length));
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Mux4
|
-- 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 <= (others => '0');
|
ramraddr_int <= (others => '0');
|
ramraddr_base <= (others => '0');
|
|
ramraddr_offset <= (others => '0');
|
|
elsif CLK'event and CLK = '1' then
|
elsif CLK'event and CLK = '1' then
|
ramraddr_offset <= unsigned(fifo_ramraddr(to_integer(idx_reg)));
|
raddr_base_line <= line_inblk_cnt * unsigned(img_size_x);
|
ramraddr_base <= to_unsigned(2**C_SUBF_ADDRW, C_SUBF_ADDRW+1) *
|
raddr_tmp <= (read_block_cnt & "000") + pix_inblk_cnt;
|
idx_reg;
|
|
ramraddr <= std_logic_vector(ramraddr_base(ramraddr'range) +
|
ramraddr_int <= raddr_tmp + raddr_base_line;
|
resize(unsigned(ramraddr_offset), ramraddr'length));
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end architecture RTL;
|
end architecture RTL;
|
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|