📄 csc.vhd
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY csc IS
GENERIC (N : INTEGER := 8 ); --输入输出宽度
PORT ( Clock : IN STD_LOGIC; --时钟
ClockEnable : IN STD_LOGIC; --时钟使能
Reset : IN STD_LOGIC; --复位
R : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); --输入R
G : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); --输入G
B : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); --输入B
Y : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); --输出Y
Cb : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); --输出Cb
Cr : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0) --输出Cr
);
END csc;
ARCHITECTURE RTL OF csc IS
--定义转换矩阵系数和表示系数的二进制数宽数
--转换矩阵第一行
CONSTANT CST_Y601_red : INTEGER := 66;
CONSTANT CST_Y601_green : INTEGER := 129;
CONSTANT CST_Y601_blue : INTEGER := 25;
CONSTANT CST_Y601_Prec : INTEGER := 8; -- 8-bit (256)
--转换矩阵第二行
CONSTANT CST_Cb_red : INTEGER := 38;
CONSTANT CST_Cb_green : INTEGER := 74;
CONSTANT CST_Cb_blue : INTEGER := 112;
CONSTANT CST_Cb_Prec : INTEGER := 8; -- 8-bit (256)
--转换矩阵第三行
CONSTANT CST_Cr_red : INTEGER := 112;
CONSTANT CST_Cr_green : INTEGER := 94;
CONSTANT CST_Cr_blue : INTEGER := 18;
CONSTANT CST_Cr_Prec : INTEGER := 8; -- 8-bit (256)
--定义常数乘法的积的宽度
CONSTANT CST_Y601_OutSize : INTEGER := CST_Y601_Prec + N;
CONSTANT CST_Cb_OutSize : INTEGER := CST_Cb_Prec + N;
CONSTANT CST_Cr_OutSize : INTEGER := CST_Cr_Prec + N;
--定义产生平移常量需要左移的次数
CONSTANT CST_Offset_Y601_BITS :INTEGER := N + CST_Y601_Prec -9;
CONSTANT CST_Offset_Cb_BITS :INTEGER := N + CST_Cb_Prec -9;
CONSTANT CST_Offset_Cr_BITS :INTEGER := N + CST_Cr_Prec -9;
--引用乘法器
COMPONENT const_mult
GENERIC ( N : INTEGER;
M : INTEGER;
CST_MULT : INTEGER
);
PORT ( Clock : IN STD_LOGIC;
ClockEnable : IN STD_LOGIC;
Reset : IN STD_LOGIC;
Color : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
Color_Out : OUT STD_LOGIC_VECTOR(N+M-1 DOWNTO 0)
);
END COMPONENT;
--9个乘法器的输出
SIGNAL Y_R_KCM, Y_G_KCM, Y_B_KCM : STD_LOGIC_VECTOR ( CST_Y601_OutSize-1 DOWNTO 0);
SIGNAL Cb_R_KCM, Cb_G_KCM, Cb_B_KCM : STD_LOGIC_VECTOR ( CST_Cb_OutSize-1 DOWNTO 0);
SIGNAL Cr_R_KCM, Cr_G_KCM, Cr_B_KCM : STD_LOGIC_VECTOR ( CST_Cr_OutSize-1 DOWNTO 0);
--平移常量+第一个乘法器输出
SIGNAL Y_cst_G : STD_LOGIC_VECTOR (CST_Y601_OutSize-1 DOWNTO 0);
SIGNAL Cb_cst_B : STD_LOGIC_VECTOR (CST_Cb_OutSize-1 DOWNTO 0);
SIGNAL Cr_cst_R : STD_LOGIC_VECTOR (CST_Cr_OutSize-1 DOWNTO 0);
--加减法器中间变量
SIGNAL Y_Red_Blue, Y601_full : STD_LOGIC_VECTOR (CST_Y601_OutSize-1 DOWNTO 0);
SIGNAL Cb_Red_Green, Cb_full : STD_LOGIC_VECTOR (CST_Cb_OutSize-1 DOWNTO 0);
SIGNAL Cr_Green_Blue, Cr_full : STD_LOGIC_VECTOR (CST_Cr_OutSize-1 DOWNTO 0);
--平移常量
SIGNAL CST_Offset_Y601 : INTEGER ; -- ( 16 + 0.5 ) * 2* (2**(N-8)) * 2^(CST_Y601_Prec-1)
SIGNAL CST_Offset_Cb : INTEGER ; -- ( 128 + 0.5 ) * 2 * (2**(N-8))* 2^(CST_Cb_Prec-1)
SIGNAL CST_Offset_Cr : INTEGER ; -- ( 128 + 0.5 ) * 2 * (2**(N-8))* 2^(CST_Cr_Prec-1)
BEGIN
--输出平移常量CST_Offset_Y601进程,CST_Offset_Y601=33*2**CST_Offset_Y601_BITS
PROCESS
VARIABLE Y601_temp : INTEGER;
BEGIN
Y601_temp := 33;
FOR I IN 1 TO CST_Offset_Y601_BITS LOOP
Y601_temp := Y601_temp*2;
END LOOP;
CST_Offset_Y601 <= Y601_temp;
END PROCESS;
--输出平移常量CST_Offset_Cb进程,CST_Offset_Cb=33*2**CST_Offset_Cb_BITS
PROCESS
VARIABLE Cb_temp : INTEGER;
BEGIN
Cb_temp := 257;
FOR I IN 1 TO CST_Offset_Cb_BITS LOOP
Cb_temp := Cb_temp*2;
END LOOP;
CST_Offset_Cb <= Cb_temp;
END PROCESS;
--输出平移常量CST_Offset_Cr进程,,CST_Offset_Cr=33*2**CST_Offset_Cr_BITS
PROCESS
variable Cr_temp : INTEGER;
BEGIN
Cr_temp := 257;
FOR I IN 1 TO CST_Offset_Cr_BITS LOOP
Cr_temp := Cr_temp*2;
END LOOP;
CST_Offset_Cr <= Cr_temp;
END PROCESS;
-- ---------------------------------
-- 计算Y分量
-- ---------------------------------
--常数乘法器
Y601_KCM_red: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Y601_red
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => R,
Color_Out => Y_R_KCM
);
--常数乘法器
Y601_KCM_green: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Y601_green
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => G,
Color_Out => Y_G_KCM
);
--常数乘法器
Y601_KCM_blue: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Y601_blue
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => B,
Color_Out => Y_B_KCM
);
-- 做G + 平移常量运算, 平移常量已经变大0.5,以补偿截断造成的偏差
CST_Green_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Y_cst_G <= (OTHERS => '0');
ELSIF (Clock'event and Clock = '1') THEN
IF (ClockEnable = '1') THEN
Y_cst_G <= UNSIGNED(Y_G_KCM) + CST_Offset_Y601 ; -- 加16.5的有移若干位
END IF;
END IF;
END PROCESS;
-- 做(R + B)运算
Y_Red_Blue_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Y_Red_Blue <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') THEN
Y_Red_Blue <= UNSIGNED( Y_R_KCM ) + UNSIGNED( Y_B_KCM ) ;
END IF;
END IF;
END PROCESS;
-- 做(R + B) + (G + 平移常量)运算
Y601_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Y601_full <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') THEN
Y601_full <= UNSIGNED( Y_Red_Blue) + UNSIGNED( Y_cst_G );
END IF;
END IF;
END PROCESS;
-- ---------------------------------
-- 计算Cb分量
-- ---------------------------------
--常数乘法器
Cb_KCM_red: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cb_red
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => R,
Color_Out => Cb_R_KCM
);
--常数乘法器
Cb_KCM_green: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cb_green
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => G,
Color_Out => Cb_G_KCM
);
--常数乘法器
Cb_KCM_blue: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cb_blue
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => B,
Color_Out => Cb_B_KCM
);
--做B + 平移常量运算, 平移常量已经变大0.5,以补偿截断造成的偏差
CST_Blue_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cb_cst_B <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') then
Cb_cst_B <= UNSIGNED( Cb_B_KCM ) + CST_Offset_Cb ; -- add 128.5 (scaled up by coefficient precision)
END IF;
END IF;
END PROCESS;
-- 做R+G运算
Cb_Red_Green_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cb_Red_Green <= (OTHERS => '0');
ELSIF (Clock'event and Clock = '1') THEN
IF (ClockEnable = '1') THEN
Cb_Red_Green <= UNSIGNED( Cb_R_KCM ) + UNSIGNED( Cb_G_KCM ) ;
END IF;
END IF;
END PROCESS;
-- 做 (B + 平移常量) - (R + G)运算
Cb_Subt: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cb_full <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') THEN
Cb_full <= UNSIGNED( Cb_cst_B) - UNSIGNED( Cb_Red_Green ) ;
END IF;
END IF;
END PROCESS;
-- ---------------------------------
-- 计算Cr分量
-- ---------------------------------
--常数乘法器
Cr_KCM_red: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cr_red
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => R,
Color_Out => Cr_R_KCM
);
--常数乘法器
Cr_KCM_green: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cr_green
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => G,
Color_Out => Cr_G_KCM
);
--常数乘法器
Cr_KCM_blue: const_mult
GENERIC MAP (
N => N,
M => CST_Y601_Prec,
CST_MULT => CST_Cr_blue
)
PORT MAP (
Clock => Clock,
ClockEnable => ClockEnable,
Reset => Reset,
Color => B,
Color_Out => Cr_B_KCM
);
-- 做(R + 平移常量)运算,平移常量已经变大0.5,以补偿截断造成的偏差
CST_Red_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cr_cst_R <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') THEN
Cr_cst_R <= UNSIGNED( Cr_R_KCM) + CST_Offset_Cr ; -- add 128.5 (scaled up by coefficient precision)
END IF;
END IF;
END PROCESS;
-- 做G + B运算
Cr_Green_Blue_Adder: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cr_Green_Blue <= (others => '0');
ELSIF (Clock'event and Clock = '1') THEN
IF (ClockEnable = '1') THEN
Cr_Green_Blue <= UNSIGNED( Cr_G_KCM ) + UNSIGNED( Cr_B_KCM ) ;
END IF;
END IF;
END PROCESS;
-- 做(R + 平移常量) - (G + B)运算
Cr_Subt: PROCESS (Clock, Reset)
BEGIN
IF (Reset = '1') THEN
Cr_full <= (OTHERS => '0');
ELSIF (Clock'event AND Clock = '1') THEN
IF (ClockEnable = '1') THEN
Cr_full <= UNSIGNED( Cr_cst_R ) - UNSIGNED( Cr_Green_Blue );
END IF;
END IF;
END PROCESS;
-- 输出截断
Y <= Y601_full(CST_Y601_OutSize-1 DOWNTO CST_Y601_OutSize-N); -- divide by 2^(CST_Y601_OutSize-8)...
Cb <= Cb_full(CST_Cb_OutSize-1 DOWNTO CST_Cb_OutSize-N); -- divide by 2^(CST_Cb_OutSize-8)...
Cr <= Cr_full(CST_Cr_OutSize-1 DOWNTO CST_Cr_OutSize-N); -- divide by 2^(CST_Cr_OutSize-8)...
END RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -