📄 huffman_en.v
字号:
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 + -