📄 dct.vhd
字号:
BEGIN
IF (RST = '1') THEN
add_sub1a <= "0000000000";
add_sub2a <= "0000000000";
add_sub3a <= "0000000000";
add_sub4a <= "0000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (toggleA = '1') THEN
add_sub1a <= "0" & (xa7_reg + xa0_reg);
add_sub2a <= "0" & (xa6_reg + xa1_reg);
add_sub3a <= "0" & (xa5_reg + xa2_reg);
add_sub4a <= "0" & (xa4_reg + xa3_reg);
ELSE
IF (toggleA = '0') THEN
add_sub1a <= "0" & (xa7_reg - xa0_reg);
add_sub2a <= "0" & (xa6_reg - xa1_reg);
add_sub3a <= "0" & (xa5_reg - xa2_reg);
add_sub4a <= "0" & (xa4_reg - xa3_reg);
END IF;
END IF;
END IF;
END PROCESS;
--The above if else statement used to get the add_sub signals can also be
--implemented. The above if else statement used to get the add_sub signals
-- can also be implemented using the adsu16 library element as follows
--ADSU8 adsu8_1 (.A(xa0_reg), .B(xa7_reg), .ADD(toggleA), .CI(1'b0), .S(add_sub1a_all), .OFL(add_sub1a_ofl), .CO(open));
--ADSU8 adsu8_2 (.A(xa1_reg), .B(xa6_reg), .ADD(toggleA), .CI(1'b0), .S(add_sub2a_all), .OFL(add_sub1a_ofl), .CO(open));
--ADSU8 adsu8_3 (.A(xa2_reg), .B(xa5_reg), .ADD(toggleA), .CI(1'b0), .S(add_sub3a_all), .OFL(add_sub1a_ofl), .CO(open));
--ADSU8 adsu8_4 (.A(xa3_reg), .B(xa4_reg), .ADD(toggleA), .CI(1'b0), .S(add_sub4a_all), .OFL(add_sub1a_ofl), .CO(open));
-- In addition, Coregen can be used to create adder/subtractor units specific to a particular
-- In addition, Coregen can be used to create adder/subtractor units specific to a particular
-- device. The coregen model is then instantiated in the design file. The verilog file from
-- coregen can be used along with the design files for simulation and implementation.
--add_sub adsu8_1 (.A(xa0_reg), .B(xa7_reg), .ADD(toggleA), .CLK(CLK), .Q(add_sub1a));
--add_sub adsu8_2 (.A(xa1_reg), .B(xa6_reg), .ADD(toggleA), .CLK(CLK), .Q(add_sub2a));
--add_sub adsu8_3 (.A(xa2_reg), .B(xa5_reg), .ADD(toggleA), .CLK(CLK), .Q(add_sub3a));
--add_sub adsu8_4 (.A(xa3_reg), .B(xa4_reg), .ADD(toggleA), .CLK(CLK), .Q(add_sub4a));
-- 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
PROCESS (RST, CLK)
BEGIN
IF (RST = '1') THEN
i_wait <= "01";
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF (i_wait /= "00") THEN
i_wait <= i_wait - "01";
ELSE
i_wait <= "00";
END IF;
END IF;
END PROCESS;
-- 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
-- sign and magnitude separated here. magnitude of 9 std_logics is stored in *comp
P_comp1a: process (RST,CLK)
begin
if (RST = '1') then
addsub1a_comp <= (others => '0'); save_sign1a <= '0';
elsif (rising_edge (CLK)) then
if(add_sub1a(9) = '0') then
addsub1a_comp <= add_sub1a(7 downto 0); save_sign1a <= '0';
else
addsub1a_comp <= (not(add_sub1a(7 downto 0))) + '1'; save_sign1a <= '1';
end if;
end if;
end process P_comp1a;
P_comp2a: process (RST,CLK)
begin
if (RST = '1') then
addsub2a_comp <= (others => '0'); save_sign2a <= '0';
elsif (rising_edge (CLK)) then
if(add_sub2a(9) = '0') then
addsub2a_comp <= add_sub2a(7 downto 0); save_sign2a <= '0';
else
addsub2a_comp <= (not(add_sub2a(7 downto 0))) + '1'; save_sign2a <= '1';
end if;
end if;
end process P_comp2a;
P_comp3a: process (RST,CLK)
begin
if (RST = '1') then
addsub3a_comp <= (others => '0'); save_sign3a <= '0';
elsif (rising_edge (CLK)) then
if(add_sub3a(9) = '0') then
addsub3a_comp <= add_sub3a(7 downto 0); save_sign3a <= '0';
else
addsub3a_comp <= (not(add_sub3a(7 downto 0))) + '1'; save_sign3a <= '1';
end if;
end if;
end process P_comp3a;
P_comp4a: process (RST,CLK)
begin
if (RST = '1') then
addsub4a_comp <= (others => '0'); save_sign4a <= '0';
elsif (rising_edge (CLK)) then
if(add_sub4a(9) = '0') then
addsub4a_comp <= add_sub4a(7 downto 0); save_sign4a <= '0';
else
addsub4a_comp <= (not(add_sub4a(7 downto 0))) + '1'; save_sign4a <= '1';
end if;
end if;
end process P_comp4a;
p1a_all <= (addsub1a_comp * memory1a(6 downto 0));
p2a_all <= (addsub2a_comp * memory2a(6 downto 0));
p3a_all <= (addsub3a_comp * memory3a(6 downto 0));
p4a_all <= (addsub4a_comp * memory4a(6 downto 0));
-- The following instantiation can be used while targetting Virtex2
--MULT18X18 mult1a (.A({9'b0,addsub1a_comp}), .B({11'b0,memory1a[6:0]}), .P(p1a_all));
--MULT18X18 mult2a (.A({9'b0,addsub2a_comp}), .B({11'b0,memory2a[6:0]}), .P(p2a_all));
--MULT18X18 mult3a (.A({9'b0,addsub3a_comp}), .B({11'b0,memory3a[6:0]}), .P(p3a_all));
--MULT18X18 mult4a (.A({9'b0,addsub4a_comp}), .B({11'b0,memory4a[6:0]}), .P(p4a_all));
xor1a <= (save_sign1a) xor (memory1a(7));
xor2a <= (save_sign2a) xor (memory2a(7));
xor3a <= (save_sign3a) xor (memory3a(7));
xor4a <= (save_sign4a) xor (memory4a(7));
P_prodA:process(CLK,RST)
begin
if (RST = '1') then
p1a <= (others =>'0'); p2a <= (others =>'0');
p3a <= (others =>'0'); p4a <= (others =>'0'); indexi<= 7;
elsif (rising_edge (CLK)) then
if(i_wait = "00") then
if (xor1a = '1') then p1a <= not("0000" & p1a_all(14 downto 0)) + '1';
elsif (xor1a = '0') then p1a <= ("0000" & p1a_all(14 downto 0)); end if;
if (xor2a = '1') then p2a <= not("0000" & p2a_all(14 downto 0)) + '1';
elsif (xor2a = '0') then p2a <= ("0000" & p2a_all(14 downto 0)); end if;
if (xor3a = '1') then p3a <= not("0000" & p3a_all(14 downto 0)) + '1';
elsif (xor3a = '0') then p3a <= ("0000" & p3a_all(14 downto 0)); end if;
if (xor4a = '1') then p4a <= not("0000" & p4a_all(14 downto 0)) + '1';
elsif (xor4a = '0') then p4a <= ("0000" & p4a_all(14 downto 0)); end if;
if (indexi = 7) then
indexi <= 0;
else
indexi <= indexi + 1;
end if;
end if;
end if;
end process P_prodA;
--always @ (posedge RST or posedge CLK)
-- always @ (posedge RST or posedge CLK)
-- begin
-- if (RST)
-- begin
-- p1a <= 19'b0; p2a <= 19'b0; p3a <= 19'b0; p4a <= 19'b0; indexi<= 7;
-- end
-- else if (i_wait == 2'b00)
-- begin
-- p1a <= (save_sign1a ^ memory1a[7]) ? (-addsub1a_comp * memory1a[6:0]) :(addsub1a_comp * memory1a[6:0]);
-- p2a <= (save_sign2a ^ memory2a[7]) ? (-addsub2a_comp * memory2a[6:0]) :(addsub2a_comp * memory2a[6:0]);
-- p3a <= (save_sign3a ^ memory3a[7]) ? (-addsub3a_comp * memory3a[6:0]) :(addsub3a_comp * memory3a[6:0]);
-- p4a <= (save_sign4a ^ memory4a[7]) ? (-addsub4a_comp * memory4a[6:0]) :(addsub4a_comp * memory4a[6:0]);
-- if (indexi == 7)
-- indexi <= 0;
-- else
-- indexi <= indexi + 1;
-- end
-- end
-- Final adder. Adding the ouputs of the 4 multipliers
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
z_out_int1 <= "0000000000000000000";
z_out_int2 <= "0000000000000000000";
z_out_int <= "0000000000000000000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
z_out_int1 <= p1a + p2a;
z_out_int2 <= p3a + p4a;
z_out_int <= z_out_int1 + z_out_int2;
END IF;
END PROCESS;
z_out_rnd <= (z_out_int(18 downto 8) + "00000000001") WHEN z_out_int(7) = '1' ELSE z_out_int(18 downto 8);
-- 1 sign std_logic, 11 data std_logic
z_out <= z_out_rnd ;
-- 1D-DCT END
-- tranpose memory to store intermediate Z coeeficients
-- store the 64 coeeficients in the first 64 locations of the RAM
-- first valid adder output is at the 15th clk. (input reg + 8 std_logic SR + add_sub + comp. Signal + reg prod
-- first valid adder output is at the 15th clk. (input reg + 8 std_logic SR + add_sub + comp. Signal + reg prod
-- + 2 partial prod adds) So the RAM is enabled at the 15th clk)
PROCESS (CLK, RST)
BEGIN
IF (RST = '1') THEN
cntr12 <= "0000";
ELSIF (CLK'EVENT AND CLK = '1') THEN
cntr12 <= cntr12 + "0001";
END IF;
END PROCESS;
en_ram1 <= '0' WHEN RST = '1' ELSE '1' WHEN (cntr12 = "1101") 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";
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -