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

📄 huffman_en.v

📁 用于FPGA的huffman算法的HDL编码
💻 V
📖 第 1 页 / 共 3 页
字号:
       codelength1 <= 5'b0;  vlcode1 <= 18'b0;
       end
   else if (rdy_in == 1'b1 & cntr64 == 7'b0000010)
       begin
	    codelength1 <= {1'b0,codelength_dc};
       vlcode1 <= {8'b0,vlcode_dc};
       end
   else
      begin
		 codelength1 <= codelength_ac;
      vlcode1 <= {vlcode_ac};
      end
   end

/*****************************************************************************/

/* pipeline code and codelength. This is done to match the pipestages with
cl_sum_prev which is multiplied with vlcode. */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       codelength2 <= 5'b0; 
       vlcode2 <= 18'b0; vlcode3 <= 18'b0;vlcode4 <= 18'b0;
       end
   else if (rdy_in == 1'b1)
       begin
	     codelength2 <= codelength1; 
       vlcode2 <= vlcode1; vlcode3 <= vlcode2;vlcode4 <= vlcode3;
       end
   end


/*****************************************************************************/
/* The maximum length of the vlc code can be 18 bits + 6 bits = 24 bits. This happens 
when a run level pair not defined in the table is encountered. In this case , a 6 bit 
escape code followed by 6 bit run code and 12 bit level code is used.  The minimum 
length of the vlc code is 2 bits. This happens when encoding an "EOB" symbol. After 
finding the vlc code for a particular run/level pair, the code is shifted into a 
barrel shifter.

Every time there are 16 bits in the barrel shifter, the contends of the shifter is
enabled out as the huffman_out signal. Each run length value is read in and the corresponding 
vlc code is found out (vlcode_dc or vlcode_ac1). For each code, the codelength is also
stored in a ROM. The codelengths are added up (cl_sum) and when it reaches 16 or 32, 
the code is sent out. 

The maximum  value for cl_sum happens when a 15 bit code is followed by a 24 bit
code. So the max. value for cl_sum is 15 + 24 = 39. The barrel shifter has 39 valid
registers. For ease of coding, 48 (3 * 16) registers are used. These registers are
divided into upper_reg, middle_reg and lower_reg. Each time upper_reg if full (ie., 
16 or more bits in barrel shifter), the contends are sent out. The remaining bits
, if any, in the middle_reg are moved up to the upper_reg. If the barrel shifter 
has 32 or more valid data, the upper and middle registers are full and the upper
reg data is sent out followed by the middle reg data. The remaining bits, if any 
in the lower register is moved up to the upper register.*/

/*****************************************************************************/
/* calculate sum of codelength. set half flag and full flag . Half flags indicates
that the upper_reg is full and full flag indicates that the lower register is full.
cl_sum_prev gives the sum of the codelengths which is used to set the flags. cl_sum
is used to find out the number of shifts to be done in the barrel shifts.*/

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       cl_sum <= 6'b100111; cl_sum_prev <= 6'b0;
       half_flag1 <= 1'b0; full_flag1 <= 1'b0;
       end
   else if ( cl_sum_rdy == 1'b1)
       begin
          if (cl_sum_prev < 6'd16)
            begin  
            cl_sum_prev <= codelength1 + cl_sum_prev;
            cl_sum <= (6'b100111 - cl_sum_prev);
            half_flag1 <= 1'b0;
            full_flag1 <= 1'b0;
			     end
          else if (cl_sum_prev <= 6'd32 && cl_sum_prev >= 6'd16)
            begin 
            cl_sum_prev <= codelength1 + (cl_sum_prev - 5'b10000);
            cl_sum <= (6'b100111 - cl_sum_prev);
            half_flag1 <= 1'b1;
            full_flag1 <= 1'b0;
			     end
          else if (cl_sum_prev >= 6'd32)
            begin 
            cl_sum_prev <= codelength1 + (cl_sum_prev - 6'b100000);
            cl_sum <= (6'b100111 - cl_sum_prev);
            half_flag1 <= 1'b1;
            full_flag1 <= 1'b1;
			     end
       end
   end

/*****************************************************************************/

/* barrel shifting done using multiplier. Barrel shifting coefficients are
stored in a ROM and selected depending on the value of cl_sum */

always @ (posedge CLK)
   begin
   if (RST)
       begin
       cl_sum_shift <= 39'b0; 
       end
  else 
    begin
    case (cl_sum)
       6'd0 : begin cl_sum_shift <=  39'b000000000000000000000000000000000000000; end   
       6'd1 : begin cl_sum_shift <=  39'b000000000000000000000000000000000000010; end   
       6'd2 : begin cl_sum_shift <=  39'b000000000000000000000000000000000000100; end   
       6'd3 : begin cl_sum_shift <=  39'b000000000000000000000000000000000001000; end   
       6'd4 : begin cl_sum_shift <=  39'b000000000000000000000000000000000010000; end   
       6'd5 : begin cl_sum_shift <=  39'b000000000000000000000000000000000100000; end   
       6'd6 : begin cl_sum_shift <=  39'b000000000000000000000000000000001000000; end   
       6'd7 : begin cl_sum_shift <=  39'b000000000000000000000000000000010000000; end   
       6'd8 : begin cl_sum_shift <=  39'b000000000000000000000000000000100000000; end   
       6'd9 : begin cl_sum_shift <=  39'b000000000000000000000000000001000000000; end   
       6'd10 : begin cl_sum_shift <= 39'b000000000000000000000000000010000000000; end   
       6'd11 : begin cl_sum_shift <= 39'b000000000000000000000000000100000000000; end   
       6'd12 : begin cl_sum_shift <= 39'b000000000000000000000000001000000000000; end   
       6'd13 : begin cl_sum_shift <= 39'b000000000000000000000000010000000000000; end   
       6'd14 : begin cl_sum_shift <= 39'b000000000000000000000000100000000000000; end   
       6'd15 : begin cl_sum_shift <= 39'b000000000000000000000001000000000000000; end   
       6'd16 : begin cl_sum_shift <= 39'b000000000000000000000010000000000000000; end   
       6'd17 : begin cl_sum_shift <= 39'b000000000000000000000100000000000000000; end   
       6'd18 : begin cl_sum_shift <= 39'b000000000000000000001000000000000000000; end   
       6'd19 : begin cl_sum_shift <= 39'b000000000000000000010000000000000000000; end   
       6'd20 : begin cl_sum_shift <= 39'b000000000000000000100000000000000000000; end   
       6'd21 : begin cl_sum_shift <= 39'b000000000000000001000000000000000000000; end   
       6'd22 : begin cl_sum_shift <= 39'b000000000000000010000000000000000000000; end   
       6'd23 : begin cl_sum_shift <= 39'b000000000000000100000000000000000000000; end   
       6'd24 : begin cl_sum_shift <= 39'b000000000000001000000000000000000000000; end   
       6'd25 : begin cl_sum_shift <= 39'b000000000000010000000000000000000000000; end   
       6'd26 : begin cl_sum_shift <= 39'b000000000000100000000000000000000000000; end   
       6'd27 : begin cl_sum_shift <= 39'b000000000001000000000000000000000000000; end   
       6'd28 : begin cl_sum_shift <= 39'b000000000010000000000000000000000000000; end   
       6'd29 : begin cl_sum_shift <= 39'b000000000100000000000000000000000000000; end   
       6'd30 : begin cl_sum_shift <= 39'b000000001000000000000000000000000000000; end   
       6'd31 : begin cl_sum_shift <= 39'b000000010000000000000000000000000000000; end   
       6'd32 : begin cl_sum_shift <= 39'b000000100000000000000000000000000000000; end   
       6'd33 : begin cl_sum_shift <= 39'b000001000000000000000000000000000000000; end   
       6'd34 : begin cl_sum_shift <= 39'b000010000000000000000000000000000000000; end   
       6'd35 : begin cl_sum_shift <= 39'b000100000000000000000000000000000000000; end   
       6'd36 : begin cl_sum_shift <= 39'b001000000000000000000000000000000000000; end   
       6'd37 : begin cl_sum_shift <= 39'b010000000000000000000000000000000000000; end   
       6'd38 : begin cl_sum_shift <= 39'b100000000000000000000000000000000000000; end    
       default : begin cl_sum_shift <= 39'b000000000000000000000000000000000000000; end  
       endcase
       end
end

/*****************************************************************************/
/* multiplier used to do barrel shifting of codeword. flags pipeleined to match
the pipe line stages of upper, middle and lower registers. */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       mult_out <= 39'b0; 
       full_flag2 <= 1'b0; half_flag2 <= 1'b0;
       full_flag3 <= 1'b0; half_flag3 <= 1'b0;
       full_flag4 <= 1'b0; half_flag4 <= 1'b0;
       full_flag5 <= 1'b0; half_flag5 <= 1'b0;
       full_flag6 <= 1'b0;
       end
   else if (rdy_in == 1'b1)
       begin
         mult_out <= vlcode4 * cl_sum_shift;
         full_flag2 <= full_flag1; half_flag2 <= half_flag1;
         full_flag3 <= full_flag2; half_flag3 <= half_flag2;
         full_flag4 <= full_flag3; half_flag4 <= half_flag3;
         full_flag5 <= full_flag4; half_flag5 <= half_flag4;
         full_flag6 <= full_flag5; 
       end
end

/*****************************************************************************/
always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       upper_reg1 <= 16'b0; middle_reg1 <= 16'b0; lower_reg1 <= 16'b0;
       end
   else if (rdy_in == 1'b1)
       begin
         case({full_flag4, half_flag4})
         2'b00: begin upper_reg1[16:1] <= mult_out[38:23] | upper_reg1[16:1];
                      middle_reg1 <= mult_out[22:7] ;
                      lower_reg1 <= {mult_out[6:0],9'b0 }; end
         2'b01: begin upper_reg1[16:1] <= mult_out[38:23] | middle_reg1[16:1];
                      middle_reg1 <= mult_out[22:7];
                      lower_reg1 <= {mult_out[6:0],9'b0}; end
         2'b11: begin upper_reg1 <= mult_out[38:23] | lower_reg1;
                      middle_reg1 <= mult_out[22:7];
                      lower_reg1 <= {16'b0}; end
         default:begin upper_reg1 <= upper_reg1;
                      middle_reg1 <= middle_reg1;
                      lower_reg1 <= lower_reg1; end
         endcase
       end     
   end

/*****************************************************************************/

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       upper_reg2 <= 16'b0; middle_reg2 <= 16'b0; 
       middle_reg3 <= 16'b0; 
       end
   else if (rdy_in == 1'b1)
       begin
          upper_reg2 <= upper_reg1;
          middle_reg2 <= middle_reg1;
          middle_reg3 <= middle_reg2;
          
       end     
   end

/*****************************************************************************/

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       huffman_out <= 16'b0; 
       end
   else if (rdy_in == 1'b1)
       begin
       if (half_flag5 == 1'b1)
           huffman_out <= upper_reg2;
       else if (full_flag6 == 1'b1)
           huffman_out <= middle_reg3;
			end
    end

/*****************************************************************************/

/* counter that counts upto 64. */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       cntr64 <= 7'b1000000;
       end
   else if (rdy_in == 1'b1)
        begin
          if (cntr64 < 7'b1000000)
              cntr64 <= cntr64 + 1;
          else 
              cntr64 <= 7'b0000001;
        end
  end  

/* cl_sum starts after 2 clks from reset. */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       cl_sum_rdy <= 1'b0;
       end
   else 
        begin
          if (cntr64 == 7'b0000010)
              cl_sum_rdy <= 1'b1;
          else 
              cl_sum_rdy <= cl_sum_rdy;
        end
  end  
/*****************************************************************************/

/* counter that counts upto 64. */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       rdy_out <= 1'b0;
       end
   else if (rdy_in == 1'b1)
        begin
        rdy_out <= 1'b1;
        end
  end  

/*****************************************************************************/
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -