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

Subversion Repositories rtf8088

[/] [rtf8088/] [trunk/] [rtl/] [verilog/] [DECODE.v] - Diff between revs 3 and 4

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 4
// ============================================================================
// ============================================================================
//  DECODE
//  DECODE
//  - decode / dispatch instruction
//  - decode / dispatch instruction
//
//
//
//
//  (C) 2009-2012  Robert Finch
//  (C) 2009-2012  Robert Finch
//  Stratford
//  Stratford
//  robfinch[remove]@opencores.org
//  robfinch[remove]@opencores.org
//
//
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//
//
//
//
//  Verilog 
//  Verilog 
//
//
// Decode / dispatch instruction
// Decode / dispatch instruction
// ============================================================================
// ============================================================================
//
//
DECODE:
DECODE:
        casex(ir)
        casex(ir)
        `MORE1: state <= XI_FETCH;
        `MORE1: state <= XI_FETCH;
        `MORE2: state <= XI_FETCH;
        `MORE2: state <= XI_FETCH;
        `EXTOP: state <= XI_FETCH;
        `EXTOP: state <= XI_FETCH;
 
 
        `DEC_REG,`INC_REG:
        `DEC_REG,`INC_REG:
                begin
                begin
                        w <= 1'b1;
                        w <= 1'b1;
                        rrr <= ir[2:0];
                        rrr <= ir[2:0];
                        state <= REGFETCHA;
                        state <= REGFETCHA;
                end
                end
 
 
        `LEA: state <= EXECUTE;
        `LEA: state <= EXECUTE;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Immediate Loads
        // Immediate Loads
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
 
 
        `MOV_I2AL,`MOV_I2DL,`MOV_I2CL,`MOV_I2BL,`MOV_I2AH,`MOV_I2DH,`MOV_I2CH,`MOV_I2BH:
        `MOV_I2AL,`MOV_I2DL,`MOV_I2CL,`MOV_I2BL,`MOV_I2AH,`MOV_I2DH,`MOV_I2CH,`MOV_I2BH:
                begin
                begin
                        `INITIATE_CODE_READ
                        `INITIATE_CODE_READ
                        state <= MOV_I2BYTREG;
                        state <= MOV_I2BYTREG;
                end
                end
 
 
        `MOV_I2AX,`MOV_I2DX,`MOV_I2CX,`MOV_I2BX,`MOV_I2SP,`MOV_I2BP,`MOV_I2SI,`MOV_I2DI:
        `MOV_I2AX,`MOV_I2DX,`MOV_I2CX,`MOV_I2BX,`MOV_I2SP,`MOV_I2BP,`MOV_I2SI,`MOV_I2DI:
                begin
                begin
                        w <= 1'b1;
                        w <= 1'b1;
                        rrr <= ir[2:0];
                        rrr <= ir[2:0];
                        if (ip==16'hFFFF) begin
                        if (ip==16'hFFFF) begin
                                int_num <= 8'h0d;
                                int_num <= 8'h0d;
                                state <= INT2;
                                state <= INT2;
                        end
                        end
                        else
                        else
                                state <= FETCH_IMM16;
                                state <= FETCH_IMM16;
                end
                end
 
 
        `XLAT:
        `XLAT:
                if (!cyc_o) begin
                if (!cyc_o) begin
                        cyc_type <= `CT_RDMEM;
                        cyc_type <= `CT_RDMEM;
                        cyc_o <= 1'b1;
                        cyc_o <= 1'b1;
                        stb_o <= 1'b1;
                        stb_o <= 1'b1;
                        adr_o <= {seg_reg,`SEG_SHIFT} + bx + al;
                        adr_o <= {seg_reg,`SEG_SHIFT} + bx + al;
                end
                end
                else if (ack_i) begin
                else if (ack_i) begin
                        cyc_type <= `CT_PASSIVE;
                        cyc_type <= `CT_PASSIVE;
                        cyc_o <= 1'b0;
                        cyc_o <= 1'b0;
                        stb_o <= 1'b0;
                        stb_o <= 1'b0;
                        res <= dat_i;
                        res <= dat_i;
                        wrregs <= 1'b1;
                        wrregs <= 1'b1;
                        w <= 1'b0;
                        w <= 1'b0;
                        rrr <= 3'd0;
                        rrr <= 3'd0;
                        state <= IFETCH;
                        state <= IFETCH;
                end
                end
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Arithmetic Operations
        // Arithmetic Operations
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `AAA,`AAS:
        `AAA,`AAS:
                begin
                begin
                        state <= IFETCH;
                        state <= IFETCH;
                        wrregs <= 1'b1;
                        wrregs <= 1'b1;
                        w <= 1'b1;
                        w <= 1'b1;
                        rrr <= 3'd0;
                        rrr <= 3'd0;
                        res <= alu_o;
                        res <= alu_o;
                        af <= (al[3:0]>4'h9 || af);
                        af <= (al[3:0]>4'h9 || af);
                        cf <= (al[3:0]>4'h9 || af);
                        cf <= (al[3:0]>4'h9 || af);
                end
                end
        `ADD_ALI8,`ADC_ALI8,`SUB_ALI8,`SBB_ALI8,`AND_ALI8,`OR_ALI8,`XOR_ALI8,`CMP_ALI8:
        `ADD_ALI8,`ADC_ALI8,`SUB_ALI8,`SBB_ALI8,`AND_ALI8,`OR_ALI8,`XOR_ALI8,`CMP_ALI8:
                begin
                begin
                        w <= 1'b0;
                        w <= 1'b0;
                        a <= {{8{al[7]}},al};
                        a <= {{8{al[7]}},al};
                        rrr <= 3'd0;
                        rrr <= 3'd0;
                        state <= FETCH_IMM8;
                        state <= FETCH_IMM8;
                end
                end
        `ADD_AXI16,`ADC_AXI16,`SUB_AXI16,`SBB_AXI16,`AND_AXI16,`OR_AXI16,`XOR_AXI16,`CMP_AXI16:
        `ADD_AXI16,`ADC_AXI16,`SUB_AXI16,`SBB_AXI16,`AND_AXI16,`OR_AXI16,`XOR_AXI16,`CMP_AXI16:
                begin
                begin
                        w <= 1'b1;
                        w <= 1'b1;
                        a <= ax;
                        a <= ax;
                        rrr <= 3'd0;
                        rrr <= 3'd0;
                        if (ip==16'hFFFF) begin
                        if (ip==16'hFFFF) begin
                                int_num <= 8'h0d;
                                int_num <= 8'h0d;
                                state <= INT2;
                                state <= INT2;
                        end
                        end
                        else
                        else
                                state <= FETCH_IMM16;
                                state <= FETCH_IMM16;
                end
                end
        `ALU_I2R8:
        `ALU_I2R8:
                begin
                begin
                        state <= FETCH_IMM8;
                        state <= FETCH_IMM8;
                        a <= rrro;
                        a <= rrro;
                end
                end
        `ALU_I2R16:
        `ALU_I2R16:
                begin
                begin
                        state <= FETCH_IMM16;
                        state <= FETCH_IMM16;
                        a <= rrro;
                        a <= rrro;
                end
                end
        `XCHG_AXR:
        `XCHG_AXR:
                begin
                begin
                        state <= IFETCH;
                        state <= IFETCH;
                        wrregs <= 1'b1;
                        wrregs <= 1'b1;
                        w <= 1'b1;
                        w <= 1'b1;
                        rrr <= ir[2:0];
                        rrr <= ir[2:0];
                        res <= ax;
                        res <= ax;
                        case(ir[2:0])
                        case(ir[2:0])
                        3'd0:   ax <= ax;
                        3'd0:   ax <= ax;
                        3'd1:   ax <= cx;
                        3'd1:   ax <= cx;
                        3'd2:   ax <= dx;
                        3'd2:   ax <= dx;
                        3'd3:   ax <= bx;
                        3'd3:   ax <= bx;
                        3'd4:   ax <= sp;
                        3'd4:   ax <= sp;
                        3'd5:   ax <= bp;
                        3'd5:   ax <= bp;
                        3'd6:   ax <= si;
                        3'd6:   ax <= si;
                        3'd7:   ax <= di;
                        3'd7:   ax <= di;
                        endcase
                        endcase
                end
                end
        `CBW: begin ax[15:8] <= {8{ax[7]}}; state <= IFETCH; end
        `CBW: begin ax[15:8] <= {8{ax[7]}}; state <= IFETCH; end
        `CWD:
        `CWD:
                begin
                begin
                        state <= IFETCH;
                        state <= IFETCH;
                        wrregs <= 1'b1;
                        wrregs <= 1'b1;
                        w <= 1'b1;
                        w <= 1'b1;
                        rrr <= 3'd2;
                        rrr <= 3'd2;
                        res <= {16{ax[15]}};
                        res <= {16{ax[15]}};
                end
                end
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // String Operations
        // String Operations
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `LODSB: state <= LODS;
        `LODSB: state <= LODS;
        `LODSW: state <= LODS;
        `LODSW: state <= LODS;
        `STOSB: state <= STOS;
        `STOSB: state <= STOS;
        `STOSW: state <= STOS;
        `STOSW: state <= STOS;
        `MOVSB: state <= MOVS;
        `MOVSB: state <= MOVS;
        `MOVSW: state <= MOVS;
        `MOVSW: state <= MOVS;
        `CMPSB: state <= CMPSB;
        `CMPSB: state <= CMPSB;
        `CMPSW: state <= CMPSW;
        `CMPSW: state <= CMPSW;
        `SCASB: state <= SCASB;
        `SCASB: state <= SCASB;
        `SCASW: state <= SCASW;
        `SCASW: state <= SCASW;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Stack Operations
        // Stack Operations
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `PUSH_REG: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_REG: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_DS: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_DS: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_ES: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_ES: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_SS: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_SS: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_CS: begin sp <= sp_dec; state <= PUSH; end
        `PUSH_CS: begin sp <= sp_dec; state <= PUSH; end
        `PUSHF: begin sp <= sp_dec; state <= PUSH; end
        `PUSHF: begin sp <= sp_dec; state <= PUSH; end
        `POP_REG: state <= POP;
        `POP_REG: state <= POP;
        `POP_DS: state <= POP;
        `POP_DS: state <= POP;
        `POP_ES: state <= POP;
        `POP_ES: state <= POP;
        `POP_SS: state <= POP;
        `POP_SS: state <= POP;
        `POPF: state <= POP;
        `POPF: state <= POP;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Flow controls
        // Flow controls
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `NOP: state <= IFETCH;
        `NOP: state <= IFETCH;
        `HLT: if (pe_nmi | (irq_i & ie)) state <= IFETCH;
        `HLT: if (pe_nmi | (irq_i & ie)) state <= IFETCH;
        `WAI: if (!busy_i) state <= IFETCH;
        `WAI: if (!busy_i) state <= IFETCH;
        `LOOP: begin cx <= cx_dec; state <= BRANCH1; end
        `LOOP: begin cx <= cx_dec; state <= BRANCH1; end
        `LOOPZ: begin cx <= cx_dec; state <= BRANCH1; end
        `LOOPZ: begin cx <= cx_dec; state <= BRANCH1; end
        `LOOPNZ: begin cx <= cx_dec; state <= BRANCH1; end
        `LOOPNZ: begin cx <= cx_dec; state <= BRANCH1; end
        `Jcc: state <= BRANCH1;
        `Jcc: state <= BRANCH1;
        `JCXZ: state <= BRANCH1;
        `JCXZ: state <= BRANCH1;
        `JMPS: state <= BRANCH1;
        `JMPS: state <= BRANCH1;
        `JMPF: state <= FETCH_OFFSET;
        `JMPF: state <= FETCH_OFFSET;
        `CALL: begin sp <= sp_dec; state <= FETCH_DISP16; end
        `CALL: begin sp <= sp_dec; state <= FETCH_DISP16; end
        `CALLF: begin sp <= sp_dec; state <= FETCH_OFFSET; end
        `CALLF: begin sp <= sp_dec; state <= FETCH_OFFSET; end
        `RET: state <= RETPOP;          // data16 is zero
        `RET: state <= RETPOP;          // data16 is zero
        `RETPOP: state <= FETCH_STK_ADJ1;
        `RETPOP: state <= FETCH_STK_ADJ1;
        `RETF: state <= RETFPOP;        // data16 is zero
        `RETF: state <= RETFPOP;        // data16 is zero
        `RETFPOP: state <= FETCH_STK_ADJ1;
        `RETFPOP: state <= FETCH_STK_ADJ1;
        `IRET: state <= IRET1;
        `IRET: state <= IRET1;
        `INT: state <= INT;
        `INT: state <= INT;
        `INT3: begin int_num <= 8'd3; state <= INT2; end
        `INT3: begin int_num <= 8'd3; state <= INT2; end
        `INTO:
        `INTO:
                if (vf) begin
                if (vf) begin
                        int_num <= 8'd4;
                        int_num <= 8'd4;
                        state <= INT2;
                        state <= INT2;
                end
                end
                else
                else
                        state <= IFETCH;
                        state <= IFETCH;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Flag register operations
        // Flag register operations
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `STI: begin ie <= 1'b1; state <= IFETCH; end
        `STI: begin ie <= 1'b1; state <= IFETCH; end
        `CLI: begin ie <= 1'b0; state <= IFETCH; end
        `CLI: begin ie <= 1'b0; state <= IFETCH; end
        `STD: begin df <= 1'b1; state <= IFETCH; end
        `STD: begin df <= 1'b1; state <= IFETCH; end
        `CLD: begin df <= 1'b0; state <= IFETCH; end
        `CLD: begin df <= 1'b0; state <= IFETCH; end
        `STC: begin cf <= 1'b1; state <= IFETCH; end
        `STC: begin cf <= 1'b1; state <= IFETCH; end
        `CLC: begin cf <= 1'b0; state <= IFETCH; end
        `CLC: begin cf <= 1'b0; state <= IFETCH; end
        `CMC: begin cf <=  !cf; state <= IFETCH; end
        `CMC: begin cf <=  !cf; state <= IFETCH; end
        `LAHF:
        `LAHF:
                begin
                begin
                        ax[15] <= sf;
                        ax[15] <= sf;
                        ax[14] <= zf;
                        ax[14] <= zf;
                        ax[12] <= af;
                        ax[12] <= af;
                        ax[10] <= pf;
                        ax[10] <= pf;
                        ax[8] <= cf;
                        ax[8] <= cf;
                        state <= IFETCH;
                        state <= IFETCH;
                end
                end
        `SAHF:
        `SAHF:
                begin
                begin
                        sf <= ah[7];
                        sf <= ah[7];
                        zf <= ah[6];
                        zf <= ah[6];
                        af <= ah[4];
                        af <= ah[4];
                        pf <= ah[2];
                        pf <= ah[2];
                        cf <= ah[0];
                        cf <= ah[0];
                        state <= IFETCH;
                        state <= IFETCH;
                end
                end
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // IO instructions
        // IO instructions
        // - fetch port number, then vector
        // - fetch port number, then vector
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `INB: state <= INB;
        `INB: state <= INB;
        `INW: state <= INW;
        `INW: state <= INW;
        `OUTB: state <= OUTB;
        `OUTB: state <= OUTB;
        `OUTW: state <= OUTW;
        `OUTW: state <= OUTW;
        `INB_DX: begin ea <= {`SEG_SHIFT,dx}; state <= INB1; end
        `INB_DX: begin ea <= {`SEG_SHIFT,dx}; state <= INB1; end
        `INW_DX: begin ea <= {`SEG_SHIFT,dx}; state <= INW1; end
        `INW_DX: begin ea <= {`SEG_SHIFT,dx}; state <= INW1; end
        `OUTB_DX: begin ea <= {`SEG_SHIFT,dx}; state <= OUTB1; end
        `OUTB_DX: begin ea <= {`SEG_SHIFT,dx}; state <= OUTB1; end
        `OUTW_DX: begin ea <= {`SEG_SHIFT,dx}; state <= OUTW1; end
        `OUTW_DX: begin ea <= {`SEG_SHIFT,dx}; state <= OUTW1; end
        `INSB: state <= INSB;
        `INSB: state <= INSB;
        `OUTSB: state <= OUTSB;
        `OUTSB: state <= OUTSB;
        `OUTSW: state <= OUTSW;
        `OUTSW: state <= OUTSW;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // Control Prefix
        // Control Prefix
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `LOCK: begin lock_insn <= ir; state <= IFETCH; end
        `LOCK: begin lock_insn <= ir; state <= IFETCH; end
        `REPZ,`REPNZ,`CS,`DS,`ES,`SS: state <= IFETCH;
        `REPZ,`REPNZ,`CS,`DS,`ES,`SS: state <= IFETCH;
 
 
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        // disp16 instructions
        // disp16 instructions
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        `MOV_M2AL,`MOV_M2AX,`MOV_AL2M,`MOV_AX2M,`CALL,`JMP:
        `MOV_M2AL,`MOV_M2AX,`MOV_AL2M,`MOV_AX2M,`CALL,`JMP:
                begin
                begin
                        `INITIATE_CODE_READ
                        `INITIATE_CODE_READ
                        state <= FETCH_DISP16_ACK;
                        state <= FETCH_DISP16_ACK;
                end
                end
 
 
        default:
        default:
                begin
                begin
 
                if (v) shftamt <= cl[3:0];
 
                else shftamt <= 4'd1;
                //-----------------------------------------------------------------
                //-----------------------------------------------------------------
                // MOD/RM instructions
                // MOD/RM instructions
                //-----------------------------------------------------------------
                //-----------------------------------------------------------------
                $display("Fetching mod/rm");
                $display("Fetching mod/rm");
                if (ir==`MOV_R2S || ir==`MOV_S2R)
                if (ir==`MOV_R2S || ir==`MOV_S2R)
                        w <= 1'b1;
                        w <= 1'b1;
                if (ir==`LDS || ir==`LES)
                if (ir==`LDS || ir==`LES)
                        w <= 1'b1;
                        w <= 1'b1;
                if (fetch_modrm) begin
                if (fetch_modrm) begin
                        `INITIATE_CODE_READ
                        `INITIATE_CODE_READ
                        state <= EACALC;
                        state <= EACALC;
                end
                end
                else
                else
                        state <= IFETCH;
                        state <= IFETCH;
                end
                end
        endcase
        endcase
 
 

powered by: WebSVN 2.1.0

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