📄 compressor.vhd
字号:
signal WriteTables : std_logic;
signal TableData : std_logic_vector(5 downto 0);
signal Table : std_logic;
signal ZRLing : std_logic;
signal RFDInt : std_logic;
signal RFDIntData : std_logic_vector(7 downto 0);
function Multiplier (Num, Prod : in std_logic_vector) return std_logic_vector;
function Multiplier (Num, Prod : in std_logic_vector) return std_logic_vector is
variable result : std_logic_vector(19 downto 0) := (others => '0');
begin --8 bits * 10 bits both unsigned = 18 bits
result := ('0' & Num(7 downto 0)) * ('0' & Prod);
return result(17 downto 0);
end Multiplier;
function MultiplierQ (Num, Prod : in std_logic_vector) return std_logic_vector;
function MultiplierQ (Num, Prod : in std_logic_vector) return std_logic_vector is
variable result : std_logic_vector(26 downto 0);
variable UNum : std_logic_vector(11 downto 0);
begin --it is like Multiplier but admits bigger operands: Num (10..0) (signed) and Prod (10..0) (unsigned)
--max result = 1000_0000_0000 * 111_1111_1111 = 1(sign)11_1111_1111_1000_0000_0000 (-2.048 * 2.047 = -4.192.256)
--UPDATE: now Prod may be of up to 13 bits (12..0), so the result will be 24..0
if Num(Num'High) = '1' then --negative number?
UNum := not (Num) + 1; --two's complement to make it positive
else
UNum := Num;
end if;
result := ('0' & UNum) * ('0' & Prod);
if Num(Num'High) = '1' then --negative result
result := (not result) + 1; --2's Complement
end if;
return result(24 downto 0);
end MultiplierQ;
function Mult_Columns (Line : in std_logic_vector) return std_logic_vector;
function Mult_Columns (Line : in std_logic_vector) return std_logic_vector is
variable result : std_logic_vector(12 downto 0);
begin
--This function is optimized and is designed to multiply times the maximum allowed
--number of columns in an image. Here, it has been set to 352, in accordance with
--the buffers (as stated in documentation), but, changing their depth, one can
--easily change the maximum number of columns, changing also this function and the next.
--Multiply times 352 (101100000) is the same as multiplying times 256 plus multiplying times 64 plus times 32
--that is, the number shifted left 8 positions + the number shifted 6 + the number shifted 5
result := "0000000000000" + (Line & "00000000") + (Line & "000000") + (Line & "00000");
return result; --with Line max=1111, the max. result will be=1010010100000 (12..0)
end Mult_Columns;
function Mult_Half_Columns (Line : in std_logic_vector) return std_logic_vector;
function Mult_Half_Columns (Line : in std_logic_vector) return std_logic_vector is
variable result : std_logic_vector(10 downto 0);
begin
--This function is optimized and is designed to multiply times HALF the maximum allowed
--number of columns in an image. Here, it has been set to 176, in accordance with
--the buffers (as stated in documentation), but, changing their depth, one can
--easily change the maximum number of columns, changing also this function and the previous.
--Multiply times 176(10110000) is the same as multiplying times 128 plus multiplying times 32 + times 16
--that is, the number shifted left 7 positions + the number shifted 5 + the number shifted 4
result := "00000000000" + (Line & "0000000") + (Line & "00000") + (Line & "0000");
return result; --with Line max=111, the max. result will be=10011010000 (10..0)
end Mult_Half_Columns;
function GetCategory (Coef : in std_logic_vector) return integer;
--function fixed to work under ModelSim by Peter Eisemann
function GetCategory (Coef : in std_logic_vector) return integer is
--tells us the category of the coefficient (AC and DC) based on a "sign-less" version of itself!
variable Coeff : std_logic_vector(Coef'High downto 0);
variable result: integer := 0;
begin
if Coef(Coef'High) = '1' then
Coeff := (not Coef) + 1;
else
Coeff := Coef;
end if;
categoryloop:for index in Coeff'range loop
if Coeff(index) = '1' then
-- return (index + 1); Eim
result := (index +1);
exit categoryloop when Coeff(index) = '1';
end if;
end loop categoryloop;
return result;
end GetCategory;
-- function GetCategory (Coef : in std_logic_vector) return integer;
--
-- function GetCategory (Coef : in std_logic_vector) return integer is
-- --tells us the category of the coefficient (AC and DC) based on a "sign-less" version of itself!
-- variable Coeff : std_logic_vector(Coef'High downto 0);
-- begin
-- if Coef(Coef'High) = '1' then
-- Coeff := (not Coef) + 1;
-- else
-- Coeff := Coef;
-- end if;
-- for index in Coeff'range loop
-- if Coeff(index) = '1' then
-- return (index + 1);
-- end if;
-- end loop;
-- return 0;
-- end GetCategory;
function AppendHuffmanWord (HuffmanWord, Code : in std_logic_vector; Pos : in integer) return std_logic_vector;
function AppendHuffmanWord (HuffmanWord, Code : in std_logic_vector; Pos : in integer) return std_logic_vector is
variable result : std_logic_vector(22 downto 0);
begin
result := HuffmanWord;
for i in (Code'length-1) downto 0 loop
result(Pos-i) := Code(i); --Code(Code'length-1-i); --MSB first!!
--IMPORTANT: the std_logic_vector is "to", not "downto", that's why the MSB is opposite as usual
end loop;
return result;
end AppendHuffmanWord;
--this function is an overload with Code as std_logic (used when it must only append the sign)
function AppendHuffmanWord (HuffmanWord : in std_logic_vector; Code : in std_logic; Pos : in integer) return std_logic_vector;
function AppendHuffmanWord (HuffmanWord : in std_logic_vector; Code : in std_logic; Pos : in integer) return std_logic_vector is
variable result : std_logic_vector(22 downto 0);
begin
result := HuffmanWord;
result(Pos) := Code;
return result;
end AppendHuffmanWord;
--this one is to define the MSB of Code in case it is not length-1, so that CodeLength is the new length-1
function AppendHuffmanWordL (HuffmanWord, Code : in std_logic_vector; CodeLength : in integer; Pos : in integer) return std_logic_vector;
function AppendHuffmanWordL (HuffmanWord, Code : in std_logic_vector; CodeLength : in integer; Pos : in integer) return std_logic_vector is
variable result : std_logic_vector(22 downto 0);
begin
result := HuffmanWord;
for i in Code'length downto 0 loop
if i < CodeLength then --this may look redundant but it avoids an "unbound loop" error
result(Pos-i) := Code(CodeLength-1-i); --careful! here bit 0 is the LSB, X-File
end if;
end loop;
return result;
end AppendHuffmanWordL;
function To_std_logicvpor11(ZeroRun : in integer) return std_logic_vector;
function To_std_logicvpor11(ZeroRun : in integer) return std_logic_vector is
--returns the integer times 11 in a std_logic_vector(8 downto 0)
begin
case ZeroRun is
when 0 =>
return "000000000";
when 1 =>
return "000001011";
when 2 =>
return "000010110";
when 3 =>
return "000100001";
when 4 =>
return "000101100";
when 5 =>
return "000110111";
when 6 =>
return "001000010";
when 7 =>
return "001001101";
when 8 =>
return "001011000";
when 9 =>
return "001100011";
when 10 =>
return "001101110";
when 11 =>
return "001111001";
when 12 =>
return "010000100";
when 13 =>
return "010001111";
when 14 =>
return "010011010";
when others => --15 =>
return "010100101"; --165
end case;
end To_std_logicvpor11;
function To_std_logicv(Cat : in integer) return std_logic_vector;
function To_std_logicv(Cat : in integer) return std_logic_vector is
begin
case Cat is
when 0 =>
return "0000";
when 1 =>
return "0001";
when 2 =>
return "0010";
when 3 =>
return "0011";
when 4 =>
return "0100";
when 5 =>
return "0101";
when 6 =>
return "0110";
when 7 =>
return "0111";
when 8 =>
return "1000";
when 9 =>
return "1001";
when others => -- 10 => there won't be 11 because we only use it for AC
return "1010";
end case;
end To_std_logicv;
function GetMagnitude (Coef : in std_logic_vector; Cat : in integer) return std_logic_vector;
function GetMagnitude (Coef : in std_logic_vector; Cat : in integer) return std_logic_vector is
begin
case Cat is
when 0 =>
return "000000000000"; --we avoid this case with an if because it wouldn't be correct
when 1 =>
return "000000000000"; --we avoid this case with an if because it wouldn't be correct
when 2 =>
return (Coef - "10");
when 3 =>
return (Coef - "100");
when 4 =>
return (Coef - "1000");
when 5 =>
return (Coef - "10000");
when 6 =>
return (Coef - "100000");
when 7 =>
return (Coef - "1000000");
when 8 =>
return (Coef - "10000000");
when 9 =>
return (Coef - "100000000");
when 10 =>
return (Coef - "1000000000");
when others => --11 =>
return (Coef - "10000000000");
end case;
end GetMagnitude;
function CompressDC(Cat : in integer; LumaBlock : in std_logic) return std_logic_vector;
function CompressDC(Cat : in integer; LumaBlock : in std_logic) return std_logic_vector is
variable result : std_logic_vector(14 downto 0) := (others => '0');
begin --the four MSBs of result keep the number of the MSB bit of the data in the LSBs
if LumaBlock = '1' then --compress with DC Luminance Table
case Cat is
when 0 =>
result := "000100000000000";
when 1 =>
result := "001000000000010";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -