📄 dct.vhd
字号:
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; END PROCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -