📄 idct.vhd
字号:
xa2_in <= "000000000000"; xa3_in <= "000000000000";
xa4_in <= "000000000000"; xa5_in <= "000000000000";
xa6_in <= "000000000000"; xa7_in <= "000000000000";
END IF;
END IF;
END PROCESS;
-- shifted inputs registered every 8th clk (using cntr8)
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
cntr8 <= "0000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1') THEN
IF (cntr8 < "1000") THEN
cntr8 <= cntr8 + "0001";
ELSE
cntr8 <= "0001";
END IF;
ELSE
cntr8 <= "0000";
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
prod_en1 <= "0000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1') THEN
IF (prod_en1 < "1001") THEN
prod_en1 <= prod_en1 + "0001";
ELSE
prod_en1 <= "1001";
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
xa0_reg <= "000000000000"; xa1_reg <= "000000000000";
xa2_reg <= "000000000000"; xa3_reg <= "000000000000";
xa4_reg <= "000000000000"; xa5_reg <= "000000000000";
xa6_reg <= "000000000000"; xa7_reg <= "000000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (cntr8 = "1000") THEN
xa0_reg <= xa0_in; xa1_reg <= xa1_in;
xa2_reg <= xa2_in; xa3_reg <= xa3_in;
xa4_reg <= xa4_in; xa5_reg <= xa5_in;
xa6_reg <= xa6_in; xa7_reg <= xa7_in;
ELSE
END IF;
END IF;
END PROCESS;
-- take absolute value of signals
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
xa0_reg_comp <= "00000000000"; xa1_reg_comp <= "00000000000";
xa2_reg_comp <= "00000000000"; xa3_reg_comp <= "00000000000";
xa4_reg_comp <= "00000000000"; xa5_reg_comp <= "00000000000";
xa6_reg_comp <= "00000000000"; xa7_reg_comp <= "00000000000";
xa0_reg_sign <= '0'; xa1_reg_sign <= '0';
xa2_reg_sign <= '0'; xa3_reg_sign <= '0';
xa4_reg_sign <= '0'; xa5_reg_sign <= '0';
xa6_reg_sign <= '0'; xa7_reg_sign <= '0';
ELSIF (CLK'EVENT AND CLK = '1') THEN
if (xa0_reg(11) = '0') then xa0_reg_comp <= xa0_reg(10 downto 0);
else xa0_reg_comp <= not(xa0_reg(10 downto 0)) + '1'; end if;
if (xa1_reg(11) = '0') then xa1_reg_comp <= xa1_reg(10 downto 0);
else xa1_reg_comp <= not(xa1_reg(10 downto 0)) + '1'; end if;
if (xa2_reg(11) = '0') then xa2_reg_comp <= xa2_reg(10 downto 0);
else xa2_reg_comp <= not(xa2_reg(10 downto 0)) + '1'; end if;
if (xa3_reg(11) = '0') then xa3_reg_comp <= xa3_reg(10 downto 0);
else xa3_reg_comp <= not(xa3_reg(10 downto 0)) + '1'; end if;
if (xa4_reg(11) = '0') then xa4_reg_comp <= xa4_reg(10 downto 0);
else xa4_reg_comp <= not(xa4_reg(10 downto 0)) + '1'; end if;
if (xa5_reg(11) = '0') then xa5_reg_comp <= xa5_reg(10 downto 0);
else xa5_reg_comp <= not(xa5_reg(10 downto 0)) + '1'; end if;
if (xa6_reg(11) = '0') then xa6_reg_comp <= xa6_reg(10 downto 0);
else xa6_reg_comp <= not(xa6_reg(10 downto 0)) + '1'; end if;
if (xa7_reg(11) = '0') then xa7_reg_comp <= xa7_reg(10 downto 0);
else xa7_reg_comp <= not(xa7_reg(10 downto 0)) + '1'; end if;
xa0_reg_sign <= xa0_reg(11); xa1_reg_sign <= xa1_reg(11);
xa2_reg_sign <= xa2_reg(11); xa3_reg_sign <= xa3_reg(11);
xa4_reg_sign <= xa4_reg(11); xa5_reg_sign <= xa5_reg(11);
xa6_reg_sign <= xa6_reg(11); xa7_reg_sign <= xa7_reg(11);
END IF;
END PROCESS;
-- multiply the outputs of the add/sub block with the 8 sets of stored coefficients
-- The inputs are shifted thru 8 registers in 8 clk cycles. The ouput of the shift
-- The inputs are shifted thru 8 registers in 8 clk cycles. The ouput of the shift
-- registers are registered at the 9th clk. The values are then added or subtracted at the 10th
-- clk. The first mutiplier output is obtained at the 11th clk. Memoryx[0] shd be accessed
-- at the 11th clk
--wait state counter
-- First valid add_sub appears at the 10th clk (8 clks for shifting inputs,
-- 9th clk for registering shifted input and 10th clk for add_sub
-- to synchronize the i value to the add_sub value, i value is incremented
-- only after 10 clks using i_wait
-- max value for p1a = 2047*126. = 18 bits
p1a_all <= xa7_reg_comp(10 downto 0) * memory1a(6 downto 0) ;
p2a_all <= xa6_reg_comp(10 downto 0) * memory2a(6 downto 0) ;
p3a_all <= xa5_reg_comp(10 downto 0) * memory3a(6 downto 0) ;
p4a_all <= xa4_reg_comp(10 downto 0) * memory4a(6 downto 0) ;
p5a_all <= xa3_reg_comp(10 downto 0) * memory5a(6 downto 0) ;
p6a_all <= xa2_reg_comp(10 downto 0) * memory6a(6 downto 0) ;
p7a_all <= xa1_reg_comp(10 downto 0) * memory7a(6 downto 0) ;
p8a_all <= xa0_reg_comp(10 downto 0) * memory8a(6 downto 0) ;
-- The following instantiation can be used while targetting Virtex2
--MULT18X18 mult1a (.A({10'b0,xa7_reg_comp[7:0]}), .B({11'b0,memory1a[6:0]}), .P(p1a_all));
--MULT18X18 mult2a (.A({10'b0,xa6_reg_comp[7:0]}), .B({11'b0,memory2a[6:0]}), .P(p2a_all));
--MULT18X18 mult3a (.A({10'b0,xa5_reg_comp[7:0]}), .B({11'b0,memory3a[6:0]}), .P(p3a_all));
--MULT18X18 mult4a (.A({10'b0,xa4_reg_comp[7:0]}), .B({11'b0,memory4a[6:0]}), .P(p4a_all));
--MULT18X18 mult5a (.A({10'b0,xa3_reg_comp[7:0]}), .B({11'b0,memory5a[6:0]}), .P(p5a_all));
--MULT18X18 mult6a (.A({10'b0,xa2_reg_comp[7:0]}), .B({11'b0,memory6a[6:0]}), .P(p6a_all));
--MULT18X18 mult7a (.A({10'b0,xa1_reg_comp[7:0]}), .B({11'b0,memory7a[6:0]}), .P(p7a_all));
--MULT18X18 mult8a (.A({10'b0,xa0_reg_comp[7:0]}), .B({11'b0,memory8a[6:0]}), .P(p8a_all));
xor1a <= (xa7_reg_sign) xor (memory1a(7));
xor2a <= (xa6_reg_sign) xor (memory2a(7));
xor3a <= (xa5_reg_sign) xor (memory3a(7));
xor4a <= (xa4_reg_sign) xor (memory4a(7));
xor5a <= (xa3_reg_sign) xor (memory5a(7));
xor6a <= (xa2_reg_sign) xor (memory6a(7));
xor7a <= (xa1_reg_sign) xor (memory7a(7));
xor8a <= (xa0_reg_sign) xor (memory8a(7));
PROCESS (RST, CLK)
BEGIN
IF (RST = '1') THEN
p1a <= "0000000000000000000000";
p2a <= "0000000000000000000000";
p3a <= "0000000000000000000000";
p4a <= "0000000000000000000000";
p5a <= "0000000000000000000000";
p6a <= "0000000000000000000000";
p7a <= "0000000000000000000000";
p8a <= "0000000000000000000000";
indexi_val <= "000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1' AND prod_en1 = "1001") THEN
if (xor1a = '1') then p1a <= not("000000" & p1a_all(15 downto 0)) + '1';
elsif (xor1a = '0') then p1a <= ("000000" & p1a_all(15 downto 0)); end if;
if (xor2a = '1') then p2a <= not("000000" & p2a_all(15 downto 0)) + '1';
elsif (xor2a = '0') then p2a <= ("000000" & p2a_all(15 downto 0)); end if;
if (xor3a = '1') then p3a <= not("000000" & p3a_all(15 downto 0)) + '1';
elsif (xor3a = '0') then p3a <= ("000000" & p3a_all(15 downto 0)); end if;
if (xor4a = '1') then p4a <= not("000000" & p4a_all(15 downto 0)) + '1';
elsif (xor4a = '0') then p4a <= ("000000" & p4a_all(15 downto 0)); end if;
if (xor5a = '1') then p5a <= not("000000" & p5a_all(15 downto 0)) + '1';
elsif (xor5a = '0') then p5a <= ("000000" & p5a_all(15 downto 0)); end if;
if (xor6a = '1') then p6a <= not("000000" & p6a_all(15 downto 0)) + '1';
elsif (xor6a = '0') then p6a <= ("000000" & p6a_all(15 downto 0)); end if;
if (xor7a = '1') then p7a <= not("000000" & p7a_all(15 downto 0)) + '1';
elsif (xor7a = '0') then p7a <= ("000000" & p7a_all(15 downto 0)); end if;
if (xor8a = '1') then p8a <= not("000000" & p8a_all(15 downto 0)) + '1';
elsif (xor8a = '0') then p8a <= ("000000" & p8a_all(15 downto 0)); end if;
IF (indexi_val = "111") THEN
indexi_val <= "000";
ELSE
indexi_val <= indexi_val + "001";
END IF;
ELSE
p1a <= "0000000000000000000000";
p2a <= "0000000000000000000000";
p3a <= "0000000000000000000000";
p4a <= "0000000000000000000000";
p5a <= "0000000000000000000000";
p6a <= "0000000000000000000000";
p7a <= "0000000000000000000000";
p8a <= "0000000000000000000000";
END IF;
END IF;
END PROCESS;
-- Final adder. Adding the ouputs of the 4 multipliers
-- max value for z_out_int = 2047*126*8 = 2063376 = 21 bits
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
z_out_int1 <= "0000000000000000000000";
z_out_int2 <= "0000000000000000000000";
z_out_int3 <= "0000000000000000000000";
z_out_int4 <= "0000000000000000000000";
z_out_int <= "0000000000000000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
z_out_int1 <= p1a + p2a;
z_out_int2 <= p3a + p4a;
z_out_int3 <= p5a + p6a;
z_out_int4 <= p7a + p8a;
z_out_int <= z_out_int1 + z_out_int2 + z_out_int3 + z_out_int4;
END IF;
END PROCESS;
-- rounding of the value
-- max value for a 1D-DCT output is "11111111"*126*8/256=1004.
-- max value for a 1D-DCT output is "11111111"*126*8/256=1004.
-- To represent this we need only 10 bits, plus 1 bit for sign
z_out_rnd <= z_out_int(18 downto 8) ;
z_out <= (z_out_rnd + "00000000001") WHEN z_out_int(7) = '1' ELSE z_out_rnd;
-- 1D-DCT END
-- tranpose memory to store intermediate Z coefficients
-- store the 64 coefficients in the first 64 locations of the RAM
-- first valid final (product) adder ouput is at the 13th clk. 8clk SR
-- first valid final (product) adder ouput is at the 13th clk. 8clk SR
-- + 1 clk reg + 1 clk comp + 1 clk prod. + 2 clks summing.
-- So the RAM is enabled at the 11th clk)
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
cntr11 <= "0000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (rdy_in = '1') THEN
cntr11 <= cntr11 + "0001";
END IF;
END IF;
END PROCESS;
en_ram1 <= '0' WHEN RST = '1' ELSE '1' WHEN (cntr11 = "1100") ELSE en_ram1;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
en_ram1reg <= '0';
ELSIF (CLK'EVENT AND CLK = '1') THEN
en_ram1reg <= en_ram1;
END IF;
END PROCESS;
-- After the RAM is enabled, data is written into the RAM1 for 64 clk cycles. Data is written in into
-- After the RAM is enabled, data is written into the RAM1 for 64 clk cycles. Data is written in into
-- each consecutive location . After 64 locations are written into, RAM1 goes into read mode and RAM2 goes into
-- write mode. The cycle then repeats.
-- For either RAM, data is written into each consecutive location. However , data is read in a different order. If data
-- is assumed to be written in each row at a time, in an 8x8 matrix, data is read each column at a time. ie., after
-- the first data is read out, every eight data is read out . Then the 2nd data is read out followed be every 8th.
-- the write is as follows:
-- 1w(ram_locn1) 2w(ram_locn2) 3w(ram_locn3) 4w(ram_locn4) 5w(ram_locn5) 6w(ram_locn6) 7w(ram_locn7) 8w(ram_locn8)
-- 9w(ram_locn9) 10w(ram_locn10) 11w(ram_locn11) 12w(ram_locn12) 13w(ram_locn13) 14w(ram_locn14) 15w(ram_locn15) 16w(ram_locn16)
-- ..................
-- 57w(ram_locn57) 58w(ram_locn58) 59w(ram_locn59) 60w(ram_locn60) 61w(ram_locn61) 62w(ram_locn62) 63w(ram_locn63) 64w(ram_locn64)
-- the read is as follows:
-- 1r(ram_locn1) 9r(ram_locn2) . . . 57r(ram_locn8)
-- 2r(ram_locn9) 10r(ram_locn10) . . . 58r(ram_locn16)
-- 3r(ram_locn17) 11r(ram_locn18) . . . 59r(ram_locn24)
-- 4r(ram_locn25) 12r(ram_locn26) . . . 60r(ram_locn32)
-- 5r(ram_locn33) 13r(ram_locn34) . . . 61r(ram_locn40)
-- 6r(ram_locn41) 14r(ram_locn42) . . . 62r(ram_locn48)
-- 7r(ram_locn49) 15r(ram_locn50) . . . 63r(ram_locn56)
-- 8r(ram_locn57) 16r(ram_locn58) . . . 64r(ram_locn64)
-- where "xw" is the xth write and "ram_locnx" is the xth ram location and "xr" is the xth read. Reading
-- is advanced by the read counter rd_cntr, nd writing by the write counter wr_cntr.
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
rd_cntr(5 downto 3) <= "111";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (en_ram1reg = '1') THEN
rd_cntr(5 downto 3) <= rd_cntr(5 downto 3) + "001";
END IF;
END IF;
END PROCESS;
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
rd_cntr(2 downto 0) <= "111";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -