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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [DECODER.v] - Blame information for rev 14

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

Line No. Rev Author Line
1 9 ns32kum
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2
//
3
// This file is part of the M32632 project
4
// http://opencores.org/project,m32632
5
//
6
// Filename: DECODER.v
7 14 ns32kum
// Version:  1.1 bug fix
8
// History:  1.0 first release of 30 Mai 2015
9
// Date:     21 January 2016
10 9 ns32kum
//
11 14 ns32kum
// Copyright (C) 2016 Udo Moeller
12 9 ns32kum
// 
13
// This source file may be used and distributed without 
14
// restriction provided that this copyright statement is not 
15
// removed from the file and that any derivative work contains 
16
// the original copyright notice and the associated disclaimer.
17
// 
18
// This source file is free software; you can redistribute it 
19
// and/or modify it under the terms of the GNU Lesser General 
20
// Public License as published by the Free Software Foundation;
21
// either version 2.1 of the License, or (at your option) any 
22
// later version. 
23
// 
24
// This source is distributed in the hope that it will be 
25
// useful, but WITHOUT ANY WARRANTY; without even the implied 
26
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
27
// PURPOSE. See the GNU Lesser General Public License for more 
28
// details. 
29
// 
30
// You should have received a copy of the GNU Lesser General 
31
// Public License along with this source; if not, download it 
32
// from http://www.opencores.org/lgpl.shtml 
33
// 
34
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
//
36
//      Modules contained in this file:
37
//      DECODER         Instruction Decoding and Flow Control
38
//
39 11 ns32kum
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 9 ns32kum
 
41 11 ns32kum
module DECODER ( BCLK, BRESET, INT_N, NMI_N, ANZ_VAL, OPREG, CFG, PSR, ACC_DONE, DC_ABORT, IC_ABORT, ACB_ZERO, DONE,
42 9 ns32kum
                                 PC_SAVE, STRING, INIT_DONE, ILL, UNDEF, TRAPS, IC_READ, STOP_CINV,
43 11 ns32kum
                                 GENSTAT, DISP, IMME_Q, DISP_BR, USED, NEW, LOAD_PC, NEXT_PCA, RDAA, RDAB, OPER, START, LD_OUT, LD_DIN, LD_IMME,
44
                                 INFO_AU, ACC_FELD, WREN, WRADR, WMASKE, WR_REG, DETOIP, MMU_UPDATE, RESTART, STOP_IC, RWVAL, ENA_HK, ILO, COP_OP );
45 9 ns32kum
 
46
        input                   BCLK,BRESET;
47
        input                   INT_N,NMI_N;    // external inputs
48
        input    [2:0]   ANZ_VAL;
49
        input   [55:0]   OPREG;                  // the OPREG contains the bytes to decode, OPREG[55:32] are don't care
50
        input    [8:0]   CFG;                    // CONFIG : many bits are don't-care
51
        input   [11:0]   PSR;
52
        input                   ACC_DONE;
53
        input                   DC_ABORT,IC_ABORT;
54
        input                   ACB_ZERO;
55
        input                   DONE;
56
        input   [31:0]   PC_SAVE;
57
        input    [4:0]   STRING;
58
        input                   INIT_DONE;
59
        input                   ILL,UNDEF;
60
        input    [5:0]   TRAPS;
61
        input                   IC_READ;
62
        input                   STOP_CINV;              // not to mix it up with STOP_IC
63
 
64
        output   [2:0]   GENSTAT;
65 11 ns32kum
        output  [31:0]   DISP,IMME_Q,DISP_BR;    // three main data busses : Displacement, Immediate and Displacement for Branch
66 9 ns32kum
        output   [2:0]   USED;
67
        output                  NEW;
68
        output                  LOAD_PC;
69
        output                  NEXT_PCA;
70
        output   [7:0]   RDAA,RDAB;
71
        output  [10:0]   OPER;
72
        output   [1:0]   START,LD_OUT;
73
        output                  LD_DIN,LD_IMME;
74
        output   [6:0]   INFO_AU;
75
        output  [14:0]   ACC_FELD;
76
        output                  WREN;
77
        output   [5:0]   WRADR;
78
        output   [1:0]   WMASKE;
79
        output  reg             WR_REG;
80
        output  [12:0]   DETOIP;
81
        output   [1:0]   MMU_UPDATE;
82
        output                  RESTART;
83
        output                  STOP_IC;
84
        output   [2:0]   RWVAL;
85
        output                  ENA_HK;
86
        output  reg             ILO;
87
        output  [23:0]   COP_OP;
88
 
89
        reg             [31:0]   DISP,disp_val;
90
        reg             [10:0]   oper_i;
91
        reg              [2:0]   USED;
92
        reg             [14:0]   ACC_FELD;
93
        reg              [1:0]   ldoreg;
94
        reg                             wren_i;
95
        reg              [5:0]   wradr_i;
96
        reg              [1:0]   wmaske_i;
97
        reg              [1:0]   START;
98
        reg             [23:0]   COP_OP;
99
        reg                             spupd_i;
100
        reg              [3:0]   disp_sel;
101
        reg             [52:0]   op1_feld;
102
        reg             [47:0]   op2_feld;
103
        reg             [47:0]   op3_feld;
104
        reg             [47:0]   op_feld_reg;
105
        reg             [31:0]   imme_i;
106
        reg              [2:0]   valid;
107
        reg              [7:0]   phase_reg;
108
        reg              [3:0]   di_stat;        // Displacement Status
109
        reg              [3:0]   cc_feld;
110
        reg              [1:0]   ex_br_op;
111
        reg                             acb_reg;
112
        reg                             jsr_flag;
113
        reg              [8:0]   waitop,wait_reg;
114
        reg                             branch;
115
        reg              [3:0]   dim_feld;
116
        reg             [66:0]   new_op;
117
        reg                             short_op_reg;
118
        reg             [15:0]   idx_reg;
119
        reg             [35:0]   gen_src1;
120
        reg             [33:0]   gen_src2;
121
        reg                             qw_flag;
122
        reg                             long_reg;
123
        reg                             new_spsel;
124
        reg                             s_user,old_su;
125
        reg              [1:0]   stack_sel;      // Stack select for USER and SUPERVISOR
126
        reg              [1:0]   s_mod;          // Modifier for Stack select
127
        reg                             upd_info,dw_info;
128
        reg              [2:0]   rpointer;
129
        reg              [5:0]   resto;          // for RESTORE
130
        reg                             init_rlist;
131
        reg                             new_fp;
132
        reg                             format1;
133
        reg                             ldpc_phase;
134
        reg                             reti_flag;
135
        reg                             no_t2p;
136
        reg                             iabort,ia_save;
137
        reg                             mmu_sel;
138
        reg              [1:0]   nmi_reg;
139
        reg                             nmi_flag,int_flag;
140
        reg                             type_nmi;
141
        reg              [3:0]   exc_vector;
142
        reg                             phase_exc;
143
        reg              [3:0]   ovf_pipe;
144
        reg                             dbg_s,dbg_trap,dbg_en,addr_cmp;
145
        reg                             ssrc_flag,sdest_flag;
146
        reg                             op_setcfg,setcfg_lsb;
147
        reg                             inss_op;
148
        reg                             exin_cmd,extract;       // EXT/INS
149
        reg                             bit_reg;        // Flag for Bit opcodes : Source2 = Reg
150
        reg                             kurz_st;        // Flag for MOVM/CMPM
151
        reg                             kill_opt;       // Flag for optimized MOVS
152
        reg                             cmps_flag;      // Flag for CMPS
153
        reg                             skps_flag;      // Flag for SKPS
154
        reg                             mt_flag;        // Flag for Match and Translate
155
        reg                             spu_block;      // block of SP update at Long operation
156
        reg                             dia_op,dia_flag;        // Flag for DIA
157
        reg                             m_ussu,m_usel,dc_user;  // MOVUS/SU
158
        reg                             rwval_flag,wrval_flag;  // RDVAL/WRVAL
159
        reg                             cinv_flag;      // Flag for CINV
160
        reg              [5:0]   lmrreg;
161
        reg                             no_init,a_ivar;
162
        reg                             index_cmd;
163
        reg                             stop_d;
164
        reg                             dc_ilo;
165
 
166
        wire                    PHASE_0;
167
        wire     [7:0]   phase_ein;      // Phase after ABORT has changed the content to 0
168
        wire                    de_flag,ivec_flag;
169
        wire                    next;
170
        wire    [18:0]   new_addr,pop_fp,save_pc;
171
        wire    [13:0]   new_regs;
172
        wire     [7:0]   new_ph,ppfp;
173
        wire     [7:0]   new_nx;
174
        wire                    op_1byte,op_12byte,op_2byte,op_3byte;
175
        wire                    jump;
176
        wire                    short_op,short_def;
177
        wire                    acb_op,acb_flag;
178
        wire                    zero,carry_psr,negativ,larger,flag;
179
        wire                    valid_size;
180
        wire                    op_ok;
181
        wire                    stop;
182
        wire    [47:0]   opc_bits;
183
        wire    [47:0]   op_feld;
184
        wire     [2:0]   atys,atyd;
185
        wire     [3:0]   auop_s,auop_d;
186
        wire                    long,src2_flag,dest_flag;
187
        wire     [6:0]   src_1,src_2,src_1l,src_2l;
188
        wire     [1:0]   src1_le,src2_le;
189
        wire                    acc1,acc2;
190
        wire                    spupd;
191
        wire     [6:0]   saver;  // for SAVE
192
        wire     [2:0]   reg_nr;
193
        wire                    save_reg;
194
        wire                    ld_disp,disp_ok;
195
        wire                    store_pc;
196
        wire                    do_xor;
197
        wire                    do_long;
198
        wire     [1:0]   idx_n,n_idx;
199
        wire                    idx;
200
        wire     [1:0]   otype;
201
        wire    [10:0]   opera,op_str,op_sho;
202
        wire     [5:0]   dest_r,dest_rl;
203
        wire                    phase_idx;
204
        wire    [15:0]   idx_bytes,idx_feld;
205
        wire     [3:0]   idx_1,idx_2;
206
        wire     [4:0]   src1_addr,src2_addr;
207
        wire     [6:0]   usp_1,usp_2;
208
        wire    [33:0]   tos_oper;
209 11 ns32kum
        wire    [18:0]   adrd1,exr11,exr12,adrd2,adwr2,exr22,exw22,re_wr,st_src,st_src2,st_dest,st_len,st_trde,st_trs2;
210 9 ns32kum
        wire     [7:0]   phrd1,phrd2,phwr2;
211
        wire     [6:0]   rega1,irrw1,rega2,irrw2;
212
        wire     [3:0]   nxrd1,nxrw2;
213
        wire                    rmw;
214
        wire     [6:0]   quei1,quet1;            // Registeradr
215
        wire     [7:0]   endea,goacb,dowait;     // Phase
216
        wire     [3:0]   diacb;                          // DIMM access
217
        wire                    qword;
218
        wire     [6:0]   stack,no_modul,ttstak;
219
        wire    [12:0]   pop_1;
220
        wire                    mpoi_1,mpoi_2;
221
        wire     [1:0]   src1_tos;               // the code for REUSE is 2'b11
222
        wire                    svc_flag,bpt_flag,flag_flag,trac_flag;
223
        wire     [3:0]   misc_vectors;
224
        wire     [2:0]   psr_code;
225
        wire                    exception;
226
        wire                    interrupt;
227
        wire                    abort;          // DC_ABORT | iabort;
228
        wire                    abo_int;
229
        wire                    iabo_fall;
230
        wire                    abbruch,fpu_trap,dvz_trap;
231
        wire                    abbruch2;
232
        wire                    dbg_flag;
233
        wire                    ovf_op,ovf2_op,ovf_flag;
234
        wire                    pc_match;
235
        wire                    no_trap;
236
        wire    [10:0]   op_psr,op_scp;
237
        wire    [30:0]   ai_next;
238
        wire                    set_src,set_dest,clr_sflag;
239
        wire     [7:0]   rrepa;  // Repair Phase of Abort for String opcodes
240
        wire     [7:0]   ph_str; // working phase String
241
        wire                    ph_match;
242
        wire                    t2p;
243
        wire                    rw_bit,op_ilo;
244
        wire                    setcfg;
245
        wire                    string_ende;
246
        wire                    wlor;   // Flag to generate WR_REG signal
247
        wire     [5:0]   wstr0,wstr1,wstr2;
248
        wire     [6:0]   rstr0,rstr1,rstr2;
249
        wire                    rett_exc;
250
        wire                    chk_rmw;
251
 
252
        // Variables for 2- and 3-Byte Dekoder :
253
        reg              [5:0]   hzr_c;  // CASE Statement
254
        wire     [1:0]   hzl_a;
255
        wire     [2:0]   hzl_b;
256
        wire     [5:0]   hzr_a,hzr_b,hzr_s;
257
        wire                    hdx_a;
258
        wire                    hdo_b;
259
        wire     [3:0]   hdo_a,hdo_c,hdo_e;
260
        wire     [7:0]   hdo_d;
261
        wire     [1:0]   hdl_b,hdl_d,hdl_f,hdl_g,hdl_h;
262
        wire     [2:0]   hdl_a,hdl_c,hdl_e;
263
        wire     [5:0]   hdr_a,hdr_b,hdr_c,hdr_d,hdr_e,hdr_f,hdr_g,hdr_m;
264
 
265
        wire    [66:0]   state_0,state_group_50,state_group_60;  // for the Gruppe 2 opcodes
266
 
267
        // Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
268
 
269
        parameter addr_nop      = 19'b10_0000_0000_0_0000_0000; // all parameter to 0
270
        parameter push_op       = 19'b10_0111_0000_1_1010_0000; // i.e. for BSR, ENTER ...
271
        parameter push_ea       = 19'b10_0111_0000_1_1010_0011; // SAVE middle
272
        parameter pop_op        = 19'b10_1011_0010_1_0000_1000; // RET/RESTORE
273
        parameter adddisp       = 19'b10_0010_0000_0_0000_0011; // for RET : reuse of EA
274
        parameter adddispn      = 19'b10_0010_0000_0_0000_0000; // for RETT : add Disp to Stack
275
        parameter save_sp       = 19'b10_0000_0000_1_0000_0000; // u.a. RET : update of Stack
276
        parameter next_po       = 19'b10_1011_0010_1_0000_1011; // RESTORE middle
277
        parameter dispmin       = 19'b10_0010_0000_0_0100_0011; // Reuse for ENTER
278 11 ns32kum
        parameter rmod_rxp      = 19'b10_1001_0000_1_0000_0100; // MODUL+0 read : SB , SP Update , therefore no LDEA
279 9 ns32kum
        parameter rmod_rtt      = 19'b10_1001_0000_0_0000_0100; // MODUL+0 read : SB , no LDEA
280
        parameter rmod_4        = 19'b10_1011_0000_0_0001_0100; // MODUL+4 read : Link Table Base
281
        parameter rmod_8        = 19'b10_1011_0000_0_0010_0100; // MODUL+8 read : Program Base
282
        parameter rdltab        = 19'b10_1010_0000_0_1000_0000; // Link table read - EA Phase
283
        parameter ea_push       = 19'b10_0110_0000_0_1010_0011; // CXP : 2. Push EA Phase
284
        parameter ea_min8       = 19'b10_1010_0000_0_1011_0011; // CXP : reuse of MOD+8
285
        parameter pop_ru        = 19'b10_1010_0010_0_0000_1011; // RXP : EA Phase MOD POP
286
        parameter rd_icu        = 19'b00_1001_0000_0_1100_0010; // Read ICU : Byte of fix address
287
        parameter get_vec       = 19'b10_1001_0000_0_01xx_0000; // Read Exception-Vector : Index Exception No.
288 11 ns32kum
        parameter get_veci      = 19'b10_1001_0110_0_0000_0000; // Read Exception-Vector : Index external Interrupt
289 9 ns32kum
        parameter load_ea       = 19'b10_0010_0000_0_0000_0000; // used for store of TEAR and MSR
290
        parameter save_msr      = 19'b10_0010_0001_0_0000_0000; // used for store of TEAR and MSR
291
        parameter ivar_adr      = 19'b10_0000_0100_0_0000_0010; // only pass SRC1
292
        parameter st_trans      = 19'b00_1001_0100_0_0000_0000; // Translate at String : SRC1 + SRC2 , Byte
293
        parameter src_x         = 7'hxx;
294
        parameter dest_x        = 6'hxx;
295
        parameter imme          = {1'b1,6'hxx};
296
        parameter frame         = 7'h18;
297
        parameter ibase         = 7'h1E;
298
        parameter modul         = 7'h1F;
299
        parameter w_msr         = 6'h0A;
300
        parameter w_tear        = 6'h0B;
301
        parameter fsr_r         = 6'h17;        // not defined register for FSR for opcodes LFSR and SFSR
302
        parameter temp_l        = 6'h3C;
303
        parameter temp_h        = 6'h3D;        // second last space for 8B TEMP register
304
        parameter temp_1        = 6'h3E;        // Backup for register at String operations
305
        parameter temp_2        = 6'h3F;
306
        parameter rtmpl         = 7'h3C;
307
        parameter rtmph         = 7'h3D;
308
        parameter rtmp1         = 7'h3E;
309
        parameter rtmp2         = 7'h3F;
310 14 ns32kum
        parameter op_mov        = 11'h345;
311
        parameter op_adr        = 11'h349;
312 9 ns32kum
        parameter op_add        = 11'h340;      // for CXP
313
        parameter op_flip       = 11'h364;      // for CXP : LSHD -16,Ri
314
        parameter op_lmr        = 11'h36A;      // for LPR CFG, LMR and CINV
315
        parameter op_wrp        = 11'h387;      // for CXP : write PSR , used also for Exception processing
316
        parameter op_ldp        = 11'h388;      // for RETT and RETI : load of PSR from Stack
317
        parameter op_zex        = 11'h076;      // Zero Extension for ICU Vector - is also used at String Option "T"
318
        parameter op_cop        = 8'hDD;        // Coprozessor Opcode
319
 
320 11 ns32kum
        // ++++++++++++++++++++++++++  The switch logic for the state machine  +++++++++++++++++++++++++++++
321 9 ns32kum
 
322
        always @(ANZ_VAL)
323
                case (ANZ_VAL)
324
                  3'd0  : valid = 3'b000;
325
                  3'd1  : valid = 3'b001;
326
                  3'd2  : valid = 3'b011;
327
                default : valid = 3'b111;
328
                endcase
329
 
330
        assign next = ( PHASE_0 ? op_ok :               // Opcode decoded or Exception processed
331
                                                // Displacement or Immediate operand and external memory access can happen in parallel
332
                                                // i.e. addressing mode Memory Relative
333
                                    (  ((~dim_feld[0] | ACC_DONE) & (~dim_feld[3] | di_stat[0]))  // ACC_DONE resets dim_feld
334
                                                // long operation
335
                                     & ~(long_reg & ~DONE) ) )
336
                                                // hard break : abort or fpu_trap or dvz_trap or ovf_flag
337
                                  | abbruch ;
338
 
339
        always @(posedge BCLK or negedge BRESET)
340
                if (!BRESET) long_reg <= 1'b0;
341
                  else
342
                        long_reg <= next ? do_long : long_reg;  // START[1]
343
 
344
        always @(posedge BCLK or negedge BRESET)        // the central phase register
345
                if (!BRESET) phase_reg <= 8'h0;
346
                  else
347
                        if (next) phase_reg <= new_op[47:40];
348
 
349
        always @(*)     // next switch of micro program counter
350
                casex ({PHASE_0,op_ok,dim_feld[3],di_stat[0]})
351
                  4'b11_xx : USED = {1'b0,~op_1byte,(op_1byte | op_3byte)};
352
                  4'b0x_11 : USED = di_stat[3:1];
353
                  default  : USED = 3'd0;
354
                endcase
355
 
356
        // Special phases
357
 
358
        assign PHASE_0 = (phase_reg == 8'h00);  // During Phase 0 the opcode is decoded
359
 
360
        assign NEXT_PCA = PHASE_0 & ~ovf_flag & ~dbg_flag;
361
 
362
        // Pulse to transfer from Trace Bit to Pending Trace Bit, only once in the beginning of phase 0
363
        // The priority is such that a TRACE exception is served before an UNDEFINED/ILLEGAL exception
364
        always @(posedge BCLK) no_t2p <= PHASE_0 & ~op_ok;
365
        assign t2p = PHASE_0 & ~no_t2p; // signal to I_PFAD
366
 
367
        // ++++++++++++++++++++++++++  global control signals  ++++++++++++++++
368
 
369
        assign de_flag   = CFG[8];
370
        assign ivec_flag = CFG[0];
371
        assign dvz_trap  = TRAPS[1];
372
        assign fpu_trap  = TRAPS[0];
373
 
374 11 ns32kum
        always @(posedge BCLK) nmi_reg  <= {nmi_reg[0],NMI_N};   // one clock sync and than falling edge detection
375 9 ns32kum
 
376
        always @(posedge BCLK or negedge BRESET)
377
                if (!BRESET) nmi_flag <= 1'b0;
378
                  else nmi_flag <= (nmi_reg == 2'b10) | (nmi_flag & ~(phase_reg == 8'h82));
379
 
380
        always @(posedge BCLK) int_flag <= PSR[11] & ~INT_N;    // one clock to synchronise
381
 
382 11 ns32kum
        assign stop              = (int_flag | nmi_flag) &   PHASE_0 & ~stop_d;         // neccesary if FPU_TRAP and INT at the same time
383 9 ns32kum
        assign interrupt = (int_flag | nmi_flag) & (~PHASE_0 |  stop_d);
384
 
385
        always @(posedge BCLK or negedge BRESET)
386
                if (!BRESET) stop_d <= 1'd0;
387
                  else stop_d <= stop;
388
 
389
        // ++++++++++++++++++++++++++  Exception processing  +++++++++++++++
390
 
391
        // IC_ABORT is valid if Opcode Decoder cannot continue
392
        assign iabo_fall = IC_ABORT & (PHASE_0 ? ~op_ok : (~di_stat[0] & dim_feld[3]));
393
 
394
        always @(posedge BCLK) iabort  <= iabo_fall & ~ia_save; // DC_ABORT ist a pulse
395
        always @(posedge BCLK) ia_save <= iabo_fall;
396
 
397
        // mmu_sel is used in ADDR_UNIT
398
        always @(posedge BCLK) mmu_sel <= DC_ABORT | (mmu_sel & ~iabort);       // 1 = DCACHE , 0 = ICACHE
399
        assign MMU_UPDATE[0] = mmu_sel;
400
 
401
        assign abort = DC_ABORT | iabort;
402
 
403
        // that is the end of String loops where interrupts are checked : 8'hC7 & 8'hCF
404 11 ns32kum
        assign string_ende = (phase_reg[7:4] == 4'hC) & (phase_reg[2:0] == 3'b111);      // attention : 8'hCF does not exist
405 9 ns32kum
 
406 11 ns32kum
        always @(posedge BCLK) if (PHASE_0 || string_ende) type_nmi <= nmi_flag;        // during processing kept stable
407 9 ns32kum
 
408
        assign svc_flag  = (OPREG[7:0] == 8'hE2) & valid[0];      // Vector  5 : 0101 , Illegal Vector  4 : 0100
409
        assign bpt_flag  = (OPREG[7:0] == 8'hF2) & valid[0];      // Vector  8 : 1000 , Undefined Vec. 10 : 1010
410
        assign flag_flag = (phase_reg  == 8'h89) & flag;                // Vector  7 - has an own state
411
        assign trac_flag = t2p & PSR[10];                                               // Vector  9 : 1001 , PSR[10] = P Bit , Pending Trace
412
        assign ovf_flag  = (ovf_pipe[3] & flag) | (ovf_pipe[1] & TRAPS[2]);             // Vector 13 : 1101
413
        assign dbg_flag  = dbg_trap | (dbg_s & PHASE_0);                // Vector 14 : 1110
414
 
415
        // abort + dvz_trap during a opcode, fpu_trap + ovf_flag + dbg_flag later
416
        assign abbruch  = abort | fpu_trap | dvz_trap | ovf_flag | dbg_flag;    // this 5 stop everything
417
        assign abbruch2 = abort | fpu_trap | dvz_trap | ovf_flag;       // for exc_vector generation
418
 
419
        // forces the next step of state machine (op_ok), generates otype="11" for Trap Service
420
        assign exception = interrupt | svc_flag | bpt_flag | ILL | UNDEF | trac_flag | abbruch;
421
 
422
        // a TRACE Exception is done before the opcode execution
423 11 ns32kum
        assign misc_vectors = trac_flag ? 4'h9 : {(bpt_flag | UNDEF),(svc_flag | ILL),UNDEF,svc_flag};  // the vectors are exclusiv
424 9 ns32kum
 
425
        always @(posedge BCLK)
426
                if (PHASE_0 || abbruch) // ABORTs, fpu_trap, dvz_trap + ovf_flag can happen every time
427
                  begin
428 11 ns32kum
                        exc_vector <= abbruch ? (abbruch2  ? {ovf_flag,(dvz_trap | ovf_flag),~ovf_flag,(fpu_trap | ovf_flag)} : 4'hE)
429 9 ns32kum
                                                                  : (interrupt ? {3'b0,nmi_flag} : misc_vectors);       // misc_vectors is default
430
                  end
431
                  else
432
                    if (flag_flag) exc_vector <= 4'h7;  // FLAG-Trap
433
                      else
434
                                if (interrupt && string_ende) exc_vector <= {3'b0,nmi_flag};
435
 
436 11 ns32kum
        assign psr_code[2] = ~psr_code[1];                                              // Absicht : codiert das Sichern des PSR bei Exception-Entry 
437
        assign psr_code[1] = abort | ILL | UNDEF | trac_flag;   // enable for reseting the P-Bit during write of PSR to stack
438 9 ns32kum
        assign psr_code[0] = (interrupt & ~fpu_trap) | abort;    // enable for reseting the I-Bit of new PSR
439
 
440
        // valid codes are x'89 to x'8F
441 11 ns32kum
        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
442 9 ns32kum
 
443 11 ns32kum
        // Specialitiies : ABORT stores address & flags , the Interrrupts read vectors : all is used in big CASE
444 9 ns32kum
        assign abo_int = (exc_vector == 4'h2) | (exc_vector[3:1] == 3'b000);
445
        assign ai_next = (exc_vector == 4'h2) ? {load_ea,8'h84,4'h0} : {rd_icu,8'h82,4'h1};
446
 
447 11 ns32kum
        assign save_pc = {7'b10_0010_0,dia_flag,7'b00_0_0000,dia_flag,3'b001};  // Exception : PC_ARCHI => EA, special case DIA
448
        assign no_trap = ~fpu_trap & ~ovf_flag & ~dbg_flag;     // suppresion of WREN and LD_OUT[1] and ADDR_UNIT operation
449 9 ns32kum
 
450
        // ++++++++++++++++++++++++++  Overflow Trap  ++++++++++++++
451
 
452
        always @(posedge BCLK)
453
                if (ovf_flag || !PSR[4]) ovf_pipe <= 4'd0;
454
                  else
455 11 ns32kum
                        if (PHASE_0) ovf_pipe <= {ovf_pipe[2],(ovf_op & op_ok),ovf_pipe[0],(ovf2_op & op_ok)};   // V-Bit switches on
456 9 ns32kum
 
457
        assign ovf_op =  ( ((OPREG[6:2] == 5'b000_11)   // ADDQi
458
                                          | (OPREG[3:2] == 2'b00)) & (OPREG[1:0] != 2'b10))              // ADDi,ADDCi,SUBi,SUBCi
459
                                        | ((OPREG[7:0] == 8'h4E) & OPREG[13] & (OPREG[11:10] == 2'b00))  // NEGi,ABSi
460
                                        | ((OPREG[7:0] == 8'hEE) & ~OPREG[10]);  // CHECKi
461
 
462 11 ns32kum
        assign ovf2_op =  ((OPREG[6:2] == 5'b100_11) & (OPREG[1:0] != 2'b10))    // ACBi, these overflows have no FLAG
463 9 ns32kum
                                        | ((OPREG[13:10] == 4'h1) & (OPREG[7:0] == 8'h4E))       // ASHi
464
                                        | ( OPREG[13] & (OPREG[11] == OPREG[10]) & (OPREG[7:0] == 8'hCE)); // MULi,DEIi,QUOi,DIVi
465
 
466
        // ++++++++++++++++++++++++++  Debug Trap  ++++++++++++++
467
 
468
        always @(posedge BCLK or negedge BRESET)
469
                if (!BRESET) dbg_s <= 1'b0;
470
                  else dbg_s <= dbg_trap | (dbg_s & ~((exc_vector == 4'hE) & (phase_reg == 8'h81)));
471
 
472
        always @(posedge BCLK) dbg_en <= op_ok | ~PHASE_0;
473
 
474
        assign pc_match = dbg_en & TRAPS[3] & PHASE_0 & ~exception;     // TRAPS[3] is only combinatorical
475
 
476 11 ns32kum
        always @(posedge BCLK) dbg_trap <= (pc_match | (addr_cmp & PHASE_0)) & TRAPS[5];        // TRAPS[5] = Enable Trap
477 9 ns32kum
 
478
        always @(posedge BCLK) addr_cmp <= TRAPS[4] | (addr_cmp & ~PHASE_0);    // TRAPS[4] = CAR HIT
479
 
480
        // ++++++++++++++++++++++++++  Special case String Abort  ++++++++++++++
481
 
482 11 ns32kum
        // Flags cleared if entry and exit of string operation and during  Abort sequence, not valid for MOVM/CMPM
483 9 ns32kum
        // special case UNTIL/WHILE : reset if exit (op_feld_reg[17] = 1 = UNTIL)
484 11 ns32kum
        assign clr_sflag =         (phase_reg == 8'hC0) | (phase_reg == 8'hC7) | (phase_reg == 8'hC8) | (phase_reg == 8'h81)
485 9 ns32kum
                                           | (((phase_reg == 8'hD7) | (phase_reg == 8'hDF)) & ~(STRING[3] ^ op_feld_reg[17])) ;
486
        assign set_src   =     (phase_reg == 8'hC1) | (phase_reg == 8'hC9);
487
        assign set_dest  =     (phase_reg == 8'hC4) | (phase_reg == 8'hCC);
488
 
489
        always @(posedge BCLK or negedge BRESET)        // R1 is modified
490
                if (!BRESET) ssrc_flag <= 1'b0;
491
                  else ssrc_flag <= (set_src & ~kurz_st) | (ssrc_flag & ~clr_sflag);
492
 
493
        always @(posedge BCLK or negedge BRESET)        // R2 is modified
494
                if (!BRESET) sdest_flag <= 1'b0;
495
                  else sdest_flag <= (set_dest & ~kurz_st) | (sdest_flag & ~clr_sflag);
496
 
497
        assign rrepa = {7'b1000_011,~sdest_flag};       // R1 and if necessary R2 restore
498
 
499
        // ++++++++++++++++++++++++++  The one byte opcodes  +++++++++++++++++++
500
 
501 11 ns32kum
        // The one byte opcodes have a special case : one byte opcode but the second byte should be valid too
502 9 ns32kum
        // Used with SAVE, RESTORE, ENTER and EXIT with their reg list. 
503
        // The advantage is that the reg list is store in op_feld_reg.
504
 
505
        //      [52:34] addressing
506
        //      [33:20] register
507
        //      [19:18] 1 or 2 Byte opcode
508
        //      [17:16] BSR/BR
509
        //       [15:8] next phase
510
        //        [7:4] START + LD_OUT
511
        //        [3:0] operand access : Displacement or Speicher
512
 
513
        always @(*)             // SVC (E2) and BPT (F2) decode as exception
514
                casex (OPREG[7:0])
515
                        8'hxA : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b01,8'h01,4'h0,4'hE};       // Bcc , DISP read
516
                        8'h02 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b10,8'h01,4'h0,4'hE};       // BSR , DISP read
517
                        8'h12 : op1_feld = {pop_op  , src_x, stack, 2'b01,2'b00,8'h2A,4'h0,4'h1};       // RET , DISP later
518
                        8'h22 : op1_feld = {rmod_4      , src_x, modul, 2'b01,2'b00,8'h35,4'h0,4'h1};   // CXP
519
                        8'h32 : op1_feld = {pop_op,   src_x, stack, 2'b01,2'b00,8'h40,4'h0,4'h1};       // RXP
520
                        8'h42 : op1_feld = {pop_op,       src_x, stack, 2'b01,2'b00,8'h46,4'h0,4'h1};   // RETT
521
                        8'h52 : op1_feld = {rd_icu,       src_x, src_x, 2'b01,2'b00,8'h45,4'h0,4'h1};   // RETI
522
                        8'h62 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h30,4'h0,4'h0};       // SAVE
523
                        8'h72 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0};       // RESTORE
524
                        8'h82 : op1_feld = {push_op , frame, stack, 2'b10,2'b00,8'h2D,4'h2,4'h1};       // ENTER : PUSH FP
525
                        8'h92 : op1_feld = {addr_nop, src_x, src_x, 2'b10,2'b00,8'h32,4'h0,4'h0};       // EXIT : POP FP
526
                        8'hA2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h00,4'h0,4'h0};       // NOP
527
                        8'hB2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0};       // WAIT
528
                        8'hC2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h88,4'h0,4'h0};       // DIA
529
                        8'hD2 : op1_feld = {addr_nop, src_x, src_x, 2'b01,2'b00,8'h89,4'h0,4'h0};       // FLAG
530
                  default : op1_feld = {19'hxxxxx,14'hxxxx,     2'b00,2'b00,16'hxxxx};
531
                endcase
532
 
533
        assign op_1byte  = op1_feld[18] &  valid[0];
534
        assign op_12byte = op1_feld[19] & (valid[1:0] == 2'b11);
535
 
536
        assign new_addr = op1_feld[52:34];
537
        assign new_regs = op1_feld[33:20];
538
        assign new_ph   = op1_feld[15:8];
539
        assign new_nx   = op1_feld[7:0]; // at Bcond DISP read
540
 
541
        assign pop_fp   = new_fp ? pop_op : addr_nop;
542
        assign ppfp             = new_fp ? 8'h34 : 8'h00;
543
 
544
        always @(posedge BCLK)
545
                if (PHASE_0)
546
                  begin
547
                        ex_br_op        <= op1_feld[17:16];     // BSR/BR
548
                        cc_feld         <= OPREG[7:4];
549
                        new_fp          <= (OPREG[7:6] == 2'b10);       // not decoded complete but is sufficient
550
                        reti_flag       <= OPREG[4];            // only difference between RETI and RETT is important
551
                        dia_op          <= OPREG[6];            // only difference between DIA and WAIT is important
552
                  end
553
 
554 11 ns32kum
        always @(posedge BCLK) dia_flag <= dia_op & (phase_reg == 8'h88);       // special case DIA compared to WAIT : Addr DIA to Stack
555 9 ns32kum
 
556 11 ns32kum
        always @(posedge BCLK)  // Format 1 opcodes write always DWord to reg, the same is true for Exceptions
557 9 ns32kum
                if (PHASE_0 || abbruch) format1 <= (valid[0] & (OPREG[3:0] == 4'h2)) | exception;
558
                  else
559
                        if (flag_flag || (interrupt && string_ende)) format1 <= 1'b1;
560
 
561
        //                                      Branch etc.                             CXP                                             CXPD
562 11 ns32kum
        assign store_pc = (phase_reg == 8'd1) | (phase_reg == 8'h37) | (phase_reg == 8'h6B);    // only save in DIN Reg of DATENPFAD
563 9 ns32kum
        assign jump = (ex_br_op[0] & branch) | (acb_reg & ~ACB_ZERO) | ex_br_op[1];
564
 
565 11 ns32kum
        always @(posedge BCLK) ldpc_phase <=  (phase_reg == 8'h3E)      // PC load at CXP/Traps , all one clock cycle guaranted
566 9 ns32kum
                                                                                | (phase_reg == 8'h43)  // PC load at RXP
567
                                                                                | ((phase_reg == 8'h49) & reti_flag)    // PC load at RETI
568
                                                                                | (phase_reg == 8'h4E)  // PC load at RETT
569
                                                                                | (phase_reg == 8'h66)  // PC load at JUMP/JSR/CASE
570
                                                                                | (phase_reg == 8'h7B); // PC load at DE = Direct Exception
571
 
572
        assign NEW = ((phase_reg == 8'd1) &  jump & di_stat[0]) | LOAD_PC;
573 11 ns32kum
        assign LOAD_PC = ((phase_reg == 8'h2B) & di_stat[0])     // only one pulse, but DISP must be ok => di_stat[0] (RET)
574 9 ns32kum
                                        | ldpc_phase;
575
 
576
        assign no_modul = de_flag ? {1'b0,dest_x} : {1'b1,modul[5:0]};
577
 
578
        assign negativ   = PSR[7];
579
        assign zero      = PSR[6];
580
        assign flag              = PSR[5];
581
        assign larger    = PSR[2];
582
        assign carry_psr = PSR[0];
583
 
584 11 ns32kum
        assign rett_exc = ~reti_flag & (phase_reg == 8'h4B);    // special case RETT : Stack can change during opcode
585 9 ns32kum
        always @(posedge BCLK) phase_exc <= (phase_reg == 8'h80);       // 1. Exception phase
586 11 ns32kum
        always @(negedge BCLK) if (PHASE_0 || phase_exc || rett_exc) s_user <= PSR[9];  // Select Bit for Stack, delayed update
587 9 ns32kum
        always @(negedge BCLK)
588
                if (PHASE_0 || phase_exc) s_mod <= {PSR[9],~PSR[9]};
589
                  else
590
                        if (rett_exc) s_mod <= s_mod | {PSR[9],~PSR[9]};        // Both can be updated
591
 
592
        always @(cc_feld or zero or carry_psr or larger or negativ or flag)
593
                case (cc_feld)
594
                  4'h0 : branch =  zero;                // EQual
595
                  4'h1 : branch = ~zero;                // Not Equal
596
                  4'h2 : branch =  carry_psr;   // Carry Set
597
                  4'h3 : branch = ~carry_psr;   // Carry Clear
598
                  4'h4 : branch =  larger;              // Higher
599
                  4'h5 : branch = ~larger;              // Lower or Same
600
                  4'h6 : branch =  negativ;             // Greater Than
601
                  4'h7 : branch = ~negativ;             // Less or Equal
602
                  4'h8 : branch =  flag;                // Flag Set
603
                  4'h9 : branch = ~flag;                // Flag Clear
604
                  4'hA : branch = ~larger  & ~zero;     // LOwer
605
                  4'hB : branch =  larger  |  zero;     // Higher or Same
606
                  4'hC : branch = ~negativ & ~zero;     // Less Than
607
                  4'hD : branch =  negativ |  zero;     // Greater or Equal
608
                  4'hE : branch = 1'b1;                 // True
609
                  4'hF : branch = 1'b0;                 // False
610
                endcase
611
 
612
        // +++++++++++++++++++++++  Register List Processing  ++++++++++++++++++++++++++++
613
 
614
        always @(posedge BCLK) init_rlist <= PHASE_0 | (phase_reg == 8'h2E);
615
 
616
        always @(posedge BCLK)
617
                if (PHASE_0) rpointer <= 3'b000;
618
                  else
619
                        if (ACC_DONE || init_rlist) rpointer <= reg_nr;
620
 
621 11 ns32kum
        REG_LIST scanner ( .DIN(op_feld_reg[22:15]), .INIT(init_rlist), .IPOS(rpointer), .VALID(save_reg), .OPOS(reg_nr) );
622 9 ns32kum
 
623
        assign saver = {4'h0,reg_nr};
624
 
625 11 ns32kum
        always @(posedge BCLK) if (ACC_DONE || init_rlist) resto <= {3'h0,~reg_nr};     // EXIT and RESTORE have the list mirrored : R0...R7
626 9 ns32kum
 
627 11 ns32kum
        // ++++++++++++++++++++++++++  Processing of Displacement and Immediate Operand  +++++++++++++++++++
628 9 ns32kum
 
629
        always @(posedge BCLK or negedge BRESET)        // Flag for DISP and IMME access
630
                if (!BRESET) dim_feld[3] <= 1'b0;
631
                  else dim_feld[3] <= next ? new_op[3] : ~di_stat[0] & dim_feld[3];
632
 
633
        always @(posedge BCLK) if (next) dim_feld[2:1] <= new_op[2:1];
634
 
635
        always @(posedge BCLK or negedge BRESET)        // Flag for external access
636
                if (!BRESET) dim_feld[0] <= 1'b0;
637
                  else dim_feld[0] <= next ? new_op[0] : ~ACC_DONE & dim_feld[0];
638
 
639
        // special case QWORD, last term for security
640
        always @(posedge BCLK) qw_flag <= dim_feld[0] & ACC_DONE & (ACC_FELD[13:12] == 2'b11) & ~qw_flag;
641
 
642 11 ns32kum
        assign LD_IMME = (dim_feld[3] & (dim_feld[2:1] != 2'b11)) | short_op | store_pc;        // Data multiplexer
643
        assign LD_DIN  =  (di_stat[0] & dim_feld[3] & (dim_feld[2:1] != 2'b11))                          // Enable for DIN Register
644
                                        | (ACC_DONE   & dim_feld[0]) | qw_flag | short_op | store_pc;            // next not possible : i.e. immediate and disp parallel
645 9 ns32kum
        assign ld_disp = (dim_feld[3:1] == 3'b111);                                                                                     // Enable for DISP Register
646
 
647
        // Signal to ADDR_UNIT , only Displacement critical
648
        assign disp_ok = ld_disp ? di_stat[0] : 1'b1;
649
 
650 11 ns32kum
        always @(dim_feld or OPREG or valid or ANZ_VAL) // Bit 0 is "Data ok", the upper 3 bits are for USED
651 9 ns32kum
                casex ({dim_feld[2:1],OPREG[7:6]})
652
                  4'b00_xx : di_stat = {3'b001,valid[0]};
653
                  4'b01_xx : di_stat = {3'b010,(valid[1] & valid[0])};
654
                  4'b10_xx : di_stat = {3'b100,ANZ_VAL[2]};
655
                  4'b11_0x : di_stat = {3'b001,valid[0]};
656
                  4'b11_10 : di_stat = {3'b010,(valid[1] & valid[0])};
657
                  4'b11_11 : di_stat = {3'b100,ANZ_VAL[2]};
658
                endcase
659
 
660
        always @(OPREG)
661
                casex (OPREG[7:6])
662
                  2'b0x : disp_val = {{26{OPREG[6]}},OPREG[5:0]};
663
                  2'b10 : disp_val = {{19{OPREG[5]}},OPREG[4:0],OPREG[15:8]};
664
                  2'b11 : disp_val = {{3{OPREG[5]}},OPREG[4:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
665
                endcase
666
 
667
        assign DISP_BR = disp_val;      // DISP is also used for Bcc opcode
668
 
669
        // The generator for DISP : data is used in ADDR_UNIT
670
        always @(*)
671
                casex ({ld_disp,disp_sel})      //      disp_sel from new_op
672
                  5'b1_00xx : DISP = disp_val;
673
                  5'b1_01xx : DISP = 32'h0 - disp_val;  // special case for ENTER
674
                  5'b1_1xxx : DISP = {disp_val[29:0],2'b00};     // DISP*4 for External Address Mode
675
                  5'b0_11xx : DISP = {20'hFFFFF,3'h7,type_nmi,8'h00};    // Interrupt Service Address
676
                  5'b0_1000 : DISP = 32'hFFFF_FFFF;             // PUSH Byte
677
                  5'b0_1001 : DISP = 32'hFFFF_FFFE;             // PUSH Word
678
                  5'b0_1010 : DISP = 32'hFFFF_FFFC;             // PUSH DWord
679
                  5'b0_1011 : DISP = 32'hFFFF_FFF8;             // PUSH QWord
680
                  5'b0_01xx : DISP = {26'h0,exc_vector,2'b00};          // the exception vector as Offset for INTBASE
681
                  5'b0_00xx : DISP = {28'h0,disp_sel[1:0],2'b00};        // 0,+4,+8,+12 used with MOD, default is 0
682
                endcase
683
 
684
        always @(short_op or dim_feld or OPREG or op_setcfg or setcfg_lsb)
685
                casex ({short_op,dim_feld[2:1]})
686
                  3'b000 : imme_i = op_setcfg ? {28'h0000_00F,OPREG[2:0],setcfg_lsb} : {24'hxx_xxxx,OPREG[7:0]};
687
                  3'b001 : imme_i =    {16'hxxxx,OPREG[7:0],OPREG[15:8]};
688
                  3'b01x : imme_i = {OPREG[7:0],OPREG[15:8],OPREG[23:16],OPREG[31:24]};
689
                  3'b1xx : imme_i = {{29{OPREG[10]}},OPREG[9:7]};       // for MOVQ etc. only OPREG can be used
690
                endcase
691
 
692
        assign IMME_Q = store_pc ? PC_SAVE : imme_i;
693
 
694
        // ++++++++++++++  Stack Control  +++++++++++++++++
695
 
696
        always @(posedge BCLK or negedge BRESET)
697
                if (!BRESET) new_spsel <= 1'b0;
698
                  else new_spsel <= spupd | (new_spsel & ~PHASE_0 & ~fpu_trap & ~dvz_trap);
699
 
700 11 ns32kum
        always @(posedge BCLK) upd_info <= PHASE_0 & new_spsel; // one clock cycle earlier a change occurs, i.e. ADDF TOS,F0 => fpu_trap
701 9 ns32kum
 
702
        assign do_xor = fpu_trap ? upd_info : (PHASE_0 & new_spsel);
703
 
704
        always @(negedge BCLK or negedge BRESET)
705
                if (!BRESET) stack_sel <= 2'b00;
706
                  else
707
                        if (do_xor) stack_sel <= stack_sel ^ s_mod;
708
 
709
        // Special case RETT
710 11 ns32kum
        always @(posedge BCLK) if (!phase_reg[1]) old_su <= s_user;     // is tested in state x'49 and used in x'4B
711 9 ns32kum
        assign ttstak = {1'b0,((old_su == PSR[9]) ^ stack_sel[PSR[9]]),3'b110,PSR[9],1'b1};
712
 
713
        // ++++++++++++++  2 byte opcodes  +++++++++++++++++
714
 
715
        // Hint : short_op is decoded separatly
716
 
717
        // [47:45]      Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
718
        // [44:42]      Destination : like [47:45]
719
        //        [41]  long opcode     [41:39] only for standard sequenz - not Gruppe 2
720
        //    [40]      src2_flag - Source 2 is read
721
        //        [39]  dest_flag - a target operand exists
722
        // [38:33]      src1_r Register field, no message about Immediate
723
        // [32:27]      src2_r Register field
724
        // [26:25]      src1_le Length of Source1 - this is used for qword
725
        // [24:23]      src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE 
726
        // [22:18]      src1 field
727
        // [17:13]      src2 field
728
        // [12:11]      op_type 2 Bit for sort of opcode
729
        //    [10]      FL : F=1/L=0
730
        //   [9:8]      original BWD : B=00/W=01/D=11
731
        //   [7:0]      opcode: operation code
732
 
733 11 ns32kum
        assign valid_size = (OPREG[1:0] != 2'b10) & (valid[1:0] == 2'b11);        // valid size + valid OPREG-Bytes
734 9 ns32kum
 
735
        assign hzl_a = (OPREG[1:0] == 2'b11) ? 2'b10 : OPREG[1:0];        // length field recoded
736
        assign hzl_b = {1'b0,OPREG[1:0]};                // standard Length field
737
        assign hzr_a = {3'b000,OPREG[13:11]};   // SRC2 or SRC1 regfield
738
        assign hzr_b = {3'b000,OPREG[8:6]};             // SRC2 regfield
739 11 ns32kum
        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
740 9 ns32kum
        // Special case LPR & SPR regfield:
741
        always @(OPREG or stack_sel or s_user)
742
                casex ({OPREG[10:7]})
743
                  4'b1001 : hzr_c = {stack_sel[s_user],3'b110,s_user,1'b1};     // USER or SUPERVISOR Stack
744
                  4'b1011 : hzr_c = {stack_sel[1]         ,3'b110,1'b1,  1'b1}; // USER Stack
745
                  4'b1100 : hzr_c = OPREG[6] ? temp_h : 6'h1C;  // CFG special case : LPR : SPR
746
                  default : hzr_c = {2'b01,OPREG[10:7]};
747
                endcase
748
 
749 11 ns32kum
        // Unfortunately SETCFG must be implemented : it is transformed to a two byte opcode with one byte IMM operand
750 9 ns32kum
        assign setcfg = (OPREG[13:0] == 14'h0B0E) & (valid[1:0] == 2'b11);
751
 
752
        always @(*)
753
          casex ({setcfg,OPREG[10:2]})
754
                // Short-Op Codes , ACB is an ADD with following jump
755 11 ns32kum
                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
756
                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
757
                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
758 9 ns32kum
                // Scond is moving the SHORT operand in the Integer area as condition field
759 11 ns32kum
                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)
760
                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
761
                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
762 9 ns32kum
                // Format 3 opcodes :
763 11 ns32kum
                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
764
                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
765
                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
766 9 ns32kum
                // Format 4 opcodes : main group
767 11 ns32kum
                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]};
768
                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
769
                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
770 9 ns32kum
                10'b0xxxx_x1101 : op2_feld = (OPREG[10:9] == 2'b00) ?    // target is Register => standard flow
771
                                                                         {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
772
                                                                   : {6'o14,3'o2,hzr_a,hzr_b,hzl_a,2'b00,OPREG[15:6],           2'b10,hzl_b,4'h4,OPREG[5:2]};
773
                // ADJSPi
774 11 ns32kum
                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
775 9 ns32kum
                // ADDR, length field not valid
776
                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};
777 11 ns32kum
                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
778 9 ns32kum
                // SETCFG => MOV Befehl , SRC1 is genrated for 32 bit , target is Register temp_h
779
                10'b1xxxx_xxxxx  : op2_feld = {40'b001001_001_000000_111101_00_10_10100_00000_00_011,                     8'h76};
780
                default                 : op2_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
781
          endcase
782
 
783 11 ns32kum
        assign op_2byte = (valid_size | setcfg) & ~op2_feld[7]; // it must be for sure shown "Invalid Opcode"
784 9 ns32kum
 
785
        // Special case : the quick opcodes with the exception SPR and LPR
786 11 ns32kum
        assign short_op = ((~OPREG[5]) | (OPREG[6:4] == 3'b011)) & (OPREG[3:2] == 2'b11) & valid_size & PHASE_0;
787 9 ns32kum
        always @(posedge BCLK) if (PHASE_0) short_op_reg <= short_op;
788
        assign short_def =  PHASE_0 ? short_op : short_op_reg;                                                  // for the big state machine
789 11 ns32kum
        assign op_sho = (OPREG[6:4] == 3'b011) ? 11'h07A : op_mov;      // Special case Scond at Index as Dest. , used only in Phase 0
790 9 ns32kum
 
791
        // 2. special case ACB
792
        assign acb_op = (OPREG[6:2] == 5'h13) & valid_size;
793
        always @(posedge BCLK) if (PHASE_0) acb_reg <= acb_op;
794
        assign acb_flag = PHASE_0 ? acb_op : acb_reg;
795 11 ns32kum
        assign goacb = acb_flag ? 8'h28 : 8'h00;        // x'28 = 40 , wait jump at REG operation - short-op special case
796 9 ns32kum
 
797 11 ns32kum
        // 3. special case load of PSR and Init-Done opcodes : because of U bit in PSR a restart must follow,
798 9 ns32kum
        // CINV and LMR PTB must wait until Init-Done and than Restart.
799
        // All variants of LPR and BIC/S have an extra cycle due to TRACE operation
800
        always @(OPREG)
801
                casex (OPREG[18:0])
802
                  19'bxxx_xxxxx_1101_110_11_xx : waitop = 9'h14C;       // LPRi PSR,...
803
                  19'bxxx_xxxxx_1100_110_11_xx : waitop = 9'h174;       // LPRi CFG,...
804
                  19'bxxx_xxxxx_0x10_111_11_xx : waitop = 9'h14C;       // BICPSRi/BISPSRi ...
805
                  19'bxxxx_x_0010_xx_0000_1110 : waitop = 9'h174;       // SETCFG []
806
                  19'bxxxx_0_0010_xx_0001_1110 : waitop = 9'h174;       // LMR  - at the end Restart
807
                  19'bxxxx_0_1001_xx_0001_1110 : waitop = 9'h174;       // CINV - at the end Restart
808
                  default                                          : waitop = 9'h000;
809
                endcase
810
 
811
        assign dowait = waitop[7:0];     // is used in Phase 0 if PSR is loaded from Register
812
        always @(posedge BCLK) if (PHASE_0) wait_reg <= waitop;
813
 
814
        // Here 2. and 3. special case are coming together:
815
        // Phase definition, end over jump for ACB , not used in Phase 0
816
        assign endea = acb_reg ? 8'h01 : (wait_reg[8] ? wait_reg[7:0] : 8'h00);
817
        assign diacb = acb_reg ? 4'hE : 4'h0;   // load Disp ?
818
 
819
        // special case ADJSPi : SP=SRC2 always 32 Bit
820
        always @(posedge BCLK)
821
                if (PHASE_0) dw_info <= (OPREG[10:2] == 9'b1010_11111);
822
                  else dw_info <= dw_info & ~phase_reg[7];      // for security at ABORT
823
 
824
        // SETCFG : Flag to transform the Byte Immeadiate operand
825
        always @(posedge BCLK) if (PHASE_0) op_setcfg  <= setcfg;
826
        always @(posedge BCLK) if (PHASE_0) setcfg_lsb <= OPREG[15];
827
 
828
        always @(posedge BCLK) if (PHASE_0) jsr_flag <= (OPREG[10:2] == 9'b1100_11111);         // JSR : for PUSH
829
        always @(posedge BCLK)  // Bit opcodes to Register and EXT:SRC1 / INS:SRC2
830 11 ns32kum
                if (PHASE_0) bit_reg  <= ((OPREG[3] ? ((OPREG[7:6] == 2'd0) ? OPREG[23:22] : OPREG[18:17]) : OPREG[10:9]) == 2'b00);
831
        always @(posedge BCLK) if (PHASE_0) exin_cmd <= (~OPREG[10] & (OPREG[6:0] == 7'h2E)) & (valid[2:0] == 3'b111);
832 9 ns32kum
        always @(posedge BCLK) if (PHASE_0) extract <= ~OPREG[7];
833 11 ns32kum
        always @(posedge BCLK) if (PHASE_0) inss_op <= (OPREG[13:10] == 4'h2) & (OPREG[7:0] == 8'hCE) & (valid[2:0] == 3'b111);   // INSS
834 9 ns32kum
 
835
        // ++++++++++++++  3 byte opcodes  +++++++++++++++++
836
 
837
        // [47:45]      Source : [2] TOS=>(SP), [1] Ri => (Ri), [0] 1=access of memory
838
        // [44:42]      Destination : like [47:45]
839
        //        [41]  long opcode     [41:39] only for standard sequenz - not Gruppe 2
840
        //    [40]      src2_flag - Source 2 is read
841
        //        [39]  dest_flag - a target operand exists
842
        // [38:33]      src1_r Register field, no message about Immediate
843
        // [32:27]      src2_r Register field
844
        // [26:25]      src1_le Length of Source1 - this is used for qword
845
        // [24:23]      src2_le Length of Source2 : 00=1/01=2/10=4/11=8 Bytes => WMASKE 
846
        // [22:18]      src1 field
847
        // [17:13]      src2 field
848
        // [12:11]      op_type 2 Bit for sort of opcode
849
        //    [10]      FL : F=1/L=0
850
        //   [9:8]      original BWD : B=00/W=01/D=11
851
        //   [7:0]      opcode: operation code
852
 
853
        assign hdx_a = OPREG[7] ? OPREG[8] : OPREG[10];
854
        assign hdo_a = OPREG[13:10];
855
        assign hdo_b = ~hdx_a;                          // long operation if L
856
        assign hdo_c = {1'b0,OPREG[10],OPREG[7:6]};     // Format 8 opcodes
857
        assign hdo_d = {6'b0101_00,OPREG[10],1'b0};     // CMPM/S or MOVM/S : 8'h52 or 8'h50
858
        assign hdo_e = {3'b011,OPREG[10]};      // Special codes for LOGB and SCALB due to DP_OUT datapath
859
        // Definitions of length
860
        assign hdl_a = {1'b0,OPREG[9:8]};       // i size, is used in OPER
861 11 ns32kum
        assign hdl_b = (OPREG[9:8] == 2'b11) ? 2'b10 : OPREG[9:8];      // recode length field, is used in ACC field
862 9 ns32kum
        assign hdl_c = OPREG[10:8];                     // FL + BWD
863
        assign hdl_d = {1'b1,~hdx_a};           // length FP
864
        assign hdl_e = {OPREG[8],2'bxx};        // BWD don't care
865 11 ns32kum
        assign hdl_f = (OPREG[18:17] == 2'b00) ? OPREG[9:8] : {OPREG[8],~(OPREG[9] ^ OPREG[8])};        // exclusiv for DEI
866 9 ns32kum
        assign hdl_g = {(OPREG[9:8] != 2'b00),(OPREG[9:8] == 2'b00)};   // exclusiv for EXT/EXTS base operand
867
        assign hdl_h = {(OPREG[9:8] != 2'b00),(OPREG[9:8] != 2'b01)};   // exclusiv for CHECK bound operand
868
        // Register definitions
869
        assign hdr_a = {3'b000,OPREG[21:19]};   // SRC1 Integer Register
870
        assign hdr_b = {3'b000,OPREG[16:14]};   // SRC2 Integer Register
871
        assign hdr_c = hdx_a ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
872
        assign hdr_d = hdx_a ? {2'b10,OPREG[16:15],1'b0,OPREG[14]} : {2'b10,OPREG[16:14],1'b1};
873
        assign hdr_e = OPREG[11] ? {2'b10,OPREG[21:20],1'b0,OPREG[19]} : {2'b10,OPREG[21:19],1'b1};
874
        assign hdr_f = OPREG[11] ? {2'b10,OPREG[16:14],1'b1}               : {2'b10,OPREG[16:15],1'b0,OPREG[14]};
875 14 ns32kum
        assign hdr_g = {3'b000,OPREG[16:15],~OPREG[14]};        // exclusiv for DEI/MEI
876 9 ns32kum
        assign hdr_m = {3'b001,OPREG[17:15]};   // MMU Register Index 8-15
877
 
878
        always @(*)
879
                casex (OPREG[13:3])
880 11 ns32kum
                  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
881
                  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
882
                  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
883
                  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
884
                  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
885
                  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
886
                  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
887 9 ns32kum
        // Floating Point opcodes
888 11 ns32kum
                  11'b000x_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_a,hdr_d, hdl_b,hdl_d,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};      // MOVif
889
                  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
890
                  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
891
                  11'b10xx_xx_0011x : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};      // ROUNDi,TRUNCi
892
                  11'b111x_xx_00111 : op3_feld = {6'o11,hdo_b,2'b01,hdr_c,hdr_b, hdl_d,hdl_b,OPREG[23:14],2'b00,hdl_c,4'h9,hdo_a};      // FLOORi
893
                  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
894
                  11'b0x00_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};      // ADDf,SUBf
895
                  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
896
                  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
897
                  11'b1100_0x_10111 : op3_feld = {6'o11,hdo_b,2'b11,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};      // MULf
898
                  11'b0010_0x_1011x : op3_feld = {6'o11,hdo_b,2'b10,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b00,hdl_e,4'hB,hdo_a};      // CMPf
899
                  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
900
                  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
901
                  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
902
                  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
903 9 ns32kum
        // MMU opcodes
904 11 ns32kum
                  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
905
                  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
906 9 ns32kum
        // String opcodes
907 11 ns32kum
                  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
908
                  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
909 9 ns32kum
        // Custom opcodes
910 11 ns32kum
                  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};
911 9 ns32kum
        // Integer Divisionen : QUOi REMi DIVi MODi and DEIi + MEIi
912 11 ns32kum
                  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};
913
                  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
914 9 ns32kum
        // Gruppe 2 opcodes
915 11 ns32kum
                  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
916
                  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
917 14 ns32kum
                  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
918 11 ns32kum
                  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
919 14 ns32kum
                  11'b0100_0x_1111x : op3_feld = {6'o11,3'o7,hdr_c,hdr_d, hdl_d,hdl_d,OPREG[23:14],2'b10,hdl_e,4'hB,hdo_e};     // SCALB
920 11 ns32kum
                  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
921 14 ns32kum
                  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
922 9 ns32kum
                  11'b0x1x_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ?      // target is register => standard flow
923
                                                                                 {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
924
                                                                           : {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
925
                  11'b1110_xx_0100x : op3_feld = (OPREG[18:17] == 2'b00) ?      // target is register => standard flow
926
                                                                                 {6'o11,3'o3,hdr_a,hdr_b, hdl_b,2'b10,OPREG[23:14],2'b00,hdl_a,4'h6,hdo_a}      // IBIT
927
                                                                           : {6'o14,3'o3,hdr_a,hdr_b, hdl_b,2'b00,OPREG[23:14],2'b10,hdl_a,4'h6,hdo_a};
928 11 ns32kum
                  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'h6,hdo_a}; // ADDP,SUBP
929
                  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
930
                  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
931
                  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
932
                  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
933 14 ns32kum
                  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
934 11 ns32kum
        // Gruppe 2 opcodes can have dedicated operation codes. Therefore the operation code definition here is "don't care"
935
                  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 
936
                  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
937 9 ns32kum
 
938
                  default                   : op3_feld = {40'hxx_xxxx_xxxx,4'hA,4'hx};
939
                endcase
940
 
941 11 ns32kum
        assign op_3byte = (valid[2:0] == 3'b111) & (OPREG[2:0] == 3'b110) & (op3_feld[7:4] != 4'hA);      // valid for all incl. CUSTOM
942 9 ns32kum
 
943
        // +++++++++++++  Evaluation for 2 and 3 byte opcodes  ++++++++++++++++++
944
 
945
        // for one byte opcodes special treatmant neccessary
946
        assign opc_bits = op_3byte ? op3_feld : op2_feld;
947
 
948 11 ns32kum
        assign op_ok = (op_1byte | op_12byte | op_2byte | op_3byte | exception) & ~stop;        // used for computation of USED
949 9 ns32kum
 
950
        always @(posedge BCLK) if (PHASE_0) op_feld_reg <= opc_bits;
951
        assign op_feld = PHASE_0 ? opc_bits : op_feld_reg;      // constant for all following cycles
952
 
953
        // Evaluation of op_feld :
954
 
955
        assign atys              = op_feld[47:45];      // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
956
        assign atyd              = op_feld[44:42];      // [2] : TOS=>(SP), [1] : Ri => (Ri), [0] : 1=access of memory
957
        assign long              = op_feld[41];
958
        assign src2_flag = op_feld[40];
959
        assign dest_flag = op_feld[39];
960
 
961
        assign src_1    = {1'b0,op_feld[38:33]};
962
        assign src_2    = {1'b0,op_feld[32:27]};
963
        assign src1_le  = op_feld[26:25];
964
        assign src2_le  = op_feld[24:23];
965 11 ns32kum
        assign acc1     = (op_feld[22:21] != 2'b00) | atys[1];  // external access Source1 or "addr" : Reg => (Reg)
966
        assign acc2     = (op_feld[17:16] != 2'b00) | atyd[1];  // external access Source2 or "addr" : Reg => (Reg)
967 9 ns32kum
        assign wlor             = dest_flag & ~acc2;
968 11 ns32kum
        assign idx_n    = {1'b0,(op_feld[22:20] == 3'b111)} + {1'b0,(op_feld[17:15] == 3'b111)};        // Index : 0,1 or 2
969 9 ns32kum
        assign idx              = (idx_n != 2'b00);     // Index is active
970
        assign n_idx    = idx_n - 2'b01;
971
 
972
        // The field otype is used only in Phase 0
973 11 ns32kum
        assign otype    = exception ? 2'b11 : ((op_1byte | op_12byte) ? 2'b01 : opc_bits[12:11]);       // string opcodes use code 2'b10
974 9 ns32kum
 
975
        assign opera    = op_feld[10:0];
976
 
977
        assign dest_r   = src_2[5:0];
978
        assign dest_rl  = {dest_r[5:1],1'b0};
979
 
980
        // +++++++++++++++++++++++++  Coprocessor operations field  ++++++++++++++++++++++++++++++
981
 
982
        always @(posedge BCLK) if (PHASE_0) COP_OP <= OPREG[23:0];
983
 
984
        // +++++++++++++++++++++++++  Special signals for LMR and CINV  ++++++++++++++++++++++++++
985
        // op_lmr is constant = parameter
986
 
987
        assign STOP_IC  = (phase_reg == 8'h74) | (phase_reg == 8'h75);
988
 
989
        // CINV uses Register x'30 - x'37 :  CINV = 110... , LMR = 001... otherwise CFG
990 11 ns32kum
        always @(posedge BCLK) if (PHASE_0) lmrreg <= op_3byte ? {{2{OPREG[13]}},~OPREG[13],OPREG[17:15]} : 6'h1C;
991 9 ns32kum
 
992 11 ns32kum
        always @(posedge BCLK) no_init <= (lmrreg[5:4] == 2'b00) & (lmrreg[3:1] != 3'b110);     // LMR waits for INIT at PTB0/1
993 9 ns32kum
        // a_ivar = "Addresse IVAR0/1"
994 11 ns32kum
        always @(posedge BCLK) a_ivar  <= STOP_IC;      // Phase 74 & 75, is used at INFO_AU together with IC_READ
995 9 ns32kum
 
996
        // CINV detection for IC_CACHE
997
        always @(posedge BCLK)
998
                if (PHASE_0) cinv_flag <= OPREG[13] & (OPREG[7:0] == 8'h1E);
999
                        else cinv_flag <= cinv_flag & ~phase_reg[7];    // reset at exception
1000
 
1001
        assign ENA_HK = ~(cinv_flag & STOP_IC); // always "1", if CINV then "0" 
1002
 
1003
        // +++++++++++++++++++++++++  USER flag for MOVUS & MOVSU  ++++++++++++++++++++++++
1004
 
1005
        always @(posedge BCLK)
1006
                if (PHASE_0) m_ussu <= (~OPREG[13] & (OPREG[11:10] == 2'b11) & (OPREG[7:0] == 8'hAE));
1007
                        else m_ussu <= m_ussu & ~phase_reg[7];  // reset at exception
1008
 
1009
        always @(posedge BCLK) if (PHASE_0) m_usel <= OPREG[12];
1010
 
1011
        // +++++++++++++++++++++++++  USER flag for RDVAL & WRVAL  ++++++++++++++++++++++++
1012
 
1013
        always @(posedge BCLK)
1014
                if (PHASE_0) rwval_flag <= (OPREG[13:11] == 3'd0) & (OPREG[7:0] == 8'h1E);
1015
                        else rwval_flag <= rwval_flag & ~phase_reg[7];  // reset at exception
1016
 
1017
        always @(posedge BCLK) if (PHASE_0) wrval_flag <= OPREG[10];    // Difference RDVAL=0 and WRVAL=1
1018
 
1019
        // +++++++++++++++++++++++++  Flags for CBIT/I+SBIT/I+IBIT  +++++++++++++++++++++++
1020
 
1021 11 ns32kum
        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));
1022 9 ns32kum
        assign op_ilo = rw_bit & op_feld_reg[0]; // Interlocked : CBITI and SBITI
1023
 
1024
        // +++++++++++++++++++++++++++++  Operations for String processing  +++++++++++++++++
1025
        // Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
1026
 
1027 11 ns32kum
        assign st_src   = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1000};        // [15] = BACKWARD
1028
        assign st_src2  = {STRING[1:0],5'b1010_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011};        // Reuse EA
1029
        assign st_dest  = {STRING[1:0],5'b0110_0,(op_feld_reg[15] & ~kurz_st),STRING[1:0],9'b0_0000_1011};        // Reuse EA
1030
        assign st_trde  = {2'b00,      5'b0110_0, op_feld_reg[15],            2'b00,      9'b0_0000_1000};      // after Translate to Dest
1031
        assign st_trs2  = {STRING[1:0],5'b1010_0, op_feld_reg[15],            STRING[1:0],9'b0_0000_1000};        // after Match to SRC2
1032 9 ns32kum
        assign st_len   = {STRING[1:0],17'b0000_0000_0_0000_0000};       // length important for qw_flag
1033
 
1034
        // Signals of DETOIP go to I_PFAD
1035 11 ns32kum
        always @(posedge BCLK) if (PHASE_0) kill_opt <= ~OPREG[7] & (OPREG[17:15] != 3'b000);   // watch difference of MOVM and MOVS
1036 9 ns32kum
        assign ph_match = (phase_reg[7:4] == 4'hD) & (phase_reg[2:0] == 3'd7);   // Phase D7 and DF
1037
 
1038
        assign op_str   = {op_feld_reg[10:8],6'b0101_00,op_feld_reg[1],1'b1}; // Opcode 8'h51 or 8'h53;
1039
        assign op_scp   = {op_feld_reg[10:8],8'h41};    // normal CMPi
1040
        assign ph_str   = {4'hC,op_feld_reg[1],3'b001}; // Phase 8'hC1 (MOVS/M) or 8'hC9 (CMPS/M)
1041
 
1042 11 ns32kum
        always @(posedge BCLK) kurz_st <= (phase_reg == 8'h65) | (kurz_st & ~PHASE_0);                  // Flag for MOVM/CMPM
1043
        always @(posedge BCLK) if (PHASE_0) cmps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b01);   // Flag for CMPS
1044
        always @(posedge BCLK) if (PHASE_0) skps_flag <= ~OPREG[7] & (OPREG[11:10] == 2'b11);   // Flag for SKPS
1045
        always @(posedge BCLK) if (PHASE_0) mt_flag <= ~OPREG[7] & (OPREG[17] | OPREG[15]);             // Flag for Match and Translate
1046 9 ns32kum
 
1047
        assign wstr0    = {{4{kurz_st}},2'b00};
1048
        assign wstr1    = {{4{kurz_st}},2'b01};
1049
        assign wstr2    = {{4{kurz_st}},2'b10};
1050
        assign rstr0    = {1'b0,wstr0};
1051
        assign rstr1    = {1'b0,wstr1};
1052
        assign rstr2    = {1'b0,wstr2};
1053
 
1054
        // +++++++++++++++++++++++++++++++++++  Index processing  +++++++++++++++++++++++++++++++++++++++++
1055
 
1056
        assign phase_idx = (phase_reg == 8'h02) | (phase_reg == 8'h50);
1057
 
1058
        assign idx_bytes = idx_1[2] ? OPREG[15:0] : {OPREG[7:0],OPREG[7:0]};       // here last access of OPREG
1059
        always @(posedge BCLK) if (phase_idx) idx_reg <= idx_bytes;
1060
        assign idx_feld = (phase_idx) ? idx_bytes : idx_reg;
1061
 
1062
        // +++++++++++++++++++++++++++++++++++  The big state machine  ++++++++++++++++++++++++++++++++++++
1063
 
1064
        // Hints :
1065
        // 1. At short-op SRC1 is out of memory to use TEMP
1066
        // 2. At SRC2 rmw suppresed TOS and changed it to (SP)
1067
        // 3. The Long-operation path takes the dest_r address to write if WR_REG activ
1068 11 ns32kum
        // 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
1069 9 ns32kum
 
1070
        // Source 1
1071
 
1072
        assign idx_1 = {1'b0,(op_feld[22:20] == 3'b111),op_feld[19:18]};
1073
        assign src1_addr = idx_1[2] ? idx_feld[7:3] : op_feld[22:18];
1074
        assign stack  = {1'b0,stack_sel[s_user],3'b110,s_user,1'b1};
1075
        assign usp_1  = src1_addr[0] ? stack : {5'b0_0110,src1_addr[1:0]};
1076
        assign src_1l = {src_1[6:1],1'b0};
1077
        assign pop_1  = {2'b00,src1_le,9'h108}; // SP update, DISP=0 and POST
1078 11 ns32kum
        assign mpoi_1 = (src1_addr[4:2] == 3'b100) | (src1_addr == 5'h16);      // Pointer in memory always DWord
1079 9 ns32kum
        assign auop_s = atys[0] ? 4'b1011 : 4'b0010;     // Only make effective address ?
1080 14 ns32kum
        assign src1_tos = (op_feld[22:18] == 5'h17) & ~atys[2] ? 2'b11 : 2'b00; // Source 1 is true TOS
1081 9 ns32kum
 
1082
        // Nextfield : 11=DISP read
1083
        // Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
1084
        always @(*)
1085
                casex (src1_addr)       //       RWLF   IDX    ADDR_F NEUP  SRC_REG                   NEXT
1086 11 ns32kum
                  // Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
1087 9 ns32kum
                  5'b00xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b000,atys[0]};
1088
                  // Register relativ : 0(R0)
1089
                  5'b01xxx : gen_src1 = {auop_s, idx_1,9'h000,8'h07,4'h0,src1_addr[2:0],3'b111,atys[0]};
1090
                  // Memory relativ : 0(0(SB))
1091 11 ns32kum
                  5'b100xx : gen_src1 = {4'b1011,4'h0, 9'h000,8'h06,usp_1,                        4'b1111};                     // 1. access always full
1092 9 ns32kum
                  // Immediate
1093
                  5'b10100 : gen_src1 = (src1_le == 2'b11) ?
1094
                                                                {4'h0,   4'h0, 9'h000,8'h0B,src_x,                        1'b1,2'b10,1'b0}      // load in DWord pieces
1095
                                                          : {4'h0,   4'h0, 9'h000,8'h07,src_x,                    1'b1,src1_le,1'b0};
1096 11 ns32kum
                  5'b10101 : gen_src1 = {auop_s, idx_1,9'h002,8'h07,src_x,                        3'b111,atys[0]};       // Absolut Addressing
1097
                  5'b10110 : gen_src1 = {4'b1011,4'h0, 9'h014,8'h05,7'h1F,                        4'b0001};                     // External with MOD Register +4
1098 9 ns32kum
                  5'b10111 : gen_src1 = (idx_1[2] | atys[2]) ?                                                                                  // Access class "addr" ?
1099
                                                                {auop_s, idx_1,9'h000,8'h07,stack,                        3'b000,atys[0]}        // 0(SP) : no TOS flag
1100
                                                          : {4'b1011,pop_1,       8'h07,stack,                    4'b0001};                     // TOS
1101
                  // Memory Space : 0(SB)
1102 11 ns32kum
                  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
1103 9 ns32kum
                  5'b11001 : gen_src1 = {auop_s, idx_1,9'h000,8'h07,stack,                        3'b111,atys[0]};       // SP
1104
                  5'b11011 : gen_src1 = {auop_s, idx_1,9'h001,8'h07,src_x,                        3'b111,atys[0]};       // PC relativ
1105
                  default  : gen_src1 = 36'hx_xxxx_xxxx;        // don't care
1106
                endcase
1107
 
1108
        assign adrd1 = {(mpoi_1 ? 2'b10 : src1_le),gen_src1[35:19]};    // Addressfield : 19 Bits
1109
        assign phrd1 = gen_src1[18:11];                                 // next phase
1110
        assign rega1 = gen_src1[10:4];                                  // Source 1 Register
1111
        assign irrw1 = {4'b0,idx_feld[2:0]};                     // Index-Register
1112
        assign nxrd1 = gen_src1[3:0];                                    // Memory/Disp/Immediate operation
1113
        assign exr11 = {2'b10  ,4'b1011,4'h0 ,9'h080};  // 2. access external with Mem.-Pointer + 4* Disp
1114
        assign exr12 = {src1_le,auop_s,idx_1,9'h000};   // for Memory Relative and EXT in last step
1115
 
1116
        // Source 2 resp. Destination
1117
 
1118
        assign rmw = src2_flag & dest_flag;
1119
        assign idx_2 = {1'b0,(op_feld[17:15] == 3'b111),op_feld[14:13]};        // 4 bits
1120
        assign src2_addr = idx_2[2] ? idx_feld[15:11] : op_feld[17:13];
1121
        assign usp_2 = src2_addr[0] ? stack : {5'b0_0110,src2_addr[1:0]};
1122
        assign src_2l = {src_2[6:1],1'b0};
1123 11 ns32kum
        assign mpoi_2 = (src2_addr[4:2] == 3'b100) | (src2_addr == 5'h16);      // Pointer in memory always DWord
1124 9 ns32kum
        assign auop_d = atyd[0] ? 4'b1011 : 4'b0010;     // Only make effective address ?
1125
 
1126
        // The next assessment processes TOS separated for PUSH and POP
1127
        assign tos_oper =                       src2_flag ?
1128 11 ns32kum
                                                                {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
1129
                                                          : {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
1130 9 ns32kum
 
1131
        // Nextfield : 11=DISP read
1132
        // Address field : Size:2 RD WR LDEA FULLACC INDEX:4 SPUPD disp_val:4 POST CLRMSW SRC2SEL:2
1133
        always @(*)
1134
                casex (src2_addr)       //       RW:W  RW:R  LF    IDX   ADDR_F NEUP   SRC_REG          NEXT
1135 11 ns32kum
                  // Special case which is only valid at INDEX or "addr" : REG -> ADDR , DISP=0 : starts immediate at read
1136
                  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]};
1137 9 ns32kum
                  // Register relativ : 0(R0)
1138 11 ns32kum
                  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]};
1139 9 ns32kum
                  // Memory relativ : 0(0(SB))
1140 11 ns32kum
                  5'b100xx : gen_src2 = {2'b10,2'b10,2'b11,4'h0, 9'h000,4'h6,usp_2,             4'b1111};       // 1. access always full
1141 9 ns32kum
                  // Immediate
1142
                  5'b10100 : gen_src2 = (src2_le == 2'b11) ?
1143
                                                                {2'b00,2'b00,2'b00,4'h0, 9'h000,4'hB,src_x,             1'b1,2'b10,1'b0}        // load in DWord pieces
1144
                                                          : {2'b00,2'b00,2'b00,4'h0, 9'h000,4'h7,src_x,         1'b1,src2_le,1'b0};
1145 11 ns32kum
                  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
1146
                  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
1147 9 ns32kum
                  5'b10111 : gen_src2 = (idx_2[2] | rmw | atyd[2]) ?
1148 11 ns32kum
                                                                {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
1149 9 ns32kum
                                                          : tos_oper;   // TOS : 2 cases for PUSH and POP
1150
                  // Memory Space
1151 11 ns32kum
                  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]};
1152 9 ns32kum
                  5'b11001 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h000,4'h7,stack,               3'b111,atyd[0]};
1153 11 ns32kum
                  5'b11011 : gen_src2 = {1'b0,atyd[0],auop_d,     idx_2,9'h001,4'h7,src_x,               3'b111,atyd[0]}; // PC relativ
1154 9 ns32kum
                  default  : gen_src2 = 34'hx_xxxx_xxxx;        // don't care
1155
                endcase
1156
 
1157
        assign adrd2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[31:15]};
1158
        assign adwr2 = {(mpoi_2 ? 2'b10 : src2_le),gen_src2[33:32],gen_src2[29:15]};
1159
        assign phrd2 = {4'h1,gen_src2[14:11]};                          // Phase for Read Source 2
1160
        assign phwr2 = {4'h2,gen_src2[14:11]};                          // Phase for Write Destination
1161
        assign rega2 = gen_src2[10:4];
1162
        assign nxrw2 = gen_src2[3:0];
1163
        assign irrw2 = {4'b0,idx_feld[10:8]};
1164
        assign re_wr = {src2_le,4'b0101,4'h0, 9'h003};          // REUSE Address : Write of rmw
1165 11 ns32kum
        assign exr22 = {src2_le,atyd[0],1'b0,1'b1,atyd[0],idx_2,9'h000};  // for Memory Relative and EXT in last step
1166
        assign exw22 = {src2_le,1'b0,atyd[0],1'b1,atyd[0],idx_2,9'h000};  // for Memory Relative and EXT in last step
1167 9 ns32kum
 
1168
        // Special case :
1169
 
1170
        assign quei1 = acc1 ? imme : src_1l;    // 8B passing either from register or from extern
1171
        // 8B is requested from both operands but only to certain times
1172
        assign qword = (phase_reg[7:4] != 4'h0) ? (src2_le == 2'b11) :  (src1_le == 2'b11);
1173
        assign quet1 = acc1 ? temp_h : src_1;   // select source during calculation
1174
 
1175
        // Output data of state machine 
1176
        //                                                      LOAD if  PULS if        simple
1177
        //                                      NEXT -> ENABLE   ENABLE         out
1178
        //  [66:48] 19  ADDR :                  X                                               ; Op-length REUSE RD/WR etc.
1179
        //      [47:40]  8      new phase               X
1180
        //      [39:33]  7      SRC1                                                    X
1181
        //      [32:26]  7      SRC2                                                    X
1182
        //         [25]  1      WREN                                    X
1183
        //      [24:19]  6      DEST                    X
1184
        //       [18:8] 11      OPER                    X
1185
        //        [7:6]  2      START                                   X
1186
        //        [5:4]  2      LD_OUT                                  X
1187
        //      [3]  1  ID Load                 X
1188
        //        [2:1]  2      ID Type                 X                                               ; 0 = DISP
1189
        //              [0]  1  MEM Access              X
1190
 
1191
        // State         acc2-src2_flag-dest_flag
1192
        // no SRC2      x               0                x
1193
        // SRC2=REG             0                1               0        ; CMP+TBIT
1194
        // SRC2=REG             0                1               1       ; all else
1195
        // SRC2=MEM             1               1               0        ; CMP+TBIT
1196
        // SRC2=MEM             1               1               1       ; all else
1197
 
1198
        // Input data for state machine
1199
 
1200
        //      8 phase_reg :   phase of state machine
1201
        //      2 otype :               Opcode type
1202
 
1203
        //      1 idx :                 Index is available : 1 or 2 , only PHASE_0
1204
        //      1 short_op :    short opcodes like ADDQ
1205
        //      1 long :                "long" opcode
1206
        //      1 qword :               8B access at Source (Exception DEI+MEI)
1207
 
1208
        //      1 acc1 :                Reg/Extern SRC1
1209
        //      1 acc2 :                Reg/Extern SRC2
1210
        //      1 src2_flag :   the 2. operand is being read
1211
        //      1 dest_flag :   there is a target operand : only CMP and TBIT have none
1212
 
1213
        assign phase_ein = abbruch ? 8'h00 : phase_reg;
1214
 
1215
        always @(*)             //                 "_"                                           "_"
1216
                casex ({phase_ein,otype, idx,short_def,long,qword, acc1,acc2,src2_flag,dest_flag})
1217 11 ns32kum
 {8'h00,10'b00_1xxx_xxxx}:       // Index must be loaded : phase 2 : in any case load TEMP for Short-Op and generate LD_OUT
1218 9 ns32kum
                                                        new_op = short_op ?     //                                                                                      START LD_OUT
1219
                                                                         {addr_nop,8'h02, imme, src_x, 1'b1,temp_h,             op_sho, 2'b00,2'b10,    1'b1,n_idx,1'b0}
1220
                                                                   : {addr_nop,8'h02, src_1,src_1l,1'b0,dest_x,         opera,  2'b00,~src2_flag,2'b1_1,n_idx,1'b0};
1221
 {8'h00,10'b00_01xx_x0xx}:       // Short-Op to register, LD_OUT because of CMPQ
1222
                                                        new_op = {addr_nop,goacb, imme, src_2,dest_flag,dest_r, opera,  2'b00,2'b10,    4'h0};
1223
 {8'h00,10'b00_01xx_x11x}:       // Short-Op : external operand read : SRC2 ! Data in TEMP ! Here no Index
1224
                                                        new_op = {adrd2,   phrd2, imme, rega2, 1'b1,temp_h,             op_mov, 2'b00,2'b00,    nxrw2};
1225
 {8'h00,10'b00_01xx_x10x}:       // MOVQ to Mem
1226
                                                        new_op = {adwr2,   phwr2, imme, rega2, 1'b0,dest_x,             opera,  2'b00,2'b10,    nxrw2};
1227
 {8'h00,10'b00_0000_00xx}:       // simple register operation : dest_flag controls WREN, LD_OUT for CMP
1228
                                                        new_op = {addr_nop,dowait,src_1,src_2, dest_flag,dest_r,opera,  2'b00,2'b10,    4'h0};
1229
 {8'h00,10'b00_0001_00xx}:       // "simple" Reg-Op of 8B, phase 8 after 2. DWord , not via LONG-path
1230
                                                        new_op = {addr_nop,8'h08, src_1,src_x, 1'b1,dest_r,             opera,  2'b00,2'b00,    4'h0};
1231
 {8'h00,10'b00_0010_00xx}:       // long register operation i.e. DIV - phase 31
1232
                                                        new_op = {addr_nop,8'h1F, src_1,src_2, wlor,dest_r,             opera,  2'b11,2'b00,    4'h0};
1233
 {8'h00,10'b00_0011_001x}:       // long register operation with QWORD - phase 26 then wait
1234
                                                        new_op = {addr_nop,8'h1A, src_1,src_2, 1'b0,dest_r,             opera,  2'b01,2'b00,    4'h0};
1235
 {8'h00,10'b00_00xx_1xxx}:       // Source 1 in memory - first to read , here no Index
1236
                                                        new_op = {adrd1,   phrd1, src_x,rega1, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrd1};
1237
 {8'h00,10'b00_00xx_011x}:       // Source 2 in memory - first to read (Source 1 in register)
1238
                                                        new_op = {adrd2,   phrd2, src_x,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1239
 {8'h00,10'b00_0000_0101}:       // Source 1 store in Dest : "pass through" for MOV,NEG,ABS
1240
                                                        new_op = {adwr2,   phwr2, src_1,rega2, 1'b0,dest_x,             opera,  2'b00,2'b10,    nxrw2};
1241 11 ns32kum
 {8'h00,10'b00_0001_0101}:       // Source 1 store in Dest : "pass through" for MOV,NEG,ABS for Long operands
1242
                                                        new_op = //(op_feld[17:13] == 5'h17) ?  // TOS : special case , first 8B out of Reg and then read SP
1243 9 ns32kum
                                                                         {addr_nop,8'h1C, src_1,src_1l,1'b0,dest_x,             opera,  2'b00,2'b11,    4'h0};
1244
 {8'h00,10'b00_0010_0101}:       // SRC1 -> DEST with short operands 
1245
                                                        new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_r,             opera,  2'b11,2'b00,    4'h0};
1246
 {8'h00,10'b00_0011_0x01}:       // SRC1 -> DEST i.e. ROUNDLi
1247
                                                        new_op = {addr_nop,8'h1F, src_1,src_1l,wlor,dest_r,             opera,  2'b11,2'b00,    4'h0};
1248
 
1249
                // Phase 2 : after read of Index nearly everything is repeated from PHASE_0
1250
 {8'h02,10'bxx_x1xx_x11x}:       // Short-Op : external operand read
1251
                                                        new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1252
 {8'h02,10'bxx_x1xx_x101}:       // MOVQ to Mem, data is in Out-Register
1253
                                                        new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1254
 {8'h02,10'bxx_x0xx_1xxx}:       // Source 1 in memory - first to read
1255
                                                        new_op = {adrd1,   phrd1, irrw1,rega1, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrd1};
1256
 {8'h02,10'bxx_x0xx_011x}:       // Source 2 in memory - first to read
1257
                                                        new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1258 11 ns32kum
 {8'h02,10'bxx_x00x_0101}:       // Source 1 store in Dest : "pass through" , data is already in Out-Register
1259 9 ns32kum
                                                        new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1260
 {8'h02,10'bxx_x010_0101}:       // SRC1 -> DEST with short operands
1261
                                                        new_op = {addr_nop,8'h1F, src_1,src_x, 1'b0,dest_x,             opera,  2'b11,2'b00,    4'h0};
1262
 {8'h02,10'bxx_x011_0101}:       // SRC1 -> DEST i.e. ROUNDLi 
1263
                                                        new_op = {addr_nop,8'h1F, src_1,src_1l,1'b0,dest_x,             opera,  2'b11,2'b00,    4'h0};
1264
 
1265
        // +++++++++++++++++  SRC1 operand loading  +++++++++++++++++++
1266
 
1267
                // Phase 5 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
1268
                //              next phase fix : 6
1269 11 ns32kum
 {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};
1270 9 ns32kum
                // Phase 6 : Memory-Pointer for Memory Relative and last access External
1271
                //              next phase fix : 7 , add Index
1272 11 ns32kum
 {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]};
1273 9 ns32kum
 
1274
                // Phase 7 : wait for final data , direct from PHASE_0 if TOS without Index
1275
                //              next phase : if 8B data phase 8 is neccessary
1276
                // if SRC2=REG execution started (otherwise store data in TEMP) and PHASE_0
1277 11 ns32kum
 {8'h07,10'bxx_xx00_x0xx}:       // into Register , short operation execution , but LD_OUT for PSR Update ! dest_flag => WREN
1278 9 ns32kum
                                                        new_op = {addr_nop,endea, imme, src_2, dest_flag,dest_r,opera,  2'b00,2'b10,    diacb};
1279
 {8'h07,10'bxx_xx01_x0xx}:       // into Reg but with a step om between for ABSL etc. : phase 8
1280
                                                        new_op = {addr_nop,8'h08, imme, src_x, 1'b1,dest_r,             opera,  2'b00,2'b00,    4'h0};
1281
 {8'h07,10'bxx_xx10_x0xx}:       // execute long operation , wait in phase 31
1282
                                                        new_op = {addr_nop,8'h1F, imme, src_2, wlor,dest_r,             opera,  2'b11,2'b00,    4'h0};
1283 11 ns32kum
 {8'h07,10'bxx_xx11_xx0x}:       // execute long operation : 2. operand only Dest , load LSD , phase 24 , wait in phase 31
1284 9 ns32kum
                                                        new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l,             op_mov, 2'b01,2'b00,    4'h0};
1285
 {8'h07,10'bxx_xx11_x01x}:       // lange Operation ausfuehren , LSD laden , phase 25 , warten in phase 31
1286
                                                        new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r,             opera,  2'b01,2'b00,    4'h0};
1287
 {8'h07,10'bxx_xxx0_x11x}:       // Data into TEMP , read 2. operand , is there Index ? Yes -> phase 15
1288
                                                        new_op = idx_2[2] ?
1289
                                                                         {addr_nop,8'h0F, imme, src_x, 1'b1,temp_h,             op_mov, 2'b00,2'b00,    4'h0}
1290
                                                                   : {adrd2,   phrd2, imme, rega2, 1'b1,temp_h,         op_mov, 2'b00,2'b00,    nxrw2};
1291 11 ns32kum
 {8'h07,10'bxx_xxx1_x11x}:       // 8B data in TEMP , step in between then 2. Op read : phase 10 - can only be "long" operation
1292 9 ns32kum
                                                        new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h,             op_mov, 2'b00,2'b00,    4'h0};
1293
 {8'h07,10'bxx_xx00_x101}:       // something like ABSi , execute and store (LD_OUT)
1294
                                                        new_op = idx_2[2] ?
1295
                                                                         {addr_nop,8'h10, imme, src_x, 1'b0,dest_x,             opera,  2'b00,2'b10,    4'h0}
1296
                                                                   : {adwr2,   phwr2, imme, rega2, 1'b0,dest_x,         opera,  2'b00,2'b10,    nxrw2};
1297 11 ns32kum
 {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
1298 9 ns32kum
                                                        new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x,             opera,  2'b00,2'b10,    4'h0};
1299
 {8'h07,10'bxx_xx10_x101}:       // opcodes like MOVFL
1300
                                                        new_op = {addr_nop,8'h1F, imme, src_x, 1'b0,dest_x,             opera,  2'b11,2'b00,    4'h0};
1301
 
1302
                // Phase 8 : 2. part of 64 bit data : can be reached from PHASE_0 if 8B data
1303 11 ns32kum
 {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};
1304 9 ns32kum
                // Phase 9 : step in between to get data in OUT-Reg Low , SRC1 is not possible
1305
 {8'h09,10'bxx_xxxx_xxxx}:       // afterwards to data write
1306
                                                        new_op = {addr_nop,8'h10, src_x,imme , 1'b0,dest_x,             op_mov, 2'b00,2'b01,    4'h0};
1307
                // Phase 10 : LSD data write in TEMP , source can be IMME data to
1308
 {8'h0A,10'bxx_xxxx_xxxx}:       // 8B , after TEMP there can only be a 2. operand
1309
                                                        new_op = idx_2[2] ?
1310
                                                                         {addr_nop,8'h0F, imme, src_x, 1'b1,temp_l,             op_mov, 2'b00,2'b00,    4'h0}
1311
                                                                   : {adrd2,   phrd2, imme, rega2, 1'b1,temp_l,         op_mov, 2'b00,2'b00,    nxrw2};
1312
 
1313
                // Phase 11 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
1314
 {8'h0B,10'bxx_xx0x_x0xx}:       // into Reg with step in between for ABSL etc. : phase 12
1315
                                                        new_op = {addr_nop,8'h0C, imme, src_x, 1'b1,dest_r,             opera,  2'b00,2'b00,    4'b1100};
1316
 {8'h0B,10'bxx_xx1x_x01x}:       // execute long operation , load LSD , phase 25 , wait in phase 31
1317
                                                        new_op = {addr_nop,8'h19, imme, src_2, 1'b0,dest_r,             opera,  2'b01,2'b00,    4'b1100};
1318 11 ns32kum
 {8'h0B,10'bxx_xxxx_x11x}:       // 8B data into TEMP , step in between then read 2. Op : phase 10 - can only be "long" operation
1319 9 ns32kum
                                                        new_op = {addr_nop,8'h0A, imme, src_x, 1'b1,temp_h,             op_mov, 2'b00,2'b00,    4'b1100};
1320 11 ns32kum
 {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
1321 9 ns32kum
                                                        new_op = {addr_nop,8'h09, imme, src_x, 1'b0,dest_x,             opera,  2'b00,2'b10,    4'b1100};
1322 11 ns32kum
 {8'h0B,10'bxx_xx1x_xx0x}:       // MOVLF with 8B IMME data ? Must be possible, the end in phase 24 like SRC1=MEM
1323 9 ns32kum
                                                        new_op = {addr_nop,8'h18, imme, src_x, 1'b1,temp_l,             op_mov, 2'b01,2'b00,    4'b1100};
1324
                // Phase 12 : wait for 2. part of 64 bit IMME data : after phase 0
1325 11 ns32kum
 {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};
1326 9 ns32kum
 
1327
                // Phase 15 : secure in TEMP with Index continue and read 2. operand
1328 11 ns32kum
 {8'h0F,10'bxx_xxxx_xxxx}:       new_op = {adrd2,   phrd2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1329 9 ns32kum
                // Phase 16 : after LD_OUT continue with Index and store 1. operand
1330 11 ns32kum
 {8'h10,10'bxx_xxxx_xxxx}:       new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1331 9 ns32kum
 
1332
        // +++++++++++++++++  SRC2 operand loading : phase SRC1 + 16  +++++++++++++++++++
1333
 
1334
                // Phase 21 : wait for data and Disp2 for external addressing : part 2 EA = (MOD+4)+4*DISP1
1335
                //              next phase fix : 22
1336 11 ns32kum
 {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};
1337 9 ns32kum
                // Phase 22 : Memory-Pointer for Memory Relative and last access external
1338
                //              next phase fix : 23 , add Index
1339 11 ns32kum
 {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]};
1340 9 ns32kum
 
1341
                // Phase 23 : wait for final data , direct from PHASE_0 if TOS without Index
1342
                //              next phase : if 8B data phase 24 is used
1343 11 ns32kum
 {8'h17,10'bxx_xx0x_xxx1}:       // execute short operation and write data into memory , no WREN -> phase 39 ACC_DONE
1344 9 ns32kum
                                                        new_op = {re_wr,   8'h27, quet1,imme , 1'b0,dest_r,             opera,  2'b00,2'b10,    4'b0001};
1345
 {8'h17,10'bxx_xx0x_xxx0}:       // execute short operation , no WREN -> phase 0 , CMP(+TBIT)
1346
                                                        new_op = {addr_nop,endea, quet1,imme , 1'b0,dest_r,             opera,  2'b00,2'b10,    diacb};
1347
 {8'h17,10'bxx_xx10_xxxx}:       // execute long operation , wait in phase 31
1348
                                                        new_op = {addr_nop,8'h1F, quet1,imme , wlor,dest_r,             opera,  2'b11,2'b00,    4'h0};
1349
 {8'h17,10'bxx_xx11_xxxx}:       // execute long operation , load LSD in phase 24
1350
                                                        new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r,             opera,  2'b01,2'b00,    4'h0};
1351 11 ns32kum
                // Phase 24 : load 2. part of 64 bit data : with and without wait - from 28 the phase waits , from 23 not
1352 9 ns32kum
 {8'h18,10'bxx_xxxx_0xxx}:       // execute long operation , wait in phase 31
1353
                                                        new_op = {addr_nop,8'h1F, src_1l,imme, wlor,dest_r,             opera,  2'b10,2'b00,    4'h0};
1354 11 ns32kum
 {8'h18,10'bxx_xxxx_1xxx}:       // execute long operation , wait in phase 31 , data from TEMP, used also for ROUNDLi
1355 9 ns32kum
                                                        new_op = {addr_nop,8'h1F, rtmpl,imme,  wlor,dest_r,             opera,  2'b10,2'b00,    4'h0};
1356
                // Phase 25 : load 2. part of 64 bit data : SRC1 from memory and SRC2 from Reg
1357
 {8'h19,10'bxx_xxxx_xxxx}:       // execute long operation , wait in phase 31
1358
                                                        new_op = {addr_nop,8'h1F, imme, src_2l,wlor,dest_r,             opera,  2'b10,2'b00,    4'h0};
1359
                // Phase 26 : load 2. part of 64 bit data : SRC1 from Reg and SRC2 from Reg
1360
 {8'h1A,10'bxx_xxxx_xxxx}:       // execute long operation , wait in phase 31
1361
                                                        new_op = {addr_nop,8'h1F, src_1l,src_2l,wlor,dest_r,    opera,  2'b10,2'b00,    4'h0};
1362
 
1363
                // Phase 27 : wait for 8B IMME data : switch over at address decoder , qword flag is for sure "1"
1364
 {8'h1B,10'bxx_xxxx_xxxx}:       // execute long operation , load LSD in phase 24
1365
                                                        new_op = {addr_nop,8'h18, quet1,imme , 1'b0,dest_r,             opera,  2'b01,2'b00,    4'b1100};
1366
 
1367
        // +++++++++++++++++  special case  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1368
                // Phase 28 : TOS with 8B SRC1 operand , no Index ! Jump to phase 39
1369
 {8'h1C,10'bxx_xxxx_xxxx}:       // store Source 1 in Dest : "pass through" for MOV,NEG,ABS
1370
                                                        new_op = {adwr2,   phwr2, src_x,rega2, 1'b0,dest_x,             opera,  2'b00,2'b00,    nxrw2};
1371
        // +++++++++++++++++  close operation : write out DEST , TOS update  +++++++++++++++++++
1372
 
1373
                // Phase 31 : wait for DONE of long operation
1374
 {8'h1F,10'bxx_xxxx_xxx0}:       // CMP done -> phase 0
1375
                                                        new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r,             opera,  2'b00,2'b10,    4'h0};  // no ACB
1376
 {8'h1F,10'bxx_xxxx_x0x1}:       // operation closed , data into register
1377
                                                        new_op = {addr_nop,8'h00, src_x,src_x, 1'b0,dest_r,             opera,  2'b00,2'b00,    4'h0};  // no ACB
1378 11 ns32kum
 {8'h1F,10'bxx_xxxx_x101}:       // operation closed , data into memory - first calculate address phase 32+x
1379 9 ns32kum
                                                        new_op = {adwr2,   phwr2, irrw2,rega2, 1'b0,dest_r,             opera,  2'b00,2'b00,    nxrw2};
1380
 {8'h1F,10'bxx_xxxx_x111}:       // operation closed , data into memory - address reuse phase 39 ACC_DONE
1381
                                                        new_op = {re_wr,   8'h27, src_x,src_x, 1'b0,dest_r,             opera,  2'b00,2'b00,    4'b0001};
1382
 
1383
                // Destination address calculate
1384
                // Phase 37 : wait for data and Disp2 for External addressing : part 2 EA = (MOD+4)+4*DISP1
1385
                //              next phase fix : 38
1386 11 ns32kum
 {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};
1387 9 ns32kum
                // Phase 38 : Memory-Pointer for Memory Relative and letzter Zugriff External
1388
                //              next phase fix : 39 , add Index and write
1389 11 ns32kum
 {8'h26,10'bxx_xxxx_xxxx}:       new_op = {exw22,   8'h27, irrw2,imme , 1'b0,dest_x,             opera,  2'b00,2'b00,    4'b1111};
1390 9 ns32kum
 
1391
                // Phase 39 : wait for ACC_DONE : consequent numbering : 7+32
1392
 {8'h27,10'bxx_xxxx_xxxx}:       // now operation closed , only ACB could follow
1393
                                                        new_op = {addr_nop,endea, src_x,src_x, 1'b0,dest_x,             opera,  2'b00,2'b00,    diacb};
1394
 
1395
        // +++++++++++++++ special case : ACB to Reg is to fast ! One wait cycle for ZERO-Flag
1396 11 ns32kum
 {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};
1397 9 ns32kum
 
1398
        // +++++++++++++++  The other opcodes are following  ++++++++++++++++++
1399
 
1400 11 ns32kum
 {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
1401 9 ns32kum
 
1402
                // Phase 1 : used for Bcond and ACB :
1403
 {8'h01,10'bxx_xxxx_xxxx}:       new_op = (ex_br_op[1] | jsr_flag) ?     // BSR or JSR ?
1404
                                                                         {push_op, 8'h27, imme, stack, 1'b0,dest_x,             op_mov, 2'b00,2'b10,    4'b0001}        // wait at end
1405
                                                                   : {addr_nop,8'h00, src_x,src_x, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'h0};
1406
 
1407
                // Phase 42 : RET : read of PC from Stack and DIN via SRC1 to PC
1408 11 ns32kum
 {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};
1409
                // Phase 43 : RET : Displacement add to Stack. Attention : "imme" important to keep source constant for PC
1410
 {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};
1411 9 ns32kum
                // Phase 44 : RET : Update of Stack : fixed phase
1412 11 ns32kum
 {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};
1413 9 ns32kum
 
1414
                // Phase 45 : ENTER Entry
1415 11 ns32kum
 {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};
1416 9 ns32kum
                // Phase 46 : ENTER Stack longer
1417 11 ns32kum
 {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};
1418 9 ns32kum
                // Phase 48 : SAVE/ENTER : Init phase , phases 48 & 49 very similar
1419
 {8'h30,10'bxx_xxxx_xxxx}:       new_op = save_reg ?
1420
                                                                         {push_op, 8'h31, saver,stack, 1'b0,dest_x,             op_mov, 2'b00,2'b10,    4'h1}   // 1. load SP=>EA
1421 11 ns32kum
                                                                   : {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov,      2'b00,2'b00,    4'h0};  // At ENTER FP Update
1422 9 ns32kum
                // Phase 49 : SAVE/ENTER : at the same time memory access and detection of next Reg
1423
 {8'h31,10'bxx_xxxx_xxxx}:       new_op = save_reg ?
1424
                                                                         {push_ea, 8'h31, saver,src_x, 1'b0,dest_x,             op_mov, 2'b00,2'b10,    4'h1}   // one more
1425 11 ns32kum
                                                                   : {addr_nop,8'h00, rtmpl,src_x,new_fp,frame[5:0],op_mov,      2'b00,2'b00,    4'h0};  // At ENTER FP Update
1426 9 ns32kum
 
1427
                // Phase 50 : RESTORE/EXIT Entry
1428
 {8'h32,10'bxx_xxxx_xxxx}:       new_op = save_reg ?
1429
                                                                         {pop_op,  8'h33, src_x,stack, 1'b0,dest_x,             op_mov, 2'b00,2'b00,    4'h1}
1430
                                                                   : {pop_fp,  ppfp,  src_x,frame, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    3'h0,new_fp};
1431
                // Phase 51 : RESTORE/EXIT next reg
1432
 {8'h33,10'bxx_xxxx_xxxx}:       new_op = save_reg ?
1433
                                                                         {next_po, 8'h33, imme, src_x, 1'b1,resto,              op_mov, 2'b00,2'b00,    4'h1}
1434
                                                                   : {pop_fp,  ppfp,  imme, frame, 1'b1,resto,          op_mov, 2'b00,2'b00,    3'h0,new_fp};
1435
                // Phase 52 : EXIT End
1436 11 ns32kum
 {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};
1437 9 ns32kum
 
1438
                // Phase 53 : CXP Entry : this opcode needs 12 States and 16 cycles minimum ...
1439 11 ns32kum
 {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};
1440 9 ns32kum
                // Phase 54 : CXP : Store Address Link table
1441 11 ns32kum
 {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
1442 9 ns32kum
                // Phase 55 : CXP : DISP is worked on, the return address => temp_l
1443 11 ns32kum
 {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
1444 9 ns32kum
                // Phase 56 : CXP : Access to Link table => Result is MOD-Entry => store in temp_h
1445 11 ns32kum
 {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};
1446 9 ns32kum
                // Phase 57 : CXP : store and PUSH MOD prepare , Entry from Exception Processing
1447 11 ns32kum
 {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};
1448 9 ns32kum
                // Phase 58 : CXP : PUSH of MOD ongoing, PUSH PC prepare
1449 11 ns32kum
 {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};
1450 9 ns32kum
                // Phase 59 : CXP : New EA for PC
1451 11 ns32kum
 {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};
1452 9 ns32kum
                // Phase 60 : CXP : write of PC, calculate of Offset
1453 11 ns32kum
 {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};
1454 9 ns32kum
                // Phase 61 : CXP : read from (MOD:New+8)
1455 11 ns32kum
 {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
1456 9 ns32kum
                // Phase 62 : CXP : EA Phase of SB read , new PC calculated
1457 11 ns32kum
 {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};
1458 9 ns32kum
                // Phase 63 : CXP : read of SB , new PC to ICache
1459 11 ns32kum
 {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
1460 9 ns32kum
                // Phase 47 : CXP : Last phase update of MOD prepare
1461 11 ns32kum
 {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
1462 9 ns32kum
 
1463
                // Phase 64 : RXP Entry : POP of PC , full Access
1464 11 ns32kum
 {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};
1465 9 ns32kum
                // Phase 65 : RXP : PC is read, next POP prepare
1466 11 ns32kum
 {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};
1467 9 ns32kum
                // Phase 66 : RXP : DISP is addeed to Stack and MOD is read
1468 11 ns32kum
 {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};
1469 9 ns32kum
                // Phase 67 : RXP : MOD is new
1470 11 ns32kum
 {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};
1471 9 ns32kum
                // Phase 68 : RXP : wait for SB data, parallel SP update
1472 11 ns32kum
 {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
1473 9 ns32kum
 
1474
                // Phase 69 : RETI : read of ICU for End-of-Interrupt Cycle , prepare read PC from Stack
1475 11 ns32kum
 {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};
1476 9 ns32kum
                // Phase 70 : RETI/ RETT Entry : POP of PC , full Access
1477 11 ns32kum
 {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};
1478 9 ns32kum
                // Phase 71 : RETI/RETT : PC is read, next POP prepare
1479 11 ns32kum
 {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};
1480 9 ns32kum
                // Phase 72 : RETI/RETT : DISP is added to Stack , PSR load and MOD is loaded if DE off
1481 11 ns32kum
 {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};
1482 9 ns32kum
                // Phase 73 : RETI/RETT : different paths
1483
 {8'h49,10'bxx_xxxx_xxxx}:       new_op = de_flag ?
1484
                                                                         ( reti_flag ?
1485
                                                                     {addr_nop,8'h4A, rtmph,src_x, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'h0}
1486
                                                                   : {addr_nop,8'h4B, src_x,src_x, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'h0} )
1487
                                                                   : {rmod_rtt,8'h4B, rtmph,modul, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'h1};
1488
                // Phase 74 : RETI/RETT : one pause cycle if DE on
1489 11 ns32kum
 {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};
1490 9 ns32kum
                // Phase 75 : RETI/RETT : SB read if DE off
1491
 {8'h4B,10'bxx_xxxx_xxxx}:       new_op = reti_flag ?
1492
                                                                         {addr_nop,8'h00, imme, src_x, 1'b1,6'h1A,              op_mov, 2'b00,2'b00,    4'h0}
1493
                                                                   : ( de_flag ?
1494
                                                                     {adddispn,8'h4E, src_x,ttstak,1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'hE}
1495
                                                                   : {adddispn,8'h4E, imme, ttstak,1'b1,6'h1A,          op_mov, 2'b00,2'b00,    4'hE} );
1496
                // Phase 78 : RETT : SP update
1497 11 ns32kum
 {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};
1498 9 ns32kum
 
1499
        // +++++++++++++++  special wait states for PSR and the Cache/MMU system  +++++++++++
1500
 
1501
                // Phase 76 : PSR in Word case simple delay of 2 cycles : 1. cycle does nothing
1502 11 ns32kum
 {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};
1503
                // Phase 77 : PSR in Word case simple delay of 2 cycles : 2. cycle does Restart of instruction processing
1504
 {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};
1505 9 ns32kum
                // Phase 79 : Wait for INIT_DONE from Cachesystem
1506
 {8'h4F,10'bxx_xxxx_xxxx}:       new_op = (INIT_DONE | no_init) ?
1507
                                                                         {addr_nop,8'h4D, src_x,src_x, 1'b0,dest_x,             op_mov, 2'b00,2'b00,    4'h0}
1508
                                                                   : {addr_nop,8'h4F, src_x,src_x, 1'b0,dest_x,         op_mov, 2'b00,2'b00,    4'h0};
1509
 
1510
        // +++++++++++++++  Direct Exception procession similar to CXP  ++++++++++++++++++++
1511
 
1512
                // Phase 121 : CXP : store and PUSH PSR prepare , Entry of Exception Processing
1513 11 ns32kum
 {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};
1514 9 ns32kum
                // Phase 122 : CXP : PUSH of PSR running, PUSH PC prepare - MOD like normal Exception-Flow
1515 11 ns32kum
 {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};
1516
                // Phase 123 : CXP : New EA for PC , Output of Interrupt-Vector and LOAD_PC generation, continue at standard exit
1517
 {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};
1518 9 ns32kum
 
1519
        // +++++++++++++++  here comes the general Exception Processing  ++++++++++++++++++
1520
 
1521
                // Phase 0 : Entry with saving of PC_ARCHI and PSR
1522 11 ns32kum
 {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};
1523 9 ns32kum
                // Phase 128 : different paths to three cases
1524
 {8'h80,10'bxx_xxxx_xxxx}:       new_op = abo_int ?
1525
                                                                         {ai_next[30:4],  src_x,src_x, 1'b1,temp_l,             op_adr, 2'b00,2'b00,    ai_next[3:0]}
1526
                                                                   : {get_vec, 8'h81, src_x,ibase, 1