⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dct.vhd

📁 用verilog语言实现DCT编解码 附有DCT的说明
💻 VHD
📖 第 1 页 / 共 3 页
字号:
   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 + -