JPEG解码总共分为:桶型寄存器模块,状态控制模块,huffman解码模块,反量化模块,反zig_zag模块,反idct模块,色彩空间变换模块。桶型寄存器的作用是控制数据流和去除冗余。对于数据的控制是要求桶型存储器能读取数据的任何宽度,输出的数据给状态控制模块和huffman解码模块,状态控制模块要求输入的数据有两种,一种是8位,另一种是16位,huffman解码模块要求输入的数据为不定位数,huffman编码是不定位数的编码,所以在解码的时候事先不知道被解码数据的位数。冗余信息的产生是由于在编码非标志位的数据FF 时,必须在其后加上00,而产生了冗余信息00。所以再遇到FF00的时候必须去除00。
因为在一次解码的过程中,所需要的数据位数至少为27 位,所以使用两个32 位变量的组合来提供解码所需数据。为了便于冗余处理,一次处理数据的位数必须是16 的倍数,因此至少需要64位的数据寄存器用于解码。但实际上设计了一个96 位的寄存器给寄存器增加了32 位,在此32 位中可以去除冗余信息,以确保至少有64 位去冗余后的数据用于解码。
在加载新数据的过程中,用一个8位的计数器reg_width记录桶型寄存器的的有效数据的宽度,为了保证至少有32位数据输出,只有当计数器大于64时,才可以输出32位数据用于解码,为了防止桶型移位寄存器中未解码的数据被新的数据覆盖,只有当计数器值小于64时,才开始读入新的数据。每次解码之后,计数器的值都要减去本次解码所消耗的位数,确保下次输入数据的有效性。
代码如下:
1 `timescale 1ps / 1ps 2 module regdata( 3 clk, 4 rst_n, 5 6 start, 7 data, 8 data_en, 9 data_read, 10 11 data_out, 12 dataout_en, 13 data_end, 14 15 FF00, 16 17 use_bit, 18 use_width, 19 use_byte, 20 use_word 21 ); 22 23 24 input clk;//系统输入时钟信号 25 input rst_n;//复位信号,低电平有效 26 27 input start;//开始信号 28 input [31:0] data;//输入数据 29 input data_en;//输入数据使能信号 30 output data_read;//读取存储器信号 31 32 output [31:0] data_out;//输出数据 33 output dataout_en;//数据输出使能信号 34 output data_end;//数据传输结束信号 35 36 input FF00;//允许去除冗余 37 38 input use_bit;//使用位传输数据 39 input [6:0] use_width;//传输的位宽 40 input use_byte;//每次传输一个字节 8bit 41 input use_word;//每次传输一个字 16bit 42 43 reg [95:0] reg_data;//96位的移位寄存器,用于保存每次进来的数据 44 reg [7:0] reg_width;//移位寄存器的有效数据的位数 45 46 wire valid; //有效信号, 47 assign valid = reg_width > 64; 48 //---------------------------------------------- 49 //寄存器中的数据少于64位产生读外部存储器请求信号, 50 //即移出的超过32位时候继续读入数据(读入为32位) 51 assign data_read = valid == 1'b0 & data_en == 1'b1; 52 53 always @(posedge clk or negedge rst_n) 54 begin 55 if(!rst_n) 56 begin 57 reg_data <= 96'd0; 58 reg_width <= 8'h00; 59 end 60 else 61 begin 62 if(start == 1'b1) //数据开始,清空各值 63 begin 64 reg_data <= 96'd0; 65 reg_width <= 8'h00; 66 end 67 else if(valid == 1'b0 & data_en == 1'b1) //此情况为读取新数据 68 begin 69 if(FF00 == 1'b1) //sos开始,即读表信息结束,开始解码..............允许去冗余! 70 begin 71 if(reg_data[39: 8] == 32'hFF00FF00) 72 begin 73 reg_width <= reg_width + 8'd16; 74 reg_data[95:64] <= {8'h00,reg_data[71:48]}; 75 reg_data[63:32] <= {reg_data[47:40],16'hFFFF,reg_data[7:0]}; 76 end 77 else if(reg_data[39:24] == 16'hFF00 & reg_data[15: 0] == 16'hFF00) 78 begin 79 reg_width <= reg_width + 8'd16; 80 reg_data[95:64] <= {8'h00,reg_data[71:48]}; 81 reg_data[63:32] <= {reg_data[47:40],8'hFF,reg_data[23:16],8'hFF}; 82 end 83 else if(reg_data[31: 0] == 32'hFF00FF00) 84 begin 85 reg_width <= reg_width + 8'd16; 86 reg_data[95:64] <= {16'h0000,reg_data[71:56]}; 87 reg_data[63:32] <= {reg_data[55:40],16'hFFFF}; 88 end 89 else if(reg_data[39:24] == 16'hFF00) 90 begin 91 reg_width <= reg_width + 8'd24; 92 reg_data[95:64] <= {reg_data[71:40]}; 93 reg_data[63:32] <= {8'hFF,reg_data[23:0]}; 94 end 95 else if(reg_data[31:16] == 16'hFF00) 96 begin 97 reg_width <= reg_width + 8'd24; 98 reg_data[95:64] <= {reg_data[71:40]}; 99 reg_data[63:32] <= {reg_data[39:32],8'hFF,reg_data[15:0]};100 end |