打印

JPEG解码中桶型寄存器研究

[复制链接]
1172|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xuehua230|  楼主 | 2012-10-12 14:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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

相关帖子

沙发
xuehua230|  楼主 | 2012-10-12 14:53 | 只看该作者
101                else if(reg_data[23: 8] == 16'hFF00)
102                begin
103                   reg_width <= reg_width + 8'd24;
104                                   reg_data[95:64] <= {reg_data[71:40]};
105                   reg_data[63:32] <= {reg_data[39:32],reg_data[31:24],8'hFF,reg_data[7:0]};
106                end
107                else if(reg_data[15: 0] == 16'hFF00)
108                begin
109                   reg_width <= reg_width + 8'd24;
110                                   reg_data[95:64] <= {reg_data[71:40]};
111                   reg_data[63:32] <= {reg_data[39:32],reg_data[31:16],8'hFF};
112                end
113                 else
114                 begin
115                   reg_width <= reg_width + 8'd32;
116                                   reg_data[95:64] <= reg_data[63:32];
117                   reg_data[63:32] <= reg_data[31:0];
118                end
119             end
120            
121             else   
122             begin
123                reg_width <= reg_width + 8'd32;
124                        reg_data[95:64] <= reg_data[63:32];
125                reg_data[63:32] <= reg_data[31:0];
126             end
127               
128             //reg_data[31: 0] <= {dataIn[7:0],dataIn[15:8],dataIn[23:16],dataIn[31:24]};
129               reg_data[31: 0] <= {data[31:24],data[23:16],data[15:8],data[7:0]};
130          end
131        else if(use_bit == 1'b1)
132             begin
133              reg_width <= reg_width - use_width;
134            end
135        else if(use_byte == 1'b1)
136            begin
137             reg_width <= reg_width - 8'd8;
138            end
139        else if(use_word == 1'b1)
140            begin
141             reg_width <= reg_width - 8'd16;
142            end
143       end
144    end
145   
146 //---------------------------------------------------
147 //产生数据结束信号,当读到数据为FFD9,表示结束
148 assign data_end = (
149             reg_data[31:16] == 16'hFFd9 |
150             reg_data[23: 8] == 16'hFFd9 |
151             reg_data[15: 0] == 16'hFFd9
152             );
153
154 function [31:0] result;
155       input [95:0] reg_data;
156       input [7:0]  reg_width;
157
158       case(reg_width)
159         8'd65: result = reg_data[64:33];
160         8'd66: result = reg_data[65:34];
161         8'd67: result = reg_data[66:35];
162         8'd68: result = reg_data[67:36];
163         8'd69: result = reg_data[68:37];
164         8'd70: result = reg_data[69:38];
165         8'd71: result = reg_data[70:39];
166         8'd72: result = reg_data[71:40];
167         8'd73: result = reg_data[72:41];
168         8'd74: result = reg_data[73:42];
169         8'd75: result = reg_data[74:43];
170         8'd76: result = reg_data[75:44];
171         8'd77: result = reg_data[76:45];
172         8'd78: result = reg_data[77:46];
173         8'd79: result = reg_data[78:47];
174         8'd80: result = reg_data[79:48];
175         8'd81: result = reg_data[80:49];
176         8'd82: result = reg_data[81:50];
177         8'd83: result = reg_data[82:51];
178         8'd84: result = reg_data[83:52];
179         8'd85: result = reg_data[84:53];
180         8'd86: result = reg_data[85:54];
181         8'd87: result = reg_data[86:55];
182         8'd88: result = reg_data[87:56];
183         8'd89: result = reg_data[88:57];
184         8'd90: result = reg_data[89:58];
185         8'd91: result = reg_data[90:59];
186         8'd92: result = reg_data[91:60];
187         8'd93: result = reg_data[92:61];
188         8'd94: result = reg_data[93:62];
189         8'd95: result = reg_data[94:63];
190         8'd96: result = reg_data[95:64];
191         default: result = 32'h00000000;
192       endcase
193  endfunction
194
195 reg OutEnable;
196 reg PreEnable;
197   
198 reg[31:0] data_out;
199 always @(posedge clk or negedge rst_n)
200 begin
201  if(!rst_n)
202     begin
203      OutEnable <= 1'b0;
204      PreEnable <= 1'b0;
205      data_out   <= 32'h00000000;
206      end
207  else
208      begin
209      OutEnable <= reg_width >64;
210      PreEnable <= (use_bit == 1'b1 | use_byte == 1'b1 | use_word == 1'b1);//本次有反馈使用宽度,则不输出,下次输出。即等有反馈后才输出。
211      data_out   <= result(reg_data,reg_width);
212       end
213 end
214
215 assign dataout_en = (PreEnable == 1'b0)?OutEnable:1'b0;
216      
217 endmodule
218
219   
44行:声明一个96位数据寄存器,用于保存输入的数据。

45行:用于标记数据寄存器中有效数据的位数。

52行:当数据存储器中的数据少于64位时,并且输入数据允许时候,产生读信号。

70-119行:表示在SOS段允许去除冗余信息,对各种冗余信息出现不同的位置做相应的处理。

132-143行:数据寄存器的有效数据减去用到的数据宽度,确保数据的有效。

149-153行:当读到的数据位FFD9时表示数据结束信号,EOI段。

155-194行:用一个函数来控制有效的数据。

211行:当有用到数据宽度的时候,此时数据输出使能无效,此时的数据为无效数据,要等到数据去除用到的数据,此时的数据才为有效数据。

216行:产生输出使能。

使用特权

评论回复
板凳
GoldSunMonkey| | 2012-10-12 21:55 | 只看该作者
太乱啦。整理一下就好了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

336

帖子

1

粉丝