📄 idct.vhd
字号:
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (en_ram1reg = '1' AND rd_cntr(5 downto 3) = "111") THEN
rd_cntr(2 downto 0) <= rd_cntr(2 downto 0) + "001";
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
rd_cntr(6) <= '1';
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (en_ram1reg = '1' AND rd_cntr(5 downto 0) = "111111") THEN
rd_cntr(6) <= NOT rd_cntr(6);
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
wr_cntr <= "1111111";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (en_ram1reg = '1') THEN
wr_cntr <= wr_cntr + "0000001";
ELSE
wr_cntr <= "0000000";
END IF;
END IF;
END PROCESS;
-- write function
P_ram1: process (RST,CLK)
begin
if (RST = '1') then
ram1_mem(63 downto 0) <= (others => "00000000000");
elsif (rising_edge (CLK)) then
if (en_ram1reg = '1' and wr_cntr(6) = '0' ) then
ram1_mem(CONV_INTEGER (wr_cntr(5 downto 0))) <= z_out;
end if;
end if;
end process P_ram1;
P_ram2: process (RST,CLK)
begin
if (RST = '1') then
ram2_mem(63 downto 0) <= (others => "00000000000");
elsif (rising_edge (CLK)) then
if (en_ram1reg = '1' and wr_cntr(6) = '1') then
ram2_mem(CONV_INTEGER (wr_cntr(5 downto 0))) <= z_out;
end if;
end if;
end process P_ram2;
-- read function
P_ramout: process (RST,CLK)
begin
if (RST = '1') then
data_out <= (others => '0');
elsif (rising_edge (CLK)) then
if (en_ram1reg = '1' and rd_cntr(6) = '0') then
data_out <= ram2_mem(CONV_INTEGER (rd_cntr(5 downto 0)));
elsif (en_ram1reg = '1' and rd_cntr(6) = '1') then
data_out <= ram1_mem(conv_integer (rd_cntr(5 downto 0)));
elsif (en_ram1reg = '0') then
data_out <= (others => '0');
end if;
end if;
end process P_ramout;
-- END MEMORY SECTION
-- 2D-DCT implementation same as the 1D-DCT implementation
-- First dct coeeficient appears at the output of the RAM1 after 13clk + 1clk ram in + 64
-- First dct coeeficient appears at the output of the RAM1 after 13clk + 1clk ram in + 64
-- clk cycles + 1clk ram out. including the 1 pipestage, the 2nd DCT operation starts after
-- 16 + 64 clk cycles. Pipe stages are added to match the timing with the cntr8 counter
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
data_out_pipe1 <= "00000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
data_out_pipe1 <= data_out;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
cntr80 <= "0000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1') THEN
cntr80 <= cntr80 + "0000001";
END IF;
END IF;
END PROCESS;
en_dct2d <= '0' WHEN RST = '1' ELSE '1' WHEN (cntr80 = "1001111") ELSE en_dct2d;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
en_dct2d_reg <= '0';
ELSIF (CLK'EVENT AND CLK = '1') THEN
en_dct2d_reg <= en_dct2d;
END IF;
END PROCESS;
data_out_final(10 downto 0) <= data_out_pipe1 ;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
xb0_in <= "00000000000"; xb1_in <= "00000000000";
xb2_in <= "00000000000"; xb3_in <= "00000000000";
xb4_in <= "00000000000"; xb5_in <= "00000000000";
xb6_in <= "00000000000"; xb7_in <= "00000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (en_dct2d_reg = '1') THEN
xb0_in <= data_out_final; xb1_in <= xb0_in;
xb2_in <= xb1_in; xb3_in <= xb2_in;
xb4_in <= xb3_in; xb5_in <= xb4_in;
xb6_in <= xb5_in; xb7_in <= xb6_in;
ELSE
IF (en_dct2d_reg = '0') THEN
xb0_in <= "00000000000"; xb1_in <= "00000000000";
xb2_in <= "00000000000"; xb3_in <= "00000000000";
xb4_in <= "00000000000"; xb5_in <= "00000000000";
xb6_in <= "00000000000"; xb7_in <= "00000000000";
END IF;
END IF;
END IF;
END PROCESS;
-- register inputs, inputs read in every eighth clk
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
xb0_reg <= "00000000000"; xb1_reg <= "00000000000";
xb2_reg <= "00000000000"; xb3_reg <= "00000000000";
xb4_reg <= "00000000000"; xb5_reg <= "00000000000";
xb6_reg <= "00000000000"; xb7_reg <= "00000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (cntr8 = "1000") THEN
xb0_reg <= xb0_in; xb1_reg <= xb1_in;
xb2_reg <= xb2_in; xb3_reg <= xb3_in;
xb4_reg <= xb4_in; xb5_reg <= xb5_in;
xb6_reg <= xb6_in; xb7_reg <= xb7_in;
END IF;
END IF;
END PROCESS;
-- take absolute value of signals
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
xb0_reg_comp <= "0000000000"; xb1_reg_comp <= "0000000000";
xb2_reg_comp <= "0000000000"; xb3_reg_comp <= "0000000000";
xb4_reg_comp <= "0000000000"; xb5_reg_comp <= "0000000000";
xb6_reg_comp <= "0000000000"; xb7_reg_comp <= "0000000000";
xb0_reg_sign <= '0'; xb1_reg_sign <= '0';
xb2_reg_sign <= '0'; xb3_reg_sign <= '0';
xb4_reg_sign <= '0'; xb5_reg_sign <= '0';
xb6_reg_sign <= '0'; xb7_reg_sign <= '0';
ELSIF (CLK'EVENT AND CLK = '1') THEN
if (xb0_reg(10) = '0') then xb0_reg_comp <= xb0_reg(9 downto 0);
else xb0_reg_comp <= not(xb0_reg(9 downto 0)) + '1'; end if;
if (xb1_reg(10) = '0') then xb1_reg_comp <= xb1_reg(9 downto 0);
else xb1_reg_comp <= not(xb1_reg(9 downto 0)) + '1'; end if;
if (xb2_reg(10) = '0') then xb2_reg_comp <= xb2_reg(9 downto 0);
else xb2_reg_comp <= not(xb2_reg(9 downto 0)) + '1'; end if;
if (xb3_reg(10) = '0') then xb3_reg_comp <= xb3_reg(9 downto 0);
else xb3_reg_comp <= not(xb3_reg(9 downto 0)) + '1'; end if;
if (xb4_reg(10) = '0') then xb4_reg_comp <= xb4_reg(9 downto 0);
else xb4_reg_comp <= not(xb4_reg(9 downto 0)) + '1'; end if;
if (xb5_reg(10) = '0') then xb5_reg_comp <= xb5_reg(9 downto 0);
else xb5_reg_comp <= not(xb5_reg(9 downto 0)) + '1'; end if;
if (xb6_reg(10) = '0') then xb6_reg_comp <= xb6_reg(9 downto 0);
else xb6_reg_comp <= not(xb6_reg(9 downto 0)) + '1'; end if;
if (xb7_reg(10) = '0') then xb7_reg_comp <= xb7_reg(9 downto 0);
else xb7_reg_comp <= not(xb7_reg(9 downto 0)) + '1'; end if;
xb0_reg_sign <= xb0_reg(10); xb1_reg_sign <= xb1_reg(10);
xb2_reg_sign <= xb2_reg(10); xb3_reg_sign <= xb3_reg(10);
xb4_reg_sign <= xb4_reg(10); xb5_reg_sign <= xb5_reg(10);
xb6_reg_sign <= xb6_reg(10); xb7_reg_sign <= xb7_reg(10);
END IF;
END PROCESS;
-- 10 bits * 7 bits = 16 bits
p1b_all <= xb7_reg_comp(9 downto 0) * memory1a(6 downto 0) ;
p2b_all <= xb6_reg_comp(9 downto 0) * memory2a(6 downto 0) ;
p3b_all <= xb5_reg_comp(9 downto 0) * memory3a(6 downto 0) ;
p4b_all <= xb4_reg_comp(9 downto 0) * memory4a(6 downto 0) ;
p5b_all <= xb3_reg_comp(9 downto 0) * memory5a(6 downto 0) ;
p6b_all <= xb2_reg_comp(9 downto 0) * memory6a(6 downto 0) ;
p7b_all <= xb1_reg_comp(9 downto 0) * memory7a(6 downto 0) ;
p8b_all <= xb0_reg_comp(9 downto 0) * memory8a(6 downto 0) ;
-- The following instantiation can be used while targetting Virtex2
--MULT18X18 mult1b (.A({10'b0,xb7_reg_comp[7:0]}), .B({11'b0,memory1a[6:0]}), .P(p1b_all));
--MULT18X18 mult2b (.A({10'b0,xb6_reg_comp[7:0]}), .B({11'b0,memory2a[6:0]}), .P(p2b_all));
--MULT18X18 mult3b (.A({10'b0,xb5_reg_comp[7:0]}), .B({11'b0,memory3a[6:0]}), .P(p3b_all));
--MULT18X18 mult4b (.A({10'b0,xb4_reg_comp[7:0]}), .B({11'b0,memory4a[6:0]}), .P(p4b_all));
--MULT18X18 mult5b (.A({10'b0,xb3_reg_comp[7:0]}), .B({11'b0,memory5a[6:0]}), .P(p5b_all));
--MULT18X18 mult6b (.A({10'b0,xb2_reg_comp[7:0]}), .B({11'b0,memory6a[6:0]}), .P(p6b_all));
--MULT18X18 mult7b (.A({10'b0,xb1_reg_comp[7:0]}), .B({11'b0,memory7a[6:0]}), .P(p7b_all));
--MULT18X18 mult8b (.A({10'b0,xb0_reg_comp[7:0]}), .B({11'b0,memory8a[6:0]}), .P(p8b_all));
-- multiply the outputs of the add/sub block with the 8 sets of stored coefficients
xor1b <= (xb7_reg_sign) xor (memory1a(7));
xor2b <= (xb6_reg_sign) xor (memory2a(7));
xor3b <= (xb5_reg_sign) xor (memory3a(7));
xor4b <= (xb4_reg_sign) xor (memory4a(7));
xor5b <= (xb3_reg_sign) xor (memory5a(7));
xor6b <= (xb2_reg_sign) xor (memory6a(7));
xor7b <= (xb1_reg_sign) xor (memory7a(7));
xor8b <= (xb0_reg_sign) xor (memory8a(7));
PROCESS (RST, CLK)
BEGIN
IF (RST = '1') THEN
p1b <= "0000000000000000"; p2b <= "0000000000000000";
p3b <= "0000000000000000"; p4b <= "0000000000000000";
p5b <= "0000000000000000"; p6b <= "0000000000000000";
p7b <= "0000000000000000"; p8b <= "0000000000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1' AND prod_en1 = "1001") THEN
if (xor1b = '1') then p1b <= not('0' & p1b_all(14 downto 0)) + '1';
elsif (xor1b = '0') then p1b <= ('0' & p1b_all(14 downto 0)); end if;
if (xor2b = '1') then p2b <= not('0' & p2b_all(14 downto 0)) + '1';
elsif (xor2b = '0') then p2b <= ('0' & p2b_all(14 downto 0)); end if;
if (xor3b = '1') then p3b <= not('0' & p3b_all(14 downto 0)) + '1';
elsif (xor3b = '0') then p3b <= ('0' & p3b_all(14 downto 0)); end if;
if (xor4b = '1') then p4b <= not('0' & p4b_all(14 downto 0)) + '1';
elsif (xor4b = '0') then p4b <= ('0' & p4b_all(14 downto 0)); end if;
if (xor5b = '1') then p5b <= not('0' & p5b_all(14 downto 0)) + '1';
elsif (xor5b = '0') then p5b <= ('0' & p5b_all(14 downto 0)); end if;
if (xor6b = '1') then p6b <= not('0' & p6b_all(14 downto 0)) + '1';
elsif (xor6b = '0') then p6b <= ('0' & p6b_all(14 downto 0)); end if;
if (xor7b = '1') then p7b <= not('0' & p7b_all(14 downto 0)) + '1';
elsif (xor7b = '0') then p7b <= ('0' & p7b_all(14 downto 0)); end if;
if (xor8b = '1') then p8b <= not('0' & p8b_all(14 downto 0)) + '1';
elsif (xor8b = '0') then p8b <= ('0' & p8b_all(14 downto 0)); end if;
ELSE
p1b <= "0000000000000000";
p2b <= "0000000000000000";
p3b <= "0000000000000000";
p4b <= "0000000000000000";
p5b <= "0000000000000000";
p6b <= "0000000000000000";
p7b <= "0000000000000000";
p8b <= "0000000000000000";
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
idct_2d_int1 <= "00000000000000000000";
idct_2d_int2 <= "00000000000000000000";
idct_2d_int3 <= "00000000000000000000";
idct_2d_int4 <= "00000000000000000000";
idct_2d_int <= "00000000000000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
idct_2d_int1 <= "0000" & (p1b + p2b);
idct_2d_int2 <= "0000" & (p3b + p4b);
idct_2d_int3 <= "0000" & (p5b + p6b);
idct_2d_int4 <= "0000" & (p7b + p8b);
idct_2d_int <= idct_2d_int1 + idct_2d_int2 + idct_2d_int3 + idct_2d_int4;
END IF;
END PROCESS;
-- max value for a input signal to dct is "11111111".
-- max value for a input signal to dct is "11111111".
-- To represent this we need only 8 bits, plus 1 bit for sign
--assign idct_2d = idct_2d_int[16:8];
idct_2d <= idct_2d_int(19) & idct_2d_int(14 downto 8) ;
--assign idct_2d = idct_2d_int[7] ? (idct_2d_rnd + 1'b1) : idct_2d_rnd;
END logic;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -