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

Subversion Repositories rtf8088

[/] [rtf8088/] [trunk/] [rtl/] [verilog/] [EXECUTE.v] - Rev 8

Compare with Previous | Blame | View Log

// ============================================================================
//  (C) 2009,2010,2012  Robert Finch
//  robfinch<remove>@opencores.org
//
//  EXECUTE
//  - execute instruction
//
//
// 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 
//
// ============================================================================
//
EXECUTE:
	begin
		casex(ir)
 
		`EXTOP:
			casex(ir2)
			`LxDT: state <= FETCH_DESC;
			endcase
 
		`DAA:
			begin
				state <= IFETCH;
			end
 
		`ALU_I2R8,`ALU_I2R16,`ADD,`ADD_ALI8,`ADD_AXI16,`ADC,`ADC_ALI8,`ADC_AXI16:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				res <= alu_o;
				pf <= pres;
				af <= carry   (1'b0,a[3],b[3],alu_o[3]);
				cf <= carry   (1'b0,amsb,bmsb,resn);
				vf <= overflow(1'b0,amsb,bmsb,resn);
				sf <= resn;
				zf <= resz;
			end
 
		`AND,`OR,`XOR,`AND_ALI8,`OR_ALI8,`XOR_ALI8,`AND_AXI16,`OR_AXI16,`XOR_AXI16:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				res <= alu_o;
				pf <= pres;
				cf <= 1'b0;
				vf <= 1'b0;
				sf <= resn;
				zf <= resz;
			end
 
		`TEST:
			begin
				state <= IFETCH;
				res <= alu_o;
				pf <= pres;
				cf <= 1'b0;
				vf <= 1'b0;
				sf <= resn;
				zf <= resz;
			end
 
		`CMP,`CMP_ALI8,`CMP_AXI16:
			begin
				state <= IFETCH;
				pf <= pres;
				af <= carry   (1'b1,a[3],b[3],alu_o[3]);
				cf <= carry   (1'b1,amsb,bmsb,resn);
				vf <= overflow(1'b1,amsb,bmsb,resn);
				sf <= resn;
				zf <= resz;
			end
 
		`SBB,`SUB,`SBB_ALI8,`SUB_ALI8,`SBB_AXI16,`SUB_AXI16:
			begin
				wrregs <= 1'b1;
				state <= IFETCH;
				res <= alu_o;
				pf <= pres;
				af <= carry   (1'b1,a[3],b[3],alu_o[3]);
				cf <= carry   (1'b1,amsb,bmsb,resn);
				vf <= overflow(1'b1,amsb,bmsb,resn);
				sf <= resn;
				zf <= resz;
			end
 
		8'hF6,8'hF7:
			begin
				state <= IFETCH;
				res <= alu_o;
				case(TTT)
				3'd0:	// TEST
					begin
						pf <= pres;
						cf <= 1'b0;
						vf <= 1'b0;
						sf <= resn;
						zf <= resz;
					end
				3'd2:	// NOT
					begin
						wrregs <= 1'b1;
					end
				3'd3:	// NEG
					begin
						pf <= pres;
						af <= carry   (1'b1,1'b0,b[3],alu_o[3]);
						cf <= carry   (1'b1,1'b0,bmsb,resn);
						vf <= overflow(1'b1,1'b0,bmsb,resn);
						sf <= resn;
						zf <= resz;
						wrregs <= 1'b1;
					end
				// Normally only a single register update is required, however with 
				// multiply word both AX and DX need to be updated. So we bypass the
				// regular update here.
				3'd4:
					begin
						if (w) begin
							ax <= p32[15:0];
							dx <= p32[31:16];
							cf <= p32[31:16]!=16'd0;
							vf <= p32[31:16]!=16'd0;
						end
						else begin
							ax <= p16;
							cf <= p16[15:8]!=8'd0;
							vf <= p16[15:8]!=8'd0;
						end
					end
				3'd5:
					begin
						if (w) begin
							ax <= wp[15:0];
							dx <= wp[31:16];
							cf <= p32[31:16]!=16'd0;
							vf <= p32[31:16]!=16'd0;
						end
						else begin
							ax <= p;
							cf <= p[15:8]!=8'd0;
							vf <= p[15:8]!=8'd0;
						end
					end
				3'd6,3'd7:
					begin
						$display("state <= DIVIDE1");
						state <= DIVIDE1;
					end
				default:	;
				endcase
			end
 
		`INC_REG:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				w <= 1'b1;
				res <= alu_o;
				pf <= pres;
				af <= carry   (1'b0,a[3],b[3],alu_o[3]);
				vf <= overflow(1'b0,a[15],b[15],resnw);
				sf <= resnw;
				zf <= reszw;
			end
		`DEC_REG:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				w <= 1'b1;
				res <= alu_o;
				pf <= pres;
				af <= carry   (1'b1,a[3],b[3],alu_o[3]);
				vf <= overflow(1'b1,a[15],b[15],resnw);
				sf <= resnw;
				zf <= reszw;
			end
//		`IMUL:
//			begin
//				state <= IFETCH;
//				wrregs <= 1'b1;
//				w <= 1'b1;
//				rrr <= 3'd0;
//				res <= alu_o;
//				if (w) begin
//					cf <= wp[31:16]!={16{resnw}};
//					vf <= wp[31:16]!={16{resnw}};
//					dx <= wp[31:16];
//				end
//				else begin
//					cf <= ah!={8{resnb}};
//					vf <= ah!={8{resnb}};
//				end
//			end
 
 
		//-----------------------------------------------------------------
		// Memory Operations
		//-----------------------------------------------------------------
 
		// registers not allowed on LEA
		// invalid opcode
		//
		`LEA:
			begin
				w <= 1'b1;
				res <= ea;
				if (mod==2'b11) begin
					int_num <= 8'h06;
					state <= INT;
				end
				else begin
					state <= IFETCH;
					wrregs <= 1'b1;
				end
			end
		`LDS:
			begin
				wrsregs <= 1'b1;
				res <= alu_o;
				rrr <= 3'd3;
				state <= IFETCH;
			end
		`LES:
			begin
				wrsregs <= 1'b1;
				res <= alu_o;
				rrr <= 3'd0;
				state <= IFETCH;
			end
 
		`MOV_RR8,`MOV_RR16,
		`MOV_MR,
		`MOV_M2AL,`MOV_M2AX,
		`MOV_I2AL,`MOV_I2DL,`MOV_I2CL,`MOV_I2BL,`MOV_I2AH,`MOV_I2DH,`MOV_I2CH,`MOV_I2BH,
		`MOV_I2AX,`MOV_I2DX,`MOV_I2CX,`MOV_I2BX,`MOV_I2SP,`MOV_I2BP,`MOV_I2SI,`MOV_I2DI:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				res <= alu_o;
			end
		`XCHG_MEM:
			begin
				wrregs <= 1'b1;
				if (mod==2'b11) rrr <= rm;
				res <= alu_o;
				b <= rrro;
				state <= mod==2'b11 ? IFETCH : XCHG_MEM;
			end
		`MOV_I8M,`MOV_I16M:
			begin
				res <= alu_o;
				state <= rrr==3'd0 ? STORE_DATA : INVALID_OPCODE;
			end
 
		`MOV_S2R:
			begin
				w <= 1'b1;
				rrr <= rm;
				res <= b;
				if (mod==2'b11) begin
					state <= IFETCH;
					wrregs <= 1'b1;
				end
				else
					state <= STORE_DATA;
			end
		`MOV_R2S:
			begin
				wrsregs <= 1'b1;
				res <= alu_o;
				state <= IFETCH;
			end
 
		`LODSB:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				w <= 1'b0;
				rrr <= 3'd0;
				res <= a[7:0];
				if ( df) si <= si_dec;
				if (!df) si <= si_inc;
			end
		`LODSW:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				w <= 1'b1;
				rrr <= 3'd0;
				res <= a;
				if ( df) si <= si - 16'd2;
				if (!df) si <= si + 16'd2;
			end
 
		8'hD0,8'hD1,8'hD2,8'hD3,8'hC0,8'hC1:
			begin
				state <= IFETCH;
				wrregs <= 1'b1;
				rrr <= rm;
				if (w)
					case(rrr)
					3'b000:	// ROL
						begin
							res <= shlo[15:0]|shlo[31:16];
							cf <= bmsb;
							vf <= bmsb^b[14];
						end
					3'b001:	// ROR
						begin
							res <= shruo[15:0]|shruo[31:16];
							cf <= b[0];
							vf <= cf^b[15];
						end
					3'b010:	// RCL
						begin
							res <= shlco[16:1]|shlco[32:17];
							cf <= b[15];
							vf <= b[15]^b[14];
						end
					3'b011:	// RCR
						begin
							res <= shrcuo[15:0]|shrcuo[31:16];
							cf <= b[0];
							vf <= cf^b[15];
						end
					3'b100:	// SHL
						begin
							res <= shlo[15:0];
							cf <= shlo[16];
							vf <= b[15]^b[14];
						end
					3'b101:	// SHR
						begin
							res <= shruo[31:16];
							cf <= shruo[15];
							vf <= b[15];
						end
					3'b111:	// SAR
						begin
							res <= shro;
							cf <= b[0];
							vf <= 1'b0;
						end
					endcase
				else
					case(rrr)
					3'b000:	// ROL
						begin
							res <= shlo8[7:0]|shlo8[15:8];
							cf <= b[7];
							vf <= b[7]^b[6];
						end
					3'b001:	// ROR
						begin
							res <= shruo8[15:8]|shruo8[7:0];
							cf <= b[0];
							vf <= cf^b[7];
						end
					3'b010:	// RCL
						begin
							res <= shlco8[8:1]|shlco8[16:9];
							cf <= b[7];
							vf <= b[7]^b[6];
						end
					3'b011:	// RCR
						begin
							res <= shrcuo8[15:8]|shrcuo8[7:0];
							cf <= b[0];
							vf <= cf^b[7];
						end
					3'b100:	// SHL
						begin
							res <= shlo8[7:0];
							cf <= shlo8[8];
							vf <= b[7]^b[6];
						end
					3'b101:	// SHR
						begin
							res <= shruo8[15:8];
							cf <= shruo8[7];
							vf <= b[7];
						end
					3'b111:	// SAR
						begin
							res <= shro8;
							cf <= b[0];
							vf <= 1'b0;
						end
					endcase
			end
 
		//-----------------------------------------------------------------
		//-----------------------------------------------------------------
		`GRPFF:
			begin
				case(rrr)
				3'b000:		// INC
					begin
						state <= IFETCH;
						wrregs <= 1'b1;
						af <= carry   (1'b0,a[3],b[3],alu_o[3]);
						vf <= overflow(1'b0,a[15],b[15],alu_o[15]);
						w <= 1'b1;
						res <= alu_o;
						rrr <= rm;
						pf <= pres;
						sf <= resnw;
						zf <= reszw;
					end
				3'b001:		// DEC
					begin
						state <= IFETCH;
						wrregs <= 1'b1;
						af <= carry   (1'b1,a[3],b[3],alu_o[3]);
						vf <= overflow(1'b1,a[15],b[15],alu_o[15]);
						w <= 1'b1;
						res <= alu_o;
						rrr <= rm;
						pf <= pres;
						sf <= resnw;
						zf <= reszw;
					end
				3'b010:	begin sp <= sp_dec; state <= CALL_IN; end
				// These two should not be reachable here, as they would
				// be trapped by the EACALC.
				3'b011:	state <= CALL_FIN;	// CALL FAR indirect
				3'b101:	// JMP FAR indirect
					begin
						ip <= offset;
						cs <= selector;
						state <= IFETCH;
					end
				3'b110:	begin sp <= sp_dec; state <= PUSH; end
				default:
					begin
						af <= carry   (1'b0,a[3],b[3],alu_o[3]);
						vf <= overflow(1'b0,a[15],b[15],alu_o[15]);
					end
				endcase
			end
 
		//-----------------------------------------------------------------
		//-----------------------------------------------------------------
		default:
			state <= IFETCH;
		endcase
	end
 
 

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.