OpenCores
URL https://opencores.org/ocsvn/video_dithering/video_dithering/trunk

Subversion Repositories video_dithering

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /video_dithering/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/dither.vhd
0,0 → 1,117
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity eDither is
generic
(
img_width : integer := 512;
img_height : integer := 512;
color_width : integer := 8;
reduced_width : integer := 4
);
port
(
clk : in std_logic;
enable : in std_logic;
x : in integer range 0 to img_width-1;
din_r : in std_logic_vector(color_width-1 downto 0);
din_g : in std_logic_vector(color_width-1 downto 0);
din_b : in std_logic_vector(color_width-1 downto 0);
dout_r : out std_logic_vector(color_width-1 downto 0) := (others => '0');
dout_g : out std_logic_vector(color_width-1 downto 0) := (others => '0');
dout_b : out std_logic_vector(color_width-1 downto 0) := (others => '0')
);
end entity;
 
architecture arch of eDither is
constant dither_bits : integer := color_width - reduced_width;
 
-- intermediate signals for caclulation
type t_dither_rgb is array(1 to 3) of unsigned(dither_bits-1 downto 0);
signal dither_buffer_next : t_dither_rgb := (others => (others =>'0'));
signal dither_buffer_newline : t_dither_rgb := (others => (others =>'0'));
signal dither_buffer_toRam : t_dither_rgb := (others => (others =>'0'));
signal dither_buffer_fromRam : t_dither_rgb := (others => (others =>'0'));
-- infered ram for holding old pixel information
type t_dither_buffer is array(0 to img_width-1) of unsigned((dither_bits * 3)-1 downto 0);
signal dither_buffer : t_dither_buffer := (others => (others => '0'));
signal index : integer range 0 to img_width-1 := 0;
signal AddrA : integer range 0 to img_width-1 := 0;
signal AddrB : integer range 0 to img_width-1 := 0;
signal WEA : std_logic := '0';
 
begin
 
process (clk)
type t_intermediate is array(1 to 3) of unsigned(color_width downto 0);
variable intermediate_color : t_intermediate;
begin
if rising_edge(clk) then
-- calculate dithered colors
if (enable = '1') then
intermediate_color(1) := ("0" & unsigned(din_r)) + dither_buffer_next(1) + unsigned(dither_buffer_fromRam(1));
intermediate_color(2) := ("0" & unsigned(din_g)) + dither_buffer_next(2) + unsigned(dither_buffer_fromRam(2));
intermediate_color(3) := ("0" & unsigned(din_b)) + dither_buffer_next(3) + unsigned(dither_buffer_fromRam(2));
for c in 1 to 3 loop
 
if (intermediate_color(c)(8) = '1') then intermediate_color(c) := '0' & to_unsigned((2**color_width) - 1, color_width); end if;
dither_buffer_next(c) <= "0" & intermediate_color(c)(dither_bits-1 downto 1);
dither_buffer_newline(c) <= "00" & intermediate_color(c)(dither_bits-1 downto 2);
dither_buffer_toRam(c) <= ("00" & intermediate_color(c)(dither_bits-1 downto 2)) + dither_buffer_newline(c);
end loop;
else
intermediate_color(1) := "0" & unsigned(din_r);
intermediate_color(2) := "0" & unsigned(din_g);
intermediate_color(3) := "0" & unsigned(din_b);
end if;
-- calculate address for line buffer + enable
if (x<img_width-2) then
AddrB <= x+2;
elsif (x=img_width-2) then
AddrB <= 0;
else
AddrB <= 1;
end if;
index <= x;
AddrA <= index;
if (enable = '1') then
WEA <= '1';
else
WEA <= '0';
end if;
-- line buffer memory
if (WEA = '1') then
dither_buffer(AddrA) <= dither_buffer_toRam(1) & dither_buffer_toRam(2) & dither_buffer_toRam(3);
end if;
dither_buffer_fromRam(1) <= dither_buffer(AddrB)((dither_bits * 3)-1 downto (dither_bits * 2));
dither_buffer_fromRam(2) <= dither_buffer(AddrB)((dither_bits * 2)-1 downto dither_bits);
dither_buffer_fromRam(3) <= dither_buffer(AddrB)(dither_bits-1 downto 0);
-- map outputs
dout_r <= std_logic_vector(intermediate_color(1)(color_width-1 downto 0));
dout_g <= std_logic_vector(intermediate_color(2)(color_width-1 downto 0));
dout_b <= std_logic_vector(intermediate_color(3)(color_width-1 downto 0));
end if;
end process;
 
end architecture;
/tb.vhd
0,0 → 1,214
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_textio.all;
use STD.textio.all;
 
 
entity tb is
end entity;
 
architecture arch of tb is
constant img_width : integer := 256;
constant img_height : integer := 512;
constant reduced_width : integer := 4;
 
type bit_vector_file is file of bit_vector;
file read_file : bit_vector_file open read_mode is "input.bmp";
 
type std_file is file of character;
file write_file : std_file open write_mode is "output.bmp";
signal clk : std_logic := '1';
type t_color is array(1 to 3) of std_logic_vector(7 downto 0);
type t_bmp is array(0 to img_width, 0 to img_height) of t_color;
signal bmp_read : t_bmp;
signal bmp_out : t_bmp := (others => (others => (others => (others => '0'))));
signal enable : std_logic := '0';
signal din_r : std_logic_vector(7 downto 0) := (others => '0');
signal din_g : std_logic_vector(7 downto 0) := (others => '0');
signal din_b : std_logic_vector(7 downto 0) := (others => '0');
signal dout_r : std_logic_vector(7 downto 0);
signal dout_g : std_logic_vector(7 downto 0);
signal dout_b : std_logic_vector(7 downto 0);
signal x_count : integer := 0;
signal y_count : integer := 0;
signal x_in : integer := 0;
signal y_in : integer := 1;
signal x_out : integer := 0;
signal y_out : integer := 1;
signal running : std_logic := '0';
signal done : std_logic := '0';
begin
clk <= not clk after 5 ns;
pcreate_pixelpositions : process (clk)
begin
if rising_edge(clk) then
if (running = '1' and done = '0') then
if (x_count < img_width-1) then
x_count <= x_count + 1;
else
x_count <= 0;
if (y_count< img_height-1) then
y_count <= y_count + 1;
else
done <= '1';
end if;
end if;
-- for test only one half of image is dithered
if (y_count < img_height / 2) then
enable <= '1';
else
enable <= '0';
end if;
x_in <= x_count;
y_in <= y_count;
x_out <= x_in;
y_out <= y_in;
din_r <= bmp_read(x_count,y_count)(1);
din_g <= bmp_read(x_count,y_count)(2);
din_b <= bmp_read(x_count,y_count)(3);
bmp_out(x_out,y_out)(1) <= dout_r(7 downto 7 - reduced_width + 1) & (7 - reduced_width downto 0 => '0');
bmp_out(x_out,y_out)(2) <= dout_g(7 downto 7 - reduced_width + 1) & (7 - reduced_width downto 0 => '0');
bmp_out(x_out,y_out)(3) <= dout_b(7 downto 7 - reduced_width + 1) & (7 - reduced_width downto 0 => '0');
end if;
end if;
end process;
idither : entity work.eDither
generic map
(
img_width => img_width,
img_height => img_height,
color_width => 8,
reduced_width => reduced_width
)
port map
(
clk => clk,
enable => enable,
x => x_in,
din_r => din_r,
din_g => din_g,
din_b => din_b,
dout_r => dout_r,
dout_g => dout_g,
dout_b => dout_b
);
 
pfile_actions : process
variable next_vector : bit_vector (0 downto 0);
variable actual_len : natural;
variable addr : unsigned(17 downto 0) := (others => '0');
variable to_write : signed(15 downto 0);
variable read_byte : std_logic_vector(7 downto 0);
-- copy from std_logic_arith, not used here because numeric std is also included
function CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER) return STD_LOGIC_VECTOR is
variable result: STD_LOGIC_VECTOR (SIZE-1 downto 0);
variable temp: integer;
begin
temp := ARG;
for i in 0 to SIZE-1 loop
if (temp mod 2) = 1 then
result(i) := '1';
else
result(i) := '0';
end if;
if temp > 0 then
temp := temp / 2;
elsif (temp > integer'low) then
temp := (temp - 1) / 2; -- simulate ASR
else
temp := temp / 2; -- simulate ASR
end if;
end loop;
return result;
end;
variable std_buffer : character;
begin
-- copy bmp header
for i in 1 to 51 loop
read(read_file, next_vector, actual_len);
std_buffer := character'val(to_integer(unsigned(CONV_STD_LOGIC_VECTOR(bit'pos(next_vector(0)), 8))));
write(write_file, std_buffer);
end loop;
 
-- read in bmp color data
for y in 0 to img_height-1 loop
for x in 0 to img_width-1 loop
for c in 1 to 3 loop
read(read_file, next_vector, actual_len);
read_byte := CONV_STD_LOGIC_VECTOR(bit'pos(next_vector(0)), 8);
bmp_read(x,y)(c) <= read_byte;
wait for 5 ns;
end loop;
end loop;
end loop;
running <= '1';
wait until done = '1';
-- write result to bmp
for y in 0 to img_height-1 loop
for x in 0 to img_width-1 loop
for c in 1 to 3 loop
std_buffer := character'val(to_integer(unsigned(bmp_out(x,y)(c))));
write(write_file, std_buffer);
 
end loop;
end loop;
end loop;
running <= '0';
ASSERT false REPORT "End of Test" SEVERITY FAILURE;
wait;
end process;
end architecture;
 
 
 
 
 
/input.bmp Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
input.bmp Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.