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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [pipeline/] [microcode.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 microcode(
    input               clk,
    input               rst_n,
 
    input               micro_reset,
 
    input               exc_init,
    input               exc_load,
    input       [31:0]  exc_eip,
 
    input       [31:0]  task_eip,
 
    //command control
    input               real_mode,
    input               v8086_mode,
    input               protected_mode,
 
    input               io_allow_check_needed,
    input               exc_push_error,
    input               cr0_pg,
    input               oflag,
    input               ntflag,
    input       [1:0]   cpl,
 
    input       [31:0]  glob_param_1,
    input       [31:0]  glob_param_3,
    input       [63:0]  glob_descriptor,
 
    //decoder
    output              micro_busy,
    input               dec_ready,
 
    input       [95:0]  decoder,
    input       [31:0]  dec_eip,
    input               dec_operand_32bit,
    input               dec_address_32bit,
    input       [1:0]   dec_prefix_group_1_rep,
    input               dec_prefix_group_1_lock,
    input       [2:0]   dec_prefix_group_2_seg,
    input               dec_prefix_2byte,
    input       [3:0]   dec_consumed,
    input       [2:0]   dec_modregrm_len,  
    input               dec_is_8bit,
    input       [6:0]   dec_cmd,
    input       [3:0]   dec_cmdex,
 
    input               dec_is_complex,
 
    //micro
    input               rd_busy,
    output              micro_ready,
 
    output      [87:0]  micro_decoder,
    output      [31:0]  micro_eip,
    output              micro_operand_32bit,
    output              micro_address_32bit,
    output      [1:0]   micro_prefix_group_1_rep,
    output              micro_prefix_group_1_lock,
    output      [2:0]   micro_prefix_group_2_seg,
    output              micro_prefix_2byte,
    output      [3:0]   micro_consumed,
    output      [2:0]   micro_modregrm_len,
    output              micro_is_8bit,
    output      [6:0]   micro_cmd,
    output      [3:0]   micro_cmdex
);
 
//------------------------------------------------------------------------------
 
wire task_start;
 
wire m_overlay;
wire m_load;
 
//------------------------------------------------------------------------------
 
reg         mc_operand_32bit;
reg         mc_address_32bit;
reg [1:0]   mc_prefix_group_1_rep;
reg         mc_prefix_group_1_lock;
reg [2:0]   mc_prefix_group_2_seg;
reg         mc_prefix_2byte;
reg [87:0]  mc_decoder;
reg [2:0]   mc_modregrm_len;
reg         mc_is_8bit;
 
reg [6:0]   mc_cmd;
reg [3:0]   mc_cmdex;
reg [3:0]   mc_consumed;
reg [31:0]  mc_eip;
 
reg [5:0]   mc_step;
reg [3:0]   mc_cmdex_last;
//------------------------------------------------------------------------------
 
assign micro_busy  = rd_busy || m_overlay;
 
assign micro_ready = ~(micro_reset) && ((~(m_overlay) && dec_ready) || (m_overlay && ~(rd_busy)));
 
assign m_load      = dec_ready && dec_is_complex;
 
assign m_overlay   = mc_cmd != `CMD_NULL;
 
assign task_start  = micro_cmd == `CMD_task_switch_4 && micro_cmdex == `CMDEX_task_switch_4_STEP_1 && micro_ready;
 
//------------------------------------------------------------------------------
 
wire [6:0]  mc_cmd_next;
wire [6:0]  mc_cmd_current;
 
wire [3:0]  mc_cmdex_current;
 
microcode_commands microcode_commands_inst(
    .clk                    (clk),
    .rst_n                  (rst_n),
 
    .protected_mode         (protected_mode),    //input
    .real_mode              (real_mode),         //input
    .v8086_mode             (v8086_mode),        //input
 
    .io_allow_check_needed  (io_allow_check_needed), //input
    .exc_push_error         (exc_push_error),        //input
    .cr0_pg                 (cr0_pg),                //input
    .oflag                  (oflag),                 //input
    .ntflag                 (ntflag),                //input
    .cpl                    (cpl),    //input [1:0]
 
    .glob_param_1           (glob_param_1),    //input [31:0]
    .glob_param_3           (glob_param_3),    //input [31:0]
    .glob_descriptor        (glob_descriptor), //input [63:0]
 
    .mc_operand_32bit       (mc_operand_32bit),   //input
 
    .mc_cmd                 (mc_cmd),     //input [6:0]
    .mc_decoder             (mc_decoder), //input [87:0]
 
    .mc_step                (mc_step),    //input [5:0]
    .mc_cmdex_last          (mc_cmdex_last),  //input [3:0]
 
 
    .mc_cmd_next            (mc_cmd_next),        //output [6:0]
    .mc_cmd_current         (mc_cmd_current),     //output [6:0]
    .mc_cmdex_current       (mc_cmdex_current)    //output [3:0]
);
 
 
//------------------------------------------------------------------------------
 
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_operand_32bit       <= `FALSE; else if(m_load) mc_operand_32bit       <= dec_operand_32bit;       else if(exc_init) mc_operand_32bit       <= `FALSE;  end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_address_32bit       <= `FALSE; else if(m_load) mc_address_32bit       <= dec_address_32bit;       else if(exc_init) mc_address_32bit       <= `FALSE;  end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_prefix_group_1_rep  <= 2'd0;   else if(m_load) mc_prefix_group_1_rep  <= dec_prefix_group_1_rep;  else if(exc_init) mc_prefix_group_1_rep  <= 2'd0;    end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_prefix_group_1_lock <= `FALSE; else if(m_load) mc_prefix_group_1_lock <= dec_prefix_group_1_lock; else if(exc_init) mc_prefix_group_1_lock <= `FALSE;  end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_prefix_group_2_seg  <= 3'd3;   else if(m_load) mc_prefix_group_2_seg  <= dec_prefix_group_2_seg;  else if(exc_init) mc_prefix_group_2_seg  <= 3'd3;    end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_prefix_2byte        <= `FALSE; else if(m_load) mc_prefix_2byte        <= dec_prefix_2byte;        else if(exc_init) mc_prefix_2byte        <= `FALSE;  end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_decoder             <= 88'd0;  else if(m_load) mc_decoder             <= decoder[87:0];           else if(exc_init) mc_decoder             <= 88'd0;   end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_modregrm_len        <= 3'd0;   else if(m_load) mc_modregrm_len        <= dec_modregrm_len;        else if(exc_init) mc_modregrm_len        <= 3'd0;    end
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) mc_is_8bit             <= `FALSE; else if(m_load) mc_is_8bit             <= dec_is_8bit;             else if(exc_init) mc_is_8bit             <= `FALSE;  end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)       mc_cmd <= `CMD_NULL;
    else if(exc_init)       mc_cmd <= `CMD_int;
    else if(micro_reset)    mc_cmd <= `CMD_NULL;
    else if(m_load)         mc_cmd <= dec_cmd;
    else if(micro_ready)    mc_cmd <= mc_cmd_next;
end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)   mc_cmdex <= 4'd0;
    else if(m_load)     mc_cmdex <= dec_cmdex;
    else if(exc_init)   mc_cmdex <= `CMDEX_int_STEP_0;
end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)   mc_consumed <= 4'd0;
    else if(m_load)     mc_consumed <= dec_consumed;
    else if(task_start) mc_consumed <= 4'd0;
    else if(exc_load)   mc_consumed <= 4'd0;
end
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)   mc_eip <= 32'd0;
    else if(m_load)     mc_eip <= dec_eip;
    else if(task_start) mc_eip <= task_eip;
    else if(exc_load)   mc_eip <= exc_eip;
end
 
//------------------------------------------------------------------------------
 
assign micro_operand_32bit       = (m_overlay)? mc_operand_32bit       : dec_operand_32bit;
assign micro_address_32bit       = (m_overlay)? mc_address_32bit       : dec_address_32bit;
assign micro_prefix_group_1_rep  = (m_overlay)? mc_prefix_group_1_rep  : dec_prefix_group_1_rep;
assign micro_prefix_group_1_lock = (m_overlay)? mc_prefix_group_1_lock : dec_prefix_group_1_lock;
assign micro_prefix_group_2_seg  = (m_overlay)? mc_prefix_group_2_seg  : dec_prefix_group_2_seg;
assign micro_prefix_2byte        = (m_overlay)? mc_prefix_2byte        : dec_prefix_2byte;
assign micro_decoder             = (m_overlay)? mc_decoder             : decoder[87:0];
assign micro_modregrm_len        = (m_overlay)? mc_modregrm_len        : dec_modregrm_len;
assign micro_is_8bit             = (m_overlay)? mc_is_8bit             : dec_is_8bit;
 
assign micro_cmd =
    (exc_load)?   mc_cmd :
    (m_overlay)?        mc_cmd_current :
                        dec_cmd;
 
assign micro_cmdex =
    (exc_load)?   mc_cmdex :
    (m_overlay)?        mc_cmdex_current :
                        dec_cmdex;
 
assign micro_consumed =
    (task_start)?       4'd0 :
    (exc_load)?   4'd0 :
    (m_overlay)?        mc_consumed :
                        dec_consumed;
 
assign micro_eip =
    (task_start)?   task_eip :
    (exc_load)?     exc_eip :
    (m_overlay)?    mc_eip :
                    dec_eip;
 
//------------------------------------------------------------------------------
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)       mc_step <= 6'd0;
    else if(m_load)         mc_step <= 6'd1;
    else if(micro_ready)    mc_step <= mc_step + 6'd1;
    else if(exc_init)       mc_step <= 6'd1;
end
 
 
always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)       mc_cmdex_last <= 4'd0;
    else if(micro_ready)    mc_cmdex_last <= micro_cmdex;
    else if(exc_init)       mc_cmdex_last <= `CMDEX_int_STEP_0;
end
 
//------------------------------------------------------------------------------
 
// synthesis translate_off
wire _unused_ok = &{ 1'b0, decoder[95:88], 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.