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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [DECODER.v] - Rev 49

Compare with Previous | Blame | View Log

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// This file is part of the M32632 project
// http://opencores.org/project,m32632
//
//	Filename:	DECODER.v
//	Version:	3.2 bug fix	
//  History:	3.0 of 2 December 2018
//				2.0 of 11 August 2016
//				1.0 first release of 30 Mai 2015
//	Date:		17 January 2021
//
// Copyright (C) 2021 Udo Moeller
// 
// This source file may be used and distributed without 
// restriction provided that this copyright statement is not 
// removed from the file and that any derivative work contains 
// the original copyright notice and the associated disclaimer.
// 
// 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 2.1 of the License, or (at your option) any 
// later version. 
// 
// This source 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 Lesser General Public License for more 
// details. 
// 
// You should have received a copy of the GNU Lesser General 
// Public License along with this source; if not, download it 
// from http://www.opencores.org/lgpl.shtml 
// 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//	Modules contained in this file:
//	DECODER		Instruction Decoding and Flow Control
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
module DECODER ( BCLK, BRESET, INT_N, NMI_N, ANZ_VAL, OPREG, CFG, PSR, ACC_DONE, DC_ABORT, IC_ABORT, ACB_ZERO, DONE,
				 PC_SAVE, STRING, INIT_DONE, ILL, UNDEF, TRAPS, IC_READ, STOP_CINV,
				 GENSTAT, DISP, IMME_Q, DISP_BR, USED, NEW, LOAD_PC, NEXT_PCA, RDAA, RDAB, OPER, START, LD_OUT, LD_DIN, LD_IMME,
				 INFO_AU, ACC_FELD, WREN, WRADR, WMASKE, WR_REG, DETOIP, MMU_UPDATE, RESTART, STOP_IC, RWVAL, ENA_HK, ILO, COP_OP,
				 PHOUT );
 
	input			BCLK,BRESET;
	input			INT_N,NMI_N;	// external inputs
	input	 [2:0]	ANZ_VAL;
	input	[55:0]	OPREG;			// the OPREG contains the bytes to decode, OPREG[55:32] are don't care
	input	 [8:0]	CFG;			// CONFIG : many bits are don't-care
	input	[11:0]	PSR;
	input			ACC_DONE;
	input			DC_ABORT,IC_ABORT;
	input			ACB_ZERO;
	input			DONE;
	input	[31:0]	PC_SAVE;
	input	 [4:0]	STRING;
	input			INIT_DONE;
	input			ILL,UNDEF;
	input	 [5:0]	TRAPS;
	input			IC_READ;
	input			STOP_CINV;		// not to mix it up with STOP_IC
 
	output	 [2:0]	GENSTAT;
	output	[31:0]	DISP,IMME_Q,DISP_BR;	// three main data busses : Displacement, Immediate and Displacement for Branch
	output	 [2:0]	USED;
	output			NEW;
	output			LOAD_PC;
	output			NEXT_PCA;
	output	 [7:0]	RDAA,RDAB;
	output	[10:0]	OPER;
	output	 [1:0]	START,LD_OUT;
	output			LD_DIN,LD_IMME;
	output	 [6:0]	INFO_AU;
	output	[14:0]	ACC_FELD;
	output			WREN;
	output	 [5:0]	WRADR;
	output	 [1:0]	WMASKE;
	output	reg		WR_REG;
	output	[12:0]	DETOIP;
	output	 [1:0]	MMU_UPDATE;
	output			RESTART;
	output			STOP_IC;
	output	 [2:0]	RWVAL;
	output			ENA_HK;
	output	reg		ILO;
	output	[23:0]	COP_OP;
	output	 [7:0]	PHOUT;		// for Debug purposes, phase_reg output
 
	reg		[31:0]	DISP,disp_val;
	reg		[10:0]	oper_i;
	reg		 [2:0]	USED;
	reg		[14:0]	ACC_FELD;
	reg		 [1:0]	ldoreg;
	reg				wren_i;
	reg		 [5:0]	wradr_i;
	reg		 [1:0]	wmaske_i;
	reg		 [1:0]	start_i;
	reg		[23:0]	COP_OP;
	reg				spupd_i;
	reg		 [3:0]	disp_sel;
	reg		[52:0]	op1_feld;
	reg		[47:0]	op2_feld;
	reg		[47:0]	op3_feld;
	reg		[47:0]	op_feld_reg;
	reg		[31:0]	imme_i;
	reg		 [2:0]	valid;
	reg		 [7:0]	phase_reg;
	reg		 [3:0]	di_stat;	// Displacement Status
	reg		 [3:0]	cc_feld;
	reg		 [1:0]	ex_br_op;
	reg				acb_reg;
	reg				jsr_flag;
	reg		 [8:0]	waitop,wait_reg;
	reg				branch;
	reg		 [3:0]	dim_feld;
	reg		[66:0]	new_op;
	reg				short_op_reg;
	reg		[15:0]	idx_reg;
	reg		[35:0]	gen_src1;
	reg		[33:0]	gen_src2;
	reg				qw_flag;
	reg				long_reg;
	reg				new_spsel;
	reg				s_user,old_su;
	reg		 [1:0]	stack_sel;	// Stack select for USER and SUPERVISOR
	reg		 [1:0]	s_mod;		// Modifier for Stack select
	reg				upd_info,dw_info;
	reg		 [2:0]	rpointer;
	reg		 [5:0]	resto;		// for RESTORE
	reg				init_rlist;
	reg				new_fp;
	reg				format1;
	reg				ldpc_phase;
	reg				reti_flag;
	reg				no_t2p;
	reg				iabort,ia_save;
	reg				mmu_sel;
	reg		 [1:0]	nmi_reg;
	reg				nmi_flag,int_flag;
	reg				type_nmi;
	reg		 [3:0]	exc_vector;
	reg				phase_exc;
	reg		 [3:0]	ovf_pipe;
	reg				dbg_s,dbg_trap,dbg_en,addr_cmp;
	reg				ssrc_flag,sdest_flag;
	reg				op_setcfg,setcfg_lsb;
	reg				inss_op;
	reg				exin_cmd,extract;	// EXT/INS
	reg				bit_reg;	// Flag for Bit opcodes : Source2 = Reg
	reg				kurz_st;	// Flag for MOVM/CMPM
	reg				kill_opt;	// Flag for optimized MOVS
	reg				cmps_flag;	// Flag for CMPS
	reg				skps_flag;	// Flag for SKPS
	reg				mt_flag;	// Flag for Match and Translate
	reg				spu_block;	// block of SP update at Long operation
	reg				dia_op,dia_flag;	// Flag for DIA
	reg				m_ussu,m_usel,dc_user;	// MOVUS/SU
	reg				rwval_flag,wrval_flag;	// RDVAL/WRVAL
	reg				cinv_flag;	// Flag for CINV
	reg		 [5:0]	lmrreg;
	reg				no_init,a_ivar;
	reg				index_cmd;
	reg				stop_d;
	reg				dc_ilo;
 
	wire			PHASE_0;
	wire	 [7:0]	phase_ein;	// Phase after ABORT has changed the content to 0
	wire			de_flag,ivec_flag;
	wire			next;
	wire	[18:0]	new_addr,pop_fp,save_pc;
	wire	[13:0]	new_regs;
	wire	 [7:0]	new_ph,ppfp;
	wire	 [7:0]	new_nx;
	wire			op_1byte,op_12byte,op_2byte,op_3byte;
	wire			jump;
	wire			short_op,short_def;
	wire			opt_imme;
	wire	 [7:0]	opti_byte;
	wire			acb_op,acb_flag;
	wire			zero,carry_psr,negativ,larger,flag;
	wire			valid_size;
	wire			op_ok;
	wire			stop;
	wire	[47:0]	opc_bits;
	wire	[47:0]	op_feld;
	wire	 [2:0]	atys,atyd;
	wire	 [3:0]	auop_s,auop_d;
	wire			long,src2_flag,dest_flag;
	wire	 [6:0]	src_1,src_2,src_1l,src_2l;
	wire	 [1:0]	src1_le,src2_le;
	wire			acc1,acc2;
	wire			spupd;
	wire	 [6:0]	saver;	// for SAVE
	wire	 [2:0]	reg_nr;
	wire			save_reg;
	wire			ld_disp,disp_ok;
	wire			store_pc;
	wire			do_xor;
	wire			do_long;
	wire	 [1:0]	idx_n,n_idx;
	wire			idx;
	wire	 [1:0]	otype;
	wire	[10:0]	opera,op_str,op_sho;
	wire	 [5:0]	dest_r,dest_rl;
	wire			phase_idx;
	wire	[15:0]	idx_bytes,idx_feld;
	wire	 [3:0]	idx_1,idx_2;
	wire	 [4:0]	src1_addr,src2_addr;
	wire	 [6:0]	usp_1,usp_2;
	wire	[33:0]	tos_oper;
	wire	[18:0]	adrd1,exr11,exr12,adrd2,adwr2,exr22,exw22,re_wr,st_src,st_src2,st_dest,st_len,st_trde,st_trs2;
	wire	 [7:0]	phrd1,phrd2,phwr2;
	wire	 [6:0]	rega1,irrw1,rega2,irrw2;
	wire	 [3:0]	nxrd1,nxrw2;
	wire			rmw;
	wire	 [6:0]	quei1,quet1;		// Registeradr
	wire	 [7:0]	endea,goacb,dowait;	// Phase
	wire	 [3:0]	diacb;				// DIMM access
	wire			qword;
	wire	 [6:0]	stack,no_modul,ttstak;
	wire	[12:0]	pop_1;
	wire			mpoi_1,mpoi_2;
	wire	 [1:0]	src1_tos;		// the code for REUSE is 2'b11
	wire			svc_flag,bpt_flag,flag_flag,trac_flag;
	wire	 [3:0]	misc_vectors;
	wire	 [2:0]	psr_code;
	wire			exception;
	wire			interrupt;
	wire			abort;		// DC_ABORT | iabort;
	wire			abo_int;
	wire			iabo_fall;
	wire			abbruch,fpu_trap,dvz_trap;
	wire			abbruch2;
	wire			dbg_flag;
	wire			ovf_op,ovf2_op,ovf_flag;
	wire			pc_match;
	wire			no_trap;
	wire	[10:0]	op_psr,op_scp;
	wire	[30:0]	ai_next;
	wire			set_src,set_dest,clr_sflag;
	wire	 [7:0]	rrepa;	// Repair Phase of Abort for String opcodes
	wire	 [7:0]	ph_str;	// working phase String
	wire			ph_match;
	wire			t2p;
	wire			rw_bit,op_ilo;
	wire			setcfg;
	wire			string_ende;
	wire			wlor;	// Flag to generate WR_REG signal
	wire	 [5:0]	wstr0,wstr1,wstr2;
	wire	 [6:0]	rstr0,rstr1,rstr2;
	wire			rett_exc;
	wire			chk_rmw;
 
	// Variables for 2- and 3-Byte Dekoder :
	reg		 [5:0]	hzr_c;	// CASE Statement
	wire	 [1:0]	hzl_a;
	wire	 [2:0]	hzl_b;
	wire	 [5:0]	hzr_a,hzr_b,hzr_s;
	wire			hdx_a;
	wire	 [3:0]	hdo_a,hdo_c,hdo_e;
	wire	 [7:0]	hdo_d;
	wire	 [1:0]	hdl_b,hdl_d,hdl_f,hdl_g,hdl_h;
	wire	 [2:0]	hdl_a,hdl_c,hdl_e;
	wire	 [5:0]	hdr_a,hdr_b,hdr_c,hdr_d,hdr_e,hdr_f,hdr_g,hdr_m;
 
	wire	[66:0]	state_0,state_group_50,state_group_60;	// for the Gruppe 2 opcodes
 
	// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
 
	parameter addr_nop	= 19'b10_0000_0000_0_0000_0000;	// all parameter to 0
	parameter push_op	= 19'b10_0111_0000_1_1010_0000;	// i.e. for BSR, ENTER ...
	parameter push_ea	= 19'b10_0111_0000_1_1010_0011;	// SAVE middle
	parameter pop_op	= 19'b10_1011_0010_1_0000_1000;	// RET/RESTORE
	parameter adddisp	= 19'b10_0010_0000_0_0000_0011;	// for RET : reuse of EA
	parameter adddispn	= 19'b10_0010_0000_0_0000_0000;	// for RETT : add Disp to Stack
	parameter save_sp	= 19'b10_0000_0000_1_0000_0000;	// u.a. RET : update of Stack
	parameter next_po	= 19'b10_1011_0010_1_0000_1011;	// RESTORE middle
	parameter dispmin	= 19'b10_0010_0000_0_0100_0011;	// Reuse for ENTER
	parameter rmod_rxp	= 19'b10_1001_0000_1_0000_0100;	// MODUL+0 read : SB , SP Update , therefore no LDEA
	parameter rmod_rtt	= 19'b10_1001_0000_0_0000_0100;	// MODUL+0 read : SB , no LDEA
	parameter rmod_4	= 19'b10_1011_0000_0_0001_0100;	// MODUL+4 read : Link Table Base
	parameter rmod_8	= 19'b10_1011_0000_0_0010_0100;	// MODUL+8 read : Program Base
	parameter rdltab	= 19'b10_1010_0000_0_1000_0000;	// Link table read - EA Phase
	parameter ea_push	= 19'b10_0110_0000_0_1010_0011;	// CXP : 2. Push EA Phase
	parameter ea_min8	= 19'b10_1010_0000_0_1011_0011;	// CXP : reuse of MOD+8
	parameter pop_ru	= 19'b10_1010_0010_0_0000_1011;	// RXP : EA Phase MOD POP
	parameter rd_icu	= 19'b00_1001_0000_0_1100_0010;	// Read ICU : Byte of fix address
	parameter get_vec	= 19'b10_1001_0000_0_01xx_0000;	// Read Exception-Vector : Index Exception No.
	parameter get_veci	= 19'b10_1001_0110_0_0000_0000;	// Read Exception-Vector : Index external Interrupt
	parameter load_ea	= 19'b10_0010_0000_0_0000_0000;	// used for store of TEAR and MSR
	parameter save_msr	= 19'b10_0010_0001_0_0000_0000;	// used for store of TEAR and MSR
	parameter ivar_adr	= 19'b10_0000_0100_0_0000_0010;	// only pass SRC1
	parameter st_trans	= 19'b00_1001_0100_0_0000_0000;	// Translate at String : SRC1 + SRC2 , Byte
	parameter src_x		= 7'hxx;
	parameter dest_x	= 6'hxx;
	parameter imme		= {1'b1,6'hxx};
	parameter frame		= 7'h18;
	parameter ibase		= 7'h1E;
	parameter modul		= 7'h1F;
	parameter w_msr		= 6'h0A;
	parameter w_tear	= 6'h0B;
	parameter fsr_r		= 6'h17;	// not defined register for FSR for opcodes LFSR and SFSR
	parameter temp_l	= 6'h3C;
	parameter temp_h	= 6'h3D;	// second last space for 8B TEMP register
	parameter temp_1	= 6'h3E;	// Backup for register at String operations
	parameter temp_2	= 6'h3F;
	parameter rtmpl		= 7'h3C;
	parameter rtmph		= 7'h3D;
	parameter rtmp1		= 7'h3E;
	parameter rtmp2		= 7'h3F;
	parameter op_mov	= 11'h345;
	parameter op_adr	= 11'h349;
	parameter op_add	= 11'h340;	// for CXP
	parameter op_flip	= 11'h364;	// for CXP : LSHD -16,Ri
	parameter op_lmr	= 11'h36A;	// for LPR CFG, LMR and CINV
	parameter op_wrp	= 11'h387;	// for CXP : write PSR , used also for Exception processing
	parameter op_ldp	= 11'h388;	// for RETT and RETI : load of PSR from Stack
	parameter op_zex	= 11'h076;	// Zero Extension for ICU Vector - is also used at String Option "T"
	parameter op_cop	= 8'hDD;	// Coprozessor Opcode
 
	// ++++++++++++++++++++++++++  The switch logic for the state machine  +++++++++++++++++++++++++++++
 
	always @(ANZ_VAL)
		case (ANZ_VAL)
		  3'd0  : valid = 3'b000;
		  3'd1  : valid = 3'b001;
		  3'd2  : valid = 3'b011;
		default : valid = 3'b111;
		endcase
 
	assign next = ( PHASE_0 ? op_ok :		// Opcode decoded or Exception processed
						// Displacement or Immediate operand and external memory access can happen in parallel
						// i.e. addressing mode Memory Relative
				    (  ((~dim_feld[0] | ACC_DONE) & (~dim_feld[3] | di_stat[0]))	// ACC_DONE resets dim_feld
						// long operation
				     & ~(long_reg & ~DONE) ) )
						// hard break : abort or fpu_trap or dvz_trap or ovf_flag
				  | abbruch ;
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) long_reg <= 1'b0;
		  else
			long_reg <= next ? do_long : long_reg;	// START[1]
 
	always @(posedge BCLK or negedge BRESET)	// the central phase register
		if (!BRESET) phase_reg <= 8'h0;
		  else
			if (next) phase_reg <= new_op[47:40];
 
	assign PHOUT = phase_reg;	// only to debug
 
	always @(*)	// next switch of micro program counter
		casex ({PHASE_0,op_ok,dim_feld[3],di_stat[0]})
		  4'b11_xx : USED = {1'b0,~op_1byte,(op_1byte | op_3byte)} + {2'd0,opt_imme};
		  4'b0x_11 : USED = di_stat[3:1];
		  default  : USED = 3'd0;
		endcase
 
	// Special phases
 
	assign PHASE_0 = (phase_reg == 8'h00);	// During Phase 0 the opcode is decoded
 
	assign NEXT_PCA = PHASE_0 & ~ovf_flag & ~dbg_flag;
 
	// Pulse to transfer from Trace Bit to Pending Trace Bit, only once in the beginning of phase 0
	// The priority is such that a TRACE exception is served before an UNDEFINED/ILLEGAL exception
	always @(posedge BCLK) no_t2p <= PHASE_0 & ~op_ok;
	assign t2p = PHASE_0 & ~no_t2p;	// signal to I_PFAD
 
	// ++++++++++++++++++++++++++  global control signals  ++++++++++++++++
 
	assign de_flag   = CFG[8];
	assign ivec_flag = CFG[0];
	assign dvz_trap  = TRAPS[1];
	assign fpu_trap  = TRAPS[0];
 
	always @(posedge BCLK) nmi_reg	<= {nmi_reg[0],NMI_N};	// one clock sync and than falling edge detection
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) nmi_flag <= 1'b0;
		  else nmi_flag <= (nmi_reg == 2'b10) | (nmi_flag & ~(phase_reg == 8'h82));
 
	always @(posedge BCLK) int_flag <= PSR[11] & ~INT_N;	// one clock to synchronise
 
	assign stop		 = (int_flag | nmi_flag) &   PHASE_0 & ~stop_d;		// neccesary if FPU_TRAP and INT at the same time
	assign interrupt = (int_flag | nmi_flag) & (~PHASE_0 |  stop_d);
 
	always @(posedge BCLK or negedge BRESET) 
		if (!BRESET) stop_d <= 1'd0;
		  else stop_d <= stop;
 
	// ++++++++++++++++++++++++++  Exception processing  +++++++++++++++
 
	// IC_ABORT is valid if Opcode Decoder cannot continue
	assign iabo_fall = IC_ABORT & (PHASE_0 ? ~op_ok : (~di_stat[0] & dim_feld[3]));
 
	always @(posedge BCLK) iabort  <= iabo_fall & ~ia_save;	// DC_ABORT ist a pulse
	always @(posedge BCLK) ia_save <= iabo_fall;
 
	// mmu_sel is used in ADDR_UNIT
	always @(posedge BCLK) mmu_sel <= DC_ABORT | (mmu_sel & ~iabort);	// 1 = DCACHE , 0 = ICACHE
	assign MMU_UPDATE[0] = mmu_sel;
 
	assign abort = DC_ABORT | iabort;
 
	// that is the end of String loops where interrupts are checked : 8'hC7 & 8'hCF
	assign string_ende = (phase_reg[7:4] == 4'hC) & (phase_reg[2:0] == 3'b111);	// attention : 8'hCF does not exist
 
	always @(posedge BCLK) if (PHASE_0 || string_ende) type_nmi <= nmi_flag;	// during processing kept stable
 
	assign svc_flag  = (OPREG[7:0] == 8'hE2) & valid[0];	// Vector  5 : 0101 , Illegal Vector  4 : 0100
	assign bpt_flag  = (OPREG[7:0] == 8'hF2) & valid[0];	// Vector  8 : 1000 , Undefined Vec. 10 : 1010
	assign flag_flag = (phase_reg  == 8'h89) & flag;		// Vector  7 - has an own state
	assign trac_flag = t2p & PSR[10];						// Vector  9 : 1001 , PSR[10] = P Bit , Pending Trace
	assign ovf_flag  = (ovf_pipe[3] & flag) | (ovf_pipe[1] & TRAPS[2]);		// Vector 13 : 1101
	assign dbg_flag  = dbg_trap | (dbg_s & PHASE_0);		// Vector 14 : 1110
 
	// abort + dvz_trap during a opcode, fpu_trap + ovf_flag + dbg_flag later
	assign abbruch  = abort | fpu_trap | dvz_trap | ovf_flag | dbg_flag;	// this 5 stop everything
	assign abbruch2 = abort | fpu_trap | dvz_trap | ovf_flag;	// for exc_vector generation
 
	// forces the next step of state machine (op_ok), generates otype="11" for Trap Service
	assign exception = interrupt | svc_flag | bpt_flag | ILL | UNDEF | trac_flag | abbruch;	
 
	// a TRACE Exception is done before the opcode execution
	assign misc_vectors = trac_flag ? 4'h9 : {(bpt_flag | UNDEF),(svc_flag | ILL),UNDEF,svc_flag};	// the vectors are exclusiv
 
	always @(posedge BCLK)
		if (PHASE_0 || abbruch)	// ABORTs, fpu_trap, dvz_trap + ovf_flag can happen every time
		  begin
			exc_vector <= abbruch ? (abbruch2  ? {ovf_flag,(dvz_trap | ovf_flag),~ovf_flag,(fpu_trap | ovf_flag)} : 4'hE)
								  : (interrupt ? {3'b0,nmi_flag} : misc_vectors);	// misc_vectors is default
		  end
		  else
		    if (flag_flag) exc_vector <= 4'h7;	// FLAG-Trap
		      else
				if (interrupt && string_ende) exc_vector <= {3'b0,nmi_flag};
 
	assign psr_code[2] = ~psr_code[1];						// Absicht : codiert das Sichern des PSR bei Exception-Entry 
	assign psr_code[1] = abort | ILL | UNDEF | trac_flag;	// enable for reseting the P-Bit during write of PSR to stack
	assign psr_code[0] = (interrupt & ~fpu_trap) | abort;	// enable for reseting the I-Bit of new PSR
 
	// valid codes are x'89 to x'8F
	assign op_psr = {8'b0_00_1000_1,psr_code};	// is used during first clock cylce after exception, is transfered as OPCODE to I_PFAD
 
	// Specialitiies : ABORT stores address & flags , the Interrrupts read vectors : all is used in big CASE
	assign abo_int = (exc_vector == 4'h2) | (exc_vector[3:1] == 3'b000);
	assign ai_next = (exc_vector == 4'h2) ? {load_ea,8'h84,4'h0} : {rd_icu,8'h82,4'h1};
 
	assign save_pc = {7'b10_0010_0,dia_flag,7'b00_0_0000,dia_flag,3'b001};	// Exception : PC_ARCHI => EA, special case DIA
	assign no_trap = ~fpu_trap & ~ovf_flag & ~dbg_flag;	// suppresion of WREN and LD_OUT[1] and ADDR_UNIT operation
 
	// ++++++++++++++++++++++++++  Overflow Trap  ++++++++++++++
 
	always @(posedge BCLK)
		if (ovf_flag || !PSR[4]) ovf_pipe <= 4'd0;
		  else
			if (PHASE_0) ovf_pipe <= {ovf_pipe[2],(ovf_op & op_ok),ovf_pipe[0],(ovf2_op & op_ok)};	// V-Bit switches on
 
	assign ovf_op =  ( ((OPREG[6:2] == 5'b000_11)	// ADDQi
					  | (OPREG[3:2] == 2'b00)) & (OPREG[1:0] != 2'b10))		// ADDi,ADDCi,SUBi,SUBCi
					| ((OPREG[7:0] == 8'h4E) & OPREG[13] & (OPREG[11:10] == 2'b00))	// NEGi,ABSi
					| ((OPREG[7:0] == 8'hEE) & ~OPREG[10]);	// CHECKi
 
	assign ovf2_op =  ((OPREG[6:2] == 5'b100_11) & (OPREG[1:0] != 2'b10))	// ACBi, these overflows have no FLAG
					| ((OPREG[13:10] == 4'h1) & (OPREG[7:0] == 8'h4E))	// ASHi
					| ( OPREG[13] & (OPREG[11] == OPREG[10]) & (OPREG[7:0] == 8'hCE)); // MULi,DEIi,QUOi,DIVi
 
	// ++++++++++++++++++++++++++  Debug Trap  ++++++++++++++
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) dbg_s <= 1'b0;
		  else dbg_s <= dbg_trap | (dbg_s & ~((exc_vector == 4'hE) & (phase_reg == 8'h81)));
 
	always @(posedge BCLK) dbg_en <= op_ok | ~PHASE_0;
 
	assign pc_match = dbg_en & TRAPS[3] & PHASE_0 & ~exception;	// TRAPS[3] is only combinatorical
 
	always @(posedge BCLK) dbg_trap <= (pc_match | (addr_cmp & PHASE_0)) & TRAPS[5];	// TRAPS[5] = Enable Trap
 
	always @(posedge BCLK) addr_cmp <= TRAPS[4] | (addr_cmp & ~PHASE_0);	// TRAPS[4] = CAR HIT
 
	// ++++++++++++++++++++++++++  Special case String Abort  ++++++++++++++
 
	// Flags cleared if entry and exit of string operation and during  Abort sequence, not valid for MOVM/CMPM
	// special case UNTIL/WHILE : reset if exit (op_feld_reg[17] = 1 = UNTIL)
	assign clr_sflag = 	   (phase_reg == 8'hC0) | (phase_reg == 8'hC7) | (phase_reg == 8'hC8) | (phase_reg == 8'h81)
					   | (((phase_reg == 8'hD7) | (phase_reg == 8'hDF)) & ~(STRING[3] ^ op_feld_reg[17])) ;
	assign set_src	 =     (phase_reg == 8'hC1) | (phase_reg == 8'hC9);
	assign set_dest	 =     (phase_reg == 8'hC4) | (phase_reg == 8'hCC);
 
	always @(posedge BCLK or negedge BRESET)	// R1 is modified
		if (!BRESET) ssrc_flag <= 1'b0;
		  else ssrc_flag <= (set_src & ~kurz_st) | (ssrc_flag & ~clr_sflag);
 
	always @(posedge BCLK or negedge BRESET)	// R2 is modified
		if (!BRESET) sdest_flag <= 1'b0;
		  else sdest_flag <= (set_dest & ~kurz_st) | (sdest_flag & ~clr_sflag);
 
	assign rrepa = {7'b1000_011,~sdest_flag};	// R1 and if necessary R2 restore
 
	// ++++++++++++++++++++++++++  The one byte opcodes  +++++++++++++++++++
 
	// The one byte opcodes have a special case : one byte opcode but the second byte should be valid too
	// Used with SAVE, RESTORE, ENTER and EXIT with their reg list. 
	// The advantage is that the reg list is store in op_feld_reg.
 
	//	[52:34]	addressing
	//	[33:20] register
	//	[19:18]	1 or 2 Byte opcode
	//	[17:16]	BSR/BR
	// 	 [15:8]	next phase
	//	  [7:4]	START + LD_OUT
	//	  [3:0]	operand access : Displacement or Speicher
 
	always @(*)		// SVC (E2) and BPT (F2) decode as exception
		casex (OPREG[7:0])
			8'hxA : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b01,8'h01,4'h0,4'hE};	// Bcc , DISP read
			8'h02 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b10,8'h01,4'h0,4'hE};	// BSR , DISP read
			8'h12 : op1_feld = {pop_op  , src_x, stack, 2'b01,2'b00,8'h2A,4'h0,4'h1};	// RET , DISP later
			8'h22 : op1_feld = {rmod_4	, src_x, modul, 2'b01,2'b00,8'h35,4'h0,4'h1};	// CXP
			8'h32 : op1_feld = {pop_op,   src_x, stack, 2'b01,2'b00,8'h40,4'h0,4'h1};	// RXP
			8'h42 : op1_feld = {pop_op,	  src_x, stack, 2'b01,2'b00,8'h46,4'h0,4'h1};	// RETT
			8'h52 : op1_feld = {rd_icu,	  src_x, src_x, 2'b01,2'b00,8'h45,4'h0,4'h1};	// RETI
			8'h62 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h30,4'h0,4'h0};	// SAVE
			8'h72 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0};	// RESTORE
			8'h82 : op1_feld = {push_op , frame, stack, 2'b10,2'b00,8'h2D,4'h2,4'h1};	// ENTER : PUSH FP
			8'h92 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0};	// EXIT : POP FP
			8'hA2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h00,4'h0,4'h0};	// NOP
			8'hB2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0};	// WAIT
			8'hC2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0};	// DIA
			8'hD2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h89,4'h0,4'h0};	// FLAG
		  default : op1_feld = {19'hxxxxx,14'hxxxx,     2'b00,2'b00,16'hxxxx};
		endcase
 
	assign op_1byte  = op1_feld[18] & valid[0];
	assign op_12byte = op1_feld[19] & valid[1];
 
	assign new_addr = op1_feld[52:34];
	assign new_regs = op1_feld[33:20];
	assign new_ph   = op1_feld[15:8];
	assign new_nx   = op1_feld[7:0];	// at Bcond DISP read
 
	assign pop_fp	= new_fp ? pop_op : addr_nop;
	assign ppfp		= new_fp ? 8'h34 : 8'h00;
 
	always @(posedge BCLK)
		if (PHASE_0)
		  begin
			ex_br_op	<= op1_feld[17:16];	// BSR/BR
			cc_feld		<= OPREG[7:4];
			new_fp		<= (OPREG[7:6] == 2'b10);	// not decoded complete but is sufficient
			reti_flag	<= OPREG[4];		// only difference between RETI and RETT is important
			dia_op		<= OPREG[6];		// only difference between DIA and WAIT is important
		  end
 
	always @(posedge BCLK) dia_flag <= dia_op & (phase_reg == 8'h88);	// special case DIA compared to WAIT : Addr DIA to Stack
 
	always @(posedge BCLK)	// Format 1 opcodes write always DWord to reg, the same is true for Exceptions
		if (PHASE_0 || abbruch) format1 <= (valid[0] & (OPREG[3:0] == 4'h2)) | exception;
		  else
			if (flag_flag || (interrupt && string_ende)) format1 <= 1'b1;
 
	//					Branch etc.				CXP						CXPD
	assign store_pc = (phase_reg == 8'd1) | (phase_reg == 8'h37) | (phase_reg == 8'h6B);	// only save in DIN Reg of DATENPFAD
	assign jump = (ex_br_op[0] & branch) | (acb_reg & ~ACB_ZERO) | ex_br_op[1];
 
	always @(posedge BCLK) ldpc_phase <=  (phase_reg == 8'h3E)	// PC load at CXP/Traps , all one clock cycle guaranted
										| (phase_reg == 8'h43)	// PC load at RXP
										| ((phase_reg == 8'h49)	& reti_flag)	// PC load at RETI
										| ((phase_reg == 8'h4E) & next)	// PC load at RETT - here not one clock cycle guaranted
										| (phase_reg == 8'h66)	// PC load at JUMP/JSR/CASE
										| (phase_reg == 8'h7B);	// PC load at DE = Direct Exception
 
	assign NEW = ((phase_reg == 8'd1) &  jump & di_stat[0]) | LOAD_PC;
	assign LOAD_PC = ((phase_reg == 8'h2B) & di_stat[0])	// only one pulse, but DISP must be ok => di_stat[0] (RET)
					| ldpc_phase;
 
	assign no_modul = de_flag ? {1'b0,dest_x} : {1'b1,modul[5:0]};
 
	assign negativ	 = PSR[7];
	assign zero      = PSR[6];
	assign flag		 = PSR[5];
	assign larger	 = PSR[2];
	assign carry_psr = PSR[0];
 
	assign rett_exc = ~reti_flag & (phase_reg == 8'h4B);	// special case RETT : Stack can change during opcode
	always @(posedge BCLK) phase_exc <= (phase_reg == 8'h80);	// 1. Exception phase
	always @(negedge BCLK) if (PHASE_0 || phase_exc || rett_exc) s_user <= PSR[9];	// Select Bit for Stack, delayed update
	always @(negedge BCLK)
		if (PHASE_0 || phase_exc) s_mod <= {PSR[9],~PSR[9]};
		  else
			if (rett_exc) s_mod <= s_mod | {PSR[9],~PSR[9]};	// Both can be updated
 
	always @(cc_feld or zero or carry_psr or larger or negativ or flag)
		case (cc_feld)
		  4'h0 : branch =  zero;		// EQual
		  4'h1 : branch = ~zero;		// Not Equal
		  4'h2 : branch =  carry_psr;	// Carry Set
		  4'h3 : branch = ~carry_psr;	// Carry Clear
		  4'h4 : branch =  larger;		// Higher
		  4'h5 : branch = ~larger;		// Lower or Same
		  4'h6 : branch =  negativ;		// Greater Than
		  4'h7 : branch = ~negativ;		// Less or Equal
		  4'h8 : branch =  flag;		// Flag Set
		  4'h9 : branch = ~flag;		// Flag Clear
		  4'hA : branch = ~larger  & ~zero;	// LOwer
		  4'hB : branch =  larger  |  zero;	// Higher or Same
		  4'hC : branch = ~negativ & ~zero;	// Less Than
		  4'hD : branch =  negativ |  zero;	// Greater or Equal
		  4'hE : branch = 1'b1;			// True
		  4'hF : branch = 1'b0;			// False
		endcase
 
	// +++++++++++++++++++++++  Register List Processing  ++++++++++++++++++++++++++++
 
	always @(posedge BCLK) init_rlist <= PHASE_0 | (phase_reg == 8'h2E);
 
	always @(posedge BCLK)
		if (PHASE_0) rpointer <= 3'b000;
		  else
			if (ACC_DONE || init_rlist) rpointer <= reg_nr;
 
	REG_LIST scanner ( .DIN(op_feld_reg[22:15]), .INIT(init_rlist), .IPOS(rpointer), .VALID(save_reg), .OPOS(reg_nr) );
 
	assign saver = {4'h0,reg_nr};
 
	always @(posedge BCLK) if (ACC_DONE || init_rlist) resto <= {3'h0,~reg_nr};	// EXIT and RESTORE have the list mirrored : R0...R7
 
	// ++++++++++++++++++++++++++  Processing of Displacement and Immediate Operand  +++++++++++++++++++
 
	always @(posedge BCLK or negedge BRESET)	// Flag for DISP and IMME access
		if (!BRESET) dim_feld[3] <= 1'b0;
		  else dim_feld[3] <= next ? new_op[3] : ~di_stat[0] & dim_feld[3];
 
	always @(posedge BCLK) if (next) dim_feld[2:1] <= new_op[2:1];
 
	always @(posedge BCLK or negedge BRESET) 	// Flag for external access
		if (!BRESET) dim_feld[0] <= 1'b0;
		  else dim_feld[0] <= next ? new_op[0] : ~ACC_DONE & dim_feld[0];
 
	// special case QWORD, last term for security
	always @(posedge BCLK) qw_flag <= dim_feld[0] & ACC_DONE & (ACC_FELD[13:12] == 2'b11) & ~qw_flag;
 
	assign LD_IMME = (dim_feld[3] & (dim_feld[2:1] != 2'b11)) | short_op | store_pc;	// Data multiplexer
	assign LD_DIN  =  (di_stat[0] & dim_feld[3] & (dim_feld[2:1] != 2'b11))				// Enable for DIN Register
					| (ACC_DONE   & dim_feld[0]) | qw_flag | short_op | store_pc;		// next not possible : i.e. immediate and disp parallel
	assign ld_disp = (dim_feld[3:1] == 3'b111);											// Enable for DISP Register
 
	// Signal to ADDR_UNIT , only Displacement critical
	assign disp_ok = ld_disp ? di_stat[0] : 1'b1;
 
	always @(dim_feld or OPREG or valid or ANZ_VAL)	// Bit 0 is "Data ok", the upper 3 bits are for USED
		casex ({dim_feld[2:1],OPREG[7:6]})
		  4'b00_xx : di_stat = {3'b001,valid[0]};
		  4'b01_xx : di_stat = {3'b010,valid[1]};
		  4'b10_xx : di_stat = {3'b100,ANZ_VAL[2]};
		  4'b11_0x : di_stat = {3'b001,valid[0]};
		  4'b11_10 : di_stat = {3'b010,valid[1]};
		  4'b11_11 : di_stat = {3'b100,ANZ_VAL[2]};
		endcase
 
	always @(OPREG)
		casex (OPREG[7:6])
		  2'b0x : disp_val = {{26{OPREG[6]}},OPREG[5:0]};
		  2'b10 : disp_val = {{19{OPREG[5]}},OPREG[4:0],OPREG[15:8]};
		  2'b11 : disp_val = {{3{OPREG[5]}},OPREG[4:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
		endcase
 
	assign DISP_BR = disp_val;	// DISP is also used for Bcc opcode
 
	// The generator for DISP : data is used in ADDR_UNIT
	always @(*)
		casex ({ld_disp,disp_sel})	//	disp_sel from new_op
		  5'b1_00xx : DISP = disp_val;
		  5'b1_01xx : DISP = 32'h0 - disp_val;	// special case for ENTER
		  5'b1_1xxx : DISP = {disp_val[29:0],2'b00};	// DISP*4 for External Address Mode
		  5'b0_11xx : DISP = {20'hFFFFF,3'h7,type_nmi,8'h00};	// Interrupt Service Address
		  5'b0_1000 : DISP = 32'hFFFF_FFFF;		// PUSH Byte
		  5'b0_1001 : DISP = 32'hFFFF_FFFE;		// PUSH Word
		  5'b0_1010 : DISP = 32'hFFFF_FFFC;		// PUSH DWord
		  5'b0_1011 : DISP = 32'hFFFF_FFF8;		// PUSH QWord
		  5'b0_01xx : DISP = {26'h0,exc_vector,2'b00};		// the exception vector as Offset for INTBASE
		  5'b0_00xx : DISP = {28'h0,disp_sel[1:0],2'b00};	// 0,+4,+8,+12 used with MOD, default is 0
		endcase
 
	always @(*)
		casex ({short_op,dim_feld[2:1]})
		  3'b000 : imme_i = op_setcfg ? {28'h0000_00F,OPREG[2:0],setcfg_lsb} : {24'hxx_xxxx,OPREG[7:0]};
		  3'b001 : imme_i =    {16'hxxxx,OPREG[7:0],OPREG[15:8]};
		  3'b01x : imme_i = {OPREG[7:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
		  3'b1xx : imme_i = opt_imme ? {24'hxxxx_xx,opti_byte} : {{29{OPREG[10]}},OPREG[9:7]};	// for MOVQ etc. only OPREG can be used
		endcase
 
	assign IMME_Q = store_pc ? PC_SAVE : imme_i;
 
	// ++++++++++++++  Stack Control  +++++++++++++++++
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) new_spsel <= 1'b0;
		  else new_spsel <= spupd | (new_spsel & ~PHASE_0 & ~fpu_trap & ~dvz_trap);
 
	always @(posedge BCLK) upd_info <= PHASE_0 & new_spsel;	// one clock cycle earlier a change occurs, i.e. ADDF TOS,F0 => fpu_trap
 
	assign do_xor = fpu_trap ? upd_info : (PHASE_0 & new_spsel);
 
	always @(negedge BCLK or negedge BRESET)
		if (!BRESET) stack_sel <= 2'b00;
		  else
			if (do_xor) stack_sel <= stack_sel ^ s_mod;
 
	// Special case RETT
	always @(posedge BCLK) if (!phase_reg[1]) old_su <= s_user;	// is tested in state x'49 and used in x'4B
	assign ttstak = {1'b0,((old_su == PSR[9]) ^ stack_sel[PSR[9]]),3'b110,PSR[9],1'b1};
 
	// ++++++++++++++  2 byte opcodes  +++++++++++++++++
 
	// Hint : short_op is decoded separatly
 
	// [47:45]	Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
	// [44:42]	Destination : like [47:45]
	// 	  [41]	long opcode	[41:39] only for standard sequenz - not Gruppe 2
	//    [40]	src2_flag - Source 2 is read
	// 	  [39]	dest_flag - a target operand exists
	// [38:33]	src1_r Register field, no message about Immediate
	// [32:27]	src2_r Register field
	// [26:25]	src1_le Length of Source1 - this is used for qword
	// [24:23]	src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE 
	// [22:18]	src1 field
	// [17:13]	src2 field
	// [12:11]	op_type 2 Bit for sort of opcode
	//    [10]	FL : F=1/L=0
	//   [9:8]	original BWD : B=00/W=01/D=11
	//   [7:0]	opcode: operation code
 
	assign valid_size = (OPREG[1:0] != 2'b10) & valid[1];	// valid size + valid OPREG-Bytes
 
	assign hzl_a = (OPREG[1:0] == 2'b11) ? 2'b10 : OPREG[1:0];	// length field recoded
	assign hzl_b = {1'b0,OPREG[1:0]};		// standard Length field
	assign hzr_a = {3'b000,OPREG[13:11]};	// SRC2 or SRC1 regfield
	assign hzr_b = {3'b000,OPREG[8:6]};		// SRC2 regfield
	assign hzr_s = {((OPREG[15:11] == 5'h17) ^ stack_sel[s_user]),3'b110,s_user,1'b1};	// USER or SUPERVISOR Stack, TOS special case
	// Special case LPR & SPR regfield:
	always @(OPREG or stack_sel or s_user)
		casex ({OPREG[10:7]})
		  4'b1001 : hzr_c = {stack_sel[s_user],3'b110,s_user,1'b1};	// USER or SUPERVISOR Stack
		  4'b1011 : hzr_c = {stack_sel[1]	  ,3'b110,1'b1,  1'b1};	// USER Stack
		  4'b1100 : hzr_c = OPREG[6] ? temp_h : 6'h1C;	// CFG special case : LPR : SPR
		  default : hzr_c = {2'b01,OPREG[10:7]};
		endcase
 
	// Unfortunately SETCFG must be implemented : it is transformed to a two byte opcode with one byte IMM operand
	assign setcfg = (OPREG[13:0] == 14'h0B0E) & valid[1];
 
	always @(*)
	  casex ({setcfg,OPREG[10:2]})
		// Short-Op Codes , ACB is an ADD with following jump
		10'b0xxxx_x0011 : op2_feld = {6'o11,3'o3,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h40};	// ADDQ ACB
		10'b0xxxx_00111 : op2_feld = {6'o11,3'o2,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h41};	// CMPQ
		10'b0xxxx_01011 : op2_feld = {6'o11,3'o1,hzr_c,hzr_a,hzl_a,hzl_a,5'h00,OPREG[15:11],2'b00,hzl_b,8'h45};	// SPR
		// Scond is moving the SHORT operand in the Integer area as condition field
		10'b0xxxx_01111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h7A};	// Format 7, A=(UNDEF)
		10'b0xxxx_10111 : op2_feld = {6'o11,3'o1,6'hxx,hzr_a,hzl_a,hzl_a,5'h14,OPREG[15:11],2'b00,hzl_b,8'h45};	// MOVQ
		10'b0xxxx_11011 : op2_feld = {6'o11,3'o1,hzr_a,hzr_c,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h76};	// LPR => MOVZiD
		// Format 3 opcodes :
		10'b00x10_11111 : op2_feld = {6'o11,3'o1,hzr_a,6'h1D,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b00,hzl_b,4'h3,OPREG[10:7]}; // BIC/SPSR
		10'b0x100_11111 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // JUMP/JSR
		10'b01110_11111 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CASE
		// Format 4 opcodes : main group
		10'b0xxxx_xxxx0 : op2_feld = {6'o11,3'o3,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6],		2'b00,hzl_b,4'h4,OPREG[5:2]};
		10'b0xxxx_x0001 : op2_feld = {6'o11,3'o2,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6],		2'b00,hzl_b,4'h4,OPREG[5:2]}; //CMP no WR
		10'b0xxxx_x0101 : op2_feld = {6'o11,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6],		2'b00,hzl_b,4'h4,OPREG[5:2]}; //MOV no 2.Op
		10'b0xxxx_x1101 : op2_feld = (OPREG[10:9] == 2'b00) ?	// target is Register => standard flow
									 {6'o11,3'o2,hzr_a,hzr_b,hzl_a,2'bxx,OPREG[15:6],		2'b00,hzl_b,4'h4,OPREG[5:2]}	// TBIT
								   : {6'o14,3'o2,hzr_a,hzr_b,hzl_a,2'b00,OPREG[15:6],		2'b10,hzl_b,4'h4,OPREG[5:2]};
		// ADJSPi
		10'b01010_11111 : op2_feld = {6'o11,3'o3,hzr_a,hzr_s,hzl_a,2'b10,OPREG[15:11],5'h00,2'b00,hzl_b,8'h48};	// is a SUBD
		// ADDR, length field not valid
		10'b0xxxx_x1001 : op2_feld = {6'o61,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:6],		2'b00,hzl_b,8'h49};
		10'b00000_11111 : op2_feld = {6'o71,3'o1,hzr_a,hzr_b,hzl_a,hzl_a,OPREG[15:11],5'h00,2'b10,hzl_b,4'h3,OPREG[10:7]}; // CXPD no Opcode
		// SETCFG => MOV Befehl , SRC1 is genrated for 32 bit , target is Register temp_h
		10'b1xxxx_xxxxx	: op2_feld = {40'b001001_001_000000_111101_00_10_10100_00000_00_011,			8'h76};
		default	 		: op2_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
	  endcase
 
	assign op_2byte = (valid_size | setcfg) & ~op2_feld[7];	// it must be for sure shown "Invalid Opcode"
 
	// Special case : the quick opcodes with the exception SPR and LPR
	assign short_op = ((((~OPREG[5]) | (OPREG[6:4] == 3'b011)) & (OPREG[3:2] == 2'b11) & valid_size) | opt_imme) & PHASE_0;
	always @(posedge BCLK) if (PHASE_0) short_op_reg <= short_op;
	assign short_def =  PHASE_0 ? short_op : short_op_reg;							// for the big state machine
	assign op_sho = (OPREG[6:4] == 3'b011) ? 11'h07A : op_mov;	// Special case Scond at Index as Dest. , used only in Phase 0
 
	// 2. special case ACB
	assign acb_op = (OPREG[6:2] == 5'h13) & valid_size;
	always @(posedge BCLK) if (PHASE_0) acb_reg <= acb_op;
	assign acb_flag = PHASE_0 ? acb_op : acb_reg;
	assign goacb = acb_flag ? 8'h28 : 8'h00;	// x'28 = 40 , wait jump at REG operation - short-op special case
 
	// 3. special case load of PSR and Init-Done opcodes : because of U bit in PSR a restart must follow,
	// CINV and LMR PTB must wait until Init-Done and than Restart.
	// All variants of LPR and BIC/S have an extra cycle due to TRACE operation
	always @(OPREG)
		casex (OPREG[18:0])
		  19'bxxx_xxxxx_1101_110_11_xx : waitop = 9'h14C;	// LPRi PSR,...
		  19'bxxx_xxxxx_1100_110_11_xx : waitop = 9'h174;	// LPRi CFG,...
		  19'bxxx_xxxxx_0x10_111_11_xx : waitop = 9'h14C;	// BICPSRi/BISPSRi ...
		  19'bxxxx_x_0010_xx_0000_1110 : waitop = 9'h174;	// SETCFG []
		  19'bxxxx_0_0010_xx_0001_1110 : waitop = 9'h174;	// LMR  - at the end Restart
		  19'bxxxx_0_1001_xx_0001_1110 : waitop = 9'h174;	// CINV - at the end Restart
		  default					   : waitop = 9'h000;
		endcase
 
	assign dowait = waitop[7:0];	// is used in Phase 0 if PSR is loaded from Register
	always @(posedge BCLK) if (PHASE_0) wait_reg <= waitop;
 
	// Here 2. and 3. special case are coming together:
	// Phase definition, end over jump for ACB , not used in Phase 0
	assign endea = acb_reg ? 8'h01 : (wait_reg[8] ? wait_reg[7:0] : 8'h00);	
	assign diacb = acb_reg ? 4'hE : 4'h0;	// load Disp ?
 
	// special case ADJSPi : SP=SRC2 always 32 Bit
	always @(posedge BCLK)
		if (PHASE_0) dw_info <= (OPREG[10:2] == 9'b1010_11111);
		  else dw_info <= dw_info & ~phase_reg[7];	// for security at ABORT
 
	// SETCFG : Flag to transform the Byte Immeadiate operand
	always @(posedge BCLK) if (PHASE_0) op_setcfg  <= setcfg;
	always @(posedge BCLK) if (PHASE_0) setcfg_lsb <= OPREG[15];
 
	always @(posedge BCLK) if (PHASE_0) jsr_flag <= (OPREG[10:2] == 9'b1100_11111);		// JSR : for PUSH
	always @(posedge BCLK)	// Bit opcodes to Register and EXT:SRC1 / INS:SRC2
		if (PHASE_0) bit_reg  <= ((OPREG[3] ? ((OPREG[7:6] == 2'd0) ? OPREG[23:22] : OPREG[18:17]) : OPREG[10:9]) == 2'b00);
	always @(posedge BCLK) if (PHASE_0) exin_cmd <= (~OPREG[10] & (OPREG[6:0] == 7'h2E)) & valid[2];
	always @(posedge BCLK) if (PHASE_0) extract <= ~OPREG[7];
	always @(posedge BCLK) if (PHASE_0) inss_op <= (OPREG[13:10] == 4'h2) & (OPREG[7:0] == 8'hCE) & valid[2];	// INSS
 
	// ++++++++++++++  3 byte opcodes  +++++++++++++++++
 
	// [47:45]	Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
	// [44:42]	Destination : like [47:45]
	// 	  [41]	long opcode	[41:39] only for standard sequenz - not Gruppe 2
	//    [40]	src2_flag - Source 2 is read
	// 	  [39]	dest_flag - a target operand exists
	// [38:33]	src1_r Register field, no message about Immediate
	// [32:27]	src2_r Register field
	// [26:25]	src1_le Length of Source1 - this is used for qword
	// [24:23]	src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE 
	// [22:18]	src1 field
	// [17:13]	src2 field
	// [12:11]	op_type 2 Bit for sort of opcode
	//    [10]	FL : F=1/L=0
	//   [9:8]	original BWD : B=00/W=01/D=11
	//   [7:0]	opcode: operation code
 
	assign hdx_a = OPREG[7] ? OPREG[8] : OPREG[10];
	assign hdo_a = OPREG[13:10];
	assign hdo_c = {1'b0,OPREG[10],OPREG[7:6]};	// Format 8 opcodes
	assign hdo_d = {6'b0101_00,OPREG[10],1'b0};	// CMPM/S or MOVM/S : 8'h52 or 8'h50
	assign hdo_e = {3'b011,OPREG[10]};	// Special codes for LOGB and SCALB due to DP_OUT datapath
	// Definitions of length
	assign hdl_a = {1'b0,OPREG[9:8]};	// i size, is used in OPER
	assign hdl_b = (OPREG[9:8] == 2'b11) ? 2'b10 : OPREG[9:8];	// recode length field, is used in ACC field
	assign hdl_c = OPREG[10:8];			// FL + BWD
	assign hdl_d = {1'b1,~hdx_a};		// length FP
	assign hdl_e = {OPREG[8],2'bxx};	// BWD don't care
	assign hdl_f = (OPREG[18:17] == 2'b00) ? OPREG[9:8] : {OPREG[8],~(OPREG[9] ^ OPREG[8])};	// exclusiv for DEI
	assign hdl_g = {(OPREG[9:8] != 2'b00),(OPREG[9:8] == 2'b00)};	// exclusiv for EXT/EXTS base operand
	assign hdl_h = {(OPREG[9:8] != 2'b00),(OPREG[9:8] != 2'b01)};	// exclusiv for CHECK bound operand
	// Register definitions
	assign hdr_a = {3'b000,OPREG[21:19]};	// SRC1 Integer Register
	assign hdr_b = {3'b000,OPREG[16:14]};	// SRC2 Integer Register
	assign hdr_c = hdx_a ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
	assign hdr_d = hdx_a ? {2'b10,OPREG[16:15],1'b0,OPREG[14]} : {2'b10,OPREG[16:14],1'b1};
	assign hdr_e = OPREG[11] ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
	assign hdr_f = OPREG[11] ? {2'b10,OPREG[16:14],1'b1}		   : {2'b10,OPREG[16:15],1'b0,OPREG[14]};
	assign hdr_g = {3'b000,OPREG[16:15],~OPREG[14]};	// exclusiv for DEI and MEI
	assign hdr_m = {3'b001,OPREG[17:15]};	// MMU Register Index 8-15
 
	always @(*)
		casex (OPREG[13:3])
		  11'b1000_xx_1100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};	// MULi
		  11'b000x_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a};	// ROTi,ASHi
		  11'b0101_xx_0100x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, 2'b00,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a};	// LSHi
		  11'b1x0x_xx_0100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a};	// NEGi,NOTi,ABSi,COMi
		  11'b010x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b01,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};	// MOVX/ZiW
		  11'b011x_xx_1100x : op3_feld = {6'o11,3'o1,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};	// MOVX/ZiD
		  11'b0001_xx_0110x : op3_feld = {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b00,hdl_a,4'h8,hdo_c};	// FFSi
	// Floating Point opcodes
		  11'b000x_xx_0011x : op3_feld = {6'o11,3'o5,hdr_a,hdr_d, hdl_b,hdl_d,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};	// MOVif
		  11'b010x_xx_0011x : op3_feld = {6'o11,3'o5,hdr_e,hdr_f, 2'b11,2'b10,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};	// MOVLF
		  11'b011x_xx_0011x : op3_feld = {6'o11,3'o5,hdr_e,hdr_f, 2'b10,2'b11,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};	// MOVFL
		  11'b10xx_xx_0011x : op3_feld = {6'o11,3'o5,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};	// ROUNDi,TRUNCi
		  11'b111x_xx_00111 : op3_feld = {6'o11,3'o5,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};	// FLOORi
		  11'b111x_xx_00110 : op3_feld = {6'o11,3'o5,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,op_cop};		// SEARCH
		  11'b0x00_0x_10111 : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// ADDf,SUBf
		  11'bxx00_0x_10110 : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop};		// Coprocessor
		  11'b1000_0x_10111 : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// DIVf
		  11'b1100_0x_10111 : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// MULf
		  11'b0010_0x_1011x : op3_feld = {6'o11,3'o6,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// CMPf
		  11'b0001_0x_10111 : op3_feld = {6'o11,3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// MOVf
		  11'bx101_0x_10111 : op3_feld = {6'o11,3'o1,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};	// NEGf,ABSf
		  11'b001x_11_00111 : op3_feld = {6'o11,3'o1,hdr_a,fsr_r, 2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h92};	// LFSR
		  11'b110x_11_00111 : op3_feld = {6'o11,3'o1,fsr_r,hdr_b, 2'b10,2'b10,5'b0,OPREG[18:14],2'b00,3'o3,8'h9C};	// SFSR
	// MMU opcodes
		  11'b0010_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00, 3'o3,8'h45};	// LMR
		  11'b0011_11_0001x : op3_feld = {6'o11,3'o1,hdr_m,hdr_a, 2'b10,2'b10,5'b0,OPREG[23:19],2'b00, 3'o3,8'h45};	// SMR
	// String opcodes
		  11'b000x_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14],     2'b10,hdl_c,hdo_d};	// MOVS,CMPS
		  11'b0011_xx_0000x : op3_feld = {6'o11,3'o0,6'hxx,6'hxx, 2'bxx,2'b10,OPREG[23:14],     2'b10,hdl_c,hdo_d};	// SKPS
	// Custom opcodes
		  11'bxx01_0x_10110 : op3_feld = {6'o11,3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,op_cop};
	// Integer Divisionen : QUOi REMi DIVi MODi and DEIi + MEIi
		  11'b11xx_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,hdo_a};
		  11'b10x1_xx_1100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_g, hdl_b,hdl_f,OPREG[23:14],2'b10,hdl_a,4'h7,hdo_a};	// DEI/MEI
	// Gruppe 2 opcodes
		  11'b0x11_xx_1010x : op3_feld = {6'o77,3'o1,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,8'h45};		// MOVUS,MOVSU
		  11'b000x_xx_1100x : op3_feld = {6'o66,3'o0,hdr_a,hdr_b, 2'bxx,2'b10,OPREG[23:14],2'b10,hdl_c, hdo_d};		// MOVM/CMPM
		  11'b001x_0x_1111x : op3_feld = {6'o11,3'o2,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hC,hdo_a};	// DOTf,POLYf
		  11'b0101_0x_1111x : op3_feld = {6'o11,3'o5,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_e};	// LOGB
		  11'b0100_0x_1111x : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_e};	// SCALB
		  11'b0011_xx_1100x : op3_feld = {6'o50,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h7,hdo_a};	// EXTS
		  11'bxxx0_xx_1110x : op3_feld = {6'o71,3'o2,hdr_a,hdr_b, hdl_h,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c};	// CHECK
		  11'b0x1x_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ?	// target is register => standard flow
										 {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}	// SBIT/CBIT
									   : {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
		  11'b1110_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ?	// target is register => standard flow
										 {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}	// IBIT
									   : {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
		  11'b1x11_xx_0100x : op3_feld = {6'o11,3'o7,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b00,hdl_a,4'h7,3'd0,OPREG[12]}; // ADDP,SUBP
		  11'bxxx0_xx_0010x : op3_feld = {6'o40,3'o0,hdr_a,hdr_b, hdl_g,hdl_b,OPREG[23:14],2'b10,hdl_c,4'h8,hdo_c}; // EXT
		  11'bxxx0_xx_1010x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // INS
		  11'b0010_xx_1100x : op3_feld = {6'o14,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_a}; // INSS
		  11'bxxx0_xx_0110x : op3_feld = {6'o61,3'o0,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b10, 3'o3,4'h8,hdo_c}; // CVTP no Opcode
		  11'bxxx1_xx_0010x : op3_feld = {6'o11,3'o2,hdr_a,hdr_b, hdl_b,hdl_b,OPREG[23:14],2'b10, 3'o3,8'h84};		// INDEX
	// Gruppe 2 opcodes can have dedicated operation codes. Therefore the operation code definition here is "don't care"
		  11'b000x_xx_0001x : op3_feld = {6'o70,3'o0,hdr_a,hdr_b, 2'b00,2'b10,OPREG[23:19],5'b0,2'b10,3'o0,8'h45};	// RDVAL+WRVAL 
		  11'b1001_11_0001x : op3_feld = {6'o11,3'o1,hdr_a,temp_h,2'b10,2'b10,OPREG[23:19],5'b0,2'b00,3'o3,8'h45};	// CINV
 
		  default	 	    : op3_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
		endcase
 
	assign op_3byte = valid[2] & (OPREG[2:0] == 3'b110) & (op3_feld[7:4] != 4'hA);	// valid for all incl. CUSTOM
 
	// +++++++++++++  Evaluation for 2 and 3 byte opcodes  ++++++++++++++++++
 
	// for one byte opcodes special treatmant neccessary
	assign opc_bits = op_3byte ? op3_feld : op2_feld;
 
	assign op_ok = (op_1byte | op_12byte | op_2byte | op_3byte | exception) & ~stop;	// used for computation of USED
 
	always @(posedge BCLK) if (PHASE_0) op_feld_reg	<= opc_bits;
	assign op_feld = PHASE_0 ? opc_bits : op_feld_reg;	// constant for all following cycles
 
	// Evaluation of op_feld :
 
	assign atys		 = op_feld[47:45];	// [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
	assign atyd		 = op_feld[44:42];	// [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
	assign long		 = op_feld[41];
	assign src2_flag = op_feld[40];
	assign dest_flag = op_feld[39];
 
	assign src_1 	= {1'b0,op_feld[38:33]};
	assign src_2 	= {1'b0,op_feld[32:27]};
	assign src1_le 	= op_feld[26:25];
	assign src2_le 	= op_feld[24:23];
	assign acc1 	= (op_feld[22:21] != 2'b00) | atys[1];	// external access Source1 or "addr" : Reg => (Reg)
	assign acc2 	= (op_feld[17:16] != 2'b00) | atyd[1];	// external access Source2 or "addr" : Reg => (Reg)
	assign wlor		= dest_flag & ~acc2;
	assign idx_n 	= {1'b0,(op_feld[22:20] == 3'b111)} + {1'b0,(op_feld[17:15] == 3'b111)};	// Index : 0,1 or 2
	assign idx 		= (idx_n != 2'b00);	// Index is active
	assign n_idx	= idx_n - 2'b01;
 
	// The field otype is used only in Phase 0
	assign otype	= exception ? 2'b11 : ((op_1byte | op_12byte) ? 2'b01 : opc_bits[12:11]);	// string opcodes use code 2'b10
 
	assign opera	= op_feld[10:0];
 
	assign dest_r	= src_2[5:0];
	assign dest_rl	= {dest_r[5:1],1'b0};
 
	// ++++++++++++++++++++++++++++ Immediate Optimization +++++++++++++++++++++++++++++++++++
 
	//						3		Byte					Immediate
	assign opt_imme =  (valid[2] & (OPREG[1:0] == 2'd0) & (OPREG[15:11] == 5'b10100) &
	//							 ADD,ADDC,SUB,SUBC,BIC,OR,AND,XOR		CMP					MOV
						( ((OPREG[10:8] != 3'b111) & (~OPREG[2] | (OPREG[5:2] == 4'h1) | (OPREG[5:2] == 4'h5))) // not ADDR und TBIT
						 |((OPREG[6:2] == 5'b11111) & (OPREG[8:7] == 2'b10) & (OPREG[10:9] != 2'b11))))	// BICPSR,BISPSR,ADJSP and ~CASE
	//						4			not Scaled Index			Immediate
					 | (ANZ_VAL[2] & (OPREG[18:16] != 3'b111) & (OPREG[23:19] == 5'b10100) &
						( ((OPREG[7:0] == 8'h4E) & ~OPREG[13] & ~OPREG[11])		// ROT,ASH,LSH but not NEG,NOT,ABS,COM
						 |((OPREG[7:0] == 8'hCE) & (OPREG[13:12] == 2'b01) & (OPREG[9:8] == 2'd0))));	// MOVX/ZBi
 
	assign opti_byte = (OPREG[1:0] == 2'b10) ? OPREG[31:24] : OPREG[23:16];
 
	// +++++++++++++++++++++++++  Coprocessor operations field  ++++++++++++++++++++++++++++++
 
	always @(posedge BCLK) if (PHASE_0) COP_OP <= OPREG[23:0];
 
	// +++++++++++++++++++++++++  Special signals for LMR and CINV  ++++++++++++++++++++++++++
	// op_lmr is constant = parameter
 
	assign STOP_IC	= (phase_reg == 8'h74) | (phase_reg == 8'h75);
 
	// CINV uses Register x'30 - x'37 :  CINV = 110... , LMR = 001... otherwise CFG
	always @(posedge BCLK) if (PHASE_0) lmrreg <= op_3byte ? {{2{OPREG[13]}},~OPREG[13],OPREG[17:15]} : 6'h1C;
 
	always @(posedge BCLK) no_init <= (lmrreg[5:4] == 2'b00) & (lmrreg[3:1] != 3'b110);	// LMR waits for INIT at PTB0/1
	// a_ivar = "Addresse IVAR0/1"
	always @(posedge BCLK) a_ivar  <= STOP_IC;	// Phase 74 & 75, is used at INFO_AU together with IC_READ
 
	// CINV detection for IC_CACHE
	always @(posedge BCLK)
		if (PHASE_0) cinv_flag <= OPREG[13] & (OPREG[7:0] == 8'h1E);
			else cinv_flag <= cinv_flag & ~phase_reg[7];	// reset at exception
 
	assign ENA_HK = ~(cinv_flag & STOP_IC);	// always "1", if CINV then "0" 
 
	// +++++++++++++++++++++++++  USER flag for MOVUS & MOVSU  ++++++++++++++++++++++++
 
	always @(posedge BCLK)
		if (PHASE_0) m_ussu <= (~OPREG[13] & (OPREG[11:10] == 2'b11) & (OPREG[7:0] == 8'hAE));
			else m_ussu <= m_ussu & ~phase_reg[7];	// reset at exception
 
	always @(posedge BCLK) if (PHASE_0) m_usel <= OPREG[12];
 
	// +++++++++++++++++++++++++  USER flag for RDVAL & WRVAL  ++++++++++++++++++++++++
 
	always @(posedge BCLK)
		if (PHASE_0) rwval_flag <= (OPREG[13:11] == 3'd0) & (OPREG[7:0] == 8'h1E);
			else rwval_flag <= rwval_flag & ~phase_reg[7];	// reset at exception
 
	always @(posedge BCLK) if (PHASE_0) wrval_flag <= OPREG[10];	// Difference RDVAL=0 and WRVAL=1
 
	// +++++++++++++++++++++++++  Flags for CBIT/I+SBIT/I+IBIT  +++++++++++++++++++++++
 
	assign rw_bit = (op_feld_reg[7:4] == 4'd6) & ((~op_feld_reg[3] & op_feld_reg[1]) | (op_feld_reg[3:0] == 4'hE));
	assign op_ilo = rw_bit & op_feld_reg[0];	// Interlocked : CBITI and SBITI
 
	// +++++++++++++++++++++++++++++  Operations for String processing  +++++++++++++++++
	// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
 
	assign st_src 	= {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1000};	// [15] = BACKWARD
	assign st_src2	= {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011};	// Reuse EA
	assign st_dest	= {STRING[1:0],5'b0110_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011};	// Reuse EA
	assign st_trde	= {2'b00,      5'b0110_0, op_feld_reg[15],            2'b00,      9'b0_0000_1000};	// after Translate to Dest
	assign st_trs2	= {STRING[1:0],5'b1010_0, op_feld_reg[15],            STRING[1:0],9'b0_0000_1000};	// after Match to SRC2
	assign st_len	= {STRING[1:0],17'b0000_0000_0_0000_0000};	// length important for qw_flag
 
	// Signals of DETOIP go to I_PFAD
	always @(posedge BCLK) if (PHASE_0) kill_opt <= ~OPREG[7] & (OPREG[17:15] != 3'b000);	// watch difference of MOVM and MOVS
	assign ph_match = (phase_reg[7:4] == 4'hD) & (phase_reg[2:0] == 3'd7);	// Phase D7 and DF
 
	assign op_str	= {op_feld_reg[10:8],6'b0101_00,op_feld_reg[1],1'b1}; // Opcode 8'h51 or 8'h53;
	assign op_scp	= {op_feld_reg[10:8],8'h41};	// normal CMPi
	assign ph_str	= {4'hC,op_feld_reg[1],3'b001};	// Phase 8'hC1 (MOVS/M) or 8'hC9 (CMPS/M)
 
	always @(posedge BCLK) kurz_st <= (phase_reg == 8'h65) | (kurz_st & ~PHASE_0);			// Flag for MOVM/CMPM
	always @(posedge BCLK) if (PHASE_0) cmps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b01);	// Flag for CMPS
	always @(posedge BCLK) if (PHASE_0) skps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b11);	// Flag for SKPS
	always @(posedge BCLK) if (PHASE_0) mt_flag <= ~OPREG[7] & (OPREG[17] | OPREG[15]);		// Flag for Match and Translate
 
	assign wstr0	= {{4{kurz_st}},2'b00};
	assign wstr1	= {{4{kurz_st}},2'b01};
	assign wstr2	= {{4{kurz_st}},2'b10};
	assign rstr0	= {1'b0,wstr0};
	assign rstr1	= {1'b0,wstr1};
	assign rstr2	= {1'b0,wstr2};
 
	// +++++++++++++++++++++++++++++++++++  Index processing  +++++++++++++++++++++++++++++++++++++++++
 
	assign phase_idx = (phase_reg == 8'h02) | (phase_reg == 8'h50);
 
	assign idx_bytes = idx_1[2] ? OPREG[15:0] : {OPREG[7:0],OPREG[7:0]};	// here last access of OPREG
	always @(posedge BCLK) if (phase_idx) idx_reg <= idx_bytes;
	assign idx_feld = (phase_idx) ? idx_bytes : idx_reg;
 
	// +++++++++++++++++++++++++++++++++++  The big state machine  ++++++++++++++++++++++++++++++++++++
 
	// Hints :
	// 1. At short-op SRC1 is out of memory to use TEMP
	// 2. At SRC2 rmw suppresed TOS and changed it to (SP)
	// 3. The Long-operation path takes the dest_r address to write if WR_REG activ
	// 4. It is ok, that an extra cycle for the read of the index registers is needed - then data could be written ins Out register
 
	// Source 1
 
	assign idx_1 = {1'b0,(op_feld[22:20] == 3'b111),op_feld[19:18]};
	assign src1_addr = idx_1[2] ? idx_feld[7:3] : op_feld[22:18];
	assign stack  = {1'b0,stack_sel[s_user],3'b110,s_user,1'b1};
	assign usp_1  = src1_addr[0] ? stack : {5'b0_0110,src1_addr[1:0]};
	assign src_1l = {src_1[6:1],1'b0};
	assign pop_1  = {2'b00,src1_le,9'h108};	// SP update, DISP=0 and POST
	assign mpoi_1 = (src1_addr[4:2] == 3'b100) | (src1_addr == 5'h16);	// Pointer in memory always DWord
	assign auop_s = atys[0] ? 4'b1011 : 4'b0010;	// Only make effective address ?
	assign src1_tos = (op_feld[22:18] == 5'h17) & ~atys[2] ? 2'b11 : 2'b00;	// Source 1 is true TOS
 
	// Nextfield : 11=DISP read
	// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
	always @(*)
		casex (src1_addr)	//	 RWLF   IDX    ADDR_F NEUP  SRC_REG 		      NEXT
		  // Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
		  5'b00xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b000,atys[0]};	
		  // Register relativ : 0(R0)
		  5'b01xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b111,atys[0]};
		  // Memory relativ : 0(0(SB))
		  5'b100xx : gen_src1 = {4'b1011,4'h0, 9'h000,8'h06,usp_1,			  4'b1111};			// 1. access always full
		  // Immediate
		  5'b10100 : gen_src1 = (src1_le == 2'b11) ? 
								{4'h0,   4'h0, 9'h000,8'h0B,src_x,			  1'b1,2'b10,1'b0}	// load in DWord pieces
							  : {4'h0,   4'h0, 9'h000,8'h07,src_x,			  1'b1,src1_le,1'b0};
		  5'b10101 : gen_src1 = {auop_s, idx_1,9'h002,8'h07,src_x,			  3'b111,atys[0]};	// Absolut Addressing
		  5'b10110 : gen_src1 = {4'b1011,4'h0, 9'h014,8'h05,7'h1F,			  4'b0001};			// External with MOD Register +4
		  5'b10111 : gen_src1 = (idx_1[2] | atys[2]) ?											// Access class "addr" ?
								{auop_s, idx_1,9'h000,8'h07,stack,			  3'b000,atys[0]}	// 0(SP) : no TOS flag
							  : {4'b1011,pop_1, 	  8'h07,stack,			  4'b0001};			// TOS
		  // Memory Space : 0(SB)
		  5'b110x0 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,5'b0_0110,src1_addr[1:0],3'b111,atys[0]};	// SB+FP
		  5'b11001 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,stack,			  3'b111,atys[0]};	// SP
		  5'b11011 : gen_src1 = {auop_s, idx_1,9'h001,8'h07,src_x,			  3'b111,atys[0]};	// PC relativ
		  default  : gen_src1 = 36'hx_xxxx_xxxx;	// don't care
		endcase
 
	assign adrd1 = {(mpoi_1 ? 2'b10 : src1_le),gen_src1[35:19]};	// Addressfield : 19 Bits
	assign phrd1 = gen_src1[18:11];					// next phase
	assign rega1 = gen_src1[10:4];					// Source 1 Register
	assign irrw1 = {4'b0,idx_feld[2:0]};			// Index-Register
	assign nxrd1 = gen_src1[3:0];					// Memory/Disp/Immediate operation
	assign exr11 = {2'b10  ,4'b1011,4'h0 ,9'h080};	// 2. access external with Mem.-Pointer + 4* Disp
	assign exr12 = {src1_le,auop_s,idx_1,9'h000};	// for Memory Relative and EXT in last step
 
	// Source 2 resp. Destination
 
	assign rmw = src2_flag & dest_flag;
	assign idx_2 = {1'b0,(op_feld[17:15] == 3'b111),op_feld[14:13]};	// 4 bits
	assign src2_addr = idx_2[2] ? idx_feld[15:11] : op_feld[17:13];
	assign usp_2 = src2_addr[0] ? stack : {5'b0_0110,src2_addr[1:0]};
	assign src_2l = {src_2[6:1],1'b0};
	assign mpoi_2 = (src2_addr[4:2] == 3'b100) | (src2_addr == 5'h16);	// Pointer in memory always DWord
	assign auop_d = atyd[0] ? 4'b1011 : 4'b0010;	// Only make effective address ?
 
	// The next assessment processes TOS separated for PUSH and POP
	assign tos_oper =			src2_flag ?
								{2'b00,atyd[0],2'b01,atyd[0],2'b00,src2_le,7'b1_0000_10,	 src1_tos,4'h7,stack,3'b0,atyd[0]}	// POP
							  : {1'b0,atyd[0],3'b001,atyd[0],4'h0,   1'b1,2'b10,src2_le,2'b0,src1_tos,4'h7,stack,3'b0,atyd[0]};	// PUSH
 
	// Nextfield : 11=DISP read
	// Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
	always @(*)
		casex (src2_addr)	//	 RW:W  RW:R  LF    IDX   ADDR_F NEUP   SRC_REG          NEXT
		  // Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
		  5'b00xxx : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b000,atyd[0]};	
		  // Register relativ : 0(R0)
		  5'b01xxx : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h000,4'h7,4'h0,src2_addr[2:0],3'b111,atyd[0]};
		  // Memory relativ : 0(0(SB))
		  5'b100xx : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h000,4'h6,usp_2,		4'b1111};	// 1. access always full
		  // Immediate
		  5'b10100 : gen_src2 = (src2_le == 2'b11) ? 
								{2'b00,2'b00,2'b00,4'h0, 9'h000,4'hB,src_x,		1'b1,2'b10,1'b0}	// load in DWord pieces
							  : {2'b00,2'b00,2'b00,4'h0, 9'h000,4'h7,src_x,		1'b1,src2_le,1'b0};
		  5'b10101 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h002,4'h7,src_x,		3'b111,atyd[0]};	// Absolut with special coding
		  5'b10110 : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h014,4'h5,7'h1F,		4'b0001};	// External with MOD Register +4
		  5'b10111 : gen_src2 = (idx_2[2] | rmw | atyd[2]) ?
								{1'b0,atyd[0],auop_d, idx_2,7'b0_0000_00,src1_tos,4'h7,stack,	3'b000,atyd[0]}	// 0(SP) : TOS + DISP=0
							  : tos_oper;	// TOS : 2 cases for PUSH and POP
		  // Memory Space
		  5'b110x0 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h000,4'h7,5'b0_0110,src2_addr[1:0],3'b111,atyd[0]};
		  5'b11001 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h000,4'h7,stack,		3'b111,atyd[0]};
		  5'b11011 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h001,4'h7,src_x,		3'b111,atyd[0]};	// PC relativ
		  default  : gen_src2 = 34'hx_xxxx_xxxx;	// don't care
		endcase
 
	assign adrd2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[31:15]};
	assign adwr2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[33:32],gen_src2[29:15]};
	assign phrd2 = {4'h1,gen_src2[14:11]};				// Phase for Read Source 2
	assign phwr2 = {4'h2,gen_src2[14:11]};				// Phase for Write Destination
	assign rega2 = gen_src2[10:4];
	assign nxrw2 = gen_src2[3:0];
	assign irrw2 = {4'b0,idx_feld[10:8]};
	assign re_wr = {src2_le,4'b0101,4'h0, 9'h003};		// REUSE Address : Write of rmw
	assign exr22 = {src2_le,atyd[0],1'b0,1'b1,atyd[0],idx_2,9'h000};	// for Memory Relative and EXT in last step
	assign exw22 = {src2_le,1'b0,atyd[0],1'b1,atyd[0],idx_2,9'h000};	// for Memory Relative and EXT in last step
 
	// Special case :
 
	assign quei1 = acc1 ? imme : src_1l;	// 8B passing either from register or from extern
	// 8B is requested from both operands but only to certain times
	assign qword = (phase_reg[7:4] != 4'h0) ? (src2_le == 2'b11) :	(src1_le == 2'b11);
	assign quet1 = acc1 ? temp_h : src_1;	// select source during calculation
 
	// Output data of state machine	
	//							LOAD if	 PULS if	simple
	//					NEXT -> ENABLE	 ENABLE		out
	//  [66:48] 19	ADDR : 			X						; Op-length REUSE RD/WR etc.
	//	[47:40]	 8	new phase		X
	//	[39:33]  7	SRC1							X
	//	[32:26]	 7	SRC2							X
	//	   [25]	 1	WREN					X
	//	[24:19]	 6	DEST			X
	// 	 [18:8] 11	OPER			X
	//	  [7:6]	 2	START					X
	//	  [5:4]  2	LD_OUT					X
	//  	[3]  1	ID Load			X
	//	  [2:1]	 2	ID Type 		X						; 0 = DISP
	//		[0]  1	MEM Access		X
 
	// State	 acc2-src2_flag-dest_flag
	// no SRC2  	x		0		x
	// SRC2=REG		0		1		0	; CMP+TBIT
	// SRC2=REG		0		1		1	; all else
	// SRC2=MEM		1		1		0	; CMP+TBIT
	// SRC2=MEM		1		1		1	; all else
 
	// Input data for state machine
 
	//	8 phase_reg : 	phase of state machine
	//	2 otype :		Opcode type
 
	//	1 idx :			Index is available : 1 or 2 , only PHASE_0
	//	1 short_op :	short opcodes like ADDQ
	//	1 long :		"long" opcode
	//	1 qword :		8B access at Source (Exception DEI+MEI)
 
	//	1 acc1 :		Reg/Extern SRC1
	//	1 acc2 :		Reg/Extern SRC2
	//	1 src2_flag :	the 2. operand is being read
	//	1 dest_flag :	there is a target operand : only CMP and TBIT have none
 
	assign phase_ein = abbruch ? 8'h00 : phase_reg;
 
	always @(*)		//		   "_"						 "_"
		casex ({phase_ein,otype, idx,short_def,long,qword, acc1,acc2,src2_flag,dest_flag})
 {8'h00,10'b00_1xxx_xxxx}:	// Index must be loaded : phase 2 : in any case load TEMP for Short-Op and generate LD_OUT
							new_op = short_op ?	// 										   	START LD_OUT
									 {addr_nop,8'h02, imme, src_x, 1'b1,temp_h,		op_sho,	2'b00,2'b10,	1'b1,n_idx,1'b0}
								   : {addr_nop,8'h02, src_1,src_1l,1'b0,dest_x,		opera,	2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
 {8'h00,10'b00_01xx_x0xx}:	// Short-Op to register, LD_OUT because of CMPQ
							new_op = {addr_nop,goacb, imme, src_2,dest_flag,dest_r,	opera,	2'b00,2'b10,	4'h0};
 {8'h00,10'b00_01xx_x11x}:	// Short-Op : external operand read : SRC2 ! Data in TEMP ! Here no Index
							new_op = {adrd2,   phrd2, imme, rega2, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	nxrw2};
 {8'h00,10'b00_01xx_x10x}:	// MOVQ to Mem
							new_op = {adwr2,   phwr2, imme, rega2, 1'b0,dest_x,		opera,	2'b00,2'b10,	nxrw2};
 {8'h00,10'b00_0000_00xx}:	// simple register operation : dest_flag controls WREN, LD_OUT for CMP
							new_op = {addr_nop,dowait,src_1,src_2, dest_flag,dest_r,opera,	2'b00,2'b10,	4'h0};
 {8'h00,10'b00_0001_00xx}:	// "simple" Reg-Op of 8B, phase 8 after 2. DWord , not via LONG-path
							new_op = {addr_nop,8'h08, src_1,src_x, 1'b1,dest_r,		opera,	2'b00,2'b00,	4'h0};
 {8'h00,10'b00_0010_00xx}:	// long register operation i.e. DIV - phase 31
							new_op = {addr_nop,8'h1F, src_1,src_2, wlor,dest_r,		opera,	2'b11,2'b00,	4'h0};
 {8'h00,10'b00_0011_001x}:	// long register operation with QWORD - phase 26 then wait
							new_op = {addr_nop,8'h1A, src_1,src_2, 1'b0,dest_r,		opera,	2'b01,2'b00,	4'h0};
 {8'h00,10'b00_00xx_1xxx}:	// Source 1 in memory - first to read , here no Index
							new_op = {adrd1,   phrd1, src_x,rega1, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrd1};
 {8'h00,10'b00_00xx_011x}:	// Source 2 in memory - first to read (Source 1 in register)
							new_op = {adrd2,   phrd2, src_x,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 {8'h00,10'b00_0000_0101}:	// Source 1 store in Dest : "pass through" for MOV,NEG,ABS
							new_op = {adwr2,   phwr2, src_1,rega2, 1'b0,dest_x,		opera,	2'b00,2'b10,	nxrw2};
 {8'h00,10'b00_0001_0101}:	// Source 1 store in Dest : "pass through" for MOV,NEG,ABS for Long operands
							new_op = //(op_feld[17:13] == 5'h17) ?	// TOS : special case , first 8B out of Reg and then read SP
									 {addr_nop,8'h1C, src_1,src_1l,1'b0,dest_x,		opera,	2'b00,2'b11,	4'h0};
 {8'h00,10'b00_0010_0101}:	// SRC1 -> DEST with short operands 
							new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_r,		opera,	2'b11,2'b00,	4'h0};
 {8'h00,10'b00_0011_0x01}:	// SRC1 -> DEST i.e. ROUNDLi
							new_op = {addr_nop,8'h1F, src_1,src_1l,wlor,dest_r,		opera,	2'b11,2'b00,	4'h0};
 
		// Phase 2 : after read of Index nearly everything is repeated from PHASE_0
 {8'h02,10'bxx_x1xx_x11x}:	// Short-Op : external operand read
							new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 {8'h02,10'bxx_x1xx_x101}:	// MOVQ to Mem, data is in Out-Register
							new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 {8'h02,10'bxx_x0xx_1xxx}:	// Source 1 in memory - first to read
							new_op = {adrd1,   phrd1, irrw1,rega1, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrd1};
 {8'h02,10'bxx_x0xx_011x}:	// Source 2 in memory - first to read
							new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 {8'h02,10'bxx_x00x_0101}:	// Source 1 store in Dest : "pass through" , data is already in Out-Register
							new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 {8'h02,10'bxx_x010_0101}:	// SRC1 -> DEST with short operands
							new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_x,		opera,	2'b11,2'b00,	4'h0};
 {8'h02,10'bxx_x011_0101}:	// SRC1 -> DEST i.e. ROUNDLi 
							new_op = {addr_nop,8'h1F, src_1,src_1l,1'b0,dest_x,		opera,	2'b11,2'b00,	4'h0};
 
	// +++++++++++++++++  SRC1 operand loading  +++++++++++++++++++
 
		// Phase 5 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
		//		next phase fix : 6
 {8'h05,10'bxx_xxxx_xxxx}:	new_op = {exr11,   8'h06, src_x,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	4'b1111};
		// Phase 6 : Memory-Pointer for Memory Relative and last access External
		//		next phase fix : 7 , add Index
 {8'h06,10'bxx_xxxx_xxxx}:	new_op = {exr12,   8'h07, irrw1,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	3'b111,atys[0]};
 
		// Phase 7 : wait for final data , direct from PHASE_0 if TOS without Index
		//		next phase : if 8B data phase 8 is neccessary
		// if SRC2=REG execution started (otherwise store data in TEMP) and PHASE_0
 {8'h07,10'bxx_xx00_x0xx}:	// into Register , short operation execution , but LD_OUT for PSR Update ! dest_flag => WREN
							new_op = {addr_nop,endea, imme, src_2, dest_flag,dest_r,opera,	2'b00,2'b10,	diacb};
 {8'h07,10'bxx_xx01_x0xx}:	// into Reg but with a step om between for ABSL etc. : phase 8
							new_op = {addr_nop,8'h08, imme, src_x, 1'b1,dest_r,		opera,	2'b00,2'b00,	4'h0};
 {8'h07,10'bxx_xx10_x0xx}:	// execute long operation , wait in phase 31
							new_op = {addr_nop,8'h1F, imme, src_2, wlor,dest_r,		opera,	2'b11,2'b00,	4'h0};
 {8'h07,10'bxx_xx11_xx0x}:	// execute long operation : 2. operand only Dest , load LSD , phase 24 , wait in phase 31
							new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l,		op_mov,	2'b01,2'b00,	4'h0};
 {8'h07,10'bxx_xx11_x01x}:	// lange Operation ausfuehren , LSD laden , phase 25 , warten in phase 31
							new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r,		opera,	2'b01,2'b00,	4'h0};
 {8'h07,10'bxx_xxx0_x11x}:	// Data into TEMP , read 2. operand , is there Index ? Yes -> phase 15
							new_op = idx_2[2] ?
									 {addr_nop,8'h0F, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0}
								   : {adrd2,   phrd2, imme, rega2, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	nxrw2};
 {8'h07,10'bxx_xxx1_x11x}:	// 8B data in TEMP , step in between then 2. Op read : phase 10 - can only be "long" operation
							new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0};
 {8'h07,10'bxx_xx00_x101}:	// something like ABSi , execute and store (LD_OUT)
							new_op = idx_2[2] ?
									 {addr_nop,8'h10, imme, src_x, 1'b0,dest_x,		opera, 	2'b00,2'b10,	4'h0}
								   : {adwr2,   phwr2, imme, rega2, 1'b0,dest_x,		opera,	2'b00,2'b10,	nxrw2};
 {8'h07,10'bxx_xx01_x101}:	// ABS etc. : LSD data over SRC2 in 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
							new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x,		opera,	2'b00,2'b10,	4'h0};
 {8'h07,10'bxx_xx10_x101}:	// opcodes like MOVFL
							new_op = {addr_nop,8'h1F, imme, src_x, 1'b0,dest_x,		opera,	2'b11,2'b00,	4'h0};
 
		// Phase 8 : 2. part of 64 bit data : can be reached from PHASE_0 if 8B data
 {8'h08,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,endea, quei1,src_x, 1'b1,dest_rl,	op_mov,	2'b00,2'b00,	diacb};
		// Phase 9 : step in between to get data in OUT-Reg Low , SRC1 is not possible
 {8'h09,10'bxx_xxxx_xxxx}:	// afterwards to data write
							new_op = {addr_nop,8'h10, src_x,imme , 1'b0,dest_x,		op_mov,	2'b00,2'b01,	4'h0};
		// Phase 10 : LSD data write in TEMP , source can be IMME data to
 {8'h0A,10'bxx_xxxx_xxxx}:	// 8B , after TEMP there can only be a 2. operand
							new_op = idx_2[2] ?
									 {addr_nop,8'h0F, imme, src_x, 1'b1,temp_l,		op_mov,	2'b00,2'b00,	4'h0}
								   : {adrd2,   phrd2, imme, rega2, 1'b1,temp_l,		op_mov,	2'b00,2'b00,	nxrw2};
 
		// Phase 11 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
 {8'h0B,10'bxx_xx0x_x0xx}:	// into Reg with step in between for ABSL etc. : phase 12
							new_op = {addr_nop,8'h0C, imme, src_x, 1'b1,dest_r,		opera,	2'b00,2'b00,	4'b1100};
 {8'h0B,10'bxx_xx1x_x01x}:	// execute long operation , load LSD , phase 25 , wait in phase 31
							new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r,		opera,	2'b01,2'b00,	4'b1100};
 {8'h0B,10'bxx_xxxx_x11x}:	// 8B data into TEMP , step in between then read 2. Op : phase 10 - can only be "long" operation
							new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'b1100};
 {8'h0B,10'bxx_xx0x_x10x}:	// ABS etc. : LSD data via SRC2 into 2. OUT-Reg , MSD data see opcode ABS/NEG/MOV , phase 9
							new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x,		opera,	2'b00,2'b10,	4'b1100};
 {8'h0B,10'bxx_xx1x_xx0x}:	// MOVLF with 8B IMME data ? Must be possible, the end in phase 24 like SRC1=MEM
							new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l,		op_mov,	2'b01,2'b00,	4'b1100};
		// Phase 12 : wait for 2. part of 64 bit IMME data : after phase 0
 {8'h0C,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,endea, imme ,src_x, 1'b1,dest_rl,	op_mov,	2'b00,2'b00,	diacb};
 
		// Phase 15 : secure in TEMP with Index continue and read 2. operand
 {8'h0F,10'bxx_xxxx_xxxx}:	new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
		// Phase 16 : after LD_OUT continue with Index and store 1. operand
 {8'h10,10'bxx_xxxx_xxxx}:	new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
 
	// +++++++++++++++++  SRC2 operand loading : phase SRC1 + 16  +++++++++++++++++++
 
		// Phase 21 : wait for data and Disp2 for external addressing : part 2 EA = (MOD+4)+4*DISP1
		//		next phase fix : 22
 {8'h15,10'bxx_xxxx_xxxx}:	new_op = {exr11,   8'h16, src_x,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	4'b1111};
		// Phase 22 : Memory-Pointer for Memory Relative and last access external
		//		next phase fix : 23 , add Index
 {8'h16,10'bxx_xxxx_xxxx}:	new_op = {exr22,   8'h17, irrw2,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	3'b111,atyd[0]};
 
		// Phase 23 : wait for final data , direct from PHASE_0 if TOS without Index
		//		next phase : if 8B data phase 24 is used
 {8'h17,10'bxx_xx0x_xxx1}:	// execute short operation and write data into memory , no WREN -> phase 39 ACC_DONE
							new_op = {re_wr,   8'h27, quet1,imme , 1'b0,dest_r,		opera,	2'b00,2'b10,	4'b0001};
 {8'h17,10'bxx_xx0x_xxx0}:	// execute short operation , no WREN -> phase 0 , CMP(+TBIT)
							new_op = {addr_nop,endea, quet1,imme , 1'b0,dest_r,		opera,	2'b00,2'b10,	diacb};
 {8'h17,10'bxx_xx10_xxxx}:	// execute long operation , wait in phase 31
							new_op = {addr_nop,8'h1F, quet1,imme , wlor,dest_r,		opera,	2'b11,2'b00,	4'h0};
 {8'h17,10'bxx_xx11_xxxx}:	// execute long operation , load LSD in phase 24
							new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r,		opera,	2'b01,2'b00,	4'h0};
		// Phase 24 : load 2. part of 64 bit data : with and without wait - from 28 the phase waits , from 23 not
 {8'h18,10'bxx_xxxx_0xxx}:	// execute long operation , wait in phase 31
							new_op = {addr_nop,8'h1F, src_1l,imme, wlor,dest_r,		opera,	2'b10,2'b00,	4'h0};
 {8'h18,10'bxx_xxxx_1xxx}:	// execute long operation , wait in phase 31 , data from TEMP, used also for ROUNDLi
							new_op = {addr_nop,8'h1F, rtmpl,imme,  wlor,dest_r,		opera,	2'b10,2'b00,	4'h0};
		// Phase 25 : load 2. part of 64 bit data : SRC1 from memory and SRC2 from Reg
 {8'h19,10'bxx_xxxx_xxxx}:	// execute long operation , wait in phase 31
							new_op = {addr_nop,8'h1F, imme, src_2l,wlor,dest_r,		opera,	2'b10,2'b00,	4'h0};
		// Phase 26 : load 2. part of 64 bit data : SRC1 from Reg and SRC2 from Reg
 {8'h1A,10'bxx_xxxx_xxxx}:	// execute long operation , wait in phase 31
							new_op = {addr_nop,8'h1F, src_1l,src_2l,wlor,dest_r,	opera,	2'b10,2'b00,	4'h0};
 
		// Phase 27 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
 {8'h1B,10'bxx_xxxx_xxxx}:	// execute long operation , load LSD in phase 24
							new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r,		opera,	2'b01,2'b00,	4'b1100};
 
	// +++++++++++++++++  special case  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		// Phase 28 : TOS with 8B SRC1 operand , no Index ! Jump to phase 39
 {8'h1C,10'bxx_xxxx_xxxx}:	// store Source 1 in Dest : "pass through" for MOV,NEG,ABS
							new_op = {adwr2,   phwr2, src_x,rega2, 1'b0,dest_x,		opera,	2'b00,2'b00,	nxrw2};
	// +++++++++++++++++  close operation : write out DEST , TOS update  +++++++++++++++++++
 
		// Phase 31 : wait for DONE of long operation
 {8'h1F,10'bxx_xxxx_xxx0}:	// CMP done -> phase 0
							new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r,		opera,	2'b00,2'b10,	4'h0};	// no ACB
 {8'h1F,10'bxx_xxxx_x0x1}:	// operation closed , data into register
							new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r,		opera,	2'b00,2'b00,	4'h0};	// no ACB
 {8'h1F,10'bxx_xxxx_x101}:	// operation closed , data into memory - first calculate address phase 32+x
							new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_r,		opera,	2'b00,2'b10,	nxrw2};
 {8'h1F,10'bxx_xxxx_x111}:	// operation closed , data into memory - address reuse phase 39 ACC_DONE
							new_op = {re_wr,   8'h27, src_x,src_x, 1'b0,dest_r,		opera,	2'b00,2'b10,	4'b0001};
 
		// Destination address calculate
		// Phase 37 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
		//		next phase fix : 38
 {8'h25,10'bxx_xxxx_xxxx}:	new_op = {exr11,   8'h26, src_x,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	4'b1111};
		// Phase 38 : Memory-Pointer for Memory Relative and letzter Zugriff External
		//		next phase fix : 39 , add Index and write
 {8'h26,10'bxx_xxxx_xxxx}:	new_op = {exw22,   8'h27, irrw2,imme , 1'b0,dest_x,		opera,	2'b00,2'b00,	4'b1111};
 
		// Phase 39 : wait for ACC_DONE : consequent numbering : 7+32
 {8'h27,10'bxx_xxxx_xxxx}:	// now operation closed , only ACB could follow
							new_op = {addr_nop,endea, src_x,src_x, 1'b0,dest_x,		opera,	2'b00,2'b00,	diacb};
 
	// +++++++++++++++ special case : ACB to Reg is to fast ! One wait cycle for ZERO-Flag
 {8'h28,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h01,src_x, src_x, 1'b0,dest_x,		opera,	2'b00,2'b00,	4'b1110};
 
	// +++++++++++++++  The other opcodes are following  ++++++++++++++++++
 
 {8'h00,10'b01_xxxx_xxxx}:	new_op = {new_addr,new_ph,new_regs,	   1'b0,dest_x,		op_mov,					new_nx};	// 1 Byte Opcodes
 
		// Phase 1 : used for Bcond and ACB :
 {8'h01,10'bxx_xxxx_xxxx}:	new_op = (ex_br_op[1] | jsr_flag) ? 	// BSR or JSR ?
									 {push_op, 8'h27, imme, stack, 1'b0,dest_x,		op_mov, 2'b00,2'b10,	4'b0001}	// wait at end
								   : {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
 
		// Phase 42 : RET : read of PC from Stack and DIN via SRC1 to PC
 {8'h2A,10'bxx_xxxx_xxxx}:  new_op = {adddisp, 8'h2B, imme, src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'hE};
		// Phase 43 : RET : Displacement add to Stack. Attention : "imme" important to keep source constant for PC
 {8'h2B,10'bxx_xxxx_xxxx}:  new_op = {save_sp, 8'h2C, imme, src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 44 : RET : Update of Stack : fixed phase
 {8'h2C,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
 
		// Phase 45 : ENTER Entry
 {8'h2D,10'bxx_xxxx_xxxx}:	new_op = {dispmin, 8'h2E, src_x,src_x, 1'b1,temp_l,		op_adr,	2'b00,2'b00,	4'hE};
		// Phase 46 : ENTER Stack longer
 {8'h2E,10'bxx_xxxx_xxxx}:	new_op = {save_sp ,8'h31, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 48 : SAVE/ENTER : Init phase , phases 48 & 49 very similar
 {8'h30,10'bxx_xxxx_xxxx}:	new_op = save_reg ?
									 {push_op, 8'h31, saver,stack, 1'b0,dest_x,		op_mov,	2'b00,2'b10,	4'h1}	// 1. load SP=>EA
								   : {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov,	2'b00,2'b00,	4'h0};	// At ENTER FP Update
		// Phase 49 : SAVE/ENTER : at the same time memory access and detection of next Reg
 {8'h31,10'bxx_xxxx_xxxx}:	new_op = save_reg ?
									 {push_ea, 8'h31, saver,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b10,	4'h1}	// one more
								   : {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov,	2'b00,2'b00,	4'h0};	// At ENTER FP Update
 
		// Phase 50 : RESTORE/EXIT Entry
 {8'h32,10'bxx_xxxx_xxxx}:	new_op = save_reg ?
									 {pop_op,  8'h33, src_x,stack, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1}
								   : {pop_fp,  ppfp,  src_x,frame, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	3'h0,new_fp};
		// Phase 51 : RESTORE/EXIT next reg
 {8'h33,10'bxx_xxxx_xxxx}:	new_op = save_reg ?
									 {next_po, 8'h33, imme, src_x, 1'b1,resto,		op_mov,	2'b00,2'b00,	4'h1}
								   : {pop_fp,  ppfp,  imme, frame, 1'b1,resto,		op_mov,	2'b00,2'b00,	3'h0,new_fp};
		// Phase 52 : EXIT End
 {8'h34,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, imme, src_x, 1'b1,frame[5:0],	op_mov,	2'b00,2'b00,	4'h0};
 
		// Phase 53 : CXP Entry : this opcode needs 12 States and 16 cycles minimum ...
 {8'h35,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h36, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 54 : CXP : Store Address Link table
 {8'h36,10'bxx_xxxx_xxxx}:	new_op = {rdltab,  8'h37, src_x,rtmph, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'hE};	// EA Phase : DISP read
		// Phase 55 : CXP : DISP is worked on, the return address => temp_l
 {8'h37,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h38, imme, rtmph, 1'b1,temp_l,		op_mov,	2'b00,2'b00,	4'h1};	// Access
		// Phase 56 : CXP : Access to Link table => Result is MOD-Entry => store in temp_h
 {8'h38,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h39, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 57 : CXP : store and PUSH MOD prepare , Entry from Exception Processing
 {8'h39,10'bxx_xxxx_xxxx}:	new_op = {push_op, 8'h3A, modul,stack, 1'b0,dest_x,		op_wrp,	2'b00,2'b10,	4'h1};
		// Phase 58 : CXP : PUSH of MOD ongoing, PUSH PC prepare
 {8'h3A,10'bxx_xxxx_xxxx}:	new_op = {ea_push, 8'h3B, rtmpl,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b10,	4'h0};
		// Phase 59 : CXP : New EA for PC
 {8'h3B,10'bxx_xxxx_xxxx}:	new_op = {save_sp, 8'h3C, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
		// Phase 60 : CXP : write of PC, calculate of Offset
 {8'h3C,10'bxx_xxxx_xxxx}:	new_op = {rmod_8,  8'h3D, rtmph,rtmph, 1'b1,temp_l,		op_flip,2'b00,2'b00,	4'h1};
		// Phase 61 : CXP : read from (MOD:New+8)
 {8'h3D,10'bxx_xxxx_xxxx}:	new_op = {ea_min8, 8'h3E, imme, rtmpl, 1'b1,temp_l,		op_add,	2'b00,2'b00,	4'h0};	// Reuse of EA
		// Phase 62 : CXP : EA Phase of SB read , new PC calculated
 {8'h3E,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h3F, rtmpl,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
		// Phase 63 : CXP : read of SB , new PC to ICache
 {8'h3F,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h2F, imme, src_x, 1'b1,6'h1A,		op_mov,	2'b00,2'b00,	4'h0};	// SB load
		// Phase 47 : CXP : Last phase update of MOD prepare
 {8'h2F,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, rtmph,src_x, 1'b1,modul[5:0],	op_mov,	2'b00,2'b00,	4'h0};	// MOD load
 
		// Phase 64 : RXP Entry : POP of PC , full Access
 {8'h40,10'bxx_xxxx_xxxx}:	new_op = {pop_ru,  8'h41, imme, src_x, 1'b1,temp_h,		op_mov, 2'b00,2'b00,	4'h0};
		// Phase 65 : RXP : PC is read, next POP prepare
 {8'h41,10'bxx_xxxx_xxxx}:	new_op = {adddisp, 8'h42, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'hF};
		// Phase 66 : RXP : DISP is addeed to Stack and MOD is read
 {8'h42,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h43, imme, src_x, 1'b1,modul[5:0],	op_mov,	2'b00,2'b00,	4'h0};
		// Phase 67 : RXP : MOD is new
 {8'h43,10'bxx_xxxx_xxxx}:	new_op = {rmod_rxp,8'h44, rtmph,modul, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h1};
		// Phase 68 : RXP : wait for SB data, parallel SP update
 {8'h44,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, imme, src_x, 1'b1,6'h1A,		op_mov,	2'b00,2'b00,	4'h0};	// SB load
 
		// Phase 69 : RETI : read of ICU for End-of-Interrupt Cycle , prepare read PC from Stack
 {8'h45,10'bxx_xxxx_xxxx}:	new_op = {pop_op,  8'h46, src_x,stack, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
		// Phase 70 : RETI/ RETT Entry : POP of PC , full Access
 {8'h46,10'bxx_xxxx_xxxx}:	new_op = {pop_ru,  8'h47, imme, src_x, 1'b1,temp_h,		op_mov, 2'b00,2'b00,	4'h0};
		// Phase 71 : RETI/RETT : PC is read, next POP prepare
 {8'h47,10'bxx_xxxx_xxxx}:	new_op = {save_sp, 8'h48, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
		// Phase 72 : RETI/RETT : DISP is added to Stack , PSR load and MOD is loaded if DE off
 {8'h48,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h49, imme, src_x, no_modul,		op_ldp,	2'b00,2'b00,	4'h0};
		// Phase 73 : RETI/RETT : different paths
 {8'h49,10'bxx_xxxx_xxxx}:	new_op = de_flag ?
									 ( reti_flag ?
								     {addr_nop,8'h4A, rtmph,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'h4B, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0} )
								   : {rmod_rtt,8'h4B, rtmph,modul, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h1};
		// Phase 74 : RETI/RETT : one pause cycle if DE on
 {8'h4A,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 75 : RETI/RETT : SB read if DE off
 {8'h4B,10'bxx_xxxx_xxxx}:	new_op = reti_flag ?
									 {addr_nop,8'h00, imme, src_x, 1'b1,6'h1A,		op_mov,	2'b00,2'b00,	4'h0}
								   : ( de_flag ?
								     {adddispn,8'h4E, src_x,ttstak,1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'hE}
								   : {adddispn,8'h4E, imme, ttstak,1'b1,6'h1A,		op_mov,	2'b00,2'b00,	4'hE} );
		// Phase 78 : RETT : SP update
 {8'h4E,10'bxx_xxxx_xxxx}:	new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
 
	// +++++++++++++++  special wait states for PSR and the Cache/MMU system  +++++++++++
 
		// Phase 76 : PSR in Word case simple delay of 2 cycles : 1. cycle does nothing
 {8'h4C,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 77 : PSR in Word case simple delay of 2 cycles : 2. cycle does Restart of instruction processing
 {8'h4D,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 79 : Wait for INIT_DONE from Cachesystem
 {8'h4F,10'bxx_xxxx_xxxx}:	new_op = (INIT_DONE | no_init) ?
									 {addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'h4F, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
 
	// +++++++++++++++  Direct Exception procession similar to CXP  ++++++++++++++++++++
 
		// Phase 121 : CXP : store and PUSH PSR prepare , Entry of Exception Processing
 {8'h79,10'bxx_xxxx_xxxx}:	new_op = {push_op, 8'h7A, modul,stack, 1'b0,dest_x,		op_wrp,	2'b00,2'b10,	4'h1};
		// Phase 122 : CXP : PUSH of PSR running, PUSH PC prepare - MOD like normal Exception-Flow
 {8'h7A,10'bxx_xxxx_xxxx}:	new_op = {ea_push, 8'h7B, rtmpl,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b10,	4'h0};
		// Phase 123 : CXP : New EA for PC , Output of Interrupt-Vector and LOAD_PC generation, continue at standard exit
 {8'h7B,10'bxx_xxxx_xxxx}:	new_op = {save_sp, 8'h4A, rtmph,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
 
	// +++++++++++++++  here comes the general Exception Processing  ++++++++++++++++++
 
		// Phase 0 : Entry with saving of PC_ARCHI and PSR
 {8'h00,10'b11_xxxx_xxxx}:	new_op = {save_pc, 8'h80, src_x,src_x, 1'b0,dest_x,		op_psr,	2'b00,2'b00,	4'h0};
		// Phase 128 : different paths to three cases
 {8'h80,10'bxx_xxxx_xxxx}:	new_op = abo_int ?
									 {ai_next[30:4],  src_x,src_x, 1'b1,temp_l,		op_adr,	2'b00,2'b00,	ai_next[3:0]}
								   : {get_vec, 8'h81, src_x,ibase, 1'b1,temp_l,		op_adr,	2'b00,2'b00,	4'h1};
		// Phase 129 : read of Exception-Vectors and store in TEMP_H , then continue at CXP if DE off
 {8'h81,10'bxx_xxxx_xxxx}:	new_op = de_flag ?
									 {addr_nop,8'h79, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'h39, imme, src_x, 1'b1,temp_h,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 130 : read of Interrupt-Vectors, Zero-Extension of Byte => TEMP_H
 {8'h82,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h83, imme, src_x, 1'b1,temp_h,		op_zex,	2'b00,2'b00,	4'h0};
		// Phase 131 : access of Exception-Vector
 {8'h83,10'bxx_xxxx_xxxx}:	new_op = (type_nmi | ~ivec_flag) ?	// NMI or non-vectored INT ?
									 {get_vec, 8'h81, src_x,ibase, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1}
								   : {get_veci,8'h81, rtmph,ibase, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h1};
 
		// Phase 132 : ABORT : store TEAR
 {8'h84,10'bxx_xxxx_xxxx}:	new_op = {save_msr,8'h85, src_x,src_x, 1'b1,w_tear,		op_adr, 2'b00,2'b00,	4'h0};
		// Phase 133 : store MSR
 {8'h85,10'bxx_xxxx_xxxx}:	new_op = (ssrc_flag | sdest_flag) ?
									 {addr_nop,rrepa, src_x,src_x, 1'b1,w_msr,		op_adr, 2'b00,2'b00,	4'h0}
								   : {get_vec ,8'h81, src_x,ibase, 1'b1,w_msr,		op_adr, 2'b00,2'b00,	4'h1};
		// Phase 134 : reload of pointers for string opcodes : R2 Dest
 {8'h86,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h87, rtmp1,src_x, 1'b1,6'h02,		op_mov, 2'b00,2'b00,	4'h0};
		// Phase 135 : reload of pointers for string opcodes : R1 Source
 {8'h87,10'bxx_xxxx_xxxx}:	new_op = {get_vec ,8'h81, rtmph,ibase, 1'b1,6'h01,		op_mov, 2'b00,2'b00,	4'h1};
 
	// +++++++++++++++++  WAIT  +++++++++++++++++++++++++++++++++
 {8'h88,10'bxx_xxxx_xxxx}:	new_op = interrupt ?
									 {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h0}	// wait ...
								   : {addr_nop,8'h88, src_x,src_x, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h0};	// Loop
 
	// +++++++++++++++++  FLAG  +++++++++++++++++++++++++++++++++
 {8'h89,10'bxx_xxxx_xxxx}:	new_op = flag ?
									 {save_pc, 8'h80, src_x,src_x, 1'b0,dest_x,		op_psr,	2'b00,2'b00,	4'h0}	// TRAP
								   : {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h0};	// continue
 
	// +++++++++++++++++  The Opcodes of Gruppe 2  +++++++++++++++
 
 {8'h00,10'b10_0xxx_xxxx}:	new_op = state_0;
	// Now the case with Index , the Long Operand is copied to OUT
 {8'h00,10'b10_1xxx_xxxx}:	new_op = {addr_nop,8'h50, src_1,src_1l,1'b0,dest_x,		opera,	2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
 
 {8'h5x,10'bxx_xxxx_xxxx}:	new_op = state_group_50;	// Gruppe 2 Opcodes
 {8'h6x,10'bxx_xxxx_xxxx}:	new_op = state_group_60;	// Gruppe 2 Opcodes
 
 // that is only for CVTP :
 {8'h73,10'bxx_xxxx_x0xx}:	new_op = {addr_nop,8'h00, src_x,src_x, 1'b1,dest_r,		op_adr, 2'b00,2'b00,	4'h0};
 {8'h73,10'bxx_xxxx_x1xx}:	new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,		op_adr,	2'b00,2'b10,	nxrw2};
 
 // that is only for LMR and CINV :
 {8'h74,10'bxx_xxxx_xxxx}:	new_op = (IC_READ | STOP_CINV) ?
									 {ivar_adr,8'h74, rtmph,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0}	// wait ...
								   : {ivar_adr,8'h75, rtmph,src_x, 1'b1,lmrreg,		op_lmr, 2'b00,2'b00,	4'h0};	// continue
 {8'h75,10'bxx_xxxx_xxxx}:	new_op = {ivar_adr,8'h4F, rtmph,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
 
	// +++++++++++++++++  The String Opcodes  +++++++++++++++++++++
 
		// Phase 192 : R0=0 ?
 {8'hC0,10'bxx_xxxx_xxxx}:	new_op = STRING[2] ?	// Is R0<>0 ?
									 {st_src,  ph_str,rstr1,rstr1, ~kurz_st,temp_h,	op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0};
		// Phase 193 : 1. part read of SRC-Register => EA
 {8'hC1,10'bxx_xxxx_xxxx}:	new_op = {st_len,  8'hC2, src_x,src_x, 1'b1,wstr1,		op_adr,	2'b00,2'b00,	4'h1};
		// Phase 194 : memory operation : read
 {8'hC2,10'bxx_xxxx_xxxx}:	new_op = mt_flag ?
									 {addr_nop,8'hD3, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
																							2'b00,2'b00,	4'h0}
								   : {load_ea, 8'hC3, imme, rstr2, 1'b0,dest_x,		op_mov, 2'b00,2'b10,	4'h0};
		// Phase 195 : Data in output register and at the same time R2 to EA
 {8'hC3,10'bxx_xxxx_xxxx}:	new_op = {st_dest, 8'hC4, rstr2,imme,  ~kurz_st,temp_1,	op_mov,	2'b00,2'b01,	4'h0};
		// Phase 196 : 1. part reuse EA and LSD of 8B data to Out-Register
 {8'hC4,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hC5, src_x,src_x, 1'b1,wstr2,		op_adr,	2'b00,2'b00,	4'h1};
		// Phase 197 : memory operation : write
 {8'hC5,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0,		op_str, 2'b00,2'b00,	4'h0};
		// Phase 199 : Test for End and Interrupt
 {8'hC7,10'bxx_xxxx_xxxx}:	new_op = (interrupt & ~kurz_st) ?
									 {save_pc, 8'h80, src_x,src_x, 1'b0,dest_x,		op_psr,	2'b00,2'b00,	4'h0}	// Interrupt !
								   : ( STRING[2] ?	// Is R0<>0 ?
									 {st_src,  ph_str,rstr1,rstr1, ~kurz_st,temp_h,	op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0} );
 // String Compare :
		// Phase 201 : 1. part read of SRC-Register => EA
 {8'hC9,10'bxx_xxxx_xxxx}:	new_op = {st_len,  8'hCA, src_x,src_x, 1'b1,wstr1,		op_adr,	2'b00,2'b00,	4'h1};
		// Phase 202 : memory operation : read
 {8'hCA,10'bxx_xxxx_xxxx}:	new_op = mt_flag ?
									 {addr_nop,8'hDB, imme, src_x, 1'b1,temp_2, (op_feld_reg[14] ? op_zex : op_mov),
																							2'b00,2'b00,	4'h0}
								   : ( skps_flag ?	// SKPS read only String1
								     {addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0,		op_str, 2'b00,2'b00,	4'h0}
								   : {load_ea, 8'hCB, imme, rstr2, 1'b1,temp_2,		op_mov, 2'b00,2'b00,	4'h0} );
		// Phase 203 : Data to output register and at the same time R2 to EA
 {8'hCB,10'bxx_xxxx_xxxx}:	new_op = {st_src2, 8'hCC, rstr2,src_x, ~kurz_st,temp_1,	op_mov,	2'b00,2'b00,	4'h0};
		// Phase 204 : 1. part reuse EA 
 {8'hCC,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hCD, src_x,src_x, 1'b1,wstr2,		op_adr,	2'b00,2'b00,	4'h1};
		// Phase 205 : memory operation : read and prepare compare
 {8'hCD,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hCE, rtmp2,imme,  1'b0,dest_x,		op_scp, 2'b00,2'b10,	4'h0};
		// Phase 206 : compare of data
 {8'hCE,10'bxx_xxxx_xxxx}:	new_op = STRING[3] ?	// Elements equal ? Same as ACB_ZERO without delay of 1 cycle
								     {addr_nop,8'hC7, rstr0,src_x, 1'b1,wstr0,		op_str, 2'b00,2'b00,	4'h0}
								   : ( kurz_st ?	// at CMPM direct end
									 {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,		op_mov,	2'b00,2'b00,	4'h0}
								   : {addr_nop,8'hC8, rtmph,src_x, 1'b1,6'h01,		op_mov,	2'b00,2'b00,	4'h0} );
		// Phase 200 : reload of R1 at CMPS, prepare reload of R2
 {8'hC8,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'h00, rtmp1,src_x, 1'b1,6'h02, 		op_mov, 2'b00,2'b00,	4'h0};
 // String Options Match and Translate for MOVS
		// Phase 211 : Test if Translate
 {8'hD3,10'bxx_xxxx_xxxx}:	new_op = op_feld_reg[14] ?	// Translate ? Translate Base is Register 3
								     {st_trans,8'hD4, rtmp2,7'h03, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h1}
								   : {addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x,		op_scp, 2'b00,2'b10,	4'h0};	// Match
		// Phase 212 : memory operation : read
 {8'hD4,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hD5, imme, src_x, 1'b1,temp_2,		op_mov, 2'b00,2'b10,	4'h0};
		// Phase 213 : Test if Match
 {8'hD5,10'bxx_xxxx_xxxx}:	new_op = op_feld_reg[16] ?	// Match ? Reference Value is Register 4
								     {addr_nop,8'hD7, rtmp2,7'h04, 1'b0,dest_x,		op_scp, 2'b00,2'b10,	4'h0}
								   : {st_trde, 8'hC4, 7'h02,7'h02, 1'b1,temp_1,		op_mov, 2'b00,2'b00,	4'h0};	// back to MOVS
		// Phase 215 : Match result evaluation
 {8'hD7,10'bxx_xxxx_xxxx}:	new_op = (STRING[3] ^ op_feld_reg[17]) ?	// Not equal? (op_feld_reg[17] = 1 = UNTIL)
								     {load_ea, 8'hC3, rtmp2,7'h02, 1'b0,dest_x,		op_mov, 2'b00,2'b10,	4'h0}	// back to MOVS
								   : {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, 		op_mov, 2'b00,2'b00,	4'h0};	// Abort, R1 back
 // String Options Match and Translate for CMPS and SKPS - to many options to get it in one state
		// Phase 218 : Test if Translate
 {8'hDB,10'bxx_xxxx_xxxx}:	new_op = op_feld_reg[14] ?	// Translate ? Translate Base is Register 3
								     {st_trans,8'hDC, rtmp2,7'h03, 1'b0,dest_x,		op_mov, 2'b00,2'b00,	4'h1}
								   : {addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x,		op_scp, 2'b00,2'b10,	4'h0};	// Match
		// Phase 220 : memory operation : read
 {8'hDC,10'bxx_xxxx_xxxx}:	new_op = {addr_nop,8'hDD, imme, src_x, 1'b1,temp_2,		op_mov, 2'b00,2'b10,	4'h0};
		// Phase 221 : Test if Match
 {8'hDD,10'bxx_xxxx_xxxx}:	new_op = op_feld_reg[16] ?	// Match ? Reference value is Register 4
								     {addr_nop,8'hDF, rtmp2,7'h04, 1'b0,dest_x,		op_scp, 2'b00,2'b10,	4'h0}
								   : ( skps_flag ?	// SKPS read only String1
								     {addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00,		op_str, 2'b00,2'b00,	4'h0}	// back to SKPS
								   : {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1,		op_mov, 2'b00,2'b00,	4'h0});	// back to CMPS
		// Phase 223 : Match result evaluation
 {8'hDF,10'bxx_xxxx_xxxx}:	new_op = (STRING[3] ^ op_feld_reg[17]) ?	// Not equal? (op_feld_reg[17] = 1 = UNTIL)
								     ( skps_flag ?	// SKPS read only String1
								     {addr_nop,8'hC7, 7'h00,src_x, 1'b1,6'h00,		op_str, 2'b00,2'b00,	4'h0}	// back to SKPS
								   : {st_trs2, 8'hCC, 7'h02,7'h02, 1'b1,temp_1,		op_mov, 2'b00,2'b00,	4'h0} )	// back to CMPS
								   : {addr_nop,8'h00, rtmph,src_x, 1'b1,6'h01, 		op_mov, 2'b00,2'b00,	4'h0};	// Abort, R1 back
 
		  default		 :  new_op = 67'hx_xxxx_xxxx_xxxx_xxxx;
		endcase
 
	// ++++++++++++++++++++++++  Deliver data of state machine  ++++++++++++++++++++++++++++
 
	// not all new_op bits are evaluated here ...
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) ACC_FELD[11:10] <= 2'b00;	// RD WR
		  else if (next) ACC_FELD[11:10] <= new_op[64:63];
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) spupd_i <= 1'b0;	// Stack Pointer Update
		  else if (next) spupd_i <= new_op[56];
 
	always @(posedge BCLK or negedge BRESET)
		if (!BRESET) oper_i <= 11'b0;
		  else if (next) oper_i <= new_op[18:8];
 
	always @(posedge BCLK)
		if (next)
		  begin
			ACC_FELD[13:12] <=  new_op[66:65];					// ASIZE[1:0]
			ACC_FELD[8:0]   <= {new_op[61:57],new_op[51:48]};	// FULLACC INDEX[3:0] POST CLRMSW SRC2SEL[1:0]
		    disp_sel <= new_op[55:52];
			wradr_i	 <= new_op[24:19];
		  end
 
	always @(posedge BCLK) wmaske_i <= src2_le;	// to simple ?
 
	always @(posedge BCLK) index_cmd <= (phase_reg == 8'h60);	// that only for INDEX
 
	// WMASKE : SP always 32 Bit, opcodes in Format 1, Reg-Nr. >31 , INDEX opcodes and the CHECK operand too
	assign WMASKE = {(spupd | format1 | wradr_i[5] | wmaske_i[1] | index_cmd | (oper_i[7:0] == 8'h83)),wmaske_i[0]};
	assign WRADR  = spupd ? {~stack[5],stack[4:0]} : wradr_i;
	assign WREN   = (spupd | wren_i) & no_trap;
	assign START  = no_trap ? start_i : 2'b0;
	assign OPER   = spupd ? op_adr				   : oper_i;
 
	always @(posedge BCLK) ACC_FELD[14] <= next & (new_op[64] | new_op[63] | new_op[62]);	// NEWACC is important
	always @(posedge BCLK) ACC_FELD[9]  <= next & new_op[62];	// LDEA is only one pulse
 
	always @(posedge BCLK) start_i <= next ? new_op[7:6] : 2'b00;
	always @(posedge BCLK) ldoreg  <= next ? new_op[5:4] : 2'b00;	// [1] = LD_OUT , [0] = LD_LDQ
	always @(posedge BCLK) wren_i  <= next & new_op[25] & ~new_op[7];	// only if no START[1] from Long-Op
 
	assign LD_OUT = {(ldoreg[1] & no_trap),ldoreg[0]};	// [1] = LD_OUT (for CMP too) , [0] = LD_LDQ
 
	assign spupd = spupd_i & ~wren_i & ~ldoreg[1] & ~spu_block;	// no Stack Update if OUT Register load or already Write-Register
 
	assign do_long = new_op[7];		// START[1] for long_reg
 
	assign RDAA = {next,new_op[39:33]};	// Source 1
	assign RDAB = {next,new_op[32:26]};	// Source 2
 
	always @(posedge BCLK) if (next) WR_REG = new_op[25] & new_op[7];	// START[1] : if WR then LONG path has register as Destination
 
	// special case : example is POLYL F2,TOS
	always @(posedge BCLK) spu_block <= DONE & WR_REG;
 
	assign MMU_UPDATE[1] = (phase_reg == 8'h84) | (phase_reg == 8'h85);	// serving the MMU at ABORT
 
	// only the real access gets USER Status : important for Memory Relative & External
	always @(posedge BCLK)										//		MOVUS					MOVSU			RDVAL/WRVAL
		if (ACC_FELD[14]) dc_user <= PSR[8] | (m_ussu & (m_usel ? (phase_reg == 8'h07) : (phase_reg == 8'h27))) | RWVAL[1];
			else dc_user <= dc_user & ~abort;
 
	always @(posedge BCLK) dc_ilo <= op_ilo &  (phase_reg == 8'h59);
	always @(posedge BCLK) ILO    <= op_ilo & ((phase_reg == 8'h59) | (phase_reg == 8'h27));
 
	assign RWVAL = {dc_ilo,(rwval_flag & (phase_reg == 8'h53)),wrval_flag};	// is used for DCACHE ILO too
 
	// Signals for the I_PATH + Debug
	assign DETOIP	= {pc_match,cmps_flag,ph_match,op_feld_reg[17],kill_opt,inss_op,exin_cmd,extract,bit_reg,kurz_st,dw_info,acb_reg,t2p};
 
	// Signals for the ADDR_UNIT : [5]=RMW Signal
	assign chk_rmw	= (phase_reg == 8'h17) | (phase_reg == 8'h58) | ((phase_reg == 8'h59) & rw_bit);	// right Gruppe 2 opcodes
	assign INFO_AU	= {no_trap,chk_rmw,(op_feld_reg[40:39] == 2'b11),RWVAL[1],(a_ivar & ~IC_READ),dc_user,disp_ok};
 
	assign RESTART = (phase_reg == 8'h4D);
 
	// Signals to generate external STATUS
	assign GENSTAT[2] = (phase_reg == 8'h88);	// WAIT Signal
	assign GENSTAT[1] = (phase_reg == 8'h82);	// Interrupt Acknowlege Cycle
	assign GENSTAT[0] = (phase_reg == 8'h45);	// End-of-Interrupt Cycle
 
	// ++++++++++++++++++++ Here is the Sub-Modul for the opcodes of Gruppe 2  ++++++++++++++++
 
	GRUPPE_2 reste_ops (.BCLK(BCLK), .PHASE_0(PHASE_0), .OPREG(OPREG[18:0]), .PHASE(phase_ein[3:0]), 
						.SRC_1(src_1), .SRC_2(src_2), .REGA1(rega1), .REGA2(rega2), .IRRW1(irrw1), .IRRW2(irrw2),
						.ADRD1(adrd1), .ADRD2(adrd2), .EXR12(exr12), .EXR22(exr22), .PHRD1(phrd1[3:0]), .PHRD2(phrd2[3:0]),
						.NXRD1(nxrd1), .NXRW2(nxrw2), .ACCA({acc1,1'b0,acc2,1'b0}), .OPERA(opera),
						.STATE_0(state_0), .STATE_GROUP_50(state_group_50), .STATE_GROUP_60(state_group_60) );
 
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.