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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [pipeline/] [decode_ready.v] - Rev 2

Compare with Previous | Blame | View Log

/*
 * Copyright (c) 2014, Aleksander Osman
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
 */
 
module decode_ready(
 
    input               enable,
    input               is_prefix,
    input       [3:0]   decoder_count,
 
    input       [95:0]  decoder,
 
    input               dec_operand_32bit,
    input               dec_address_32bit,
 
    input               dec_prefix_2byte,
    input       [2:0]   dec_modregrm_len,
 
 
    output              dec_ready_one,
    output              dec_ready_one_one,
    output              dec_ready_one_two,
    output              dec_ready_one_three,
    output              dec_ready_2byte_one,
    output              dec_ready_modregrm_one,
    output              dec_ready_2byte_modregrm,
    output              dec_ready_call_jmp_imm,
    output              dec_ready_one_imm,
    output              dec_ready_2byte_imm,
    output              dec_ready_mem_offset,
    output              dec_ready_modregrm_imm,
    output              dec_ready_2byte_modregrm_imm,
 
    input               consume_one,
    input               consume_one_one,
    input               consume_one_two,
    input               consume_one_three,
    input               consume_call_jmp_imm,
    input               consume_modregrm_one,
    input               consume_one_imm,
    input               consume_modregrm_imm,
    input               consume_mem_offset,
 
    output      [3:0]   consume_count_local,
    output              dec_is_modregrm
);
 
//------------------------------------------------------------------------------
 
wire [2:0] call_jmp_imm_len;
wire [2:0] one_imm_len;
wire [2:0] mem_offset_len;
 
wire [2:0] modregrm_imm_only_len;
wire [3:0] modregrm_imm_len;
 
//------------------------------------------------------------------------------
 
assign dec_is_modregrm = consume_modregrm_one || consume_modregrm_imm;
 
//------------------------------------------------------------------------------
 
/* 
 * CALL imm:
 * (@decoder[7:0] == 8'h9A || @decoder[7:0] == 8'hE8)
 *      decoder[7:0] == 8'h9A && operand_32bit  --> 7
 *      decoder[7:0] == 8'h9A                   --> 5
 *      operand_32bit                           --> 5
 *                                              --> 3
 * 
 * JMP imm:
 * (@decoder[7:0] == 8'hEA || @decoder[7:0] == 8'hE9 || @decoder[7:0] == 8'hEB)
 *      decoder[7:0] == 8'hEB                   --> 2
 *      decoder[7:0] == 8'hEA && operand_32bit  --> 7
 *      decoder[7:0] == 8'hEA                   --> 5
 *      operand_32bit                           --> 5
 *                                              --> 3 
 */
assign call_jmp_imm_len =
    // 8'hEB
    (decoder[1:0] == 2'b11)?                      3'd2 :
    // (8'h9A or 8'hEA) and 32bit
    (decoder[1] == 1'b1 && dec_operand_32bit)?    3'd7 :
    // (8'hE8 or 8'hE9) and 16bit
    (decoder[1] == 1'b0 && ~(dec_operand_32bit))? 3'd3 :
    // else
                                                  3'd5;
 
/* Arithmetic:
 * @decoder[7:6] == 2'b00 && @decoder[2:1] == 2'b10
 *      decoder[0] == 1'b0                      --> 2
 *      operand_32bit                           --> 5
 *                                              --> 3
 * 
 * PUSH imm:
 * (@decoder[7:0] == 8'h6A || @decoder[7:0] == 8'h68)
 *      decoder[7:0] == 8'h6A                   --> 2
 *      operand_32bit                           --> 5
 *                                              --> 3
 * 
 * TEST imm:
 * { @decoder[7:1], 1'b0 } == 8'hA8
 *      decoder[0] == 1'b0                      --> 2
 *      operand_32bit                           --> 5
 *                                              --> 3
 * MOV imm:
 * @decoder[7:4] == 4'hB
 *      decoder[7:3] != 8'hB8                   --> 2
 *      operand_32bit                           --> 5
 *                                              --> 3
 * Jcc:
 * @decoder_ready_2byte_imm && @decoder[7:4] == 4'h8
 *      operand_32bit                           --> 5
 *                                              --> 3
 */
assign one_imm_len =
    (~(dec_prefix_2byte) && ({ decoder[7:3], 3'b0 } == 8'hB0 || decoder[7:0] == 8'hA8 || decoder[7:0] == 8'h6A ||
                             { decoder[7:6], decoder[0] } == 3'b000 ))?     3'd2 :
    (dec_operand_32bit)?                                                    3'd5 :
                                                                            3'd3;
 
assign mem_offset_len = (dec_address_32bit)? 3'd5 : 3'd3;
 
/* Arithmetic:
 * (@decoder[7:0] == 8'h80 || @decoder[7:0] == 8'h81 || @decoder[7:0] == 8'h83)
 *      decoder[7:0] == 8'h80 || decoder[7:0] == 8'h83              --> 1
 *      operand_32bit                                               --> 4
 *                                                                  --> 2
 * 
 * IMUL:
 * (@decoder[7:0] == 8'h69 || @decoder[7:0] == 8'h6B)
 *      decoder[7:0] == 8'h6B                                       --> 1
 *      operand_32bit                                               --> 4
 *                                                                  --> 2
 * 
 * TEST:
 *  { @decoder[7:1], 1'b0 } == 8'hF6 && { @decoder[13:12], 1'b0 } == 3'd0
 *      decoder[7:0] == 8'hF6                                       --> 1
 *      operand_32bit                                               --> 4
 *                                                                  --> 2
 * 
 * MOV:
 *  { @decoder[7:1], 1'b0 } == 8'hC6 && @decoder[13:11] == 3'd0
 *      decoder[7:0] == 8'hC6                                       --> 1
 *      operand_32bit                                               --> 4
 *                                                                  --> 2
 * 
 * Shift:
 *  { @decoder[7:1], 1'b0 } == 8'hC0                                --> 1
 *                                                                  
 * 
 * prefix_2byte                                                     --> 1
 */
assign modregrm_imm_only_len =
    (dec_prefix_2byte || { decoder[7:1], 1'b0 } == 8'hC0 || decoder[1:0] == 2'b00 || decoder[1:0] == 2'b10 || decoder[2:0] == 3'b011)?
                                                                            3'd1 :
    (dec_operand_32bit)?                                                    3'd4 :
                                                                            3'd2;
 
 
assign modregrm_imm_len = { 1'b0, dec_modregrm_len } + { 1'b0,  modregrm_imm_only_len };
 
 
//------------------------------------------------------------------------------
 
assign consume_count_local =
    (consume_one)?              4'd1 :
    (consume_one_one)?          4'd2 :
    (consume_one_two)?          4'd3 :
    (consume_one_three)?        4'd4 :
    (consume_call_jmp_imm)?     { 1'b0, call_jmp_imm_len } :
    (consume_modregrm_one)?     { 1'b0, dec_modregrm_len } :
    (consume_one_imm)?          { 1'b0, one_imm_len } :
    (consume_modregrm_imm)?     modregrm_imm_len :
    (consume_mem_offset)?       { 1'b0, mem_offset_len } :
                                4'd0;
 
//------------------------------------------------------------------------------
 
assign dec_ready_one                = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= 4'd1;
 
assign dec_ready_one_one            = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= 4'd2;
 
assign dec_ready_one_two            = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= 4'd3;
 
assign dec_ready_one_three          = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= 4'd4;
 
assign dec_ready_2byte_one          = enable && dec_prefix_2byte && decoder_count >= 4'd1;
 
assign dec_ready_modregrm_one       = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= { 1'b0, dec_modregrm_len };
 
assign dec_ready_2byte_modregrm     = enable && dec_prefix_2byte && decoder_count >= { 1'b0, dec_modregrm_len };
 
assign dec_ready_call_jmp_imm       = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= { 1'b0, call_jmp_imm_len };
 
assign dec_ready_one_imm            = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= { 1'b0, one_imm_len };
 
assign dec_ready_2byte_imm          = enable && dec_prefix_2byte && decoder_count >= { 1'b0, one_imm_len };
 
assign dec_ready_mem_offset         = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= { 1'b0, mem_offset_len };
 
assign dec_ready_modregrm_imm       = enable && ~(is_prefix) && ~(dec_prefix_2byte) && decoder_count >= modregrm_imm_len;
 
assign dec_ready_2byte_modregrm_imm = enable && dec_prefix_2byte && decoder_count >= modregrm_imm_len;
 
//------------------------------------------------------------------------------
 
//------------------------------------------------------------------------------
 
// synthesis translate_off
wire _unused_ok = &{ 1'b0, decoder[95:8], 1'b0 };
// synthesis translate_on
 
//------------------------------------------------------------------------------
 
endmodule
 

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.