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

Subversion Repositories rtf8088

[/] [rtf8088/] [trunk/] [rtl/] [verilog/] [DECODE.v] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | 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.