zoukankan      html  css  js  c++  java
  • JPEG解码:桶型寄存器

    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
    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行:产生输出使能。


     

  • 相关阅读:
    记录一些笔记~
    JS里的居民们7-对象和数组转换
    JS里的居民们6-数组排序
    JS里的居民们5-数组(栈)
    MySQL设置当前时间为默认值的方法
    session过期问题
    MyIsam和InnoDB的区别
    ajax请求 json格式和数组格式总结
    wamp 2.5 开放访问权限和设置虚拟域名
    checkbox属性checked="checked"通过js已设置,但是不勾选
  • 原文地址:https://www.cnblogs.com/tony1224/p/2392702.html
Copyright © 2011-2022 走看看