OpenCores
URL https://opencores.org/ocsvn/mpeg2fpga/mpeg2fpga/trunk

Subversion Repositories mpeg2fpga

[/] [mpeg2fpga/] [trunk/] [rtl/] [mpeg2/] [vld.v] - Rev 2

Compare with Previous | Blame | View Log

/* 
 * vld.v
 * 
 * Copyright (c) 2007 Koen De Vleeschauwer. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE.
 */
 
/*
 * vld - Variable Length Decoder. Scalability not implemented. Maximum vertical size of image in pixels: 2800.
 */
 
`include "timescale.v"
 
`undef DEBUG
//`define DEBUG 1
//`define DEBUG_VLC 1
 
/*
 * video decoding process as specified in 13818-2, par. 7.1 through 7.6
 */
 
module vld(clk, clk_en, rst, 
  getbits, signbit, advance, align, wait_state,                                             // interface with getbits
  quant_wr_data, quant_wr_addr, quant_rst,                                                  // interface with quantizer rams via rld_fifo
  wr_intra_quant, wr_non_intra_quant, wr_chroma_intra_quant, wr_chroma_non_intra_quant,     // interface with quantizer rams via rld_fifo
  rld_wr_en, rld_cmd, dct_coeff_run, dct_coeff_signed_level, dct_coeff_end,                 // interface with rld_fifo
  quantiser_scale_code, alternate_scan, q_scale_type, macroblock_intra, intra_dc_precision, // interface with rld_fifo
  picture_coding_type, picture_structure, motion_type, dct_type,                            // interface with motcomp
  motion_vert_field_select_0_0, motion_vert_field_select_0_1,                               // interface with motcomp
  motion_vert_field_select_1_0, motion_vert_field_select_1_1,                               // interface with motcomp
  second_field, update_picture_buffers, last_frame, mb_width, mb_height, chroma_format,     // interface with motcomp
  macroblock_address, macroblock_motion_forward, macroblock_motion_backward,                // interface with motcomp
  motion_vector_valid,                                                                      // interface with motcomp - motion vectors
  pmv_0_0_0, pmv_0_0_1, pmv_1_0_0, pmv_1_0_1, pmv_0_1_0, pmv_0_1_1, pmv_1_1_0, pmv_1_1_1,   // interface with motcomp - motion vectors
  dmv_0_0, dmv_0_1, dmv_1_0, dmv_1_1,                                                       // interface with motcomp - dual prime motion vectors
  horizontal_size, vertical_size, display_horizontal_size, display_vertical_size,           // interface with syncgen
  matrix_coefficients,                                                                      // interface with yuv2rgb
  frame_rate_code, frame_rate_extension_n, frame_rate_extension_d,                          // interface with regfile
  aspect_ratio_information,
  progressive_sequence, progressive_frame, repeat_first_field, top_field_first,             // interface with resample
  vld_err                                                                                   // asserted when vld code parse error
  );
 
  input            clk;                           // clock
  input            clk_en;                        // clock enable
  input            rst;                           // synchronous active low reset
  input      [23:0]getbits;                       // bit-aligned slice data. 16 bits long as longest variable length code is 16 bits.
  input            signbit;                       // sign bit of dct coefficient
 
  output reg  [4:0]advance;                       // number of bits to advance the bitstream (advance <= 24)
  output reg       align;                         // byte-align getbits and move forward one byte.
 
  output reg  [7:0]quant_wr_data;                 // data bus for quantizer matrix rams
  output reg  [5:0]quant_wr_addr;                 // address bus for quantizer matrix rams
  output reg       quant_rst;                     // reset quant matrices to default values
  output reg       wr_intra_quant;                // write enable for intra quantiser matrix
  output reg       wr_non_intra_quant;            // write enable for non intra quantiser matrix
  output reg       wr_chroma_intra_quant;         // write enable for chroma intra quantiser matrix
  output reg       wr_chroma_non_intra_quant;     // write enable for chroma non intra quantiser matrix
 
  output reg       vld_err;                       // vld_err is asserted when a slice parsing error has occurred. self-repairing.
 
  parameter [7:0]
    STATE_NEXT_START_CODE             = 8'h00,
    STATE_START_CODE                  = 8'h01,
 
    STATE_PICTURE_HEADER              = 8'h02,
    STATE_PICTURE_HEADER0             = 8'h03,
    STATE_PICTURE_HEADER1             = 8'h04,
    STATE_PICTURE_HEADER2             = 8'h05,
 
    STATE_SEQUENCE_HEADER             = 8'h06,
    STATE_SEQUENCE_HEADER0            = 8'h07,
    STATE_SEQUENCE_HEADER1            = 8'h08,
    STATE_SEQUENCE_HEADER2            = 8'h09,
    STATE_SEQUENCE_HEADER3            = 8'h0a,
 
    STATE_GROUP_HEADER                = 8'h0b,
    STATE_GROUP_HEADER0               = 8'h0c,
 
    STATE_EXTENSION_START_CODE        = 8'h10,
    STATE_SEQUENCE_EXT                = 8'h11,
    STATE_SEQUENCE_EXT0               = 8'h12,
    STATE_SEQUENCE_EXT1               = 8'h13,
    STATE_SEQUENCE_DISPLAY_EXT        = 8'h14,
    STATE_SEQUENCE_DISPLAY_EXT0       = 8'h15,
    STATE_SEQUENCE_DISPLAY_EXT1       = 8'h16,
    STATE_SEQUENCE_DISPLAY_EXT2       = 8'h17,
    STATE_QUANT_MATRIX_EXT            = 8'h18,
    STATE_PICTURE_CODING_EXT          = 8'h19,
    STATE_PICTURE_CODING_EXT0         = 8'h1a,
    STATE_PICTURE_CODING_EXT1         = 8'h1b,
 
    STATE_LD_INTRA_QUANT0             = 8'h20,
    STATE_LD_INTRA_QUANT1             = 8'h21,
    STATE_LD_NON_INTRA_QUANT0         = 8'h22,
    STATE_LD_NON_INTRA_QUANT1         = 8'h23,
    STATE_LD_CHROMA_INTRA_QUANT1      = 8'h24,
    STATE_LD_CHROMA_NON_INTRA_QUANT1  = 8'h25,
 
    STATE_SLICE                       = 8'h31,
    STATE_SLICE_EXTENSION             = 8'h32,
    STATE_SLICE_EXTRA_INFORMATION     = 8'h33,
    STATE_NEXT_MACROBLOCK             = 8'h34,
    STATE_MACROBLOCK_SKIP             = 8'h35,
    STATE_DELAY_EMPTY_BLOCK           = 8'h36,
    STATE_EMIT_EMPTY_BLOCK            = 8'h37,
    STATE_MACROBLOCK_TYPE             = 8'h38,
    STATE_MOTION_TYPE                 = 8'h39,
    STATE_DCT_TYPE                    = 8'h3a,
    STATE_MACROBLOCK_QUANT            = 8'h3b,
 
    STATE_NEXT_MOTION_VECTOR          = 8'h40,
    STATE_MOTION_VERT_FLD_SEL         = 8'h41, // motion_vectors: motion_vertical_field_select
    STATE_MOTION_CODE                 = 8'h42, // motion_vector: motion_code
    STATE_MOTION_RESIDUAL             = 8'h43, // motion_vector: motion_residual
    STATE_MOTION_DMVECTOR             = 8'h44, // motion_vector: dmvector
    STATE_MOTION_PREDICT              = 8'h45, // motion_vector: prediction pipeline begin
    STATE_MOTION_PIPELINE_FLUSH       = 8'h46, // motion_vector: prediction pipeline end
 
    STATE_MARKER_BIT_0                = 8'h60,
    STATE_CODED_BLOCK_PATTERN         = 8'h61,
    STATE_CODED_BLOCK_PATTERN_1       = 8'h62,
    STATE_CODED_BLOCK_PATTERN_2       = 8'h63,
 
    STATE_BLOCK                       = 8'h70,
    STATE_NEXT_BLOCK                  = 8'h71,
    STATE_DCT_DC_LUMI_SIZE            = 8'h72,
    STATE_DCT_DC_CHROMI_SIZE          = 8'h73,
    STATE_DCT_DC_DIFF                 = 8'h74,
    STATE_DCT_DC_DIFF_0               = 8'h75,
    STATE_DCT_SUBS_B15                = 8'h76,
    STATE_DCT_ESCAPE_B15              = 8'h77,
    STATE_DCT_SUBS_B14                = 8'h78,
    STATE_DCT_ESCAPE_B14              = 8'h79,
    STATE_DCT_NON_INTRA_FIRST         = 8'h7a,
    STATE_NON_CODED_BLOCK             = 8'h7b,
    STATE_DCT_ERROR                   = 8'h7c,
 
    STATE_SEQUENCE_END                = 8'h80,
 
    STATE_ERROR                       = 8'hff;
 
  /* start codes */
  parameter [7:0]
    CODE_PICTURE_START                = 8'h00,
    CODE_USER_DATA_START              = 8'hb2,
    CODE_SEQUENCE_HEADER              = 8'hb3,
    CODE_SEQUENCE_ERROR               = 8'hb4,
    CODE_EXTENSION_START              = 8'hb5,
    CODE_SEQUENCE_END                 = 8'hb7,
    CODE_GROUP_START                  = 8'hb8;
 
  /* extension start codes */
  parameter [3:0]
    EXT_SEQUENCE                      = 4'b0001,
    EXT_SEQUENCE_DISPLAY              = 4'b0010,
    EXT_QUANT_MATRIX                  = 4'b0011,
    EXT_COPYRIGHT                     = 4'b0100,
    EXT_SEQUENCE_SCALABLE             = 4'b0101,
    EXT_PICTURE_DISPLAY               = 4'b0111,
    EXT_PICTURE_CODING                = 4'b1000,
    EXT_PICTURE_SPATIAL_SCALABLE      = 4'b1001,
    EXT_PICTURE_TEMPORAL_SCALABLE     = 4'b1010,
    EXT_CAMERA_PARAMETERS             = 4'b1011,
    EXT_ITU_T                         = 4'b1100;
 
`include "vld_codes.v"
 
  parameter
    STRICT_MARKER_BIT = 1'b0;  /* set to 1 to check marker bits are 1. May break some streams. */
 
  /*
   *  Table 7-7 Meaning of indices in PMV[r][s][t], vector[r][s][t] and vector'[r][s][t]
   *
   *    0                                 1
   *  r First motion vector in Macroblock Second motion vector in Macroblock
   *  s Forward motion Vector             Backwards motion Vector
   *  t Horizontal Component              Vertical Component
   *
   *  NOTE r also takes the values 2 and 3 for derived motion vectors used with dual-prime prediction.
   *  Since these motion vectors are derived they do not themselves have motion vector predictors.
   */
  parameter [2:0] /* motion vector codes */
    MOTION_VECTOR_0_0_0 = 3'd0,
    MOTION_VECTOR_0_0_1 = 3'd1,
    MOTION_VECTOR_1_0_0 = 3'd2,
    MOTION_VECTOR_1_0_1 = 3'd3,
    MOTION_VECTOR_0_1_0 = 3'd4,
    MOTION_VECTOR_0_1_1 = 3'd5,
    MOTION_VECTOR_1_1_0 = 3'd6,
    MOTION_VECTOR_1_1_1 = 3'd7;
 
  reg         [7:0]state;
  reg         [7:0]next;
 
  reg         [4:0]next_advance;
 
  reg         [5:0]cnt; // counter used when loading quant matrices
 
  /* in start code */
  wire        [7:0]start_code;
 
  /* position in video stream */
  reg              sequence_header_seen;    /* set when sequence header encountered, cleared when sequence end encountered  */
  reg              sequence_extension_seen; /* set when sequence extension encountered, cleared when sequence end encountered  */
  reg              picture_header_seen;     /* set when picture header encountered, cleared when sequence end encountered  */
 
  /* in sequence header */
  output wire[13:0]horizontal_size;
  output wire[13:0]vertical_size;
  output reg  [7:0]mb_width;   /* par. 6.3.3. width of the encoded luminance component of pictures in macroblocks */
  output reg  [7:0]mb_height;  /* par. 6.3.3. height of the encoded luminance component of frame pictures in macroblocks */
  output wire [3:0]aspect_ratio_information;
  output wire [3:0]frame_rate_code;
  wire       [29:0]bit_rate;
  wire       [17:0]vbv_buffer_size;
  wire             constrained_parameters_flag;
 
  /* in sequence header extension */
  wire        [7:0]profile_and_level_indication;
  output wire      progressive_sequence;
  output wire [1:0]chroma_format;
  wire             low_delay;
  output wire [1:0]frame_rate_extension_n;
  output wire [4:0]frame_rate_extension_d;
 
  /* in sequence display extension */
  wire        [2:0]video_format;
  wire        [7:0]colour_primaries;
  wire        [7:0]transfer_characteristics;
  output wire [7:0]matrix_coefficients;
  output wire[13:0]display_horizontal_size;
  output wire[13:0]display_vertical_size;
 
  /* in picture coding extension */
  wire        [3:0]f_code_00;
  wire        [3:0]f_code_01;
  wire        [3:0]f_code_10;
  wire        [3:0]f_code_11;
  output wire [1:0]intra_dc_precision;
  output wire [1:0]picture_structure;
  output wire      top_field_first;
  wire             frame_pred_frame_dct;
  wire             concealment_motion_vectors;
  output wire      q_scale_type;
  wire             intra_vlc_format;
  output wire      alternate_scan;
  output wire      repeat_first_field;
  wire             chroma_420_type;
  output wire      progressive_frame;
  wire             composite_display_flag;
  wire             v_axis;
  wire        [2:0]field_sequence;
  wire             sub_carrier;
  wire        [6:0]burst_amplitude;
  wire        [7:0]sub_carrier_phase;
 
  /* in group of pictures header */
  wire             drop_flag;
  wire        [4:0]time_code_hours;
  wire        [5:0]time_code_minutes;
  wire        [5:0]time_code_seconds;
  wire        [5:0]time_code_pictures;
  wire             closed_gop;
  wire             broken_link;
 
  /* in picture header */
  wire        [9:0]temporal_reference;
  output wire [2:0]picture_coding_type;
  wire       [15:0]vbv_delay;
  wire             full_pel_forward_vector;
  wire        [2:0]forward_f_code;
  wire             full_pel_backward_vector;
  wire        [2:0]backward_f_code;
 
  /* in slice */
  output reg  [4:0]quantiser_scale_code;
  reg              slice_extension_flag;
  reg              intra_slice;
  reg              slice_picture_id_enable;
  reg         [5:0]slice_picture_id;
  reg         [7:0]slice_vertical_position;
  reg              first_macroblock_of_slice;
 
  /* macroblock address increment */
  wire        [3:0]macroblock_addr_inc_length;
  wire        [5:0]macroblock_addr_inc_value;
  wire        [6:0]macroblock_addr_inc_value_ext = macroblock_addr_inc_value;
  wire             macroblock_addr_inc_escape;
  reg         [6:0]macroblock_address_increment;
  /* 
   * macroblock address is valid after STATE_MACROBLOCK_TYPE and before STATE_NEXT_BLOCK. 
   * In particular: In the first slice of a picture, macroblock_address may be 0xffff after STATE_SLICE up to STATE_MACROBLOCK_TYPE.
   */
  output reg [12:0]macroblock_address; // High Level: macroblock_address is 13 bits, 0..8159, 8160..8191 unused.
  reg        [10:0]empty_blocks;
 
  /* macroblock type */
  wire        [3:0]macroblock_type_length;
  wire        [5:0]macroblock_type_value;
  reg              macroblock_quant;
  output reg       macroblock_motion_forward;
  output reg       macroblock_motion_backward;
  reg              macroblock_pattern;
  output reg       macroblock_intra;
  reg              macroblock_type_intra;
  reg              spatial_temporal_weight_code_flag; // ought always to be zero, as we don't do scaleability
  output reg  [1:0]motion_type; // one reg for both frame_motion_type and field_motion_type
  output reg       dct_type; // dct_type == 1 : field dct coded; dct_type == 0 : frame dct coded
  /* derived variables (par. 6.3.17.1, tables 6.17 and 6.18) */
  wire             motion_vector_count_is_one;
  reg         [1:0]mv_format;
  reg              dmv;
 
  /* motion vectors */
  reg         [2:0]motion_vector;  // current motion vector
  reg         [7:0]motion_vector_reg;  // bitmask of motion vectors present
  reg         [3:0]r_size; // f_code_xx  - 4'd1;
  wire             vertical_field_select_present;
  reg         [4:0]motion_code;
  reg              motion_code_neg;
  reg         [7:0]motion_code_residual; // motion_code_residual has up to r_size = f_code_xx - 1 bits. (par. 6.3.17.3) with f_code = 1..9 (Table E-8, high level)
  reg signed  [1:0]dmvector;
 
  /*
   * par. 7.6.3.1, if f_code_xx = 15 the pmv range low..high would need 21 bits.
   * But restricting ourselves to high level@high profile allows us to pack
   * the motion vectors tighter.
   * Table E-8: for High Level f_code_0_0, f_code_1_0: 1..9
   *                           f_code_0_1, f_code_1_1: 1..5
   *
   * Hence all f_code values are in the range 1..9.
   * This implies the motion vectors are in the range -4096..4095. (par. 7.6.3.1)
   * This means we can represent all motion vectors with 13 bits.
   *
   */ 
  output reg signed [12:0]pmv_0_0_0;
  output reg signed [12:0]pmv_0_0_1;
  output reg signed [12:0]pmv_1_0_0;
  output reg signed [12:0]pmv_1_0_1;
  output reg signed [12:0]pmv_0_1_0;
  output reg signed [12:0]pmv_0_1_1;
  output reg signed [12:0]pmv_1_1_0;
  output reg signed [12:0]pmv_1_1_1;
  output reg signed [12:0]dmv_0_0; // dual-prime motion vectors
  output reg signed [12:0]dmv_1_0;
  output reg signed [12:0]dmv_0_1;                                                              
  output reg signed [12:0]dmv_1_1;                                                              
 
  /* motion vector pipeline, stage 1 */
  reg         [2:0]motion_vector_0;
  reg              motion_vector_valid_0;
  reg              motion_code_neg_0;
  reg         [3:0]r_size_0;
  reg signed  [1:0]dmvector_0;
  reg signed [12:0]pmv_0;         
  reg signed [12:0]pmv_delta_0;         
 
  /* motion vector pipeline, stage 2 */
  reg         [2:0]motion_vector_1;
  reg              motion_vector_valid_1;
  reg         [3:0]r_size_1;
  reg signed  [1:0]dmvector_1;
  reg signed [12:0]pmv_1;         
 
  /* motion vector pipeline, stage 3 */
  reg         [2:0]motion_vector_2;
  reg              motion_vector_valid_2;
  reg signed  [1:0]dmvector_2;
  reg signed [12:0]pmv_2;         
 
  /* motion vector pipeline, stage 4 */
  reg         [2:0]motion_vector_3;
  reg              motion_vector_valid_3;
  reg signed [12:0]pmv_3;         
  reg signed  [1:0]dmvector_3;
 
  /* motion vector pipeline, stage 5 */
  reg         [2:0]motion_vector_4;
  reg              motion_vector_valid_4;
  reg signed [12:0]pmv_4;         
 
  /* motion vector pipeline, stage 6 */
  reg         [2:0]motion_vector_5;
  reg              motion_vector_valid_5;
  reg signed [12:0]pmv_5;         
 
  /* motion vector pipeline, output */
  output reg       motion_vector_valid; // motion_vector valid is asserted when pmv_x_x_x dmv_x_x valid
 
  /* coded block pattern */
  reg        [11:0]coded_block_pattern;  // derived from coded_block_pattern_420, coded_block_pattern_1 and coded_block_pattern_2
 
  /* dct coefficients */
  reg         [3:0]dct_dc_size;          // holds dct_dc_size_luminance or dct_dc_size_chrominance, depending.
  reg        [10:0]dct_dc_pred;          // dct_dc_pred_0, dct_dc_pred_1 or dct_dc_pred_2, depending upon whether it's a Y, Cr or Cb block.
 
  reg        [10:0]dct_dc_pred_0;        // luminance (Y) dct dc predictor, par. 7.2.1
  reg        [10:0]dct_dc_pred_1;        // first chrominance (Cb) dct dc predictor, par. 7.2.1
  reg        [10:0]dct_dc_pred_2;        // second chrominance (Cr) dct dc predictor, par. 7.2.1
 
  /*
   * Each bit in block_pattern_code, block_lumi_code, ... corresponds to a block. 
   * The first block corresponds to the leftmost bit (= bit 11) the second block to bit 10, etc.
   *
   * For instance, this is what things look like before the first block of a 4:2:0 macroblock:
   *
   * testbench.mpeg2_decoder.vld     STATE_BLOCK
   * testbench.mpeg2_decoder.vld     coded_block_pattern:  b111111000000
   * testbench.mpeg2_decoder.vld     block_pattern_code:   b111111000000
   * testbench.mpeg2_decoder.vld     block_lumi_code:     b011110
   * testbench.mpeg2_decoder.vld     block_chromi1_code:  b0000010101010
   * testbench.mpeg2_decoder.vld     block_chromi2_code:  b0000001010101
   *
   * 6 blocks, first 4 luminance blocks, then a chromi1 (Cb) block, finally a chromi2 (Cr) block.
   * Each block, block_pattern_code, block_lumi_code, block_chromi1_code and block_chromi2_code shift left one bit:
   *
   * testbench.mpeg2_decoder.vld     STATE_NEXT_BLOCK
   * testbench.mpeg2_decoder.vld     coded_block_pattern:  b111110000000
   * testbench.mpeg2_decoder.vld     block_pattern_code:   b111110000000
   * testbench.mpeg2_decoder.vld     block_lumi_code:     b111100
   * testbench.mpeg2_decoder.vld     block_chromi1_code:  b0000101010100
   * testbench.mpeg2_decoder.vld     block_chromi2_code:  b0000010101010
   * ...
   * testbench.mpeg2_decoder.vld     STATE_NEXT_BLOCK
   * testbench.mpeg2_decoder.vld     coded_block_pattern:  b111100000000
   * testbench.mpeg2_decoder.vld     block_pattern_code:   b111100000000
   * testbench.mpeg2_decoder.vld     block_lumi_code:     b111000
   * testbench.mpeg2_decoder.vld     block_chromi1_code:  b0001010101000
   * testbench.mpeg2_decoder.vld     block_chromi2_code:  b0000101010100
   * ...
   *
   * The loop ends when all bits have been shifted out of block_pattern_code:
   *
   * testbench.mpeg2_decoder.vld     STATE_NEXT_BLOCK
   * testbench.mpeg2_decoder.vld     coded_block_pattern:  b000000000000
   * testbench.mpeg2_decoder.vld     block_pattern_code:   b000000000000
   * testbench.mpeg2_decoder.vld     block_lumi_code:     b000000
   * testbench.mpeg2_decoder.vld     block_chromi1_code:  b0101010000000
   * testbench.mpeg2_decoder.vld     block_chromi2_code:  b1010101000000
   *
   * Note there still remain bits in block_chromi1_code and block_chromi2_code:
   * these would have been used in 4:2:2 and 4:4:4 video.
   *
   */
 
  reg        [11:0]block_pattern_code;   // block_pattern_code[i] is one if the corresponding block exists in the macroblock.
  reg        [12:7]block_lumi_code;      // block_lumi_code[i] is one if the corresponding block is a luminance block. bits 6:0 are always zero.
  reg        [12:0]block_chromi1_code;   // block_chromi1_code[i] is one if the corresponding block is a Cb chrominance block.
  reg        [12:0]block_chromi2_code;   // block_chromi2_code[i] is one if the corresponding block is a Cr chrominance block.
 
  wire             dct_coefficient_escape;
  output reg  [5:0]dct_coeff_run;
  output reg signed [11:0]dct_coeff_signed_level;
  output reg       dct_coeff_end;        // asserted after last dct_coeff_run/dct_coeff_signed_level
  reg              dct_coeff_valid;
  reg              dct_error;            // set when error occurs in dct decoding
  reg         [5:0]dct_coeff_run_0;
  reg signed [11:0]dct_coeff_signed_level_0;
  reg              dct_coeff_valid_0;
  reg              dct_coeff_end_0;
  reg              dct_coeff_apply_signbit_0;
  output reg       rld_wr_en;            // asserted when dct_coeff_run, dct_coeff_signed_level, and dct_coeff_end valid, or when quantizer rams need update
  output reg  [1:0]rld_cmd;              // RLD_DCT when dct_coeff_run, dct_coeff_signed_level, and dct_coeff_end valid, RLD_QUANT when quantizer rams need update, RLD_NOOP otherwise
 
  /* coded block pattern vlc lookup */
  wire        [3:0]coded_block_pattern_length;
  wire        [5:0]coded_block_pattern_value;
 
  /* motion code vlc lookup */
  wire        [3:0]motion_code_length;
  wire        [4:0]motion_code_value;
  wire             motion_code_sign;
 
  /* dmvector vlc lookup */
  wire        [1:0]dmvector_length;
  wire             dmvector_value;
  wire             dmvector_sign;
 
  /* dct dc size luminance vlc lookup */
  wire        [3:0]dct_dc_size_luminance_length;
  wire        [4:0]dct_dc_size_luminance_value;
 
  /* dct dc size chrominance vlc lookup */
  wire        [3:0]dct_dc_size_chrominance_length;
  wire        [4:0]dct_dc_size_chrominance_value;
 
  /* dct coefficient 0 vlc lookup */
  reg        [15:0]dct_coefficient_0_decoded;
  reg        [15:0]dct_non_intra_first_coefficient_0_decoded;
 
  /* dct coefficient 1 vlc lookup */
  reg        [15:0]dct_coefficient_1_decoded;
 
`include "vlc_tables.v"
 
  /* next state logic */
  always @*
    casex (state)
      STATE_NEXT_START_CODE:           if (getbits == 24'h000001) next = STATE_START_CODE;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_START_CODE:                casex(getbits[7:0])
                                         CODE_PICTURE_START:    if (sequence_header_seen & sequence_extension_seen) next = STATE_PICTURE_HEADER;
                                                                else next = STATE_NEXT_START_CODE;
                                         CODE_USER_DATA_START:  next = STATE_NEXT_START_CODE;
					 CODE_SEQUENCE_HEADER:  next = STATE_SEQUENCE_HEADER;
					 CODE_SEQUENCE_ERROR:   next = STATE_NEXT_START_CODE;
					 CODE_EXTENSION_START:  next = STATE_EXTENSION_START_CODE;
					 CODE_SEQUENCE_END:     next = STATE_SEQUENCE_END;
					 CODE_GROUP_START:      next = STATE_GROUP_HEADER;
					 8'h01,
					 8'h02,
					 8'h03,
					 8'h04,
					 8'h05,
					 8'h06,
					 8'h07,
					 8'h08,
					 8'h09,
					 8'h0a,
					 8'h0b,
					 8'h0c,
					 8'h0d,
					 8'h0e,
					 8'h0f,
					 8'h1x,
					 8'h2x,
					 8'h3x,
					 8'h4x,
					 8'h5x,
					 8'h6x,
					 8'h7x,
					 8'h8x,
					 8'h9x,
					 8'hax:                  if (sequence_header_seen & sequence_extension_seen & picture_header_seen) next = STATE_SLICE;
                                                                 else next = STATE_NEXT_START_CODE;
					 default                 next = STATE_NEXT_START_CODE;
				       endcase 
 
      STATE_EXTENSION_START_CODE:      casex(getbits[23:20])
                                         EXT_SEQUENCE:                  next = STATE_SEQUENCE_EXT;
                                         EXT_SEQUENCE_DISPLAY:          next = STATE_SEQUENCE_DISPLAY_EXT;
                                         EXT_QUANT_MATRIX:              next = STATE_QUANT_MATRIX_EXT;
                                         EXT_COPYRIGHT:                 next = STATE_NEXT_START_CODE;
                                         EXT_SEQUENCE_SCALABLE:         next = STATE_NEXT_START_CODE;
                                         EXT_PICTURE_DISPLAY:           next = STATE_NEXT_START_CODE; // Pan & scan
                                         EXT_PICTURE_CODING:            next = STATE_PICTURE_CODING_EXT;
                                         EXT_PICTURE_SPATIAL_SCALABLE:  next = STATE_NEXT_START_CODE;
                                         EXT_PICTURE_TEMPORAL_SCALABLE: next = STATE_NEXT_START_CODE;
                                         EXT_CAMERA_PARAMETERS:         next = STATE_NEXT_START_CODE;
                                         EXT_ITU_T:                     next = STATE_NEXT_START_CODE;
                                         default                        next = STATE_NEXT_START_CODE;
                                       endcase
 
      /* par. 6.2.2.1: sequence header */
      STATE_SEQUENCE_HEADER:           next = STATE_SEQUENCE_HEADER0; 
 
      STATE_SEQUENCE_HEADER0:          next = STATE_SEQUENCE_HEADER1; 
 
      STATE_SEQUENCE_HEADER1:          next = STATE_SEQUENCE_HEADER2; 
 
      STATE_SEQUENCE_HEADER2:          if (getbits[5] || ~STRICT_MARKER_BIT) next = STATE_SEQUENCE_HEADER3; // check marker bit
                                       else next = STATE_SEQUENCE_HEADER3; 
 
      STATE_SEQUENCE_HEADER3:          if (getbits[12]) next = STATE_LD_INTRA_QUANT0;
                                       else if (getbits[11]) next = STATE_LD_NON_INTRA_QUANT0;
				       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_INTRA_QUANT0:           if (cnt != 6'b111111) next = STATE_LD_INTRA_QUANT0;
                                       else if (getbits[15]) next = STATE_LD_NON_INTRA_QUANT0;
				       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_NON_INTRA_QUANT0:       if (cnt != 6'b111111) next = STATE_LD_NON_INTRA_QUANT0;
                                       else next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.2.3: Sequence extension */ 
      STATE_SEQUENCE_EXT:              next = STATE_SEQUENCE_EXT0;
 
      STATE_SEQUENCE_EXT0:             if (getbits[11] || ~STRICT_MARKER_BIT) next = STATE_SEQUENCE_EXT1; // check marker bit
                                       else next = STATE_ERROR;
 
      STATE_SEQUENCE_EXT1:             next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.2.4: Sequence display extension */
      STATE_SEQUENCE_DISPLAY_EXT:      if (getbits[20]) next = STATE_SEQUENCE_DISPLAY_EXT0;
                                       else next = STATE_SEQUENCE_DISPLAY_EXT1;
 
      STATE_SEQUENCE_DISPLAY_EXT0:     next = STATE_SEQUENCE_DISPLAY_EXT1;
 
      STATE_SEQUENCE_DISPLAY_EXT1:     if (getbits[9]) next = STATE_SEQUENCE_DISPLAY_EXT2;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_SEQUENCE_DISPLAY_EXT2:     next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.3.2: Quant matrix  extension */
      STATE_QUANT_MATRIX_EXT:          if (getbits[23]) next = STATE_LD_INTRA_QUANT1;
                                       else if (getbits[22]) next = STATE_LD_NON_INTRA_QUANT1;
                                       else if (getbits[21]) next = STATE_LD_CHROMA_INTRA_QUANT1;
                                       else if (getbits[20]) next = STATE_LD_CHROMA_NON_INTRA_QUANT1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_INTRA_QUANT1:           if (cnt != 6'b111111) next = STATE_LD_INTRA_QUANT1;
                                       else if (getbits[14]) next = STATE_LD_NON_INTRA_QUANT1;
                                       else if (getbits[13]) next = STATE_LD_CHROMA_INTRA_QUANT1;
                                       else if (getbits[12]) next = STATE_LD_CHROMA_NON_INTRA_QUANT1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_NON_INTRA_QUANT1:       if (cnt != 6'b111111) next = STATE_LD_NON_INTRA_QUANT1;
                                       else if (getbits[13]) next = STATE_LD_CHROMA_INTRA_QUANT1;
                                       else if (getbits[12]) next = STATE_LD_CHROMA_NON_INTRA_QUANT1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_CHROMA_INTRA_QUANT1:    if (cnt != 6'b111111) next = STATE_LD_CHROMA_INTRA_QUANT1;
                                       else if (getbits[12]) next = STATE_LD_CHROMA_NON_INTRA_QUANT1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_LD_CHROMA_NON_INTRA_QUANT1: if (cnt != 6'b111111) next = STATE_LD_CHROMA_NON_INTRA_QUANT1;
                                       else next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.3.1: Picture coding extension */
      STATE_PICTURE_CODING_EXT:        next = STATE_PICTURE_CODING_EXT0;
 
      STATE_PICTURE_CODING_EXT0:       if (getbits[10]) next = STATE_PICTURE_CODING_EXT1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_PICTURE_CODING_EXT1:       next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.2.6: group of pictures header */
      STATE_GROUP_HEADER:              next = STATE_GROUP_HEADER0;
 
      STATE_GROUP_HEADER0:             next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.3: picture header */
      STATE_PICTURE_HEADER:            next = STATE_PICTURE_HEADER0;
 
      STATE_PICTURE_HEADER0:           if ((picture_coding_type == 3'h2) || (picture_coding_type == 3'h3)) next = STATE_PICTURE_HEADER1;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_PICTURE_HEADER1:           if (picture_coding_type == 3'h3) next = STATE_PICTURE_HEADER2;
                                       else next = STATE_NEXT_START_CODE;
 
      STATE_PICTURE_HEADER2:           next = STATE_NEXT_START_CODE;
 
      /* par. 6.2.4: slice */
      STATE_SLICE:                     if (getbits[18]) next = STATE_SLICE_EXTENSION; // getbits[18] is slice_extension_flag
                                       else next = STATE_NEXT_MACROBLOCK;
 
      STATE_SLICE_EXTENSION:           if (getbits[15]) next = STATE_SLICE_EXTRA_INFORMATION; // getbits[15] is extra_bit_slice
                                       else next = STATE_NEXT_MACROBLOCK;
 
      STATE_SLICE_EXTRA_INFORMATION:   if (getbits[15]) next = STATE_SLICE_EXTRA_INFORMATION; // getbits[15] indicates another extra_information_slice byte follows
                                       else next = STATE_NEXT_MACROBLOCK;
 
      STATE_NEXT_MACROBLOCK:           if (macroblock_addr_inc_escape) next = STATE_NEXT_MACROBLOCK; // macroblock address escape
                                       else if (macroblock_addr_inc_value == 6'd0) next = STATE_ERROR;
				       else if (first_macroblock_of_slice) next = STATE_MACROBLOCK_TYPE; // par. 6.3.16.1: syntax does not allow the first and last macroblock of a slice to be skipped
				       else if ((macroblock_address_increment + macroblock_addr_inc_value_ext) != 7'd1) next = STATE_MACROBLOCK_SKIP; // macroblocks skipped. macroblock_address_increment + macroblock_addr_inc_value_ext is next value of macroblock_address_increment.
                                       else next = STATE_MACROBLOCK_TYPE;
 
      STATE_MACROBLOCK_SKIP:           if (macroblock_address_increment == 7'd1) next = STATE_MACROBLOCK_TYPE;
                                       else next = STATE_DELAY_EMPTY_BLOCK;
 
      STATE_DELAY_EMPTY_BLOCK:         next = STATE_EMIT_EMPTY_BLOCK; // to avoid motion vector and dct_coeff valid at same moment
 
      STATE_EMIT_EMPTY_BLOCK:          if ((empty_blocks[10] == 1'b0) && (macroblock_address_increment == 7'd1)) next = STATE_MACROBLOCK_TYPE;  
                                       else if (empty_blocks[10] == 1'b0) next = STATE_MACROBLOCK_SKIP;  // STATE_EMIT_EMPTY_BLOCK emits a block of 8x8 zeroes. par. 7.7.2.
                                       else next = STATE_EMIT_EMPTY_BLOCK;
 
      STATE_MACROBLOCK_TYPE:           /* This is what the following lines should look like, only the variables haven't been clocked in yet,
                                        * so we address macroblock_type_value directly.
                                        * if ((macroblock_type_length == 4'b0) || (spatial_temporal_weight_code_flag)) next = STATE_ERROR; // we don't do scaleability
                                        * else next = STATE_MOTION_TYPE; // frame or field motion_type
                                        */
 
                                       // macroblock_type_length == 0 if macroblock_type code lookup fails.
                                       // macroblock_type_value[0] indicates scaleability; we don't do scaleability.
                                       if ((macroblock_type_length == 4'b0) || macroblock_type_value[0]) next = STATE_ERROR; // we don't do scaleability
                                       else next = STATE_MOTION_TYPE; // frame or field motion_type
 
      STATE_MOTION_TYPE:               if ((picture_structure == FRAME_PICTURE) && (frame_pred_frame_dct == 1'b0) && (macroblock_intra || macroblock_pattern)) next = STATE_DCT_TYPE;
                                       else next = STATE_MACROBLOCK_QUANT;
 
      STATE_DCT_TYPE:                  next = STATE_MACROBLOCK_QUANT;
 
      STATE_MACROBLOCK_QUANT:          next = STATE_NEXT_MOTION_VECTOR;
 
      /* motion_vectors */
      STATE_NEXT_MOTION_VECTOR:        if (motion_vector_reg == 8'b0) next = STATE_MOTION_PIPELINE_FLUSH;
                                       // motion_vector_reg[7] indicates whether the current motion_vector is present
                                       else if (motion_vector_reg[7] && vertical_field_select_present) next = STATE_MOTION_VERT_FLD_SEL; 
                                       else if (motion_vector_reg[7]) next = STATE_MOTION_CODE;
                                       else next = STATE_NEXT_MOTION_VECTOR; // increment motion_vector; shift motion_vector_reg one bit to the left
 
      STATE_MOTION_PIPELINE_FLUSH:     if (motion_vector_valid_0 || motion_vector_valid_1 || motion_vector_valid_2 || motion_vector_valid_3 || motion_vector_valid_4 || motion_vector_valid_5) next = STATE_MOTION_PIPELINE_FLUSH; // wait for motion vector pipeline to flush.	  
				       else // no more motion vectors present, motion vector pipeline empty.
                                         begin
                                           if (macroblock_intra && concealment_motion_vectors) next = STATE_MARKER_BIT_0;
                                           else if (macroblock_pattern) next = STATE_CODED_BLOCK_PATTERN;
                                           else next = STATE_BLOCK;
					 end
 
      STATE_MOTION_VERT_FLD_SEL:       next = STATE_MOTION_CODE; // motion_vectors(0), motion_vertical_field_select(0,0)
 
      STATE_MOTION_CODE:               // motion_vectors(0), motion_vector(0,0), motion_code(0,0,0) 
                                       if (motion_code_length == 4'b0) next = STATE_ERROR;
                                       else if ((r_size != 4'd0) && (getbits[23] != 1'b1)) next = STATE_MOTION_RESIDUAL; // (r_size != 4'd0) is equivalent to (f_code_xx != 4'd1)
                                       else if (dmv) next = STATE_MOTION_DMVECTOR;
                                       else next = STATE_MOTION_PREDICT;
 
      STATE_MOTION_RESIDUAL:           // motion_vectors(0), motion_vector(0,0), motion_residual(0,0,0)
                                       if (dmv) next = STATE_MOTION_DMVECTOR;
                                       else next = STATE_MOTION_PREDICT;
 
      STATE_MOTION_DMVECTOR:           // motion_vectors(0), motion_vector(0,0), dmvector(0)
                                       if (dmvector_length  == 2'b0) next = STATE_ERROR;
                                       else next = STATE_MOTION_PREDICT;
 
      STATE_MOTION_PREDICT:            next = STATE_NEXT_MOTION_VECTOR; // increment motion_vector; shift motion_vector_reg one bit to the left
 
      /* coded block pattern */
      STATE_MARKER_BIT_0:              // skip marker bit
                                       if (~getbits[23] && STRICT_MARKER_BIT) next = STATE_ERROR;
                                       else if (macroblock_pattern) next = STATE_CODED_BLOCK_PATTERN;
                                       else next = STATE_BLOCK;
 
      STATE_CODED_BLOCK_PATTERN:       if (coded_block_pattern_length == 4'b0) next = STATE_ERROR; // Invalid coded_block_pattern code
                                       else if (chroma_format == CHROMA422) next = STATE_CODED_BLOCK_PATTERN_1;
                                       else if (chroma_format == CHROMA444) next = STATE_CODED_BLOCK_PATTERN_2;
                                       else next = STATE_BLOCK;
 
      STATE_CODED_BLOCK_PATTERN_1:     next = STATE_BLOCK;
 
      STATE_CODED_BLOCK_PATTERN_2:     next = STATE_BLOCK;
 
      /* DCT coefficients */
      STATE_BLOCK:                     next = STATE_NEXT_BLOCK; // initialize coded_block_pattern, block_pattern_code,  block_lumi_code, block_chromi1_code, block_chromi2_code
 
      STATE_NEXT_BLOCK:                if (coded_block_pattern[11] && macroblock_intra && block_lumi_code[11]) next = STATE_DCT_DC_LUMI_SIZE; // luminance block
                                       else if (coded_block_pattern[11] && macroblock_intra) next = STATE_DCT_DC_CHROMI_SIZE; // chrominance block
                                       else if (coded_block_pattern[11]) next = STATE_DCT_NON_INTRA_FIRST;
                                       else if (block_pattern_code[11]) next = STATE_NON_CODED_BLOCK;
                                       else if (block_pattern_code != 12'b0) next = STATE_NEXT_BLOCK; // shift block_pattern_code and block_lumi_code one bit, find next block
                                       else if ((getbits[23:1] == 23'b0) || dct_error) next = STATE_NEXT_START_CODE; // end of slice, go to next start code (par. 6.2.4). In case of error, synchronize at next start code.
				       else next = STATE_NEXT_MACROBLOCK; // end of macroblock, but not end of slice: go to next macroblock. 
 
      STATE_DCT_DC_LUMI_SIZE:          if (dct_dc_size_luminance_length == 4'b0) next = STATE_DCT_ERROR;
                                       else next = STATE_DCT_DC_DIFF; // table B-12 lookup of first luminance dct coefficient
 
      STATE_DCT_DC_CHROMI_SIZE:        if (dct_dc_size_chrominance_length == 4'b0) next = STATE_DCT_ERROR;
                                       else next = STATE_DCT_DC_DIFF; // table B-13 lookup of first chrominance dct coefficient
 
      STATE_DCT_DC_DIFF:               next = STATE_DCT_DC_DIFF_0;
 
      STATE_DCT_DC_DIFF_0:             if (intra_vlc_format) next = STATE_DCT_SUBS_B15; // see table 7-3. look up subsequent dct coefficient of intra block in table B-15
                                       else next = STATE_DCT_SUBS_B14; // see table 7-3. look up subsequent dct coefficient of intra block in table B-14
 
      STATE_DCT_SUBS_B15:              // subsequent dct coefficients of intra block, as in table B-15
                                       if (getbits[23:20] == 4'b0110) next = STATE_NEXT_BLOCK; // end of this block, go to next block
                                       else if (dct_coefficient_escape) next = STATE_DCT_ESCAPE_B15; // Escape
                                       else if (dct_coefficient_1_decoded[15:11] == 5'b0) next = STATE_DCT_ERROR; // unknown code
                                       else next = STATE_DCT_SUBS_B15;
 
      STATE_DCT_ESCAPE_B15:            // table B-16 escapes to table B-15
                                       next = STATE_DCT_SUBS_B15;
 
      STATE_DCT_NON_INTRA_FIRST:       // first dct coefficient of non-intra block, as in table B-14, note 2 and 3
                                       if (dct_coefficient_escape) next = STATE_DCT_ESCAPE_B14; // table B-14 escape
                                       else if (dct_non_intra_first_coefficient_0_decoded[15:11] == 5'b0) next = STATE_DCT_ERROR; // unknown code
                                       else  next = STATE_DCT_SUBS_B14;
 
      STATE_DCT_SUBS_B14:              // table B-14 (with B-16 escapes) lookup of subsequent dct coefficients.
                                       if (getbits[23:22] == 2'b10) next = STATE_NEXT_BLOCK; // end of this block, go to next block
                                       else if (dct_coefficient_escape) next = STATE_DCT_ESCAPE_B14; // Escape
                                       else if (dct_coefficient_0_decoded[15:11] == 5'b0) next = STATE_DCT_ERROR; // unknown code
                                       else next = STATE_DCT_SUBS_B14;
 
      STATE_DCT_ESCAPE_B14:            // table B-16 escapes to table B-15
                                       next = STATE_DCT_SUBS_B14;
 
      STATE_NON_CODED_BLOCK:           next = STATE_NEXT_BLOCK; // Output end-of-block for all-zeroes non-coded block
 
      STATE_DCT_ERROR:                 next = STATE_NON_CODED_BLOCK; // Output all remaining blocks as non-coded blocks. clears coded_block_pattern and sets dct_error and vld_err flags.
 
      STATE_SEQUENCE_END:              next = STATE_NEXT_START_CODE; // Output last frame 
 
      STATE_ERROR:                     next = STATE_NEXT_START_CODE;
 
      default                          next = STATE_ERROR;
 
    endcase
 
  /* advance and align logic. advance is number of bits to advance the bitstream. */
  always @*
    if (~rst) next_advance = 5'b0;
    else
      case (state)
        STATE_NEXT_START_CODE:            next_advance = 5'd0;             // next_advance is zero in STATE_INIT; but align = 1: we move one byte at a time.
	STATE_START_CODE:                 next_advance = 5'd24;            // skip over the 24'h0001sc, where sc = start_code
	STATE_EXTENSION_START_CODE:       next_advance = 5'd4;             // skip over the extension start code
	/* par. 6.2.2.1: sequence header */
	STATE_SEQUENCE_HEADER:            next_advance = 5'd12;            // size of horizontal_size_value
	STATE_SEQUENCE_HEADER0:           next_advance = 5'd12;            // size of vertical_size_value
	STATE_SEQUENCE_HEADER1:           next_advance = 5'd8;             // size of aspect_ratio_information and frame_rate_code
	STATE_SEQUENCE_HEADER2:           next_advance = 5'd19;            // size of bit_rate_value and marker bit
	STATE_SEQUENCE_HEADER3:           next_advance = 5'd12;            // size of vbv_buffer_size[9:0], constrained_parameters_flag and load_intra_quantiser_matrix
	STATE_LD_INTRA_QUANT0:            next_advance = 5'd8;             // size of one item of quantization table
	STATE_LD_NON_INTRA_QUANT0:        next_advance = 5'd8;             // size of one item of quantization table
	/* par. 6.2.2.3: Sequence extension */
	STATE_SEQUENCE_EXT:               next_advance = 5'd15;            // size of profile_and_level_indication, progressive_sequence, chroma_format, horizontal_size ext, vertical_size ext.
	STATE_SEQUENCE_EXT0:              next_advance = 5'd13;            // size of bit_rate ext, marker bit.
	STATE_SEQUENCE_EXT1:              next_advance = 5'd16;            // size of vbv_buffer_size ext, low_delay, frame_rate_extension_n, frame_rate_extension_d
	/* par. 6.2.2.4: Sequence display extension */
	STATE_SEQUENCE_DISPLAY_EXT:       next_advance = 5'd4;             // size of video_format, colour_description
	STATE_SEQUENCE_DISPLAY_EXT0:      next_advance = 5'd24;            // size of colour_primaries, transfer_characteristics, matrix_coefficients
	STATE_SEQUENCE_DISPLAY_EXT1:      next_advance = 5'd15;            // size of display_horizontal_size, marker bit
	STATE_SEQUENCE_DISPLAY_EXT2:      next_advance = 5'd14;            // size of display_vertical_size
	/* par. 6.2.3.2: Quant matrix  extension */
	STATE_QUANT_MATRIX_EXT:           next_advance = 5'd0;             // no move
	STATE_LD_INTRA_QUANT1:            next_advance = 5'd8;             // size of one item of quantization table
	STATE_LD_NON_INTRA_QUANT1:        next_advance = 5'd8;             // size of one item of quantization table
	STATE_LD_CHROMA_INTRA_QUANT1:     next_advance = 5'd8;             // size of one item of quantization table
	STATE_LD_CHROMA_NON_INTRA_QUANT1: next_advance = 5'd8;             // size of one item of quantization table
	/* par. 6.2.3.1: Picture coding extension */
	STATE_PICTURE_CODING_EXT:         next_advance = 5'd16;            // size of f_code_00, f_code_01, f_code_10, f_code_11
	STATE_PICTURE_CODING_EXT0:        next_advance = 5'd14;            // size of intra_dc_precision .. composite_display_flag
	STATE_PICTURE_CODING_EXT1:        next_advance = 5'd20;            // size of v_axis, field_sequence, sub_carrier, burst_amplitude, sub_carrier_phase
	/* par. 6.2.2.6: group of pictures header */
	STATE_GROUP_HEADER:               next_advance = 5'd19;
	STATE_GROUP_HEADER0:              next_advance = 5'd8;
	/* par. 6.2.3: picture header */
	STATE_PICTURE_HEADER:             next_advance = 5'd13;            // size of temporal_reference, picture_coding_type
	STATE_PICTURE_HEADER0:            next_advance = 5'd16;            // size of vbv_delay
	STATE_PICTURE_HEADER1:            next_advance = 5'd4;             // size of full_pel_forward_vector, forward_f_code
	STATE_PICTURE_HEADER2:            next_advance = 5'd4;             // size of full_pel_backward_vector, backward_f_code
 
        /* par. 6.2.4: slice */
        STATE_SLICE:                      next_advance = 5'd6;
        STATE_SLICE_EXTENSION:            next_advance = 5'd9;
        STATE_SLICE_EXTRA_INFORMATION:    next_advance = 5'd9;
        STATE_NEXT_MACROBLOCK:            next_advance = macroblock_addr_inc_length;
        STATE_MACROBLOCK_SKIP:            next_advance = 5'd0;
        STATE_MACROBLOCK_TYPE:            next_advance = macroblock_type_length;
        STATE_MOTION_TYPE:                next_advance = (macroblock_motion_forward || macroblock_motion_backward) ? 
	                                                  (((picture_structure == FRAME_PICTURE) && (frame_pred_frame_dct == 1'b1)) ? 5'd0 : 5'd2)  
							  : 5'd0;
        STATE_DCT_TYPE:                   next_advance = 5'd1;
        STATE_MACROBLOCK_QUANT:           next_advance = macroblock_quant ? 5'd5 : 5'd0;
 
        STATE_NEXT_MOTION_VECTOR:         next_advance = 5'd0;
        STATE_MOTION_VERT_FLD_SEL:        next_advance = 5'd1;                         // motion_vertical_field_select
        STATE_MOTION_CODE:                next_advance = motion_code_length;           // motion_code
        STATE_MOTION_RESIDUAL:            next_advance = r_size;                       // motion_residual
        STATE_MOTION_DMVECTOR:            next_advance = dmvector_length;              // dmvector
        STATE_MOTION_PREDICT:             next_advance = 5'd0;
        STATE_MOTION_PIPELINE_FLUSH:      next_advance = 5'd0;
 
        STATE_MARKER_BIT_0:               next_advance = 5'd1;
        STATE_CODED_BLOCK_PATTERN:        next_advance = coded_block_pattern_length;
        STATE_CODED_BLOCK_PATTERN_1:      next_advance = 5'd2;
        STATE_CODED_BLOCK_PATTERN_2:      next_advance = 5'd6;
        STATE_BLOCK:                      next_advance = 5'd0;
        STATE_NEXT_BLOCK:                 next_advance = 5'd0;
        STATE_DCT_DC_LUMI_SIZE:           next_advance = dct_dc_size_luminance_length;
        STATE_DCT_DC_CHROMI_SIZE:         next_advance = dct_dc_size_chrominance_length;
        STATE_DCT_DC_DIFF:                next_advance = dct_dc_size;
 
        STATE_DCT_SUBS_B15:               next_advance = dct_coefficient_escape ? 5'd12 : dct_coefficient_1_decoded[15:11]; // escape + fixed-length run encoding as in table B-16 or variable length encoding as in table B-15
        STATE_DCT_ESCAPE_B15:             next_advance = 5'd12; // 12-bit fixed-length signed_level (table B-16)
        STATE_DCT_SUBS_B14:               next_advance = dct_coefficient_escape ? 5'd12 : dct_coefficient_0_decoded[15:11]; // escape + fixed-length run encoding as in table B-16 or variable length encoding as in table B-14
        STATE_DCT_ESCAPE_B14      :       next_advance = 5'd12; // 12-bit fixed-length signed_level (table B-16)
        STATE_DCT_NON_INTRA_FIRST:        next_advance = dct_coefficient_escape ? 5'd12 : dct_non_intra_first_coefficient_0_decoded[15:11]; // escape + fixed-length run encoding as in table B-16 or variable length encoding as in table B-14, modified as in table b-14 note 2, 3
        STATE_NON_CODED_BLOCK:            next_advance = 5'd0;
        STATE_DCT_ERROR:                  next_advance = 5'd0;
 
        STATE_SEQUENCE_END:               next_advance = 5'd0;
        STATE_ERROR:                      next_advance = 5'd0;
 
	/* default value */
	default                           next_advance = 5'd0;
      endcase
 
 
  /*
   * Note: align and advance are zero when clk_en is false; 
   * this avoids the fifo moving forward while the vld is not enabled.
   */
 
  wire next_align = (state == STATE_NEXT_START_CODE);
 
  always @(posedge clk)
    if (~rst) align <= 1'b0;
    else if (clk_en) align <= next_align;
    else align <= 1'b0;
 
  always @(posedge clk)
    if (~rst) advance <= 1'b0;
    else if (clk_en) advance <= next_advance;
    else advance <= 1'b0;
 
  /*
   * wait_state is asserted if align or advance will be non-zero during the next clock cycle, 
   * and getbits will need to do some work. 
   * Unregistered output; the registering happens in getbits.
   */
  output wait_state;
  assign wait_state = ((next_align != 1'b0) || (next_advance != 4'b0));
 
  /* state */
 
  always @(posedge clk)
    if(~rst) state <= STATE_NEXT_START_CODE;
    else if (clk_en) state <= next;
    else state <= state;
 
  always @(posedge clk)
    if (~rst) dct_error <= 1'b0;
    else if (clk_en && (state == STATE_NEXT_START_CODE)) dct_error <= 1'b0;
    else if (clk_en && (state == STATE_DCT_ERROR)) dct_error <= 1'b1;
    else dct_error <= dct_error;
 
  always @(posedge clk)
    if (~rst) vld_err <= 1'b0;
    else if (clk_en && (state == STATE_NEXT_START_CODE)) vld_err <= 1'b0;
    else if (clk_en && ((state == STATE_ERROR) || (state == STATE_DCT_ERROR))) vld_err <= 1'b1;
    else vld_err <= vld_err;
 
  /* position in video stream */
 
  always @(posedge clk)
    if (~rst) sequence_header_seen <= 1'b0;
    else if (clk_en && (state == STATE_SEQUENCE_HEADER)) sequence_header_seen <= 1'b1;
    else if (clk_en && (state == STATE_SEQUENCE_END)) sequence_header_seen <= 1'b0;
    else sequence_header_seen <= sequence_header_seen;
 
  always @(posedge clk)
    if (~rst) sequence_extension_seen <= 1'b0;
    else if (clk_en && (state == STATE_SEQUENCE_EXT)) sequence_extension_seen <= 1'b1;
    else if (clk_en && (state == STATE_SEQUENCE_END)) sequence_extension_seen <= 1'b0;
    else sequence_extension_seen <= sequence_extension_seen;
 
  always @(posedge clk)
    if (~rst) picture_header_seen <= 1'b0;
    else if (clk_en && (state == STATE_PICTURE_HEADER)) picture_header_seen <= 1'b1;
    else if (clk_en && (state == STATE_SEQUENCE_END)) picture_header_seen <= 1'b0;
    else picture_header_seen <= picture_header_seen;
 
  /* par. 6.2.2.1: Sequence header */
  loadreg #( .offset(16), .width(8), .fsm_state(STATE_START_CODE))                    loadreg_start_code (.fsm_reg(start_code), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(12), .fsm_state(STATE_SEQUENCE_HEADER))               loadreg_horizontal_size_lsb (.fsm_reg(horizontal_size[11:0]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(12), .fsm_state(STATE_SEQUENCE_HEADER0))              loadreg_vertical_size_lsb (.fsm_reg(vertical_size[11:0]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(4), .fsm_state(STATE_SEQUENCE_HEADER1))               loadreg_aspect_ratio_information(.fsm_reg(aspect_ratio_information), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(4), .width(4), .fsm_state(STATE_SEQUENCE_HEADER1))               loadreg_frame_rate_code(.fsm_reg(frame_rate_code), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(18), .fsm_state(STATE_SEQUENCE_HEADER2))              loadreg_bit_rate_lsb(.fsm_reg(bit_rate[17:0]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(10), .fsm_state(STATE_SEQUENCE_HEADER3))              loadreg_vbv_buffer_size_lsb(.fsm_reg(vbv_buffer_size[9:0]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(10), .width(1), .fsm_state(STATE_SEQUENCE_HEADER3))              loadreg_constrained_parameters_flag(.fsm_reg(constrained_parameters_flag), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* calculation of picture width in macroblocks , par. 6.3.3 */
  always @(posedge clk)
    if (~rst) mb_width <= 8'b0;
    else if (clk_en) mb_width <= (horizontal_size + 11'd15) >> 4;
    else mb_width <= mb_width;
 
  /* calculation of picture height in macroblocks , par. 6.3.3 */
  always @(posedge clk)
    if (~rst) mb_height <= 8'b0;
    else if (clk_en) mb_height <= progressive_sequence ? ((vertical_size + 11'd15) >> 4)  :  
                                    ((vertical_size + 11'd31) >> 5) << 1;  
//                                    ( (picture_structure==FRAME_PICTURE) ? (((vertical_size + 11'd31) >> 5) << 1) : ((vertical_size + 11'd31) >> 5) );  
    else mb_height <= mb_height;
 
  /* Reset quantisation matrices to default values when sequence header code is decoded (par. 6.3.11) */
  always @(posedge clk)
    if(~rst) quant_rst <= 1'b1;
    else if (clk_en) quant_rst <= (state == STATE_SEQUENCE_HEADER);
    else quant_rst <= quant_rst;
 
  always @(posedge clk)
    if (~rst) cnt <= 6'b0;
    else if (clk_en && ((state == STATE_SEQUENCE_HEADER3) || (state == STATE_QUANT_MATRIX_EXT))) cnt <= 6'h0;
    else if (clk_en && ((state == STATE_LD_INTRA_QUANT0)
                     || (state == STATE_LD_NON_INTRA_QUANT0)
                     || (state == STATE_LD_INTRA_QUANT1)
                     || (state == STATE_LD_NON_INTRA_QUANT1)
                     || (state == STATE_LD_CHROMA_INTRA_QUANT1)
                     || (state == STATE_LD_CHROMA_NON_INTRA_QUANT1))) cnt <= cnt + 1;
    else cnt <= cnt;
 
  always @(posedge clk)
    if (~rst) quant_wr_data <= 8'b0;
    else if (clk_en && (state == STATE_LD_INTRA_QUANT0)) quant_wr_data <= getbits[23:16];
    else if (clk_en && (state == STATE_LD_NON_INTRA_QUANT0)) quant_wr_data <= getbits[22:15];
    else if (clk_en && (state == STATE_LD_INTRA_QUANT1)) quant_wr_data <= getbits[22:15];
    else if (clk_en && (state == STATE_LD_NON_INTRA_QUANT1)) quant_wr_data <= getbits[21:14];
    else if (clk_en && (state == STATE_LD_CHROMA_INTRA_QUANT1)) quant_wr_data <= getbits[20:13];
    else if (clk_en && (state == STATE_LD_CHROMA_NON_INTRA_QUANT1)) quant_wr_data <= getbits[19:12];
    else quant_wr_data <= quant_wr_data;
 
  always @(posedge clk)
    if (~rst) quant_wr_addr <= 6'b0;
    else if (clk_en) quant_wr_addr <= cnt;
    else quant_wr_addr <= quant_wr_addr;
 
  always @(posedge clk)
    if (~rst) wr_intra_quant <= 1'b0;
    else if (clk_en) wr_intra_quant <= ((state == STATE_LD_INTRA_QUANT0) || (state == STATE_LD_INTRA_QUANT1));
    else wr_intra_quant <= wr_intra_quant;
 
  always @(posedge clk)
    if (~rst) wr_non_intra_quant <= 1'b0;
    else if (clk_en) wr_non_intra_quant <= ((state == STATE_LD_NON_INTRA_QUANT0) || (state == STATE_LD_NON_INTRA_QUANT1));
    else wr_non_intra_quant <= wr_non_intra_quant;
 
  always @(posedge clk)
    if (~rst) wr_chroma_intra_quant <= 1'b0;
    else if (clk_en) wr_chroma_intra_quant <= ((state == STATE_LD_INTRA_QUANT0) || (state == STATE_LD_INTRA_QUANT1) || (state == STATE_LD_CHROMA_INTRA_QUANT1));
    else wr_chroma_intra_quant <= wr_chroma_intra_quant;
 
  always @(posedge clk)
    if (~rst) wr_chroma_non_intra_quant <= 1'b0;
    else if (clk_en) wr_chroma_non_intra_quant <= ((state == STATE_LD_NON_INTRA_QUANT0) || (state == STATE_LD_NON_INTRA_QUANT1) || (state == STATE_LD_CHROMA_NON_INTRA_QUANT1));
    else wr_chroma_non_intra_quant <= wr_chroma_non_intra_quant;
 
  /* rld fifo interface */
  always @(posedge clk)
    if (~rst) rld_wr_en <= 1'b0;
    else if (clk_en) rld_wr_en <= dct_coeff_valid_0 || 
                                  ((state == STATE_SEQUENCE_HEADER) ||               // quant_rst
                                   (state == STATE_LD_INTRA_QUANT0) ||               // wr_intra_quant, wr_chroma_intra_quant
                                   (state == STATE_LD_INTRA_QUANT1) ||               // wr_intra_quant, wr_chroma_intra_quant
                                   (state == STATE_LD_NON_INTRA_QUANT0) ||           // wr_non_intra_quant, wr_chroma_non_intra_quant
                                   (state == STATE_LD_NON_INTRA_QUANT1) ||           // wr_non_intra_quant, wr_chroma_non_intra_quant
                                   (state == STATE_LD_CHROMA_INTRA_QUANT1) ||        // wr_chroma_intra_quant
                                   (state == STATE_LD_CHROMA_NON_INTRA_QUANT1));     // wr_chroma_non_intra_quant
    else rld_wr_en <= 1'b0;
 
  always @(posedge clk)
    if (~rst) rld_cmd <= 1'b0;
    else if (clk_en) rld_cmd <= ( dct_coeff_valid_0 ? RLD_DCT : 
                                  ((state == STATE_SEQUENCE_HEADER) ||               // quant_rst
                                   (state == STATE_LD_INTRA_QUANT0) ||               // wr_intra_quant, wr_chroma_intra_quant
                                   (state == STATE_LD_INTRA_QUANT1) ||               // wr_intra_quant, wr_chroma_intra_quant
                                   (state == STATE_LD_NON_INTRA_QUANT0) ||           // wr_non_intra_quant, wr_chroma_non_intra_quant
                                   (state == STATE_LD_NON_INTRA_QUANT1) ||           // wr_non_intra_quant, wr_chroma_non_intra_quant
                                   (state == STATE_LD_CHROMA_INTRA_QUANT1) ||        // wr_chroma_intra_quant
                                   (state == STATE_LD_CHROMA_NON_INTRA_QUANT1))      // wr_chroma_non_intra_quant
                                  ? RLD_QUANT : RLD_NOOP);
    else rld_cmd <= rld_cmd;
 
  /* par. 6.2.2.3: Sequence extension */ 
  loadreg #( .offset(0), .width(8), .fsm_state(STATE_SEQUENCE_EXT))                  loadreg_profile_and_level_indication(.fsm_reg(profile_and_level_indication), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(8), .width(1), .fsm_state(STATE_SEQUENCE_EXT))                  loadreg_progressive_sequence(.fsm_reg(progressive_sequence), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(9), .width(2), .fsm_state(STATE_SEQUENCE_EXT))                  loadreg_chroma_format(.fsm_reg(chroma_format), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(11), .width(2), .fsm_state(STATE_SEQUENCE_EXT))                 loadreg_horizontal_size_msb(.fsm_reg(horizontal_size[13:12]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(13), .width(2), .fsm_state(STATE_SEQUENCE_EXT))                 loadreg_vertical_size_msb(.fsm_reg(vertical_size[13:12]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(12), .fsm_state(STATE_SEQUENCE_EXT0))                loadreg_bit_rate_msb(.fsm_reg(bit_rate[29:18]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(8), .fsm_state(STATE_SEQUENCE_EXT1))                 loadreg_vbv_buffer_size_msb(.fsm_reg(vbv_buffer_size[17:10]), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(8), .width(1), .fsm_state(STATE_SEQUENCE_EXT1))                 loadreg_low_delay(.fsm_reg(low_delay), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(9), .width(2), .fsm_state(STATE_SEQUENCE_EXT1))                 loadreg_frame_rate_extension_n(.fsm_reg(frame_rate_extension_n), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(11), .width(5), .fsm_state(STATE_SEQUENCE_EXT1))                loadreg_frame_rate_extension_d(.fsm_reg(frame_rate_extension_d), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* par. 6.2.2.4: Sequence display extension */
  loadreg #( .offset(0), .width(3), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT))          loadreg_video_format(.fsm_reg(video_format), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(8), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT0))         loadreg_colour_primaries(.fsm_reg(colour_primaries), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(8), .width(8), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT0))         loadreg_transfer_characteristics(.fsm_reg(transfer_characteristics), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(16), .width(8), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT0))        loadreg_matrix_coefficients(.fsm_reg(matrix_coefficients), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(14), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT1))        loadreg_display_horizontal_size(.fsm_reg(display_horizontal_size), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(14), .fsm_state(STATE_SEQUENCE_DISPLAY_EXT2))        loadreg_display_vertical_size(.fsm_reg(display_vertical_size), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* par. 6.2.3.1: Picture coding extension */
  loadreg #( .offset(0), .width(4), .fsm_state(STATE_PICTURE_CODING_EXT))            loadreg_f_code_00(.fsm_reg(f_code_00), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(4), .width(4), .fsm_state(STATE_PICTURE_CODING_EXT))            loadreg_f_code_01(.fsm_reg(f_code_01), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(8), .width(4), .fsm_state(STATE_PICTURE_CODING_EXT))            loadreg_f_code_10(.fsm_reg(f_code_10), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(12), .width(4), .fsm_state(STATE_PICTURE_CODING_EXT))           loadreg_f_code_11(.fsm_reg(f_code_11), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(2), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_intra_dc_precision(.fsm_reg(intra_dc_precision), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(2), .width(2), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_picture_structure(.fsm_reg(picture_structure), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(4), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_top_field_first(.fsm_reg(top_field_first), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(5), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_frame_pred_frame_dct(.fsm_reg(frame_pred_frame_dct), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(6), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_concealment_motion_vectors(.fsm_reg(concealment_motion_vectors), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(7), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_q_scale_type(.fsm_reg(q_scale_type), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(8), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_intra_vlc_format(.fsm_reg(intra_vlc_format), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(9), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))           loadreg_alternate_scan(.fsm_reg(alternate_scan), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(10), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))          loadreg_repeat_first_field(.fsm_reg(repeat_first_field), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(11), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))          loadreg_chroma_420_type(.fsm_reg(chroma_420_type), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(12), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))          loadreg_progressive_frame(.fsm_reg(progressive_frame), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(13), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT0))          loadreg_composite_display_flag(.fsm_reg(composite_display_flag), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT1))           loadreg_v_axis(.fsm_reg(v_axis), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(1), .width(3), .fsm_state(STATE_PICTURE_CODING_EXT1))           loadreg_field_sequence(.fsm_reg(field_sequence), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(4), .width(1), .fsm_state(STATE_PICTURE_CODING_EXT1))           loadreg_sub_carrier(.fsm_reg(sub_carrier), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(5), .width(7), .fsm_state(STATE_PICTURE_CODING_EXT1))           loadreg_burst_amplitude(.fsm_reg(burst_amplitude), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(12), .width(8), .fsm_state(STATE_PICTURE_CODING_EXT1))          loadreg_sub_carrier_phase(.fsm_reg(sub_carrier_phase), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* par. 6.2.2.6: group of pictures header */
  loadreg #( .offset(0), .width(1), .fsm_state(STATE_GROUP_HEADER))                  loadreg_drop_flag(.fsm_reg(drop_flag), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(1), .width(5), .fsm_state(STATE_GROUP_HEADER))                  loadreg_time_code_hours(.fsm_reg(time_code_hours), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(6), .width(6), .fsm_state(STATE_GROUP_HEADER))                  loadreg_time_code_minutes(.fsm_reg(time_code_minutes), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(13), .width(6), .fsm_state(STATE_GROUP_HEADER))                 loadreg_time_code_seconds(.fsm_reg(time_code_seconds), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(6), .fsm_state(STATE_GROUP_HEADER0))                 loadreg_time_code_pictures(.fsm_reg(time_code_pictures), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(6), .width(1), .fsm_state(STATE_GROUP_HEADER0))                 loadreg_closed_gop(.fsm_reg(closed_gop), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(7), .width(1), .fsm_state(STATE_GROUP_HEADER0))                 loadreg_broken_link(.fsm_reg(broken_link), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* par. 6.2.3: picture header */
  loadreg #( .offset(0), .width(10), .fsm_state(STATE_PICTURE_HEADER))               loadreg_temporal_reference(.fsm_reg(temporal_reference), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(10), .width(3), .fsm_state(STATE_PICTURE_HEADER))               loadreg_picture_coding_type(.fsm_reg(picture_coding_type), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(16), .fsm_state(STATE_PICTURE_HEADER0))              loadreg_vbv_delay(.fsm_reg(vbv_delay), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(1), .fsm_state(STATE_PICTURE_HEADER1))               loadreg_full_pel_forward_vector(.fsm_reg(full_pel_forward_vector), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(1), .width(3), .fsm_state(STATE_PICTURE_HEADER1))               loadreg_forward_f_code(.fsm_reg(forward_f_code), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(0), .width(1), .fsm_state(STATE_PICTURE_HEADER2))               loadreg_full_pel_backward_vector(.fsm_reg(full_pel_backward_vector), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
  loadreg #( .offset(1), .width(3), .fsm_state(STATE_PICTURE_HEADER2))               loadreg_backward_f_code(.fsm_reg(backward_f_code), .clk(clk), .clk_en(clk_en), .rst(rst), .state(state), .getbits(getbits));
 
  /* par. 6.2.4: slice */
  /* macroblock address increment vlc lookup */
  assign {macroblock_addr_inc_length, macroblock_addr_inc_value, macroblock_addr_inc_escape} = macroblock_address_increment_dec(getbits[23:13]);
 
  /* macroblock type vlc lookup */
  assign {macroblock_type_length, macroblock_type_value} = macroblock_type_dec(getbits[23:18], picture_coding_type);
 
  /* coded block pattern vlc lookup */
  assign {coded_block_pattern_length, coded_block_pattern_value} = coded_block_pattern_dec(getbits[23:15]);
 
  /* motion code vlc lookup */
  assign {motion_code_length, motion_code_value, motion_code_sign} = motion_code_dec(getbits[23:13]);
 
  /* dmvector vlc lookup */
  assign {dmvector_length, dmvector_value, dmvector_sign} = dmvector_dec(getbits[23:22]);
 
  /* dct dc size luminance vlc lookup */
  assign {dct_dc_size_luminance_length, dct_dc_size_luminance_value} = dct_dc_size_luminance_dec(getbits[23:15]);
 
  /* dct dc size chrominance vlc lookup */
  assign {dct_dc_size_chrominance_length, dct_dc_size_chrominance_value} = dct_dc_size_chrominance_dec(getbits[23:14]);
 
  /* dct coefficient 0 vlc lookup */
  always @(getbits)
    dct_coefficient_0_decoded = dct_coefficient_0_dec(getbits[23:8]);
 
  /* dct first coefficient 0 vlc lookup */
  /* see note 2 and 3 of table B-14: first coefficient handled differently. */
  /* Code 2'b10 = 1, Code 2'b11 = -1 */
  always @(getbits, dct_coefficient_0_decoded)
    dct_non_intra_first_coefficient_0_decoded = getbits[23] ? {5'd2, 5'd0, 6'd1} : dct_coefficient_0_decoded;
 
  /* dct coefficient 1 vlc lookup */
  always @(getbits)
    dct_coefficient_1_decoded = dct_coefficient_1_dec(getbits[23:8]);
 
  /* internal registers */
  /* slice start code */
  /* this does not take into account slice_vertial_position_extension (par.  6.3.16). This limits vertical resolution to 2800 lines. */
  always @(posedge clk)
    if (~rst) slice_vertical_position <= 8'b0;
    else if (clk_en && (state == STATE_SLICE)) slice_vertical_position <= start_code;
    else slice_vertical_position <= slice_vertical_position;
 
  /* slice quantiser scale */
  always @(posedge clk)
    if (~rst) quantiser_scale_code <= 5'b0;
    else if (clk_en && ((state == STATE_SLICE) || ((state == STATE_MACROBLOCK_QUANT) && macroblock_quant))) quantiser_scale_code <= getbits[23:19];
    else quantiser_scale_code <= quantiser_scale_code;
 
  always @(posedge clk)
    if (~rst) slice_extension_flag <= 1'b0;
    else if (clk_en && (state == STATE_SLICE)) slice_extension_flag <= getbits[18];
    else slice_extension_flag <= slice_extension_flag;
 
  /* slice extension */
  always @(posedge clk)
    if (~rst) intra_slice <= 1'b0;
    else if (clk_en && (state == STATE_SLICE_EXTENSION)) intra_slice <= getbits[23];
    else intra_slice <= intra_slice;
 
  always @(posedge clk)
    if (~rst) slice_picture_id_enable <= 1'b0;
    else if (clk_en && (state == STATE_SLICE_EXTENSION)) slice_picture_id_enable <= getbits[22];
    else slice_picture_id_enable <= slice_picture_id_enable;
 
  always @(posedge clk)
    if (~rst) slice_picture_id <= 6'b0;
    else if (clk_en && (state == STATE_SLICE_EXTENSION)) slice_picture_id <= getbits[21:16];
    else slice_picture_id <= slice_picture_id;
 
  /* macroblock address */
  /* 
   * Note macroblock address calculation is for the restricted slice structure (par. 6.1.2.2) where slices seamlessly cover the whole picture.
   * Support for the general slice structure (par. 6.1.2.1) with gaps between slices could be added if needed.
   */
 
  always @(posedge clk)
    if (~rst) first_macroblock_of_slice <= 1'b0;
    else if (clk_en && (state == STATE_SLICE)) first_macroblock_of_slice <= 1'b1;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) first_macroblock_of_slice <= 1'b0;
    else first_macroblock_of_slice <= first_macroblock_of_slice;
 
  reg [15:0]mb_row_by_mb_width;
  wire [7:0]mb_row = start_code - 8'd1;
 
  always @(posedge clk)
    if (~rst) mb_row_by_mb_width <= 13'b0;
    else if (clk_en && (state == STATE_SLICE)) mb_row_by_mb_width <= mb_row * mb_width;
    else mb_row_by_mb_width <= mb_row_by_mb_width;
 
  /* 
   * no skipped macroblocks allowed at slice start. At slice start:
   * macroblock_address <= ( start_code - 1 ) * mb_width + macroblock_address_increment - 1; 
   * macroblock_address_increment <= 1;
   */
 
  wire [15:0]macroblock_address_increment_ext = macroblock_address_increment;
  wire [15:0]next_macroblock_address = mb_row_by_mb_width + macroblock_address_increment_ext - 16'd1;
 
  always @(posedge clk)
    if (~rst) macroblock_address <= 13'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE) && first_macroblock_of_slice) macroblock_address <= next_macroblock_address[12:0]; // macroblock in 1920x1080 are numbered 0..8159, hence 13 bits.
    else if (clk_en && ((state == STATE_MACROBLOCK_TYPE) || (state == STATE_MACROBLOCK_SKIP))) macroblock_address <= macroblock_address + 13'b1;
    else macroblock_address <= macroblock_address;
 
  always @(posedge clk)
    if (~rst) macroblock_address_increment <= 7'b0;
    else if (clk_en && ((state == STATE_SLICE) || (state == STATE_NEXT_BLOCK))) macroblock_address_increment <= 7'd0;
    else if (clk_en && (state == STATE_NEXT_MACROBLOCK) && macroblock_addr_inc_escape) macroblock_address_increment <= macroblock_address_increment + 7'd33; // par. 6.3.17, macroblock_escape
    else if (clk_en && (state == STATE_NEXT_MACROBLOCK)) macroblock_address_increment <=  macroblock_address_increment + macroblock_addr_inc_value_ext;
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP)) macroblock_address_increment <= macroblock_address_increment - 7'd1; // counting down number of macroblocks to skip
    else macroblock_address_increment <= macroblock_address_increment;
 
  always @(posedge clk)
    if (~rst) empty_blocks <= 11'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP)) 
      begin
        case (chroma_format)
          CHROMA420: empty_blocks <= {11'b11111000000};  // emit 6 empty (all-zeroes) blocks for 4:2:0
          CHROMA422: empty_blocks <= {11'b11111110000};  // emit 8 empty (all-zeroes) blocks for 4:2:2
          CHROMA444: empty_blocks <= {11'b11111111111};  // emit 12 empty (all-zeroes) blocks for 4:4:4
          default    empty_blocks <= {11'b00000000000};  // error
        endcase
      end
    else if (clk_en && (state == STATE_EMIT_EMPTY_BLOCK)) empty_blocks <= empty_blocks << 1;
    else empty_blocks <= empty_blocks;
 
  /* macroblock type */
  always @(posedge clk)
    if (~rst) macroblock_quant <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_quant <= macroblock_type_value[5];
    else macroblock_quant <= macroblock_quant;
 
  always @(posedge clk)
    if (~rst) macroblock_motion_forward <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_motion_forward <= macroblock_type_value[4];
    else macroblock_motion_forward <= macroblock_motion_forward;
 
  always @(posedge clk)
    if (~rst) macroblock_motion_backward <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_motion_backward <= macroblock_type_value[3];
    else macroblock_motion_backward <= macroblock_motion_backward;
 
  always @(posedge clk)
    if (~rst) macroblock_pattern <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_pattern <= macroblock_type_value[2];
    else macroblock_pattern <= macroblock_pattern;
 
  /*
   * macroblock_type_intra is asserted when macroblock_type indicates this macroblock is an intra macroblock.
   * Intra macroblocks are fully coded. Skipped macroblocks are fully predicted.
   * However, skipped macroblocks are never intra macroblocks. 
   * Hence macroblock_intra is low when we're emitting a skipped macroblock,
   * even if the macroblock being decoded is an intra macroblock.
   * If we're not emitting a skipped macroblock, macroblock_intra has the same
   * value as macroblock_type_intra.
   */
 
  always @(posedge clk)
    if (~rst) macroblock_type_intra <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_type_intra <= macroblock_type_value[1];
    else macroblock_type_intra <= macroblock_type_intra;
 
  always @(posedge clk)
    if (~rst) macroblock_intra <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) macroblock_intra <= macroblock_type_value[1];
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP)) macroblock_intra <= 1'b0;
    else if (clk_en) macroblock_intra <= macroblock_type_intra;
    else macroblock_intra <= macroblock_intra;
 
  always @(posedge clk)
    if (~rst) spatial_temporal_weight_code_flag <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_TYPE)) spatial_temporal_weight_code_flag <= macroblock_type_value[0];
    else spatial_temporal_weight_code_flag <= spatial_temporal_weight_code_flag;
 
  /* motion type */
  always @(posedge clk)
    // par. 6.3.17.1: In this case motion vector decoding and prediction formation shall be performed as if frame_motion_type had indicated "Frame-based prediction".
    // 2 == Frame-based prediction.
    // par. 6.3.17.1: In the case of intra macroblocks (in a field picture) when concealment_motion_vectors is equal to 1 field_motion_type is not present in the bitstream.
    // In this case, motion vector decoding and update of the motion vector predictors shall be performed as if field_motion_type had indicated "Field-based"
    // 2'b1 == Field-based prediction.
    if (~rst) motion_type <= 2'd0;
    else if (clk_en && (state == STATE_MOTION_TYPE) && (macroblock_motion_forward || macroblock_motion_backward)  && (picture_structure == FRAME_PICTURE)) motion_type <= frame_pred_frame_dct ? MC_FRAME : getbits[23:22]; /* frame_motion_type */
    else if (clk_en && (state == STATE_MOTION_TYPE) && (macroblock_motion_forward || macroblock_motion_backward)) motion_type <= getbits[23:22]; /* field_motion_type */
    else if (clk_en && (state == STATE_MOTION_TYPE) && (macroblock_intra && concealment_motion_vectors)) motion_type <= (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; /* concealment motion vectors */
    else if (clk_en && (state == STATE_MOTION_TYPE)) motion_type <= MC_NONE;
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP)) motion_type <= (picture_structure == FRAME_PICTURE) ? MC_FRAME : MC_FIELD; // par. 7.6.6 the prediction shall be made as if (field|frame)_motion_type is "Field-based"|"Frame-based"
    else motion_type <= motion_type;
 
  /* dct type */
  /*
   dct_type is a flag indicating whether the macroblock is frame DCT coded or field DCT coded. If this is set to '1', the macroblock is field DCT coded. 
   In the case that dct_type is not present in the bitstream, then the value of dct_type (used in the remainder of the decoding process) shall be derived as shown in Table 6-19. 
   (par. 6.3.17.1, Macroblock modes)
   */
 
  always @(posedge clk)
    if (~rst) dct_type <= 1'b0;
    else if (clk_en && (state == STATE_MOTION_TYPE)) dct_type <= 1'b0;
    else if (clk_en && (state == STATE_DCT_TYPE)) dct_type <= getbits[23];
    else dct_type <= dct_type;
 
  // derived variables (par. 6.3.17.1, tables 6.17 and 6.18)
  // note  spatial_temporal_weight is always zero, we don't do scaleability.
  assign motion_vector_count_is_one = (picture_structure==FRAME_PICTURE) ? (motion_type != MC_FIELD) : (motion_type != MC_16X8);
 
  always @(posedge clk)
    if (~rst) mv_format <= 2'b0;
    else if (clk_en) mv_format <= (picture_structure==FRAME_PICTURE) ? ((motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD) : MV_FIELD;
    else mv_format <= mv_format;
 
  always @(posedge clk)
    if (~rst) dmv <= 1'b0;
    else if (clk_en) dmv <= (motion_type==MC_DMV);
    else dmv <= dmv;
 
  /* motion vectors */
 
  /* motion_vectors(0), motion_vertical_field_select(0,0) */
  /* par. 6.3.17.3: The number of bits in the bitstream for motion_residual[r][s][t], r_size, is derived from f_code[s][t] as follows:
   * r_size = f_code[s][t] - 1;
   */
  always @(posedge clk)
    if (~rst) r_size <= 4'd0;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && ((motion_vector == MOTION_VECTOR_0_0_0) || (motion_vector == MOTION_VECTOR_1_0_0))) r_size <= f_code_00 - 4'd1;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && ((motion_vector == MOTION_VECTOR_0_0_1) || (motion_vector == MOTION_VECTOR_1_0_1))) r_size <= f_code_01 - 4'd1;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && ((motion_vector == MOTION_VECTOR_0_1_0) || (motion_vector == MOTION_VECTOR_1_1_0))) r_size <= f_code_10 - 4'd1;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && ((motion_vector == MOTION_VECTOR_0_1_1) || (motion_vector == MOTION_VECTOR_1_1_1))) r_size <= f_code_11 - 4'd1;
    else r_size <= r_size;
 
  // vertical_field_select_present - one if motion_vector(s) begins with a 'motion_vertical_field_select'.
  assign vertical_field_select_present = (motion_vector_count_is_one ? ( (mv_format == MV_FIELD) && (dmv != 1'b1) ) : 1'd1 ) 
                                         && ((motion_vector == MOTION_VECTOR_0_0_0) || (motion_vector == MOTION_VECTOR_1_0_0) || 
                                             (motion_vector == MOTION_VECTOR_0_1_0) || (motion_vector == MOTION_VECTOR_1_1_0)); // par. 6.2.5.1
 
  /* motion code variables, par. 6.2.5, 6.2.5.2, 6.2.5.2.1 */
  /*
   * motion_vector cycles through the different motion vectors MOTION_VECTOR_0_0_0 ... MOTION_VECTOR_1_1_1
   * The msb of  motion_vector_reg is one if the motion vector actually occurs in the bitstream.
   */
  always @(posedge clk)
    if (~rst) motion_vector <= 3'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_QUANT)) motion_vector <= MOTION_VECTOR_0_0_0; 
    else if (clk_en && (state == STATE_MOTION_PREDICT)) motion_vector <= motion_vector + 1;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && (motion_vector_reg[7] == 1'b0)) motion_vector <= motion_vector + 1;
    else motion_vector <= motion_vector;
 
  always @(posedge clk)
    if (~rst) motion_vector_reg <= 8'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_QUANT)) /* set up motion_vector_reg */
      case ({macroblock_motion_forward || (macroblock_intra && concealment_motion_vectors), macroblock_motion_backward, motion_vector_count_is_one})
        3'b000: motion_vector_reg <= 8'b00000000; // no motion vectors
        3'b001: motion_vector_reg <= 8'b00000000; // no motion vectors
        3'b100: motion_vector_reg <= 8'b11110000; // motion_code_000, 001, 100, 101
        3'b101: motion_vector_reg <= 8'b11000000; // motion_code_000, 001
        3'b010: motion_vector_reg <= 8'b00001111; // motion_code_                    010, 011, 110, 111
        3'b011: motion_vector_reg <= 8'b00001100; // motion_code_                    010, 011
        3'b110: motion_vector_reg <= 8'b11111111; // motion_code_000, 001, 100, 101, 010, 011, 110, 111
        3'b111: motion_vector_reg <= 8'b11001100; // motion_code_000, 001,           010, 011
      endcase
    else if (clk_en && (state == STATE_MOTION_PREDICT)) motion_vector_reg <= motion_vector_reg << 1;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR) && (motion_vector_reg[7] == 1'b0)) motion_vector_reg <= motion_vector_reg << 1;
    else motion_vector_reg <= motion_vector_reg;
 
  always @(posedge clk)
    if (~rst) motion_code <= 5'b0;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR)) motion_code <= 5'b0;
    else if (clk_en && (state == STATE_MOTION_CODE)) motion_code <= motion_code_value;
    else motion_code <= motion_code;
 
  always @(posedge clk)
    if (~rst) motion_code_neg <= 1'b0;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR)) motion_code_neg <= 1'b0;
    else if (clk_en && (state == STATE_MOTION_CODE)) motion_code_neg <= motion_code_sign;
    else motion_code_neg <= motion_code_neg;
 
  always @(posedge clk)
    if (~rst) motion_code_residual <= 8'b0;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR)) motion_code_residual <= 8'b0;
    else if (clk_en && (state == STATE_MOTION_RESIDUAL))
                     begin
                       case (r_size)
                        14'd00: motion_code_residual <= {8'b0}; // Error, f_code != 1 hence r_size != 0.
                        14'd01: motion_code_residual <= {7'b0, getbits[23]};
                        14'd02: motion_code_residual <= {6'b0, getbits[23:22]};
                        14'd03: motion_code_residual <= {5'b0, getbits[23:21]};
                        14'd04: motion_code_residual <= {4'b0, getbits[23:20]};
                        14'd05: motion_code_residual <= {3'b0, getbits[23:19]};
                        14'd06: motion_code_residual <= {2'b0, getbits[23:18]};
                        14'd07: motion_code_residual <= {1'b0, getbits[23:17]};
                        14'd08: motion_code_residual <=        getbits[23:16];
                        default motion_code_residual <=        getbits[23:16]; // Should never happen, as r_size is 1..8 (f_code = 1..9 in Table E-8 at high level)
                       endcase
                     end
    else motion_code_residual <= motion_code_residual;
 
  always @(posedge clk)
    if (~rst) dmvector <= 2'b0;
    else if (clk_en && (state == STATE_NEXT_MOTION_VECTOR)) dmvector <= 2'b0;
    else if (clk_en && (state == STATE_MOTION_DMVECTOR)) 
      begin
        case ({dmvector_sign, dmvector_value}) 
	  {1'b0, 1'b0}:  dmvector <= 2'b0;
	  {1'b0, 1'b1}:  dmvector <= 2'b1;
	  {1'b1, 1'b0}:  dmvector <= 2'b0;
	  {1'b1, 1'b1}:  dmvector <= -2'b1;
	endcase
      end
    else dmvector <= dmvector;
 
  /*
   * Resetting motion vector predictors, par. 7.6.3.4. 
   * Also includes updating motion vector predictors to zero, par. 7.6.3.3.
   *
   * The difference between resetting and updating is that updating occurs
   * after the motion vectors have been processed, in STATE_BLOCK
   */
 
  wire pmv_reset = (state == STATE_SLICE) || /* par. 7.6.3.4, At the start of each slice. */ 
                   ((state == STATE_MACROBLOCK_QUANT) && macroblock_intra && ~concealment_motion_vectors) || /* par. 7.6.3.4, Whenever an intra macroblock is decoded which has no concealment motion vectors. */ 
                   ((state == STATE_MACROBLOCK_QUANT) && (picture_coding_type == P_TYPE) && ~macroblock_intra && ~macroblock_motion_forward) || /* par. 7.6.3.4, In a P-picture when a non-intra macroblock is decoded in which macroblock_motion_forward is zero. */ 
		   ((state == STATE_MACROBLOCK_SKIP) && (picture_coding_type == P_TYPE)); /* par. 7.6.3.4, In a P-picture when a macroblock is skipped. Also 7.6.6.1, 7.6.6.2 */ 
 
 
  /*
   * Updating motion vector predictors. Table 7-9 and 7-10.
   * When to PMV[1][0][1:0] = PMV[0][0][1:0]
   */
 
  wire pmv_update0 =   ((picture_structure == FRAME_PICTURE) && (motion_type == MC_FRAME) && macroblock_intra) ||
                       ((picture_structure == FRAME_PICTURE) && (motion_type == MC_FRAME) && macroblock_motion_forward) ||
                       ((picture_structure == FRAME_PICTURE) && (motion_type == MC_DMV) && macroblock_motion_forward && ~macroblock_motion_backward && ~macroblock_intra) ||
		       (((picture_structure == TOP_FIELD) || (picture_structure == BOTTOM_FIELD)) && (motion_type == MC_FIELD) && macroblock_intra) ||
		       (((picture_structure == TOP_FIELD) || (picture_structure == BOTTOM_FIELD)) && (motion_type == MC_FIELD) && macroblock_motion_forward) ||
		       (((picture_structure == TOP_FIELD) || (picture_structure == BOTTOM_FIELD)) && (motion_type == MC_DMV) && macroblock_motion_forward && ~macroblock_motion_backward && ~macroblock_intra) ;
 
  /*
   * Updating motion vector predictors. Table 7-9 and 7-10.
   * When to PMV[1][1][1:0] = PMV[0][1][1:0]
   */
 
  wire pmv_update1 =  ((picture_structure == FRAME_PICTURE) && (motion_type == MC_FRAME) && ~macroblock_intra && macroblock_motion_backward) ||
		      (((picture_structure == TOP_FIELD) || (picture_structure == BOTTOM_FIELD)) && (motion_type == MC_FIELD) && ~macroblock_intra && macroblock_motion_backward) ;
 
  /* motion vector pipeline */
  always @(posedge clk)  
    if (~rst) 
      begin
        motion_vector_0 <= 2'b0;
        motion_vector_1 <= 2'b0;
        motion_vector_2 <= 2'b0;
        motion_vector_3 <= 2'b0;
        motion_vector_4 <= 2'b0;
        motion_vector_5 <= 2'b0;
      end
    else if (clk_en)
      begin
        motion_vector_0 <= motion_vector;
        motion_vector_1 <= motion_vector_0;
        motion_vector_2 <= motion_vector_1;
        motion_vector_3 <= motion_vector_2;
        motion_vector_4 <= motion_vector_3;
        motion_vector_5 <= motion_vector_4;
      end
    else 
      begin
        motion_vector_0 <= motion_vector_0;
        motion_vector_1 <= motion_vector_1;
        motion_vector_2 <= motion_vector_2;
        motion_vector_3 <= motion_vector_3;
        motion_vector_4 <= motion_vector_4;
        motion_vector_5 <= motion_vector_5;
      end
 
  always @(posedge clk)  
    if (~rst) 
      begin
        motion_vector_valid_0 <= 1'b0;
        motion_vector_valid_1 <= 1'b0;
        motion_vector_valid_2 <= 1'b0;
        motion_vector_valid_3 <= 1'b0;
        motion_vector_valid_4 <= 1'b0;
        motion_vector_valid_5 <= 1'b0;
      end
    else if (clk_en)
      begin
        motion_vector_valid_0 <= (state == STATE_MOTION_PREDICT);
        motion_vector_valid_1 <= motion_vector_valid_0;
        motion_vector_valid_2 <= motion_vector_valid_1;
        motion_vector_valid_3 <= motion_vector_valid_2;
        motion_vector_valid_4 <= motion_vector_valid_3;
        motion_vector_valid_5 <= motion_vector_valid_4;
      end
    else 
      begin
        motion_vector_valid_0 <= motion_vector_valid_0;
        motion_vector_valid_1 <= motion_vector_valid_1;
        motion_vector_valid_2 <= motion_vector_valid_2;
        motion_vector_valid_3 <= motion_vector_valid_3;
        motion_vector_valid_4 <= motion_vector_valid_4;
        motion_vector_valid_5 <= motion_vector_valid_5;
      end
 
  always @(posedge clk)  
    if (~rst) 
      begin
        r_size_0 <= 4'b0;
        r_size_1 <= 4'b0;
      end
    else if (clk_en)
      begin
        r_size_0 <= r_size;
        r_size_1 <= r_size_0;
      end
    else 
      begin
        r_size_0 <= r_size_0;
        r_size_1 <= r_size_1;
      end
 
  always @(posedge clk)  
    if (~rst) motion_code_neg_0 <= 1'b0;
    else if (clk_en) motion_code_neg_0 <= motion_code_neg;
    else motion_code_neg_0 <= motion_code_neg_0;
 
  wire signed [12:0]motion_code_signed = {8'b0, motion_code};
  wire signed [12:0]motion_code_residual_signed = {5'b0, motion_code_residual};
 
  always @(posedge clk)  
    if (~rst) pmv_delta_0 <= 13'b0;
    else if (clk_en) pmv_delta_0 <= ((r_size == 4'b0) || (motion_code == 5'b0)) ? motion_code_signed : ((motion_code_signed - 13'sd1) <<< r_size) + motion_code_residual_signed + 13'sd1;
    else pmv_delta_0 <= pmv_delta_0;
 
  wire shift_pmv = (mv_format == MV_FIELD) && (picture_structure == FRAME_PICTURE);
 
  always @(posedge clk)  
    if (~rst) 
      begin
        pmv_0 <= 13'b0;
        pmv_1 <= 13'b0;
        pmv_2 <= 13'b0;
        pmv_3 <= 13'b0;
        pmv_4 <= 13'b0;
        pmv_5 <= 13'b0;
      end
    else if (clk_en)
      begin
        /* stage 1 */
        case (motion_vector)
          MOTION_VECTOR_0_0_0: pmv_0 <= pmv_0_0_0;
          MOTION_VECTOR_0_0_1: pmv_0 <= shift_pmv ? pmv_0_0_1 >>> 1 : pmv_0_0_1;
          MOTION_VECTOR_1_0_0: pmv_0 <= pmv_1_0_0;
          MOTION_VECTOR_1_0_1: pmv_0 <= shift_pmv ? pmv_1_0_1 >>> 1 : pmv_1_0_1;
          MOTION_VECTOR_0_1_0: pmv_0 <= pmv_0_1_0;
          MOTION_VECTOR_0_1_1: pmv_0 <= shift_pmv ? pmv_0_1_1 >>> 1 : pmv_0_1_1; 
          MOTION_VECTOR_1_1_0: pmv_0 <= pmv_1_1_0;
          MOTION_VECTOR_1_1_1: pmv_0 <= shift_pmv ? pmv_1_1_1 >>> 1 : pmv_1_1_1;
          default              pmv_0 <= 13'b0;
        endcase
        /* stage 2 */
        pmv_1 <= motion_code_neg_0 ? pmv_0 - pmv_delta_0 : pmv_0 + pmv_delta_0;
        /*
         * stage 3
         * next case statement ought to be equivalent to:
         * pmv <= (pmv < low) ? (pmv + range) : ((pmv > high) ? (pmv - range) : pmv);
         *
         * As f_code_ is restricted to the range 1..9, (Table E-8, High Level)
         * r_size is restricted to the range 0..8. 
         */
        case (r_size_1)
          4'd0:   pmv_2 <= { {9{pmv_1[4]}},  pmv_1[3:0]  };
          4'd1:   pmv_2 <= { {8{pmv_1[5]}},  pmv_1[4:0]  };
          4'd2:   pmv_2 <= { {7{pmv_1[6]}},  pmv_1[5:0]  };
          4'd3:   pmv_2 <= { {6{pmv_1[7]}},  pmv_1[6:0]  };
          4'd4:   pmv_2 <= { {5{pmv_1[8]}},  pmv_1[7:0]  };
          4'd5:   pmv_2 <= { {4{pmv_1[9]}},  pmv_1[8:0]  };
          4'd6:   pmv_2 <= { {3{pmv_1[10]}}, pmv_1[9:0]  };
          4'd7:   pmv_2 <= { {2{pmv_1[11]}}, pmv_1[10:0] };
          4'd8:   pmv_2 <= { {1{pmv_1[12]}}, pmv_1[11:0] };
          default pmv_2 <=                   pmv_1[12:0]  ; // never occurs
        endcase
	/*
	 * stage 4..5: dmv calculations only
	 */
	pmv_3 <= pmv_2;
	pmv_4 <= pmv_3;
	pmv_5 <= pmv_4;
      end
    else 
      begin
        pmv_0 <= pmv_0;
        pmv_1 <= pmv_1;
        pmv_2 <= pmv_2;
        pmv_3 <= pmv_3;
        pmv_4 <= pmv_4;
        pmv_5 <= pmv_5;
      end
 
  /*
   * predicted motion vectors. 
   * pmv_reset is asserted when the motion vectors are reset to zero;
   * pmv_update0 is asserted when pmv_1_0_x <= pmv_0_0_x
   * pmv_update1 is asserted when pmv_1_1_x <= pmv_0_1_x
   */
  always @(posedge clk)  
    if (~rst) pmv_0_0_0 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_0_0_0 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_0)) pmv_0_0_0 <= pmv_5;
    else pmv_0_0_0 <= pmv_0_0_0;
 
  always @(posedge clk)  
    if (~rst) pmv_0_0_1 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_0_0_1 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_1)) pmv_0_0_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else pmv_0_0_1 <= pmv_0_0_1;
 
  always @(posedge clk)  
    if (~rst) pmv_1_0_0 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_1_0_0 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_1_0_0)) pmv_1_0_0 <= pmv_5;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_0) && pmv_update0) pmv_1_0_0 <= pmv_5;
    else pmv_1_0_0 <= pmv_1_0_0;
 
  always @(posedge clk)  
    if (~rst) pmv_1_0_1 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_1_0_1 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_1_0_1)) pmv_1_0_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_1) && pmv_update0) pmv_1_0_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else pmv_1_0_1 <= pmv_1_0_1;
 
  always @(posedge clk)  
    if (~rst) pmv_0_1_0 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_0_1_0 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_0)) pmv_0_1_0 <= pmv_5;
    else pmv_0_1_0 <= pmv_0_1_0;
 
  always @(posedge clk)  
    if (~rst) pmv_0_1_1 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_0_1_1 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_1)) pmv_0_1_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else pmv_0_1_1 <= pmv_0_1_1;
 
  always @(posedge clk)  
    if (~rst) pmv_1_1_0 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_1_1_0 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_1_1_0)) pmv_1_1_0 <= pmv_5;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_0) && pmv_update1) pmv_1_1_0 <= pmv_5;
    else pmv_1_1_0 <= pmv_1_1_0;
 
  always @(posedge clk)  
    if (~rst) pmv_1_1_1 <= 13'b0;
    else if (clk_en && pmv_reset) pmv_1_1_1 <= 13'b0;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_1_1_1)) pmv_1_1_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_1) && pmv_update1) pmv_1_1_1 <= shift_pmv ? pmv_5 <<< 1 : pmv_5;
    else pmv_1_1_1 <= pmv_1_1_1;
 
  /* motion vector field select */
  output reg       motion_vert_field_select_0_0; // motion_vertical_field_select. Indicates which reference field shall be used to form the prediction. 
                                                 // If motion_vertical_field_select[r][s] is zero, then the top reference field shall be used, 
                                                 // if it is one then the bottom reference field shall be used.
  output reg       motion_vert_field_select_0_1;
  output reg       motion_vert_field_select_1_0;
  output reg       motion_vert_field_select_1_1;
 
  always @(posedge clk)  
    if (~rst) motion_vert_field_select_0_0 <= 1'b0;
    else if (clk_en && (state == STATE_PICTURE_HEADER)) motion_vert_field_select_0_0 <= 1'b0; // I take the liberty of resetting at the start of a picture
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP) && (picture_structure != FRAME_PICTURE)) motion_vert_field_select_0_0 <= (picture_structure==BOTTOM_FIELD); // par. 7.6.6.1 and 7.6.6.3, skipped macroblocks. predict from field of same parity.
    else if (clk_en && (state == STATE_MACROBLOCK_QUANT) && (picture_coding_type == P_TYPE) && ~macroblock_intra && ~macroblock_motion_forward && (picture_structure != FRAME_PICTURE)) motion_vert_field_select_0_0 <= (picture_structure==BOTTOM_FIELD); // par. 7.6.3.5 Prediction in P pictures. non-intra mb without forward mv in a P picture. 
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && (motion_vector == MOTION_VECTOR_0_0_0)) motion_vert_field_select_0_0 <= getbits[23];
    else motion_vert_field_select_0_0 <= motion_vert_field_select_0_0;
 
  always @(posedge clk)  
    if (~rst) motion_vert_field_select_0_1 <= 1'b0;
    else if (clk_en && (state == STATE_PICTURE_HEADER)) motion_vert_field_select_0_1 <= 1'b0;
    else if (clk_en && (state == STATE_MACROBLOCK_SKIP) && (picture_structure != FRAME_PICTURE)) motion_vert_field_select_0_1 <= (picture_structure==BOTTOM_FIELD); // par. 7.6.6.1 and 7.6.6.3, skipped macroblocks. predict from field of same parity.
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && (motion_vector == MOTION_VECTOR_0_1_0)) motion_vert_field_select_0_1 <= getbits[23];
    else motion_vert_field_select_0_1 <= motion_vert_field_select_0_1;
 
  always @(posedge clk)  
    if (~rst) motion_vert_field_select_1_0 <= 1'b0;
    else if (clk_en && (state == STATE_PICTURE_HEADER)) motion_vert_field_select_1_0 <= 1'b0;
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && (motion_vector == MOTION_VECTOR_1_0_0)) motion_vert_field_select_1_0 <= getbits[23];
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && motion_vector_count_is_one && (mv_format == MV_FIELD) && ~dmv && (motion_vector == MOTION_VECTOR_0_0_0)) motion_vert_field_select_1_0 <= getbits[23]; // case of only one motion vector
    else motion_vert_field_select_1_0 <= motion_vert_field_select_1_0;
 
  always @(posedge clk)  
    if (~rst) motion_vert_field_select_1_1 <= 1'b0;
    else if (clk_en && (state == STATE_PICTURE_HEADER)) motion_vert_field_select_1_1 <= 1'b0;
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && (motion_vector == MOTION_VECTOR_1_1_0)) motion_vert_field_select_1_1 <= getbits[23];
    else if (clk_en && (state == STATE_MOTION_VERT_FLD_SEL) && motion_vector_count_is_one && (mv_format == MV_FIELD) && ~dmv && (motion_vector == MOTION_VECTOR_0_1_0)) motion_vert_field_select_1_1 <= getbits[23]; // case of only one motion vector
    else motion_vert_field_select_1_1 <= motion_vert_field_select_1_1;
 
  /* additional dual-prime arithmetic, par. 7.6.3.6 */
  always @(posedge clk)  
    if (~rst) 
      begin
        dmvector_0 <= 2'b0; 
        dmvector_1 <= 2'b0;
        dmvector_2 <= 2'b0;
        dmvector_3 <= 2'b0;
      end
    else if (clk_en)
      begin
        dmvector_0 <= dmvector;
        dmvector_1 <= dmvector_0;
        dmvector_2 <= dmvector_1;
        dmvector_3 <= dmvector_2;
      end
    else 
      begin
        dmvector_0 <= dmvector_0;
        dmvector_1 <= dmvector_1;
        dmvector_2 <= dmvector_2;
        dmvector_3 <= dmvector_3;
      end
 
  wire pmv_2_pos = (~pmv_2[12] && (pmv_2 != 13'b0)); // asserted if pmv_2 > 0
  wire top_field_at_bottom = (picture_structure==FRAME_PICTURE) && (~top_field_first);
 
  reg signed [1:0] e_parity_ref_parity_pred_4;
  reg signed [12:0]dmvector_aux_a_3;
  reg signed [12:0]dmvector_aux_b_3;
  reg signed [12:0]dmvector_aux_a_4;
  reg signed [12:0]dmvector_aux_b_4;
  reg signed [12:0]dmvector_aux_a_5;
  reg signed [12:0]dmvector_aux_b_5;
 
  always @(posedge clk)
    if (~rst) e_parity_ref_parity_pred_4 <= 2'd0;
    else if (clk_en && (motion_vector_3 == MOTION_VECTOR_0_0_0)) e_parity_ref_parity_pred_4 <= 2'd0;
    else if (clk_en && (motion_vector_3 == MOTION_VECTOR_0_0_1)) e_parity_ref_parity_pred_4 <= ((picture_structure==FRAME_PICTURE) || (picture_structure==TOP_FIELD)) ? -2'd1 : 2'd1;
    else e_parity_ref_parity_pred_4 <= e_parity_ref_parity_pred_4;
 
  always @(posedge clk)
    if (~rst)
      begin
        dmvector_aux_a_3 <= 13'd0;
        dmvector_aux_a_4 <= 13'd0;
        dmvector_aux_a_5 <= 13'd0;
      end
    else if (clk_en)
      begin
        dmvector_aux_a_3 <= pmv_2 + pmv_2_pos;
        dmvector_aux_a_4 <= {dmvector_aux_a_3[12], dmvector_aux_a_3[12:1]} + { {12{dmvector_3[1]}}, dmvector_3[0] }; // sign-extend dmvector before adding
        dmvector_aux_a_5 <= (top_field_at_bottom ? dmvector_aux_b_4 : dmvector_aux_a_4) + { {12{e_parity_ref_parity_pred_4[1]}}, e_parity_ref_parity_pred_4[0] }; // sign-extend e_parity_ref_parity_pred before adding
      end
    else 
      begin
        dmvector_aux_a_3 <= dmvector_aux_a_3;
        dmvector_aux_a_4 <= dmvector_aux_a_4;
        dmvector_aux_a_5 <= dmvector_aux_a_5;
      end
 
  always @(posedge clk)
    if (~rst)
      begin
        dmvector_aux_b_3 <= 13'd0;
        dmvector_aux_b_4 <= 13'd0;
        dmvector_aux_b_5 <= 13'd0;
      end
    else if (clk_en)
      begin
        dmvector_aux_b_3 <= (pmv_2 <<< 1) + pmv_2 + pmv_2_pos;
        dmvector_aux_b_4 <= {dmvector_aux_b_3[12], dmvector_aux_b_3[12:1]} + { {12{dmvector_3[1]}}, dmvector_3[0] }; // sign-extend dmvector before adding
        dmvector_aux_b_5 <= (top_field_at_bottom ? dmvector_aux_a_4 : dmvector_aux_b_4) - { {12{e_parity_ref_parity_pred_4[1]}}, e_parity_ref_parity_pred_4[0] }; // sign-extend e_parity_ref_parity_pred before adding
      end
    else 
      begin
        dmvector_aux_b_3 <= dmvector_aux_b_3;
        dmvector_aux_b_4 <= dmvector_aux_b_4;
        dmvector_aux_b_5 <= dmvector_aux_b_5;
      end
 
  always @(posedge clk)
    if (~rst) dmv_0_0 <= 13'd0;
    else if (clk_en && (motion_vector_valid_5) && dmv && (motion_vector_5 == MOTION_VECTOR_0_0_0)) dmv_0_0 <= dmvector_aux_a_5;
    else dmv_0_0 <= dmv_0_0;
 
  always @(posedge clk)
    if (~rst) dmv_1_0 <= 13'd0;
    else if (clk_en && (motion_vector_valid_5) && dmv && (motion_vector_5 == MOTION_VECTOR_0_0_0)) dmv_1_0 <= dmvector_aux_b_5;
    else dmv_1_0 <= dmv_1_0;
 
  always @(posedge clk)
    if (~rst) dmv_0_1 <= 13'd0;
    else if (clk_en && (motion_vector_valid_5) && dmv && (motion_vector_5 == MOTION_VECTOR_0_0_1)) dmv_0_1 <= dmvector_aux_a_5;
    else dmv_0_1 <= dmv_0_1;
 
  always @(posedge clk)
    if (~rst) dmv_1_1 <= 13'd0;
    else if (clk_en && (motion_vector_valid_5) && dmv && (motion_vector_5 == MOTION_VECTOR_0_0_1)) dmv_1_1 <= dmvector_aux_b_5;
    else dmv_1_1 <= dmv_1_1;
 
  /* motion vector output */
  always @(posedge clk)  
    if (~rst) motion_vector_valid <= 1'b0;
    /*
     * par. 7.6.6: Skipped macroblocks. 
     * In a P picture the motion vector shall be zero;
     * in a B picture the motion vectors are taken from the appropriate motion vector predictors. 
     *
     * Here:
     * - motion vectors of skipped macroblocks are reset (for P pictures) during STATE_MACROBLOCK_SKIP and valid the state after STATE_MACROBLOCK_SKIP
     * - motion vectors of non-skipped macroblocks are computed during STATE_NEXT_MOTION_VECTOR .. STATE_MOTION_PIPELINE_FLUSH. The
     *   motion vectors are valid after STATE_MOTION_PIPELINE_FLUSH, and, by extension, at STATE_BLOCK.
     */
    else if (clk_en) motion_vector_valid <= (state == STATE_MACROBLOCK_SKIP) || (state == STATE_BLOCK); 
    else motion_vector_valid <= 1'b0;
 
  /* second field */
  output reg       second_field;
 
  always @(posedge clk)
    if (~rst) second_field <= 1'b0;
    else if (clk_en && ((state == STATE_SEQUENCE_HEADER) || (state == STATE_GROUP_HEADER))) second_field <= 1'b1;
    else if (clk_en && (state == STATE_PICTURE_HEADER) && (picture_structure == FRAME_PICTURE)) second_field <= 1'b0; /* recover from illegal number of field pictures, if necessary */
    else if (clk_en && (state == STATE_PICTURE_HEADER)) second_field <= ~second_field; /* field picture */
    else second_field <= second_field;
 
  /*
     tell motion compensation to switch picture buffers.
     If frame picture, switch picture buffers every picture header.
     If field picture, switch picture buffers every other picture header. 
     (Field pictures use two picture headers, one for each field)
   */
  output reg       update_picture_buffers;
  output reg       last_frame;
 
  always @(posedge clk)
    if (~rst) update_picture_buffers <= 1'b0;
    else if (clk_en) update_picture_buffers <= ((state == STATE_PICTURE_HEADER) && ((picture_structure == FRAME_PICTURE) || second_field)) // emit frame at picture header
                                               || ((state == STATE_SEQUENCE_END) && ~last_frame); // emit last frame
    else update_picture_buffers <= 1'b0;
 
  /*
    We're at video end, tell motion compensation to emit the last frame.
   */
 
  always @(posedge clk)
    if (~rst) last_frame <= 1'b0;
    else if (clk_en && (state == STATE_SEQUENCE_END)) last_frame <= 1'b1; // end of this video bitstream
    else if (clk_en && ((state == STATE_SEQUENCE_HEADER) || (state == STATE_PICTURE_HEADER))) last_frame <= 1'b0; // start of new video bitstream
    else last_frame <= last_frame;
 
  /* dct_dc_size_luminance, dct_dc_size_chrominance and dct_dc_differential (par. 7.2.1) */
 
  always @(posedge clk)
    if (~rst) dct_dc_size <= 4'b0;
    else if (clk_en && (state == STATE_DCT_DC_LUMI_SIZE)) dct_dc_size <= dct_dc_size_luminance_value;     // table B-12 lookup
    else if (clk_en && (state == STATE_DCT_DC_CHROMI_SIZE)) dct_dc_size <= dct_dc_size_chrominance_value; // table B-13 lookup
    else dct_dc_size <= dct_dc_size;
 
  reg [10:0]dct_dc_pred_add;
  always @*
      case (dct_dc_size)
        4'd1:   dct_dc_pred_add = getbits[23];
        4'd2:   dct_dc_pred_add = getbits[23:22];
        4'd3:   dct_dc_pred_add = getbits[23:21];
        4'd4:   dct_dc_pred_add = getbits[23:20];
        4'd5:   dct_dc_pred_add = getbits[23:19];
        4'd6:   dct_dc_pred_add = getbits[23:18];
        4'd7:   dct_dc_pred_add = getbits[23:17];
        4'd8:   dct_dc_pred_add = getbits[23:16];
        4'd9:   dct_dc_pred_add = getbits[23:15];
        4'd10:  dct_dc_pred_add = getbits[23:14];
        4'd11:  dct_dc_pred_add = getbits[23:13];
        default dct_dc_pred_add = 11'd0; // error: maximum in table B-12 and B-13 is 11
      endcase
 
  reg [10:0]dct_dc_pred_sub;
  always @*
      case (dct_dc_size)
        4'd1:   dct_dc_pred_sub = 11'b1;
        4'd2:   dct_dc_pred_sub = 11'b11;
        4'd3:   dct_dc_pred_sub = 11'b111;
        4'd4:   dct_dc_pred_sub = 11'b1111;
        4'd5:   dct_dc_pred_sub = 11'b11111;
        4'd6:   dct_dc_pred_sub = 11'b111111;
        4'd7:   dct_dc_pred_sub = 11'b1111111;
        4'd8:   dct_dc_pred_sub = 11'b11111111;
        4'd9:   dct_dc_pred_sub = 11'b111111111;
        4'd10:  dct_dc_pred_sub = 11'b1111111111;
        4'd11:  dct_dc_pred_sub = 11'b11111111111;
        default dct_dc_pred_sub = 11'd0; // error: maximum in table B-12 and B-13 is 11
      endcase
 
  always @(posedge clk)
    if (~rst) dct_dc_pred <= 11'b0;
    else if (clk_en && (state == STATE_DCT_DC_LUMI_SIZE))                             dct_dc_pred <= dct_dc_pred_0; // Y block
    else if (clk_en && (state == STATE_DCT_DC_CHROMI_SIZE) && block_chromi1_code[12]) dct_dc_pred <= dct_dc_pred_1; // Cb block
    else if (clk_en && (state == STATE_DCT_DC_CHROMI_SIZE) && block_chromi2_code[12]) dct_dc_pred <= dct_dc_pred_2; // Cr block
    else if (clk_en && (state == STATE_DCT_DC_DIFF))
      begin
        if (dct_dc_size == 4'd0) dct_dc_pred <=  dct_dc_pred;
        else if (getbits[23] == 1'b0) dct_dc_pred <= dct_dc_pred + dct_dc_pred_add - dct_dc_pred_sub;
        else dct_dc_pred <= dct_dc_pred + dct_dc_pred_add;
      end
    else dct_dc_pred <= dct_dc_pred;
 
  // luminance (Y) dct dc predictor
  always @(posedge clk)
    if (~rst) dct_dc_pred_0 <= 11'b0;
    else if (clk_en && ((state == STATE_SLICE) ||  // at the start of a slice (par. 7.2.1)
                        ((state == STATE_BLOCK) && ~macroblock_intra) || // whenever a non-intra macroblock is decoded (par. 7.2.1.)
                        (state == STATE_MACROBLOCK_SKIP) )) // whenever a macroblock is skipped, i.e. when macroblock_address_increment > 1
                        dct_dc_pred_0 <= 11'b0; // the mpeg2 reference implementation (mpeg2decode) does not reset dct_dc_pred[i] to 11'd128 << intra_dc_precision; rather it adds 128 to the reconstructed output.
    else if (clk_en && (state == STATE_DCT_DC_DIFF_0) && block_lumi_code[12]) dct_dc_pred_0 <= dct_dc_pred;
    else dct_dc_pred_0 <= dct_dc_pred_0;
 
  // first chrominance (Cb) dct dc predictor
  always @(posedge clk)
    if (~rst) dct_dc_pred_1 <= 11'b0;
    else if (clk_en && ((state == STATE_SLICE) ||  // at the start of a slice (par. 7.2.1)
                        ((state == STATE_BLOCK) && ~macroblock_intra) || // whenever a non-intra macroblock is decoded (par. 7.2.1.)
                        (state == STATE_MACROBLOCK_SKIP) )) // whenever a macroblock is skipped, i.e. when macroblock_address_increment > 1
                        dct_dc_pred_1 <= 11'b0; // the mpeg2 reference implementation (mpeg2decode) does not reset dct_dc_pred[i] to 11'd128 << intra_dc_precision; rather it adds 128 to the reconstructed output.
    else if (clk_en && (state == STATE_DCT_DC_DIFF_0) && block_chromi1_code[12]) dct_dc_pred_1 <= dct_dc_pred;
    else dct_dc_pred_1 <= dct_dc_pred_1;
 
  // second chrominance (Cr) dct dc predictor
  always @(posedge clk)
    if (~rst) dct_dc_pred_2 <= 11'b0;
    else if (clk_en && ((state == STATE_SLICE) ||  // at the start of a slice (par. 7.2.1)
                        ((state == STATE_BLOCK) && ~macroblock_intra) || // whenever a non-intra macroblock is decoded (par. 7.2.1.)
                        (state == STATE_MACROBLOCK_SKIP) )) // whenever a macroblock is skipped, i.e. when macroblock_address_increment > 1
                        dct_dc_pred_2 <= 11'b0; // the mpeg2 reference implementation (mpeg2decode) does not reset dct_dc_pred[i] to 11'd128 << intra_dc_precision; rather it adds 128 to the reconstructed output.
    else if (clk_en && (state == STATE_DCT_DC_DIFF_0) && block_chromi2_code[12]) dct_dc_pred_2 <= dct_dc_pred;
    else dct_dc_pred_2 <= dct_dc_pred_2;
 
 
  /* dct coefficients */
  assign dct_coefficient_escape = (getbits[23:18] == 6'b000001); // one if dct coefficient escape in table B-14 or B-15
 
  /* dct coeeficients are vlc decoded - still unsigned - and clocked in dct_coeff_run_0 and dct_coeff_signed_level_0.
   * next clock, the sign bit is applied, and the run/level pair is clocked in dct_coeff_run and dct_coeff_signed_level .
   *
   * A non-coded block (STATE_NON_CODED_BLOCK) or a block of a skipped macroblock (STATE_EMIT_EMPTY_BLOCK) is coded as a single zero, 
   * which also is the end of block. run=0, level=0, signed_level=0, end=1, valid=1.
   */
 
  always @(posedge clk)
    if (~rst) dct_coeff_run_0 <= 5'd0;
    else if (clk_en && ((state == STATE_DCT_SUBS_B15) || (state == STATE_DCT_SUBS_B14) || (state == STATE_DCT_NON_INTRA_FIRST)) && dct_coefficient_escape) dct_coeff_run_0 <= getbits[17:12];
    else if (clk_en && (state == STATE_DCT_SUBS_B15)) dct_coeff_run_0 <= dct_coefficient_1_decoded[10:6];
    else if (clk_en && (state == STATE_DCT_SUBS_B14)) dct_coeff_run_0 <= dct_coefficient_0_decoded[10:6];
    else if (clk_en && (state == STATE_DCT_NON_INTRA_FIRST)) dct_coeff_run_0 <= dct_non_intra_first_coefficient_0_decoded[10:6];
    else if (clk_en && (state == STATE_DCT_DC_DIFF_0)) dct_coeff_run_0 <= 5'd0;  // first (=dc)  coefficient of intra block is never preceded by zeroes
    else if (clk_en && ((state == STATE_NON_CODED_BLOCK) || (state == STATE_EMIT_EMPTY_BLOCK))) dct_coeff_run_0 <= 5'd0; // non-coded block: all zeroes.
    else dct_coeff_run_0 <= dct_coeff_run_0;
 
  always @(posedge clk)
    if (~rst) dct_coeff_signed_level_0 <= 12'd0;
    else if (clk_en && ((state == STATE_DCT_ESCAPE_B15) || (state == STATE_DCT_ESCAPE_B14))) dct_coeff_signed_level_0 <= getbits[23:12];
    else if (clk_en && (state == STATE_DCT_SUBS_B15) && ~dct_coefficient_escape) dct_coeff_signed_level_0 <= dct_coefficient_1_decoded[5:0]; // still needs sign
    else if (clk_en && (state == STATE_DCT_SUBS_B14) && ~dct_coefficient_escape) dct_coeff_signed_level_0 <= dct_coefficient_0_decoded[5:0]; // still needs sign
    else if (clk_en && (state == STATE_DCT_NON_INTRA_FIRST) && ~dct_coefficient_escape) dct_coeff_signed_level_0 <= dct_non_intra_first_coefficient_0_decoded[5:0]; // still needs sign
    else if (clk_en && (state == STATE_DCT_DC_DIFF_0)) dct_coeff_signed_level_0 <= {dct_dc_pred[10], dct_dc_pred}; // sign extend dc (first) coefficient of intra block
    else if (clk_en && (state == STATE_NON_CODED_BLOCK) || (state == STATE_EMIT_EMPTY_BLOCK)) dct_coeff_signed_level_0 <= 12'd0; // non-coded block: all zeroes.
    else dct_coeff_signed_level_0 <= dct_coeff_signed_level_0;
 
  always @(posedge clk)
    if (~rst) dct_coeff_apply_signbit_0 <= 1'b0;
    else if (clk_en && ((state == STATE_DCT_DC_DIFF_0) || (state == STATE_DCT_ESCAPE_B15) || (state == STATE_DCT_ESCAPE_B14))) dct_coeff_apply_signbit_0 <= 1'b0;
    else if (clk_en && ((state == STATE_DCT_SUBS_B14) || (state == STATE_DCT_SUBS_B15) || (state == STATE_DCT_NON_INTRA_FIRST))) dct_coeff_apply_signbit_0 <= ~dct_coefficient_escape;
    else if (clk_en && (state == STATE_NON_CODED_BLOCK) || (state == STATE_EMIT_EMPTY_BLOCK)) dct_coeff_apply_signbit_0 <= 1'b0; // non-coded block: all zeroes.
    else dct_coeff_apply_signbit_0 <= dct_coeff_apply_signbit_0;
 
  always @(posedge clk)
    if (~rst) dct_coeff_valid_0 <= 1'b0;
    else if (clk_en && ((state == STATE_DCT_DC_DIFF_0) || (state == STATE_DCT_ESCAPE_B15) || (state == STATE_DCT_ESCAPE_B14) || (state == STATE_NON_CODED_BLOCK) || (state == STATE_EMIT_EMPTY_BLOCK))) dct_coeff_valid_0 <= 1'b1;
    else if (clk_en && ((state == STATE_DCT_SUBS_B14) || (state == STATE_DCT_SUBS_B15) || (state == STATE_DCT_NON_INTRA_FIRST))) dct_coeff_valid_0 <= ~dct_coefficient_escape;
    else if (clk_en) dct_coeff_valid_0 <= 1'b0; 
    else dct_coeff_valid_0 <= dct_coeff_valid_0;
 
  always @(posedge clk)
    if (~rst) dct_coeff_end_0 <= 1'b0;
    else if (clk_en) dct_coeff_end_0 <= ((state == STATE_DCT_SUBS_B14) && (getbits[23:22] == 2'b10)) || ((state == STATE_DCT_SUBS_B15) && (getbits[23:20] == 4'b0110)) || (state == STATE_NON_CODED_BLOCK) || (state == STATE_EMIT_EMPTY_BLOCK);
    else dct_coeff_end_0 <= dct_coeff_end_0;
 
  // Now we clock dct_coeff_run_0 into dct_coeff_run, dct_coeff_signed_level_0 into dct_coeff_signed_level, and apply sign bit, if needed.
  //
  always @(posedge clk)
    if (~rst) dct_coeff_run <= 5'd0;
    else if (clk_en) dct_coeff_run <= dct_coeff_run_0;
    else dct_coeff_run <= dct_coeff_run;
 
  always @(posedge clk)
    if (~rst) dct_coeff_signed_level <= 12'd0;
    else if (clk_en) dct_coeff_signed_level <= (dct_coeff_apply_signbit_0 && signbit) ? 12'd1 + ~dct_coeff_signed_level_0 : dct_coeff_signed_level_0; // 2's complement -> negative
    else dct_coeff_signed_level <= dct_coeff_signed_level;
 
  always @(posedge clk)
    if (~rst) dct_coeff_valid <= 1'b0;
    else if (clk_en) dct_coeff_valid <= dct_coeff_valid_0;
    else dct_coeff_valid <= dct_coeff_valid;
 
  always @(posedge clk)
    if (~rst) dct_coeff_end <= 1'b0;
    else if (clk_en) dct_coeff_end <= dct_coeff_end_0;
    else dct_coeff_end <= dct_coeff_end;
 
  /* coded block pattern */
  always @(posedge clk) // // par. 6.3.17.4
    if (~rst) coded_block_pattern <= 12'b0;
    else if (clk_en && (state == STATE_MOTION_PIPELINE_FLUSH))
      begin
        if (macroblock_intra) // default values
          case (chroma_format)
            CHROMA420: coded_block_pattern <= {12'b111111000000}; 
            CHROMA422: coded_block_pattern <= {12'b111111110000};
            CHROMA444: coded_block_pattern <= {12'b111111111111};
            default    coded_block_pattern <= {12'b000000000000}; // error
          endcase
        else
          coded_block_pattern <= 12'b000000000000;
      end
    else if (clk_en && (state == STATE_CODED_BLOCK_PATTERN)) coded_block_pattern <= {coded_block_pattern_value, 6'b0};
    else if (clk_en && (state == STATE_CODED_BLOCK_PATTERN_1)) coded_block_pattern <= {coded_block_pattern[11:6], getbits[23:22], 4'b0};
    else if (clk_en && (state == STATE_CODED_BLOCK_PATTERN_2)) coded_block_pattern <= {coded_block_pattern[11:6], getbits[23:18]};
    else if (clk_en && (state == STATE_NEXT_BLOCK)) coded_block_pattern <= (coded_block_pattern << 1);
    else if (clk_en && (state == STATE_DCT_ERROR)) coded_block_pattern <= 12'b000000000000; // error occurred; output remaining blocks as non-coded blocks
    else coded_block_pattern <= coded_block_pattern;
 
   /* block loop registers */
   /*
    * block_pattern_code and block_lumi_code are used in the loop which is
    * symbolically coded in par. 6.2.5 as:
    * for ( i = 0; i < block_count; i + + ) {
    *   block( i )
    *   }
    *
    * We set up two registers, block_pattern_code and block_lumi_code.
    * The "one" bits in block_pattern_code correspond to the blocks present
    * in the macroblock.
    * The "one" bits in block_lumi_code correspond to the luminance blocks
    * in the macroblock (the first four blocks).
    * Both block_pattern_code and block_lumi_code are shifted left one bit
    * after each block. Macroblock ends when block_pattern_code is zero.
    */
 
   always @(posedge clk)
     if (~rst) block_pattern_code <= 12'b0;
     else if (clk_en && (state == STATE_MOTION_PIPELINE_FLUSH)) 
       case (chroma_format)  // Table 6-20
         CHROMA420: block_pattern_code <= {12'b111111000000};
	 CHROMA422: block_pattern_code <= {12'b111111110000};
	 CHROMA444: block_pattern_code <= {12'b111111111111};
	 default    block_pattern_code <= {12'b000000000000}; // error
       endcase
     else if (clk_en && (state == STATE_NEXT_BLOCK)) block_pattern_code <= (block_pattern_code << 1);
     else block_pattern_code <= block_pattern_code;
 
   always @(posedge clk)
     if (~rst) block_lumi_code <= 6'b0;
     else if (clk_en && (state == STATE_BLOCK)) block_lumi_code <= 6'b011110;
     else if (clk_en && (state == STATE_NEXT_BLOCK)) block_lumi_code <= (block_lumi_code << 1);
     else block_lumi_code <= block_lumi_code;
 
   always @(posedge clk)
     if (~rst) block_chromi1_code <= 13'b0;
     else if (clk_en && (state == STATE_BLOCK)) block_chromi1_code <= 13'b0000010101010;
     else if (clk_en && (state == STATE_NEXT_BLOCK)) block_chromi1_code <= (block_chromi1_code << 1);
     else block_chromi1_code <= block_chromi1_code;
 
   always @(posedge clk)
     if (~rst) block_chromi2_code <= 13'b0;
     else if (clk_en && (state == STATE_BLOCK)) block_chromi2_code <= 13'b0000001010101;
     else if (clk_en && (state == STATE_NEXT_BLOCK)) block_chromi2_code <= (block_chromi2_code << 1);
     else block_chromi2_code <= block_chromi2_code;
 
`ifdef DEBUG
   always @(posedge clk)
     if (clk_en)
       case (state)
         STATE_NEXT_START_CODE:            #0 $display("%m\tSTATE_NEXT_START_CODE");
         STATE_START_CODE:                 #0 $display("%m\tSTATE_START_CODE");
         STATE_PICTURE_HEADER:             #0 $display("%m\tSTATE_PICTURE_HEADER");
         STATE_PICTURE_HEADER0:            #0 $display("%m\tSTATE_PICTURE_HEADER0");
         STATE_PICTURE_HEADER1:            #0 $display("%m\tSTATE_PICTURE_HEADER1");
         STATE_PICTURE_HEADER2:            #0 $display("%m\tSTATE_PICTURE_HEADER2");
         STATE_SEQUENCE_HEADER:            #0 $display("%m\tSTATE_SEQUENCE_HEADER");
         STATE_SEQUENCE_HEADER0:           #0 $display("%m\tSTATE_SEQUENCE_HEADER0");
         STATE_SEQUENCE_HEADER1:           #0 $display("%m\tSTATE_SEQUENCE_HEADER1");
         STATE_SEQUENCE_HEADER2:           #0 $display("%m\tSTATE_SEQUENCE_HEADER2");
         STATE_SEQUENCE_HEADER3:           #0 $display("%m\tSTATE_SEQUENCE_HEADER3");
         STATE_GROUP_HEADER:               #0 $display("%m\tSTATE_GROUP_HEADER");
         STATE_GROUP_HEADER0:              #0 $display("%m\tSTATE_GROUP_HEADER0");
         STATE_EXTENSION_START_CODE:       #0 $display("%m\tSTATE_EXTENSION_START_CODE");
         STATE_SEQUENCE_EXT:               #0 $display("%m\tSTATE_SEQUENCE_EXT");
         STATE_SEQUENCE_EXT0:              #0 $display("%m\tSTATE_SEQUENCE_EXT0");
         STATE_SEQUENCE_EXT1:              #0 $display("%m\tSTATE_SEQUENCE_EXT1");
         STATE_SEQUENCE_DISPLAY_EXT:       #0 $display("%m\tSTATE_SEQUENCE_DISPLAY_EXT");
         STATE_SEQUENCE_DISPLAY_EXT0:      #0 $display("%m\tSTATE_SEQUENCE_DISPLAY_EXT0");
         STATE_SEQUENCE_DISPLAY_EXT1:      #0 $display("%m\tSTATE_SEQUENCE_DISPLAY_EXT1");
         STATE_SEQUENCE_DISPLAY_EXT2:      #0 $display("%m\tSTATE_SEQUENCE_DISPLAY_EXT2");
         STATE_QUANT_MATRIX_EXT:           #0 $display("%m\tSTATE_QUANT_MATRIX_EXT");
         STATE_PICTURE_CODING_EXT:         #0 $display("%m\tSTATE_PICTURE_CODING_EXT");
         STATE_PICTURE_CODING_EXT0:        #0 $display("%m\tSTATE_PICTURE_CODING_EXT0");
         STATE_PICTURE_CODING_EXT1:        #0 $display("%m\tSTATE_PICTURE_CODING_EXT1");
         STATE_LD_INTRA_QUANT0:            #0 $display("%m\tSTATE_LD_INTRA_QUANT0");
         STATE_LD_INTRA_QUANT1:            #0 $display("%m\tSTATE_LD_INTRA_QUANT1");
         STATE_LD_NON_INTRA_QUANT0:        #0 $display("%m\tSTATE_LD_NON_INTRA_QUANT0");
         STATE_LD_NON_INTRA_QUANT1:        #0 $display("%m\tSTATE_LD_NON_INTRA_QUANT1");
         STATE_LD_CHROMA_INTRA_QUANT1:     #0 $display("%m\tSTATE_LD_CHROMA_INTRA_QUANT1");
         STATE_LD_CHROMA_NON_INTRA_QUANT1: #0 $display("%m\tSTATE_LD_CHROMA_NON_INTRA_QUANT1");
         STATE_SLICE:                      #0 $display("%m\tSTATE_SLICE");
         STATE_SLICE_EXTENSION:            #0 $display("%m\tSTATE_SLICE_EXTENSION");
         STATE_SLICE_EXTRA_INFORMATION:    #0 $display("%m\tSTATE_SLICE_EXTRA_INFORMATION");
         STATE_NEXT_MACROBLOCK:            #0 $display("%m\tSTATE_NEXT_MACROBLOCK");
         STATE_MACROBLOCK_SKIP:            #0 $display("%m\tSTATE_MACROBLOCK_SKIP");
         STATE_DELAY_EMPTY_BLOCK:          #0 $display("%m\tSTATE_DELAY_EMPTY_BLOCK");
         STATE_EMIT_EMPTY_BLOCK:           #0 $display("%m\tSTATE_EMIT_EMPTY_BLOCK");
         STATE_MACROBLOCK_TYPE:            #0 $display("%m\tSTATE_MACROBLOCK_TYPE");
         STATE_MOTION_TYPE:                #0 $display("%m\tSTATE_MOTION_TYPE");
         STATE_DCT_TYPE:                   #0 $display("%m\tSTATE_DCT_TYPE");
         STATE_MACROBLOCK_QUANT:           #0 $display("%m\tSTATE_MACROBLOCK_QUANT");
         STATE_NEXT_MOTION_VECTOR:         #0 $display("%m\tSTATE_NEXT_MOTION_VECTOR");
         STATE_MOTION_VERT_FLD_SEL:        #0 $display("%m\tSTATE_MOTION_VERT_FLD_SEL");
         STATE_MOTION_CODE:                #0 $display("%m\tSTATE_MOTION_CODE");
         STATE_MOTION_RESIDUAL:            #0 $display("%m\tSTATE_MOTION_RESIDUAL");
         STATE_MOTION_DMVECTOR:            #0 $display("%m\tSTATE_MOTION_DMVECTOR");
         STATE_MOTION_PREDICT:             #0 $display("%m\tSTATE_MOTION_PREDICT");
         STATE_MOTION_PIPELINE_FLUSH:      #0 $display("%m\tSTATE_MOTION_PIPELINE_FLUSH");
         STATE_MARKER_BIT_0:               #0 $display("%m\tSTATE_MARKER_BIT_0");
         STATE_CODED_BLOCK_PATTERN:        #0 $display("%m\tSTATE_CODED_BLOCK_PATTERN");
         STATE_CODED_BLOCK_PATTERN_1:      #0 $display("%m\tSTATE_CODED_BLOCK_PATTERN_1");
         STATE_CODED_BLOCK_PATTERN_2:      #0 $display("%m\tSTATE_CODED_BLOCK_PATTERN_2");
         STATE_BLOCK:                      #0 $display("%m\tSTATE_BLOCK");
         STATE_NEXT_BLOCK:                 #0 $display("%m\tSTATE_NEXT_BLOCK");
         STATE_DCT_DC_LUMI_SIZE:           #0 $display("%m\tSTATE_DCT_DC_LUMI_SIZE");
         STATE_DCT_DC_CHROMI_SIZE:         #0 $display("%m\tSTATE_DCT_DC_CHROMI_SIZE");
         STATE_DCT_DC_DIFF:                #0 $display("%m\tSTATE_DCT_DC_DIFF");
         STATE_DCT_DC_DIFF_0:              #0 $display("%m\tSTATE_DCT_DC_DIFF_0");
         STATE_DCT_SUBS_B15:               #0 $display("%m\tSTATE_DCT_SUBS_B15");
         STATE_DCT_ESCAPE_B15:             #0 $display("%m\tSTATE_DCT_ESCAPE_B15");
         STATE_DCT_SUBS_B14:               #0 $display("%m\tSTATE_DCT_SUBS_B14");
         STATE_DCT_ESCAPE_B14:             #0 $display("%m\tSTATE_DCT_ESCAPE_B14");
         STATE_DCT_NON_INTRA_FIRST:        #0 $display("%m\tSTATE_DCT_NON_INTRA_FIRST");
         STATE_NON_CODED_BLOCK:            #0 $display("%m\tSTATE_NON_CODED_BLOCK");
         STATE_DCT_ERROR:                  #0 $display("%m\tSTATE_DCT_ERROR");
         STATE_SEQUENCE_END:               #0 $display("%m\tSTATE_SEQUENCE_END");
         STATE_ERROR:                      #0 $display("%m\tSTATE_ERROR");
	 default                           begin
	                                     #0 $display("%m\tUnknown state");
					     $finish;
	                                   end
       endcase
     else
       begin
         #0 $display("%m\tnot clk_en");
       end
 
   always @(posedge clk)
     if (clk_en)
       case (state)
         STATE_SEQUENCE_HEADER2:
           begin
             $strobe ("%m\tmb_width: %d", mb_width);
             $strobe ("%m\tmb_height: %d", mb_height);
           end
 
         STATE_LD_INTRA_QUANT1,
         STATE_LD_NON_INTRA_QUANT0,
         STATE_LD_NON_INTRA_QUANT1,
         STATE_LD_CHROMA_INTRA_QUANT1,
         STATE_LD_CHROMA_NON_INTRA_QUANT1:
           begin
             $strobe ("%m\tcnt: %d", cnt);
             $strobe ("%m\tquant_wr_data: %d", quant_wr_data);
             $strobe ("%m\tquant_wr_addr: %d", quant_wr_addr);
           end  
         STATE_SLICE:
           begin
             $strobe ("%m\tslice_vertical_position: %d", slice_vertical_position);
             $strobe ("%m\tquantiser_scale_code: %d", quantiser_scale_code);
             $strobe ("%m\tslice_extension_flag: %d", slice_extension_flag);
           end
 
         STATE_SLICE_EXTENSION:
           begin
             $strobe ("%m\tintra_slice: %d", intra_slice);
             $strobe ("%m\tslice_picture_id_enable: %d", slice_picture_id_enable);
             $strobe ("%m\tslice_picture_id: %d", slice_picture_id);
           end
 
         //STATE_SLICE_EXTRA_INFORMATION:
         STATE_NEXT_MACROBLOCK:
           begin
             $strobe ("%m\tmacroblock_addr_inc_value: %d", macroblock_addr_inc_value);
             $strobe ("%m\tmacroblock_address_increment: %d", macroblock_address_increment);
           end
 
         STATE_MACROBLOCK_SKIP:
           begin
             $strobe ("%m\tmacroblock_address: %d", macroblock_address);
             $strobe ("%m\tmacroblock_address_increment: %d", macroblock_address_increment);
             $strobe ("%m\tmotion_type: %d", motion_type);
             $strobe ("%m\tpmv_reset: %d", pmv_reset);
             $strobe ("%m\tdct_dc_pred_0: %d", dct_dc_pred_0);
             $strobe ("%m\tdct_dc_pred_1: %d", dct_dc_pred_1);
             $strobe ("%m\tdct_dc_pred_2: %d", dct_dc_pred_2);
           end
 
         STATE_EMIT_EMPTY_BLOCK:
           begin
             $strobe ("%m\tempty_blocks: %11b", empty_blocks);
	   end
 
         STATE_MACROBLOCK_TYPE:
           begin
             $strobe ("%m\tmacroblock_address: %d", macroblock_address);
             $strobe ("%m\tmacroblock_address_increment: %d", macroblock_address_increment);
             $strobe ("%m\tmacroblock_quant: %d", macroblock_quant);
             $strobe ("%m\tmacroblock_motion_forward: %d", macroblock_motion_forward);
             $strobe ("%m\tmacroblock_motion_backward: %d", macroblock_motion_backward);
             $strobe ("%m\tmacroblock_pattern: %d", macroblock_pattern);
             $strobe ("%m\tmacroblock_intra: %d", macroblock_intra);
             $strobe ("%m\tspatial_temporal_weight_code_flag: %d", spatial_temporal_weight_code_flag);
             $strobe ("%m\tmotion_type: %d", motion_type);
           end
 
         STATE_MOTION_TYPE:
           begin
             $strobe ("%m\tmotion_type: %d", motion_type);
           end
 
         STATE_DCT_TYPE:
           begin
             $strobe ("%m\tdct_type: %d", dct_type);
           end
 
         STATE_MACROBLOCK_QUANT:
           begin
             if (macroblock_quant) $strobe ("%m\tquantiser_scale_code: %d", quantiser_scale_code);
             $strobe ("%m\tmotion_vector_reg: %8b", motion_vector_reg);
           end
 
         STATE_NEXT_MOTION_VECTOR:    
           begin
	     case (motion_vector)
               MOTION_VECTOR_0_0_0: $strobe ("%m\tmotion_vector: MOTION_VECTOR_0_0_0");
               MOTION_VECTOR_0_0_1: $strobe ("%m\tmotion_vector: MOTION_VECTOR_0_0_1");
               MOTION_VECTOR_1_0_0: $strobe ("%m\tmotion_vector: MOTION_VECTOR_1_0_0");
               MOTION_VECTOR_1_0_1: $strobe ("%m\tmotion_vector: MOTION_VECTOR_1_0_1");
               MOTION_VECTOR_0_1_0: $strobe ("%m\tmotion_vector: MOTION_VECTOR_0_1_0");
               MOTION_VECTOR_0_1_1: $strobe ("%m\tmotion_vector: MOTION_VECTOR_0_1_1");
               MOTION_VECTOR_1_1_0: $strobe ("%m\tmotion_vector: MOTION_VECTOR_1_1_0");
               MOTION_VECTOR_1_1_1: $strobe ("%m\tmotion_vector: MOTION_VECTOR_1_1_1");
	     endcase
             $strobe ("%m\tmotion_vector_reg: %8b", motion_vector_reg);
           end
 
         STATE_MOTION_VERT_FLD_SEL:    
           begin
             $strobe ("%m\t\tmotion_vert_field_select_0_0: %d", motion_vert_field_select_0_0);
             $strobe ("%m\t\tmotion_vert_field_select_0_1: %d", motion_vert_field_select_0_1);
             $strobe ("%m\t\tmotion_vert_field_select_1_0: %d", motion_vert_field_select_1_0);
             $strobe ("%m\t\tmotion_vert_field_select_1_1: %d", motion_vert_field_select_1_1);
           end
 
         STATE_MOTION_CODE:
           begin
             $strobe ("%m\tr_size: %d", r_size);
             $strobe ("%m\tmotion_code: %d", motion_code);
             $strobe ("%m\tmotion_code_neg: %d", motion_code_neg);
           end
 
         STATE_MOTION_RESIDUAL:
           begin
             $strobe ("%m\tmotion_code_residual: %d", motion_code_residual);
           end
 
         STATE_MOTION_DMVECTOR:
           begin
             $strobe ("%m\tdmvector: %d", dmvector);
           end
 
         STATE_MOTION_PREDICT:
           begin
             $strobe ("%m\tmotion_vector_reg: %8b", motion_vector_reg);
           end
 
 
         //STATE_MARKER_BIT_0:
         STATE_CODED_BLOCK_PATTERN,
         STATE_CODED_BLOCK_PATTERN_1,
         STATE_CODED_BLOCK_PATTERN_2:
           begin
             $strobe ("%m\tchroma_format:  d%d", chroma_format);
             $strobe ("%m\tcoded_block_pattern:  b%b", coded_block_pattern);
             $strobe ("%m\tblock_pattern_code:   b%b", block_pattern_code);
             $strobe ("%m\tblock_lumi_code:     b%b", block_lumi_code);
             $strobe ("%m\tblock_chromi1_code:  b%b", block_chromi1_code);
             $strobe ("%m\tblock_chromi2_code:  b%b", block_chromi2_code);
           end
 
         STATE_BLOCK:
           begin
             #0 $display ("%m\tblock");
             // helper regs:
             $strobe ("%m\tmacroblock_intra: b%b", macroblock_intra);
             $strobe ("%m\tmacroblock_pattern: b%b", macroblock_pattern);
             $strobe ("%m\tcoded_block_pattern:  b%b", coded_block_pattern);
             // result:
             $strobe ("%m\tblock_pattern_code:   b%b", block_pattern_code);
             $strobe ("%m\tblock_lumi_code:     b%b", block_lumi_code);
             $strobe ("%m\tblock_chromi1_code:  b%b", block_chromi1_code);
             $strobe ("%m\tblock_chromi2_code:  b%b", block_chromi2_code);
           end
 
         STATE_NEXT_BLOCK:
           begin
             $strobe ("%m\tcoded_block_pattern:  b%b", coded_block_pattern);
             $strobe ("%m\tblock_pattern_code:   b%b", block_pattern_code);
             $strobe ("%m\tblock_lumi_code:     b%b", block_lumi_code);
             $strobe ("%m\tblock_chromi1_code:  b%b", block_chromi1_code);
             $strobe ("%m\tblock_chromi2_code:  b%b", block_chromi2_code);
           end
 
         STATE_DCT_DC_LUMI_SIZE:
           begin
             $strobe ("%m\tdct_dc_size_luminance_length: %d", dct_dc_size_luminance_length);
             $strobe ("%m\tdct_dc_size_luminance_value: %d", dct_dc_size_luminance_value);
             $strobe ("%m\tdct_dc_pred: %d (%b)", dct_dc_pred, dct_dc_pred);
           end
 
         STATE_DCT_DC_CHROMI_SIZE:
           begin
             $strobe ("%m\tdct_dc_size_chrominance_length: %d", dct_dc_size_chrominance_length);
             $strobe ("%m\tdct_dc_size_chrominance_value: %d", dct_dc_size_chrominance_value);
             $strobe ("%m\tdct_dc_pred: %d (%b)", dct_dc_pred, dct_dc_pred);
           end
 
         STATE_DCT_DC_DIFF:
           begin
             $strobe ("%m\tdct_dc_size: %d", dct_dc_size);
             $strobe ("%m\tdct_dc_pred: %d (%b)", dct_dc_pred, dct_dc_pred);
           end
 
         STATE_DCT_DC_DIFF_0:
           begin
             if (block_lumi_code[12])
               begin
                 $strobe ("%m\tdct_dc_pred_0: %d (%b) (Y)", dct_dc_pred_0, dct_dc_pred_0);
               end
             else if (block_chromi1_code[12])
               begin
                 $strobe ("%m\tdct_dc_pred_1: %d (%b) (Cb)", dct_dc_pred_1, dct_dc_pred_1);
               end
             else if (block_chromi2_code[12])
               begin
                 $strobe ("%m\tdct_dc_pred_2: %d (%b) (Cr)", dct_dc_pred_2, dct_dc_pred_2);
               end
           end
 
         STATE_DCT_SUBS_B15,
         STATE_DCT_SUBS_B14,
         STATE_DCT_NON_INTRA_FIRST,
         STATE_DCT_ESCAPE_B15,
         STATE_DCT_ESCAPE_B14:
           begin
             $strobe ("%m\tdct_coeff_run_0: %d", dct_coeff_run_0);
             $strobe ("%m\tdct_coeff_signed_level_0: %0d (%12b)", dct_coeff_signed_level_0, dct_coeff_signed_level_0);
             $strobe ("%m\tsignbit: %d", signbit);
             $strobe ("%m\tdct_coeff_apply_signbit_0: %d", dct_coeff_apply_signbit_0);
             $strobe ("%m\tdct_coeff_valid_0: %d", dct_coeff_valid_0);
             $strobe ("%m\tdct_coeff_end_0: %d", dct_coeff_end_0);
 
             $strobe ("%m\tdct_coeff_run: %d", dct_coeff_run);
             $strobe ("%m\tdct_coeff_signed_level: %0d (%12b)", dct_coeff_signed_level, dct_coeff_signed_level);
             $strobe ("%m\tdct_coeff_valid: %d", dct_coeff_valid);
             $strobe ("%m\tdct_coeff_end: %d", dct_coeff_end);
           end
 
         STATE_ERROR:
           begin
             $strobe ("%m\tError");
           end
 
       endcase
 
   /* motion vector pipeline status */
   always @(posedge clk)
     if (clk_en && (state == STATE_MOTION_PREDICT))
           begin
             $strobe ("%m\tr_size: %d", r_size);
             $strobe ("%m\tmotion_code: %d", motion_code);
             $strobe ("%m\tmotion_code_residual: %d", motion_code_residual);
             $strobe ("%m\t\tmotion_vector_valid_0: %d", motion_vector_valid_0);
             $strobe ("%m\t\tmotion_vector_0: %d", motion_vector_0);
             $strobe ("%m\t\tpmv_delta_0: %d", pmv_delta_0);
             $strobe ("%m\t\tpmv_0: %d", pmv_0);
             $strobe ("%m\t\tmotion_code_neg_0: %d", motion_code_neg_0);
             $strobe ("%m\t\tr_size_0: %d", r_size_0);
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_0)
           begin
             $strobe ("%m\t\tmotion_vector_valid_1: %d", motion_vector_valid_1);
             $strobe ("%m\t\tmotion_vector_1: %d", motion_vector_1);
             $strobe ("%m\t\tpmv_1: %d", pmv_1);
             $strobe ("%m\t\tr_size_1: %d", r_size_1);
             $strobe ("%m\t\tshift_pmv: %d", shift_pmv);
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_1)
           begin
             $strobe ("%m\t\tmotion_vector_valid_2: %d", motion_vector_valid_2);
             $strobe ("%m\t\tmotion_vector_2: %d", motion_vector_2);
             $strobe ("%m\t\tpmv_2: %d", pmv_2);
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_2)
           begin
             $strobe ("%m\t\tmotion_vector_valid_3: %d", motion_vector_valid_3);
             $strobe ("%m\t\tmotion_vector_3: %d", motion_vector_3);
             $strobe ("%m\t\tpmv_3: %d", pmv_3);
             if (dmv)
               begin
                 $strobe ("%m\t\tdmvector_aux_a_3: %d", dmvector_aux_a_3);
                 $strobe ("%m\t\tdmvector_aux_b_3: %d", dmvector_aux_b_3);
               end
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_3)
           begin
             $strobe ("%m\t\tmotion_vector_valid_4: %d", motion_vector_valid_4);
             $strobe ("%m\t\tmotion_vector_4: %d", motion_vector_4);
             $strobe ("%m\t\tpmv_4: %d", pmv_4);
             if (dmv)
               begin
                 $strobe ("%m\t\tdmvector_aux_a_4: %d", dmvector_aux_a_4);
                 $strobe ("%m\t\tdmvector_aux_b_4: %d", dmvector_aux_b_4);
                 $strobe ("%m\t\te_parity_ref_parity_pred_4: %d", e_parity_ref_parity_pred_4);
               end
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_4)
           begin
             $strobe ("%m\t\tmotion_vector_valid_5: %d", motion_vector_valid_5);
             $strobe ("%m\t\tmotion_vector_5: %d", motion_vector_5);
             $strobe ("%m\t\tpmv_5: %d", pmv_5);
             if (dmv)
               begin
                 $strobe ("%m\t\tdmvector_aux_a_5: %d", dmvector_aux_a_5);
                 $strobe ("%m\t\tdmvector_aux_b_5: %d", dmvector_aux_b_5);
               end
	   end 
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_5)
       case (motion_vector_5)
         MOTION_VECTOR_0_0_1: $strobe("%m\t\tpmv: %0d,%0d", pmv_0_0_0, pmv_0_0_1);
         MOTION_VECTOR_0_1_1: $strobe("%m\t\tpmv: %0d,%0d", pmv_0_1_0, pmv_0_1_1);
         MOTION_VECTOR_1_0_1: $strobe("%m\t\tpmv: %0d,%0d", pmv_1_0_0, pmv_1_0_1);
         MOTION_VECTOR_1_1_1: $strobe("%m\t\tpmv: %0d,%0d", pmv_1_1_0, pmv_1_1_1);
       endcase
 
   always @(posedge clk)
     if (clk_en && motion_vector_valid_5 && dmv && (motion_vector_5 == MOTION_VECTOR_0_0_1))
       begin
         $strobe ("%m\t\tdmv_0_0: %d", dmv_0_0);
         $strobe ("%m\t\tdmv_0_1: %d", dmv_0_1);
         $strobe ("%m\t\tdmv_1_0: %d", dmv_1_0);
         $strobe ("%m\t\tdmv_1_1: %d", dmv_1_1);
       end
 
   always @(posedge clk)
     if (clk_en && pmv_reset)
       begin
         #0 $display ("%m\t\tresetting motion vectors. pmv_x_x_x <= 0");
       end
 
   always @(posedge clk)
     if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_0) && pmv_update0)
       begin
         #0 $display ("%m\t\tupdating motion vectors. pmv_1_0_0 <= pmv_0_0_0");
       end
 
   always @(posedge clk)
     if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_0_1) && pmv_update0)
       begin
         #0 $display ("%m\t\tupdating motion vectors. pmv_1_0_1 <= pmv_0_0_1");
       end
 
   always @(posedge clk)
     if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_0) && pmv_update1)
       begin
         #0 $display ("%m\t\tupdating motion vectors. pmv_1_1_0 <= pmv_0_1_0");
       end
 
   always @(posedge clk)
     if (clk_en && (motion_vector_valid_5) && (motion_vector_5 == MOTION_VECTOR_0_1_1) && pmv_update1)
       begin
         #0 $display ("%m\t\tupdating motion vectors. pmv_1_1_1 <= pmv_0_1_1");
       end
 
   always @(posedge clk)
     if (clk_en && ((state == STATE_MOTION_PREDICT) || pmv_reset || motion_vector_valid_5))
       begin
         $strobe ("%m\t\tpmv_0_0_0: %d", pmv_0_0_0);
         $strobe ("%m\t\tpmv_0_0_1: %d", pmv_0_0_1);
         $strobe ("%m\t\tpmv_1_0_0: %d", pmv_1_0_0);
         $strobe ("%m\t\tpmv_1_0_1: %d", pmv_1_0_1);
         $strobe ("%m\t\tpmv_0_1_0: %d", pmv_0_1_0);
         $strobe ("%m\t\tpmv_0_1_1: %d", pmv_0_1_1);
         $strobe ("%m\t\tpmv_1_1_0: %d", pmv_1_1_0);
         $strobe ("%m\t\tpmv_1_1_1: %d", pmv_1_1_1);
         $strobe ("%m\t\tmotion_vert_field_select_0_0: %d", motion_vert_field_select_0_0);
         $strobe ("%m\t\tmotion_vert_field_select_0_1: %d", motion_vert_field_select_0_1);
         $strobe ("%m\t\tmotion_vert_field_select_1_0: %d", motion_vert_field_select_1_0);
         $strobe ("%m\t\tmotion_vert_field_select_1_1: %d", motion_vert_field_select_1_1);
       end
 
   /* fifo status */
   always @(posedge clk)
     if (clk_en)
       begin
         #0 $display("%m\tgetbits: %h (%b)", getbits, getbits);
       end
 
   always @(posedge clk)
     if (clk_en)
       begin
         $strobe("%m\talign: %d advance %d", align, advance);
       end
`endif
 
endmodule
 
/*
   Extracts a register from the bitstream.
   when reset* is asserted, clear register 'fsm_reg'
   else, when in state 'fsm_state',
   clock 'width' bits at offset 'offset' in the video stream into the register 'fsm_reg'.
 
 */
 
module loadreg #(parameter offset=0, width=8, fsm_state = 8'hff) (
   input                  clk,
   input                  clk_en,
   input                  rst,
   input             [7:0]state,
   input            [23:0]getbits,
   output reg  [width-1:0]fsm_reg
   );
  always @(posedge clk)
    begin
      if (~rst) fsm_reg <= {32{1'b0}}; // gets truncated
      else if (clk_en && (state == fsm_state))
        begin
          fsm_reg <= getbits[23-offset:23-offset-width+1];
          `ifdef DEBUG
            $strobe ("%m\t%0d'd%0d (%0d'h%0h, %0d'b%0b)", width, fsm_reg, width, fsm_reg, width, fsm_reg);
          `endif
        end
      else fsm_reg <= fsm_reg;
    end
endmodule
 
/* not truncated */
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.