📄 compressor.vhd
字号:
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"; when 2 => result := "001000000000011"; when 3 => result := "001000000000100"; when 4 => result := "001000000000101";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -