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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [pipeline/] [decode.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.
 */
 
`include "defines.v"
 
module decode(
    input               clk,
    input               rst_n,
 
    input               dec_reset,
 
    //global input
    input       [63:0]  cs_cache,
 
    input               protected_mode,
 
    //eip
    input               pr_reset,
    input       [31:0]  prefetch_eip,
    output reg  [31:0]  eip,
 
    //fetch interface
    input       [3:0]   fetch_valid,
    input       [63:0]  fetch,
    input               fetch_limit,
    input               fetch_page_fault,
 
    output      [3:0]   dec_acceptable,
 
    //exceptions
    output reg          dec_gp_fault,
    output reg          dec_ud_fault,
    output reg          dec_pf_fault,
 
    //pipeline
    input               micro_busy,
    output              dec_ready,
 
    output      [95:0]  decoder,
    output      [31:0]  dec_eip,
    output              dec_operand_32bit,
    output              dec_address_32bit,
    output      [1:0]   dec_prefix_group_1_rep,
    output              dec_prefix_group_1_lock,
    output      [2:0]   dec_prefix_group_2_seg,
    output              dec_prefix_2byte,
    output      [3:0]   dec_consumed,
    output      [2:0]   dec_modregrm_len,  
    output              dec_is_8bit,
    output      [6:0]   dec_cmd,
    output      [3:0]   dec_cmdex,
    output              dec_is_complex
);
 
//------------------------------------------------------------------------------
 
wire        enable;
wire        instr_prefix;
wire        instr_finished;
wire        stop;
 
wire [3:0]  consume_count;
 
wire        gp_fault;
wire        pf_fault;
 
wire        is_prefix;
wire [3:0]  decoder_count;
 
wire consume_one;
wire consume_one_one;
wire consume_one_two;
wire consume_one_three;
wire consume_call_jmp_imm;
wire consume_modregrm_one;
wire consume_one_imm;
wire consume_modregrm_imm;
wire consume_mem_offset;
 
//------------------------------------------------------------------------------
 
reg gp_fault_last;
reg pf_fault_last;
 
//------------------------------------------------------------------------------
 
wire        dec_ready_one;
wire        dec_ready_one_one;
wire        dec_ready_one_two;
wire        dec_ready_one_three;
wire        dec_ready_2byte_one;
wire        dec_ready_modregrm_one;
wire        dec_ready_2byte_modregrm;
wire        dec_ready_call_jmp_imm;
wire        dec_ready_one_imm;
wire        dec_ready_2byte_imm;
wire        dec_ready_mem_offset;
wire        dec_ready_modregrm_imm;
wire        dec_ready_2byte_modregrm_imm;
 
wire [3:0]  consume_count_local;
 
wire        dec_is_modregrm;
 
decode_ready decode_ready_inst(
 
    .enable                         (enable),                       //input
    .is_prefix                      (is_prefix),                    //input
    .decoder_count                  (decoder_count),                //input [3:0]
 
    .decoder                        (decoder),                      //input [95:0]
 
    .dec_operand_32bit              (dec_operand_32bit),            //input
    .dec_address_32bit              (dec_address_32bit),            //input
 
    .dec_prefix_2byte               (dec_prefix_2byte),             //input
    .dec_modregrm_len               (dec_modregrm_len),             //input [2:0]
 
 
    .dec_ready_one                  (dec_ready_one),                //output
    .dec_ready_one_one              (dec_ready_one_one),            //output
    .dec_ready_one_two              (dec_ready_one_two),            //output
    .dec_ready_one_three            (dec_ready_one_three),          //output
    .dec_ready_2byte_one            (dec_ready_2byte_one),          //output
    .dec_ready_modregrm_one         (dec_ready_modregrm_one),       //output
    .dec_ready_2byte_modregrm       (dec_ready_2byte_modregrm),     //output
    .dec_ready_call_jmp_imm         (dec_ready_call_jmp_imm),       //output
    .dec_ready_one_imm              (dec_ready_one_imm),            //output
    .dec_ready_2byte_imm            (dec_ready_2byte_imm),          //output
    .dec_ready_mem_offset           (dec_ready_mem_offset),         //output
    .dec_ready_modregrm_imm         (dec_ready_modregrm_imm),       //output
    .dec_ready_2byte_modregrm_imm   (dec_ready_2byte_modregrm_imm), //output
 
    .consume_one                    (consume_one),                  //input
    .consume_one_one                (consume_one_one),              //input
    .consume_one_two                (consume_one_two),              //input
    .consume_one_three              (consume_one_three),            //input
    .consume_call_jmp_imm           (consume_call_jmp_imm),         //input
    .consume_modregrm_one           (consume_modregrm_one),         //input
    .consume_one_imm                (consume_one_imm),              //input
    .consume_modregrm_imm           (consume_modregrm_imm),         //input
    .consume_mem_offset             (consume_mem_offset),           //input
 
    .consume_count_local            (consume_count_local),          //output [3:0]
    .dec_is_modregrm                (dec_is_modregrm)               //output
);
 
//------------------------------------------------------------------------------
 
wire [3:0]  prefix_count;
wire        prefix_group_1_lock;
 
decode_prefix decode_prefix_inst(
    .clk                        (clk),
    .rst_n                      (rst_n),
 
    .cs_cache                   (cs_cache),                 //input [63:0]
    .dec_is_modregrm            (dec_is_modregrm),          //input
    .decoder                    (decoder),                  //input [95:0]
 
    .instr_prefix               (instr_prefix),             //input
    .instr_finished             (instr_finished),           //input
 
    .dec_operand_32bit          (dec_operand_32bit),        //output
    .dec_address_32bit          (dec_address_32bit),        //output
 
    .dec_prefix_group_1_rep     (dec_prefix_group_1_rep),   //output [1:0]
    .dec_prefix_group_1_lock    (dec_prefix_group_1_lock),  //output
    .dec_prefix_group_2_seg     (dec_prefix_group_2_seg),   //output [2:0],
 
    .dec_prefix_2byte           (dec_prefix_2byte),         //output
    .dec_modregrm_len           (dec_modregrm_len),         //output [2:0]
 
    .prefix_count               (prefix_count),             // output [3:0]
    .is_prefix                  (is_prefix),                // output
    .prefix_group_1_lock        (prefix_group_1_lock)       // output
);
 
//------------------------------------------------------------------------------
 
decode_regs decode_regs_inst(
    .clk                (clk),
    .rst_n              (rst_n),
 
    .dec_reset          (dec_reset),        //input
 
    .fetch_valid        (fetch_valid),      //input [3:0]
    .fetch              (fetch),            //input [63:0]
 
    .prefix_count       (prefix_count),     //input [3:0]
    .consume_count      (consume_count),    //input [3:0]
 
    .dec_acceptable     (dec_acceptable),   //output [3:0]
 
    .decoder            (decoder),          //output [95:0]
    .decoder_count      (decoder_count)     //output [3:0]
);
 
//------------------------------------------------------------------------------
 
wire dec_exception_ud;
 
decode_commands decode_commands_inst(
    .protected_mode                 (protected_mode),               //input
 
    .dec_ready_one                  (dec_ready_one),                //input
    .dec_ready_one_one              (dec_ready_one_one),            //input
    .dec_ready_one_two              (dec_ready_one_two),            //input
    .dec_ready_one_three            (dec_ready_one_three),          //input
    .dec_ready_2byte_one            (dec_ready_2byte_one),          //input
    .dec_ready_modregrm_one         (dec_ready_modregrm_one),       //input
    .dec_ready_2byte_modregrm       (dec_ready_2byte_modregrm),     //input
    .dec_ready_call_jmp_imm         (dec_ready_call_jmp_imm),       //input
    .dec_ready_one_imm              (dec_ready_one_imm),            //input
    .dec_ready_2byte_imm            (dec_ready_2byte_imm),          //input
    .dec_ready_mem_offset           (dec_ready_mem_offset),         //input
    .dec_ready_modregrm_imm         (dec_ready_modregrm_imm),       //input
    .dec_ready_2byte_modregrm_imm   (dec_ready_2byte_modregrm_imm), //input
 
    .decoder                        (decoder),                      //input [95:0]
    .prefix_group_1_lock            (prefix_group_1_lock),          //input
    .dec_prefix_group_1_rep         (dec_prefix_group_1_rep),       //input [1:0]
    .dec_prefix_2byte               (dec_prefix_2byte),             //input
 
    .consume_one                    (consume_one),                  //output
    .consume_one_one                (consume_one_one),              //output
    .consume_one_two                (consume_one_two),              //output
    .consume_one_three              (consume_one_three),            //output
    .consume_call_jmp_imm           (consume_call_jmp_imm),         //output
    .consume_modregrm_one           (consume_modregrm_one),         //output
    .consume_one_imm                (consume_one_imm),              //output
    .consume_modregrm_imm           (consume_modregrm_imm),         //output
    .consume_mem_offset             (consume_mem_offset),           //output
 
    .dec_exception_ud               (dec_exception_ud),             //output
 
    .dec_is_8bit                    (dec_is_8bit),                  //output
    .dec_cmd                        (dec_cmd),                      //output [6:0]
    .dec_cmdex                      (dec_cmdex),                    //output [3:0]
    .dec_is_complex                 (dec_is_complex)                //output
);
 
 
//------------------------------------------------------------------------------
 
//------------------------------------------------------------------------------
 
//------------------------------------------------------------------------------
 
//input: micro_busy, dec_reset
 
assign enable           = ~(stop);
 
assign instr_prefix     = enable && ~(dec_prefix_2byte) && is_prefix && decoder_count > 4'd0; 
 
assign dec_ready        = ~(dec_reset) && enable && ~(instr_prefix) && consume_count_local > 4'd0 && ~(micro_busy);
 
assign instr_finished   = dec_ready || dec_reset;
 
assign stop             = dec_ud_fault || dec_gp_fault || dec_pf_fault;
 
assign consume_count =
    (instr_prefix)?     4'd1 :
    (dec_reset)?        4'd0 :
    (micro_busy)?       4'd0 :
                        consume_count_local;
 
assign dec_consumed = (dec_ready)? consume_count_local + prefix_count : 4'd0;
 
 
//------------------------------------------------------------------------------
 
 
//-------------------------- GP
 
assign gp_fault = enable && ~(instr_prefix) && consume_count_local == 4'd0 && (
    ( fetch_valid == 4'd0 && fetch_limit ) ||   // external limit reached
    ( dec_acceptable == 4'd0 )                  // instruction length limit reached
);
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)   gp_fault_last <= 1'b0;
    else                gp_fault_last <= gp_fault;
end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)                   dec_gp_fault <= `FALSE;
    else if(dec_reset)                  dec_gp_fault <= `FALSE;
    else if(gp_fault && gp_fault_last)  dec_gp_fault <= `TRUE;
end
 
//-------------------------- UD
 
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)           dec_ud_fault <= `FALSE;
    else if(dec_reset)          dec_ud_fault <= `FALSE;
    else if(dec_exception_ud)   dec_ud_fault <= `TRUE;
end
 
//-------------------------- PF
 
assign pf_fault = enable && ~(instr_prefix) && consume_count_local == 4'd0 && (
    ( fetch_valid == 4'd0 && fetch_page_fault )
);
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)   pf_fault_last <= 1'b0;
    else                pf_fault_last <= pf_fault;
end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)                   dec_pf_fault <= `FALSE;
    else if(dec_reset)                  dec_pf_fault <= `FALSE;
    else if(pf_fault && pf_fault_last)  dec_pf_fault <= `TRUE;
end
 
//------------------------------------------------------------------------------ eip
 
assign dec_eip = eip + { 28'd0, dec_consumed };
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)                           eip <= `STARTUP_EIP;
    else if(pr_reset)                           eip <= prefetch_eip;
    else if(dec_ready)                          eip <= dec_eip;
end
 
//------------------------------------------------------------------------------
 
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.