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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.5/] [rtl/] [w11a/] [pdp11_sequencer.vhd] - Blame information for rev 16

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

Line No. Rev Author Line
1 2 wfjm
-- $Id: pdp11_sequencer.vhd 314 2010-07-09 17:38:41Z mueller $
2
--
3
-- Copyright 2006-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    pdp11_sequencer - syn
16
-- Description:    pdp11: CPU sequencer
17
--
18
-- Dependencies:   -
19
-- Test bench:     tb/tb_pdp11_core (implicit)
20
-- Target Devices: generic
21
-- Tool versions:  xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25
22
-- Revision History: 
23
-- Date         Rev Version  Comment
24
-- 2010-06-20   307   1.3.1  rename cpacc to cacc in vm_cntl_type
25
-- 2010-06-13   305   1.3    remove CPDIN_WE, CPDOUT_WE out ports; set
26
--                           CNTL.cpdout_we instead of CPDOUT_WE
27
-- 2010-06-12   304   1.2.8  signal cpuwait when spinning in s_op_wait
28
-- 2009-05-30   220   1.2.7  final removal of snoopers (were already commented)
29
-- 2009-05-09   213   1.2.6  BUGFIX: use is_dstkstack1246, stklim for mode=6
30
-- 2009-05-02   211   1.2.5  BUGFIX: 11/70 spl semantics again in kernel mode
31
-- 2009-04-26   209   1.2.4  BUGFIX: give interrupts priority over trap handling
32
-- 2008-12-14   177   1.2.3  BUGFIX: use is_dstkstack124, fix stklim check bug
33
-- 2008-12-13   176   1.2.2  BUGFIX: use is_pci in s_dstw_inc if DSTDEF='1'
34
-- 2008-11-30   174   1.2.1  BUGFIX: add updt_dstadsrc; prevent stale DSRC
35
-- 2008-08-22   161   1.2    rename ubf_ -> ibf_; use iblib
36
-- 2008-05-03   143   1.1.9  rename _cpursta->_cpurust; cp reset sets now
37
--                           c_cpurust_reset; proper c_cpurust_vfail handling
38
-- 2008-04-27   140   1.1.8  BUGFIX: halt cpu in case of a vector fetch error
39
--                           use cpursta to encode why cpu halts, remove cpufail
40
-- 2008-04-27   139   1.1.7  BUGFIX: correct bytop handling for address fetches;
41
--                           BUGFIX: redo mtp flow; add fork_dsta fork and ddst
42
--                                   reload in s_opa_mtp_pop_w;
43
-- 2008-04-19   137   1.1.6  BUGFIX: fix loop state in s_rti_getpc_w
44
-- 2008-03-30   131   1.1.5  BUGFIX: inc/dec by 2 for byte mode -(sp),(sp)+
45
--                             inc/dec by 2 for @(R)+ and @-(R) also for bytop's
46
-- 2008-03-02   121   1.1.4  remove snoopers; add waitsusp, redo WAIT handling
47
-- 2008-02-24   119   1.1.3  add lah,rps,wps command; revamp cp memory access
48
--                           change WAIT logic, now also bails out on cp command
49
-- 2008-01-20   112   1.1.2  rename PRESET->BRESET
50
-- 2008-01-05   110   1.1.1  rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
51
-- 2007-12-30   107   1.1    use IB_MREQ/IB_SRES interface now
52
-- 2007-06-14    56   1.0.1  Use slvtypes.all
53
-- 2007-05-12    26   1.0    Initial version 
54
------------------------------------------------------------------------------
55
 
56
library ieee;
57
use ieee.std_logic_1164.all;
58
use ieee.std_logic_arith.all;
59
 
60
use work.slvtypes.all;
61
use work.iblib.all;
62
use work.pdp11.all;
63
 
64
-- ----------------------------------------------------------------------------
65
 
66
entity pdp11_sequencer is               -- CPU sequencer
67
  port (
68
    CLK : in slbit;                     -- clock
69
    GRESET : in slbit;                  -- global reset
70
    PSW : in psw_type;                  -- processor status
71
    PC : in slv16;                      -- program counter
72
    IREG : in slv16;                    -- IREG
73
    ID_STAT : in decode_stat_type;      -- instr. decoder status
74
    DP_STAT : in dpath_stat_type;       -- data path status
75
    CP_CNTL : in cp_cntl_type;          -- console port control
76
    VM_STAT : in vm_stat_type;          -- virtual memory status port
77
    INT_PRI : in slv3;                  -- interrupt priority
78
    INT_VECT : in slv9_2;               -- interrupt vector
79
    CRESET : out slbit;                 -- console reset
80
    BRESET : out slbit;                 -- ibus reset
81
    MMU_MONI : out mmu_moni_type;       -- mmu monitor port
82
    DP_CNTL : out dpath_cntl_type;      -- data path control
83
    VM_CNTL : out vm_cntl_type;         -- virtual memory control port
84
    CP_STAT : out cp_stat_type;         -- console port status
85
    INT_ACK : out slbit;                -- interrupt acknowledge
86
    IB_MREQ : in ib_mreq_type;          -- ibus request
87
    IB_SRES : out ib_sres_type          -- ibus response    
88
  );
89
end pdp11_sequencer;
90
 
91
architecture syn of pdp11_sequencer is
92
 
93
  constant ibaddr_cpuerr : slv16 := conv_std_logic_vector(8#177766#,16);
94
 
95
  constant cpuerr_ibf_illhlt : integer := 7;
96
  constant cpuerr_ibf_adderr : integer := 6;
97
  constant cpuerr_ibf_nxm : integer := 5;
98
  constant cpuerr_ibf_iobto : integer := 4;
99
  constant cpuerr_ibf_ysv : integer := 3;
100
  constant cpuerr_ibf_rsv : integer := 2;
101
 
102
  type state_type is (
103
    s_idle,
104
    s_cp_regread,
105
    s_cp_rps,
106
    s_cp_memr_w,
107
    s_cp_memw_w,
108
    s_ifetch,
109
    s_ifetch_w,
110
    s_idecode,
111
 
112
    s_srcr_def,
113
    s_srcr_def_w,
114
    s_srcr_inc,
115
    s_srcr_inc_w,
116
    s_srcr_dec,
117
    s_srcr_dec1,
118
    s_srcr_ind,
119
    s_srcr_ind1_w,
120
    s_srcr_ind2,
121
    s_srcr_ind2_w,
122
 
123
    s_dstr_def,
124
    s_dstr_def_w,
125
    s_dstr_inc,
126
    s_dstr_inc_w,
127
    s_dstr_dec,
128
    s_dstr_dec1,
129
    s_dstr_ind,
130
    s_dstr_ind1_w,
131
    s_dstr_ind2,
132
    s_dstr_ind2_w,
133
 
134
    s_dstw_def,
135
    s_dstw_def_w,
136
    s_dstw_inc,
137
    s_dstw_inc_w,
138
    s_dstw_incdef_w,
139
    s_dstw_dec,
140
    s_dstw_dec1,
141
    s_dstw_ind,
142
    s_dstw_ind_w,
143
    s_dstw_def246,
144
 
145
    s_dsta_inc,
146
    s_dsta_incdef_w,
147
    s_dsta_dec,
148
    s_dsta_dec1,
149
    s_dsta_ind,
150
    s_dsta_ind_w,
151
 
152
    s_op_halt,
153
    s_op_wait,
154
    s_op_trap,
155
    s_op_reset,
156
    s_op_rts,
157
    s_op_rts_pop,
158
    s_op_rts_pop_w,
159
    s_op_spl,
160
    s_op_mcc,
161
    s_op_br,
162
    s_op_mark,
163
    s_op_mark1,
164
    s_op_mark_pop,
165
    s_op_mark_pop_w,
166
    s_op_sob,
167
    s_op_sob1,
168
 
169
    s_opg_gen,
170
    s_opg_gen_rmw_w,
171
    s_opg_mul,
172
    s_opg_mul1,
173
    s_opg_div,
174
    s_opg_div_cn,
175
    s_opg_div_cr,
176
    s_opg_div_sq,
177
    s_opg_div_sr,
178
    s_opg_div_zero,
179
    s_opg_ash,
180
    s_opg_ash_cn,
181
    s_opg_ashc,
182
    s_opg_ashc_cn,
183
    s_opg_ashc_wl,
184
 
185
    s_opa_jsr,
186
    s_opa_jsr1,
187
    s_opa_jsr_push,
188
    s_opa_jsr_push_w,
189
    s_opa_jsr2,
190
    s_opa_jmp,
191
    s_opa_mtp,
192
    s_opa_mtp_pop_w,
193
    s_opa_mtp_reg,
194
    s_opa_mtp_mem,
195
    s_opa_mtp_mem_w,
196
    s_opa_mfp_reg,
197
    s_opa_mfp_mem,
198
    s_opa_mfp_mem_w,
199
    s_opa_mfp_dec,
200
    s_opa_mfp_push,
201
    s_opa_mfp_push_w,
202
 
203
    s_trap_4,
204
    s_trap_10,
205
    s_trap_disp,
206
 
207
    s_int_ext,
208
 
209
    s_int_getpc,
210
    s_int_getpc_w,
211
    s_int_getps,
212
    s_int_getps_w,
213
    s_int_getsp,
214
    s_int_decsp,
215
    s_int_pushps,
216
    s_int_pushps_w,
217
    s_int_pushpc,
218
    s_int_pushpc_w,
219
 
220
    s_rti_getpc,
221
    s_rti_getpc_w,
222
    s_rti_getps,
223
    s_rti_getps_w,
224
    s_rti_newpc,
225
 
226
    s_vmerr,
227
    s_cpufail
228
  );
229
 
230
  signal R_STATE : state_type := s_idle;  -- state register
231
  signal N_STATE : state_type := s_idle;
232
 
233
  signal R_STATUS : cpustat_type := cpustat_init;
234
  signal N_STATUS : cpustat_type := cpustat_init;
235
  signal R_CPUERR : cpuerr_type := cpuerr_init;
236
  signal N_CPUERR : cpuerr_type := cpuerr_init;
237
 
238
  signal R_IDSTAT : decode_stat_type := decode_stat_init;
239
  signal N_IDSTAT : decode_stat_type := decode_stat_init;
240
 
241
  signal R_VMSTAT : vm_stat_type := vm_stat_init;
242
 
243
  signal IBSEL_CPUERR : slbit := '0';
244
 
245
begin
246
 
247
  proc_ibsel: process (IB_MREQ)
248
    variable icpuerr : slbit := '0';
249
  begin
250
    icpuerr := '0';
251
    if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_cpuerr(12 downto 1) then
252
      icpuerr := '1';
253
    end if;
254
    IBSEL_CPUERR <= icpuerr;
255
    IB_SRES.ack  <= icpuerr;
256
    IB_SRES.busy <= '0';
257
  end process proc_ibsel;
258
 
259
  proc_ibdout : process (IBSEL_CPUERR, R_CPUERR)
260
    variable cpuerrout : slv16 := (others=>'0');
261
  begin
262
    cpuerrout := (others=>'0');
263
    if IBSEL_CPUERR = '1' then
264
      cpuerrout(cpuerr_ibf_illhlt) := R_CPUERR.illhlt;
265
      cpuerrout(cpuerr_ibf_adderr) := R_CPUERR.adderr;
266
      cpuerrout(cpuerr_ibf_nxm)    := R_CPUERR.nxm;
267
      cpuerrout(cpuerr_ibf_iobto)  := R_CPUERR.iobto;
268
      cpuerrout(cpuerr_ibf_ysv)    := R_CPUERR.ysv;
269
      cpuerrout(cpuerr_ibf_rsv)    := R_CPUERR.rsv;
270
    end if;
271
    IB_SRES.dout <= cpuerrout;
272
  end process proc_ibdout;
273
 
274
  proc_status: process (CLK)
275
  begin
276
    if CLK'event and CLK='1' then
277
      if GRESET = '1' then
278
        R_STATUS <= cpustat_init;
279
        R_CPUERR <= cpuerr_init;
280
        R_IDSTAT <= decode_stat_init;
281
        R_VMSTAT <= vm_stat_init;
282
      else
283
        R_STATUS <= N_STATUS;
284
        R_CPUERR <= N_CPUERR;
285
        R_IDSTAT <= N_IDSTAT;
286
        R_VMSTAT <= VM_STAT;
287
      end if;
288
    end if;
289
  end process proc_status;
290
 
291
  proc_state: process (CLK)
292
  begin
293
    if CLK'event and CLK='1' then
294
      if GRESET = '1' then
295
        R_STATE <= s_idle;
296
      else
297
        R_STATE <= N_STATE;
298
      end if;
299
    end if;
300
  end process proc_state;
301
 
302
  proc_next: process (R_STATE, R_STATUS, PSW, PC, CP_CNTL,
303
                      ID_STAT, R_IDSTAT, IREG, VM_STAT, DP_STAT,
304
                      R_CPUERR, R_VMSTAT, IB_MREQ, IBSEL_CPUERR,
305
                      INT_PRI, INT_VECT)
306
 
307
    variable nstate : state_type;
308
    variable nstatus : cpustat_type := cpustat_init;
309
    variable ncpuerr : cpuerr_type := cpuerr_init;
310
 
311
    variable ncreset : slbit := '0';
312
    variable nbreset : slbit := '0';
313
    variable nintack : slbit := '0';
314
 
315
    variable ndpcntl : dpath_cntl_type := dpath_cntl_init;
316
    variable nvmcntl : vm_cntl_type := vm_cntl_init;
317
    variable nidstat : decode_stat_type := decode_stat_init;
318
    variable nmmumoni : mmu_moni_type := mmu_moni_init;
319
 
320
    variable imemok : boolean;
321
    variable bytop : slbit := '0';           -- local bytop  access flag
322
    variable macc  : slbit := '0';           -- local modify access flag
323
 
324
    variable lvector : slv9_2 := (others=>'0'); -- local trap/interrupt vector
325
 
326
    variable brcode : slv4 := (others=>'0'); -- reduced br opcode (15,10-8)
327
    variable brcond : slbit := '0';          -- br condition value
328
 
329
    variable is_kmode : slbit := '0';        -- cmode is kernel mode
330
    variable is_dstkstack1246 : slbit := '0'; -- dest is k-stack & mode= 1,2,4,6
331
 
332
    variable int_pending : slbit := '0';     -- an interrupt is pending
333
 
334
    alias SRCMOD : slv2 is IREG(11 downto 10); -- src register mode high
335
    alias SRCDEF : slbit is IREG(9);           -- src register mode defered
336
    alias SRCREG : slv3 is IREG(8 downto 6);   -- src register number
337
    alias DSTMODF : slv3 is IREG(5 downto 3);  -- dst register full mode
338
    alias DSTMOD : slv2 is IREG(5 downto 4);   -- dst register mode high
339
    alias DSTDEF : slbit is IREG(3);           -- dst register mode defered
340
    alias DSTREG : slv3 is IREG(2 downto 0);   -- dst register number
341
 
342
    procedure do_memread_i(nstate  : inout state_type;
343
                           ndpcntl : inout dpath_cntl_type;
344
                           nvmcntl : inout vm_cntl_type;
345
                           wstate  : in state_type) is
346
    begin
347
      ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc;       -- VA = PC
348
      nvmcntl.dspace := '0';
349
      nvmcntl.req := '1';
350
      ndpcntl.gpr_pcinc := '1';                      -- (pc)++
351
      nstate := wstate;
352
    end procedure do_memread_i;
353
 
354
    procedure do_memread_d(nstate  : inout state_type;
355
                           nvmcntl : inout vm_cntl_type;
356
                           wstate  : in state_type;
357
                           bytop   : in slbit := '0';
358
                           macc    : in slbit := '0';
359
                           is_pci  : in slbit := '0') is
360
    begin
361
      nvmcntl.dspace := not is_pci;        -- ispace if pc immediate modes
362
--      bytop := R_IDSTAT.is_bytop and not is_addr;
363
      nvmcntl.bytop := bytop;
364
      nvmcntl.macc  := macc;
365
      nvmcntl.req   := '1';
366
      nstate := wstate;
367
    end procedure do_memread_d;
368
 
369
    procedure do_memread_srcinc(nstate   : inout state_type;
370
                                ndpcntl  : inout dpath_cntl_type;
371
                                nvmcntl  : inout vm_cntl_type;
372
                                wstate   : in state_type;
373
                                nmmumoni : inout mmu_moni_type;
374
                                updt_sp  : in slbit := '0') is
375
    begin
376
      ndpcntl.abox_asel := c_abox_asel_dsrc;     -- ABOX A=DSRC
377
      ndpcntl.abox_const := "000000010";         -- ABOX const=2
378
      ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const
379
      ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
380
      ndpcntl.dsrc_sel := c_dpath_dsrc_res;      -- DSRC = DRES
381
      ndpcntl.dsrc_we := '1';                    -- update DSRC
382
      if updt_sp = '1' then
383
        nmmumoni.regmod := '1';
384
        nmmumoni.isdec := '0';
385
        ndpcntl.gpr_adst := c_gpr_sp;            -- update SP too
386
        ndpcntl.gpr_we := '1';
387
      end if;
388
      ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
389
      nvmcntl.dspace := '1';
390
      nvmcntl.req := '1';
391
      nstate := wstate;
392
    end procedure do_memread_srcinc;
393
 
394
    procedure do_memwrite(nstate  : inout state_type;
395
                          nvmcntl : inout vm_cntl_type;
396
                          wstate  : in state_type;
397
                          macc    : in slbit :='0') is
398
    begin
399
      nvmcntl.dspace := '1';
400
      nvmcntl.bytop := R_IDSTAT.is_bytop;
401
      nvmcntl.wacc := '1';
402
      nvmcntl.macc := macc;
403
      nvmcntl.req := '1';
404
      nstate := wstate;
405
    end procedure do_memwrite;
406
 
407
    procedure do_memcheck(nstate  : inout state_type;
408
                          nstatus : inout cpustat_type;
409
                          mok     : out boolean) is
410
    begin
411
      mok := false;
412
      if VM_STAT.ack = '1' then
413
        mok := true;
414
        nstatus.trap_mmu := VM_STAT.trap_mmu;
415
        if R_CPUERR.ysv = '0' then      -- ysv trap when cpuerr not yet set
416
          nstatus.trap_ysv := VM_STAT.trap_ysv;
417
        end if;
418
      elsif VM_STAT.err='1' or VM_STAT.fail='1' then
419
        nstate := s_vmerr;
420
      end if;
421
    end procedure do_memcheck;
422
 
423
    procedure do_const_opsize(ndpcntl : inout dpath_cntl_type;
424
                              bytop   : in slbit;
425
                              isdef   : in slbit;
426
                              regnum  : in slv3) is
427
    begin
428
      if bytop='0' or isdef='1' or
429
         regnum=c_gpr_pc or regnum=c_gpr_sp then
430
        ndpcntl.abox_const := "000000010";
431
      else
432
        ndpcntl.abox_const := "000000001";
433
      end if;
434
    end procedure do_const_opsize;
435
 
436
    procedure do_fork_dstr(nstate : inout state_type;
437
                           idstat : in decode_stat_type) is
438
    begin
439
      case idstat.fork_dstr is
440
        when c_fork_dstr_def => nstate := s_dstr_def;
441
        when c_fork_dstr_inc => nstate := s_dstr_inc;
442
        when c_fork_dstr_dec => nstate := s_dstr_dec;
443
        when c_fork_dstr_ind => nstate := s_dstr_ind;
444
        when others => nstate := s_cpufail;
445
      end case;
446
    end procedure do_fork_dstr;
447
 
448
    procedure do_fork_opg(nstate : inout state_type;
449
                          idstat : in decode_stat_type) is
450
    begin
451
      case idstat.fork_opg is
452
        when c_fork_opg_gen  => nstate := s_opg_gen;
453
        when c_fork_opg_wdef => nstate := s_dstw_def;
454
        when c_fork_opg_winc => nstate := s_dstw_inc;
455
        when c_fork_opg_wdec => nstate := s_dstw_dec;
456
        when c_fork_opg_wind => nstate := s_dstw_ind;
457
        when c_fork_opg_mul  => nstate := s_opg_mul;
458
        when c_fork_opg_div  => nstate := s_opg_div;
459
        when c_fork_opg_ash  => nstate := s_opg_ash;
460
        when c_fork_opg_ashc => nstate := s_opg_ashc;
461
        when others => nstate := s_cpufail;
462
      end case;
463
    end procedure do_fork_opg;
464
 
465
    procedure do_fork_opa(nstate : inout state_type;
466
                          idstat : in decode_stat_type) is
467
    begin
468
      case idstat.fork_opa is
469
        when c_fork_opa_jmp => nstate := s_opa_jmp;
470
        when c_fork_opa_jsr => nstate := s_opa_jsr;
471
        when c_fork_opa_mtp => nstate := s_opa_mtp_mem;
472
        when c_fork_opa_mfp_reg => nstate := s_opa_mfp_reg;
473
        when c_fork_opa_mfp_mem => nstate := s_opa_mfp_mem;
474
        when others => nstate := s_cpufail;
475
      end case;
476
    end procedure do_fork_opa;
477
 
478
    procedure do_fork_next(nstate   : inout state_type;
479
                           nstatus  : inout cpustat_type;
480
                           nmmumoni : inout mmu_moni_type) is
481
    begin
482
      nmmumoni.idone := '1';
483
      if unsigned(INT_PRI) > unsigned(PSW.pri) then
484
        nstate := s_idle;
485
      elsif R_STATUS.trap_mmu='1' or nstatus.trap_mmu='1' or
486
            R_STATUS.trap_ysv='1' or nstatus.trap_ysv='1' or
487
            PSW.tflag='1' then
488
        nstate := s_trap_disp;
489
      elsif R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1' then
490
        nstate := s_ifetch;
491
      else
492
        nstate := s_idle;
493
      end if;
494
    end procedure do_fork_next;
495
 
496
    procedure do_fork_next_pref(nstate   : inout state_type;
497
                                nstatus  : inout cpustat_type;
498
                                ndpcntl  : inout dpath_cntl_type;
499
                                nvmcntl  : inout vm_cntl_type;
500
                                nmmumoni : inout mmu_moni_type) is
501
    begin
502
      nmmumoni.idone := '1';
503
      if unsigned(INT_PRI) > unsigned(PSW.pri) then
504
        nstate := s_idle;
505
      elsif R_STATUS.trap_mmu='1' or nstatus.trap_mmu='1' or
506
            R_STATUS.trap_ysv='1' or nstatus.trap_ysv='1' or
507
            PSW.tflag='1' then
508
        nstate := s_trap_disp;
509
      elsif R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1' then
510
        nvmcntl.req := '1';
511
        ndpcntl.gpr_pcinc := '1';
512
        nmmumoni.istart := '1';
513
        nstate := s_ifetch_w;
514
      else
515
        nstate := s_idle;
516
      end if;
517
    end procedure do_fork_next_pref;
518
 
519
    procedure do_start_int(nstate  : inout state_type;
520
                           ndpcntl : inout dpath_cntl_type;
521
                           vector  : in slv9_2) is
522
    begin
523
      ndpcntl.dtmp_sel := c_dpath_dtmp_psw;    -- DTMP = PSW 
524
      ndpcntl.dtmp_we := '1';
525
      ndpcntl.abox_azero := '1';               -- ABOX A = 0
526
      ndpcntl.abox_const := vector & "00";     -- vector
527
      ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const(vector)
528
      ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
529
      ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
530
      ndpcntl.dsrc_we := '1';                  -- DSRC = vector
531
      nstate := s_int_getpc;
532
    end procedure do_start_int;
533
 
534
  begin
535
 
536
    nstate  := R_STATE;
537
    nstatus := R_STATUS;
538
    ncpuerr := R_CPUERR;
539
 
540
    nstatus.cpuwait := '0';             -- wait flag 0 unless set in s_op_wait
541
 
542
    ncreset := '0';
543
    nbreset := '0';
544
    nintack := '0';
545
 
546
    nidstat := R_IDSTAT;
547
 
548
    if IB_MREQ.we='1' and IBSEL_CPUERR='1' then -- write to CPUERR clears it !!
549
      ncpuerr := cpuerr_init;
550
    end if;
551
 
552
    int_pending := '0';
553
    if unsigned(INT_PRI) > unsigned(PSW.pri) then
554
      int_pending := '1';
555
    end if;
556
 
557
    imemok := false;
558
 
559
    nmmumoni := mmu_moni_init;
560
    nmmumoni.pc := PC;
561
 
562
    macc  := '0';
563
    bytop := '0';
564
    brcode := IREG(15) & IREG(10 downto 8);
565
    brcond := '1';
566
 
567
    is_kmode := '0';
568
    is_dstkstack1246 := '0';
569
 
570
    if PSW.cmode = c_psw_kmode then
571
      is_kmode := '1';
572
      if DSTREG = c_gpr_sp and
573
         (DSTMODF="001" or DSTMODF="010" or
574
          DSTMODF="100" or DSTMODF="110") then
575
        is_dstkstack1246 := '1';
576
      end if;
577
    end if;
578
 
579
    lvector := (others=>'0');
580
 
581
    nvmcntl := vm_cntl_init;
582
    nvmcntl.dspace := '1';                -- DEFAULT
583
    nvmcntl.mode := PSW.cmode;            -- DEFAULT
584
    nvmcntl.intrsv := R_STATUS.do_intrsv; -- DEFAULT
585
 
586
    ndpcntl := dpath_cntl_init;
587
    ndpcntl.gpr_asrc := SRCREG;           -- DEFAULT
588
    ndpcntl.gpr_adst := DSTREG;           -- DEFAULT
589
    ndpcntl.gpr_mode := PSW.cmode;        -- DEFAULT
590
    ndpcntl.gpr_rset := PSW.rset;         -- DEFAULT
591
    ndpcntl.gpr_we := '0';                -- DEFAULT
592
    ndpcntl.gpr_bytop := '0';             -- DEFAULT
593
    ndpcntl.gpr_pcinc := '0';             -- DEFAULT
594
 
595
    ndpcntl.psr_ccwe := '0';              -- DEFAULT
596
    ndpcntl.psr_we := '0';                -- DEFAULT
597
    ndpcntl.psr_func := "000";            -- DEFAULT
598
 
599
    ndpcntl.dsrc_sel := c_dpath_dsrc_src;
600
    ndpcntl.dsrc_we := '0';
601
    ndpcntl.ddst_sel := c_dpath_ddst_dst;
602
    ndpcntl.ddst_we := '0';
603
    ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;
604
    ndpcntl.dtmp_we := '0';
605
 
606
    ndpcntl.abox_asel := c_abox_asel_ddst;
607
    ndpcntl.abox_azero := '0';            -- DEFAULT
608
    ndpcntl.abox_const := (others=>'0');  -- DEFAULT
609
    ndpcntl.abox_bsel := c_abox_bsel_const;
610
    ndpcntl.abox_opsub := '0';            -- DEFAULT
611
 
612
    ndpcntl.dbox_srcmod := R_IDSTAT.dbox_srcmod; -- STATIC
613
    ndpcntl.dbox_dstmod := R_IDSTAT.dbox_dstmod; -- STATIC
614
    ndpcntl.dbox_cimod  := R_IDSTAT.dbox_cimod;  -- STATIC
615
    ndpcntl.dbox_cc1op  := R_IDSTAT.dbox_cc1op;  -- STATIC
616
    ndpcntl.dbox_ccmode := R_IDSTAT.dbox_ccmode; -- STATIC
617
    ndpcntl.dbox_bytop  := R_IDSTAT.is_bytop;    -- STATIC
618
 
619
    ndpcntl.lbox_func   := R_IDSTAT.lbox_func;   -- STATIC
620
    ndpcntl.lbox_bytop  := R_IDSTAT.is_bytop;    -- STATIC
621
 
622
    ndpcntl.mbox_func := R_IDSTAT.mbox_func;     -- STATIC
623
 
624
    ndpcntl.ireg_we := '0';
625
 
626
    ndpcntl.cres_sel := R_IDSTAT.res_sel;        -- DEFAULT
627
    ndpcntl.dres_sel := c_dpath_res_abox;
628
    ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc;
629
 
630
    if CP_CNTL.req='1' and R_STATUS.cmdbusy='0' then
631
      nstatus.cmdbusy := '1';
632
      nstatus.cpfunc  := CP_CNTL.func;
633
      nstatus.cprnum  := CP_CNTL.rnum;
634
    end if;
635
 
636
    if R_STATUS.cmdack = '1' then
637
      nstatus.cmdack  := '0';
638
      nstatus.cmderr  := '0';
639
      nstatus.cmdmerr := '0';
640
    end if;
641
 
642
    case R_STATE is
643
 
644
  -- idle and command port states ---------------------------------------------
645
 
646
      -- Note: s_idle was entered from suspended WAIT when waitsusp='1'
647
      -- --> all exits must check this and either return to s_op_wait
648
      --     or abort the WAIT and set waitsusp='0'
649
 
650
      when s_idle =>
651
 
652
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;   -- VA = DDST (do mux early)
653
        nstatus.cpustep := '0';
654
 
655
        if R_STATUS.cmdbusy = '1' then
656
          case R_STATUS.cpfunc is
657
 
658
            when c_cpfunc_noop =>       -- noop : no operation --------
659
              nstatus.cmdack   := '1';
660
              nstate := s_idle;
661
 
662
            when c_cpfunc_sta =>        -- sta  : cpu start -----------
663
              ncreset          := '1';
664
              nstatus.cmdack   := '1';
665
              nstatus.cpugo    := '1';
666
              nstatus.cpuhalt  := '0';
667
              nstatus.cpurust  := c_cpurust_runs;
668
              nstatus.waitsusp := '0';
669
              nstate := s_idle;
670
 
671
            when c_cpfunc_sto =>        -- sto  : cpu stop ------------
672
              nstatus.cmdack   := '1';
673
              nstatus.cpugo    := '0';
674
              nstatus.cpurust  := c_cpurust_stop;
675
              nstatus.waitsusp := '0';
676
              nstate := s_idle;
677
 
678
            when c_cpfunc_cont =>       -- cont : cpu continue --------
679
              nstatus.cmdack   := '1';
680
              nstatus.cpugo    := '1';
681
              nstatus.cpuhalt  := '0';
682
              nstatus.cpurust  := c_cpurust_runs;
683
              nstatus.waitsusp := '0';
684
              nstate := s_idle;
685
 
686
            when c_cpfunc_step =>       -- step : cpu step ------------
687
              nstatus.cmdack   := '1';
688
              nstatus.cpustep  := '1';
689
              nstatus.cpuhalt  := '0';
690
              nstatus.cpurust  := c_cpurust_step;
691
              nstatus.waitsusp := '0';
692
              if int_pending = '1' then
693
                nintack := '1';
694
                nstatus.intvect := INT_VECT;
695
                nstate := s_int_ext;
696
              else
697
                nstate := s_ifetch;
698
              end if;
699
 
700
            when c_cpfunc_rst =>        -- rst  : cpu reset (soft) ----
701
              ncreset := '1';
702
              nstatus.cmdack   := '1';
703
              nstatus.cpugo    := '0';
704
              nstatus.cpuhalt  := '0';
705
              nstatus.cpurust  := c_cpurust_reset;
706
              nstatus.waitsusp := '0';
707
              nstate := s_idle;
708
 
709
            when c_cpfunc_rreg =>       -- rreg : read register ------
710
              ndpcntl.gpr_adst := R_STATUS.cprnum;
711
              ndpcntl.ddst_sel := c_dpath_ddst_dst;
712
              ndpcntl.ddst_we := '1';
713
              nstate := s_cp_regread;
714
 
715
            when c_cpfunc_wreg =>       -- wreg : write register -----
716
              ndpcntl.dres_sel := c_dpath_res_cpdin;  -- DRES = CPDIN
717
              ndpcntl.gpr_adst := R_STATUS.cprnum;
718
              ndpcntl.gpr_we := '1';
719
              nstatus.cmdack := '1';
720
              nstate := s_idle;
721
 
722
            when c_cpfunc_rpsw =>       -- rpsw : read psw -----------
723
              ndpcntl.dtmp_sel := c_dpath_dtmp_psw;   -- DTMP = PSW 
724
              ndpcntl.dtmp_we := '1';
725
              nstate := s_cp_rps;
726
 
727
            when c_cpfunc_wpsw =>       -- wpsw : write psw ----------
728
              ndpcntl.dres_sel := c_dpath_res_cpdin;  -- DRES = CPDIN
729
              ndpcntl.psr_func := c_psr_func_wall;    -- write all fields
730
              ndpcntl.psr_we := '1';                  -- load new PS
731
              nstatus.cmdack := '1';
732
              nstate := s_idle;
733
 
734
            when c_cpfunc_rmem =>       -- rmem : read memory --------
735
              nvmcntl.cacc := '1';
736
              nvmcntl.req  := '1';
737
              nstate := s_cp_memr_w;
738
 
739
            when c_cpfunc_wmem =>       -- wmem : write memory -------
740
              ndpcntl.dres_sel := c_dpath_res_cpdin;     -- DRES = CPDIN
741
              nvmcntl.wacc := '1';                       -- write mem
742
              nvmcntl.cacc := '1';
743
              nvmcntl.req  := '1';
744
              nstate := s_cp_memw_w;
745
 
746
            when others =>
747
              nstatus.cmdack := '1';
748
              nstatus.cmderr := '1';
749
              nstate := s_idle;
750
 
751
          end case;
752
 
753
        elsif R_STATUS.waitsusp = '1' then
754
          nstatus.waitsusp := '0';
755
          nstate := s_op_wait;
756
 
757
        elsif R_STATUS.cpugo = '1' then
758
          if int_pending = '1' then
759
            nintack := '1';
760
            nstatus.intvect := INT_VECT;
761
            nstate := s_int_ext;
762
          else
763
            nstate := s_ifetch;
764
          end if;
765
 
766
        end if;
767
 
768
      when s_cp_regread =>
769
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A = DDST
770
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B = const(0)
771
        ndpcntl.dres_sel  := c_dpath_res_abox;   -- DRES = ABOX
772
        nstatus.cmdack := '1';
773
        nstate := s_idle;
774
 
775
      when s_cp_rps =>
776
        ndpcntl.abox_asel := c_abox_asel_dtmp;   -- ABOX A = DTMP
777
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B = const(0)
778
        ndpcntl.dres_sel  := c_dpath_res_abox;   -- DRES = ABOX
779
        nstatus.cmdack := '1';
780
        nstate := s_idle;
781
 
782
      when s_cp_memr_w =>
783
        nstate := s_cp_memr_w;
784
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
785
        if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then
786
          nstatus.cmdack   := '1';
787
          nstatus.trap_ysv := '0';               -- suppress traps on console
788
          nstatus.trap_mmu := '0';
789
          nstatus.cmdmerr  := VM_STAT.err or VM_STAT.fail;
790
          nstate := s_idle;
791
        end if;
792
 
793
      when s_cp_memw_w =>
794
        nstate := s_cp_memw_w;
795
        if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then
796
          nstatus.cmdack   := '1';
797
          nstatus.trap_ysv := '0';               -- suppress traps on console
798
          nstatus.trap_mmu := '0';
799
          nstatus.cmdmerr  := VM_STAT.err or VM_STAT.fail;
800
          nstate := s_idle;
801
        end if;
802
 
803
  -- instruction fetch and decode ---------------------------------------------
804
 
805
      when s_ifetch =>
806
        nmmumoni.istart := '1';         -- do here; memread_i inc PC ! 
807
        do_memread_i(nstate, ndpcntl, nvmcntl, s_ifetch_w);
808
 
809
      when s_ifetch_w =>
810
        nstate := s_ifetch_w;
811
        do_memcheck(nstate, nstatus, imemok);
812
        if imemok then
813
          ndpcntl.ireg_we := '1';
814
          nstate := s_idecode;
815
        end if;
816
 
817
      when s_idecode =>
818
        nidstat := ID_STAT;             -- register decode status
819
        if ID_STAT.force_srcsp = '1' then
820
          ndpcntl.gpr_asrc := c_gpr_sp;
821
        end if;
822
        ndpcntl.dsrc_sel := c_dpath_dsrc_src;
823
        ndpcntl.dsrc_we := '1';
824
        ndpcntl.ddst_sel := c_dpath_ddst_dst;
825
        ndpcntl.ddst_we := '1';
826
 
827
        nvmcntl.dspace := '0';
828
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc;       -- VA = PC
829
 
830
        if ID_STAT.do_pref_dec='1' and PSW.tflag='0' and int_pending='0' and
831
           R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1'
832
        then
833
          nvmcntl.req := '1';
834
          ndpcntl.gpr_pcinc := '1';                    -- (pc)++
835
          nmmumoni.istart := '1';
836
          nstatus.prefdone := '1';
837
        end if;
838
 
839
        if ID_STAT.do_fork_op = '1' then
840
          case ID_STAT.fork_op is
841
            when c_fork_op_halt => nstate := s_op_halt;
842
            when c_fork_op_wait => nstate := s_op_wait;
843
            when c_fork_op_rtti => nstate := s_rti_getpc;
844
            when c_fork_op_trap => nstate := s_op_trap;
845
            when c_fork_op_reset=> nstate := s_op_reset;
846
            when c_fork_op_rts  => nstate := s_op_rts;
847
            when c_fork_op_spl  => nstate := s_op_spl;
848
            when c_fork_op_mcc  => nstate := s_op_mcc;
849
            when c_fork_op_br   => nstate := s_op_br;
850
            when c_fork_op_mark => nstate := s_op_mark;
851
            when c_fork_op_sob  => nstate := s_op_sob;
852
            when c_fork_op_mtp  => nstate := s_opa_mtp;
853
            when others => nstate := s_cpufail;
854
          end case;
855
        elsif ID_STAT.do_fork_srcr = '1' then
856
          case ID_STAT.fork_srcr is
857
            when c_fork_srcr_def => nstate := s_srcr_def;
858
            when c_fork_srcr_inc => nstate := s_srcr_inc;
859
            when c_fork_srcr_dec => nstate := s_srcr_dec;
860
            when c_fork_srcr_ind => nstate := s_srcr_ind;
861
            when others => nstate := s_cpufail;
862
          end case;
863
        elsif ID_STAT.do_fork_dstr = '1' then
864
          do_fork_dstr(nstate, ID_STAT);
865
        elsif ID_STAT.do_fork_dsta = '1' then
866
          case ID_STAT.fork_dsta is         -- 2nd dsta fork in s_opa_mtp_pop_w
867
            when c_fork_dsta_def => do_fork_opa(nstate, ID_STAT);
868
            when c_fork_dsta_inc => nstate := s_dsta_inc;
869
            when c_fork_dsta_dec => nstate := s_dsta_dec;
870
            when c_fork_dsta_ind => nstate := s_dsta_ind;
871
            when others => nstate := s_cpufail;
872
          end case;
873
        elsif ID_STAT.do_fork_opg = '1' then
874
          do_fork_opg(nstate, ID_STAT);
875
        elsif ID_STAT.is_res = '1' then
876
          nstate := s_trap_10;           -- do trap 10;
877
        else
878
          nstate := s_cpufail;           -- catch mistakes here...
879
        end if;
880
 
881
  -- source read states -------------------------------------------------------
882
  --   flows:
883
  --     1  (r)    s_srcr_def           req (r)
884
  --               s_srcr_def_w         get (r)
885
  --               -> do_fork_dstr or do_fork_opg
886
  --              
887
  --     2  (r)+   s_srcr_inc           req (r); r+=s
888
  --               s_srcr_inc_w         get (r)
889
  --               -> do_fork_dstr or do_fork_opg
890
  --
891
  --     3  @(r)+  s_srcr_inc           req (r); r+=s
892
  --               s_srcr_inc_w         get (r)
893
  --               s_srcr_def           req @(r)
894
  --               s_srcr_def_w         get @(r)
895
  --               -> do_fork_dstr or do_fork_opg
896
  --
897
  --     4  -(r)   s_srcr_dec           r-=s
898
  --               s_srcr_dec1          req (r)
899
  --               s_srcr_inc_w         get (r)
900
  --               -> do_fork_dstr or do_fork_opg
901
  --
902
  --     5  @-(r)  s_srcr_dec           r-=s
903
  --               s_srcr_dec1          req (r)
904
  --               s_srcr_inc_w         get (r)
905
  --               s_srcr_def           req @(r)
906
  --               s_srcr_def_w         get @(r)
907
  --               -> do_fork_dstr or do_fork_opg
908
  --
909
  --     6  n(r)   s_srcr_ind           req n
910
  --               s_srcr_ind1_w        get n; ea=r+n
911
  --               s_srcr_ind2          req n(r)
912
  --               s_srcr_ind2_w        get n(r)
913
  --               -> do_fork_dstr or do_fork_opg
914
  --
915
  --     7  @n(r)  s_srcr_ind           req n
916
  --               s_srcr_ind1_w        get n; ea=r+n
917
  --               s_srcr_ind2          req n(r)
918
  --               s_srcr_ind2_w        get n(r)
919
  --               s_srcr_def           req @n(r)
920
  --               s_srcr_def_w         get @n(r)
921
  --               -> do_fork_dstr or do_fork_opg
922
 
923
      when s_srcr_def =>
924
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
925
        do_memread_d(nstate, nvmcntl, s_srcr_def_w,
926
                     bytop=>R_IDSTAT.is_bytop,
927
                     is_pci=>R_IDSTAT.is_srcpcmode1);
928
 
929
      when s_srcr_def_w =>
930
        nstate := s_srcr_def_w;
931
        do_memcheck(nstate, nstatus, imemok);
932
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
933
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
934
        if imemok then
935
          ndpcntl.dsrc_we := '1';                -- update DSRC
936
          if R_IDSTAT.do_fork_dstr = '1' then
937
            do_fork_dstr(nstate, R_IDSTAT);
938
          else
939
            do_fork_opg(nstate, R_IDSTAT);
940
          end if;
941
        end if;
942
 
943
      when s_srcr_inc =>
944
        ndpcntl.abox_asel := c_abox_asel_dsrc;   -- ABOX A=DSRC
945
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, SRCDEF, SRCREG);
946
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
947
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
948
        ndpcntl.gpr_adst := SRCREG;
949
        ndpcntl.gpr_we := '1';
950
        nmmumoni.regmod := '1';
951
        nmmumoni.isdec := '0';
952
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES (for if)
953
        if DSTREG = SRCREG then                  -- prevent stale DDST copy 
954
          ndpcntl.ddst_we := '1';                -- update DDST
955
        end if;
956
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
957
        bytop := R_IDSTAT.is_bytop and not SRCDEF;
958
        do_memread_d(nstate, nvmcntl, s_srcr_inc_w,
959
                     bytop=>bytop, is_pci=>R_IDSTAT.is_srcpc);
960
 
961
      when s_srcr_inc_w =>
962
        nstate := s_srcr_inc_w;
963
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
964
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
965
        do_memcheck(nstate, nstatus, imemok);
966
        if imemok then
967
          ndpcntl.dsrc_we := '1';                -- update DSRC
968
          if SRCDEF = '1' then
969
            nstate := s_srcr_def;
970
          else
971
            if R_IDSTAT.do_fork_dstr = '1' then
972
              do_fork_dstr(nstate, R_IDSTAT);
973
            else
974
              do_fork_opg(nstate, R_IDSTAT);
975
            end if;
976
          end if;
977
        end if;
978
 
979
      when s_srcr_dec =>
980
        ndpcntl.abox_asel := c_abox_asel_dsrc;   -- ABOX A=DSRC
981
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, SRCDEF, SRCREG);
982
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
983
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
984
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
985
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
986
        ndpcntl.dsrc_we := '1';                  -- update DSRC
987
        ndpcntl.gpr_adst := SRCREG;
988
        ndpcntl.gpr_we := '1';
989
        nmmumoni.regmod := '1';
990
        nmmumoni.isdec := '1';
991
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES (for if)
992
        if DSTREG = SRCREG then                  -- prevent stale DDST copy
993
          ndpcntl.ddst_we := '1';                -- update DDST
994
        end if;
995
        nstate := s_srcr_dec1;
996
 
997
      when s_srcr_dec1 =>
998
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
999
        bytop := R_IDSTAT.is_bytop and not SRCDEF;
1000
        do_memread_d(nstate, nvmcntl, s_srcr_inc_w, bytop=>bytop);
1001
 
1002
      when s_srcr_ind =>
1003
        do_memread_i(nstate, ndpcntl, nvmcntl, s_srcr_ind1_w);
1004
 
1005
      when s_srcr_ind1_w =>
1006
        nstate := s_srcr_ind1_w;
1007
        if R_IDSTAT.is_srcpc = '0' then
1008
          ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A = DSRC
1009
        else
1010
          ndpcntl.abox_asel := c_abox_asel_pc;   -- ABOX A = PC (for nn(pc))
1011
        end if;
1012
        ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT
1013
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1014
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
1015
        ndpcntl.ddst_sel := c_dpath_ddst_dst;    -- DDST = R(DST)
1016
        do_memcheck(nstate, nstatus, imemok);
1017
        if imemok then
1018
          ndpcntl.dsrc_we := '1';                -- update DSRC
1019
          ndpcntl.ddst_we := '1';                -- update DDST (to reload PC)
1020
          nstate := s_srcr_ind2;
1021
        end if;
1022
 
1023
      when s_srcr_ind2 =>
1024
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
1025
        bytop := R_IDSTAT.is_bytop and not SRCDEF;
1026
        do_memread_d(nstate, nvmcntl, s_srcr_ind2_w, bytop=>bytop);
1027
 
1028
      when s_srcr_ind2_w =>
1029
        nstate := s_srcr_ind2_w;
1030
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1031
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
1032
        do_memcheck(nstate, nstatus, imemok);
1033
        if imemok then
1034
          ndpcntl.dsrc_we := '1';                -- update DSRC
1035
          if SRCDEF = '1' then
1036
            nstate := s_srcr_def;
1037
          else
1038
            if R_IDSTAT.do_fork_dstr = '1' then
1039
              do_fork_dstr(nstate, R_IDSTAT);
1040
            else
1041
              do_fork_opg(nstate, R_IDSTAT);
1042
            end if;
1043
          end if;
1044
        end if;
1045
 
1046
  -- destination read states --------------------------------------------------
1047
  --   flows:
1048
  --     1  (r)    s_dstr_def           req (r) (rmw if rmw op)
1049
  --               s_dstr_def_w         get (r)
1050
  --               -> do_fork_opg
1051
  --              
1052
  --     2  (r)+   s_dstr_inc           req (r); r+=s (rmw if rmw op)
1053
  --               s_dstr_inc_w         get (r)
1054
  --               -> do_fork_opg
1055
  --
1056
  --     3  @(r)+  s_dstr_inc           req (r); r+=s
1057
  --               s_dstr_inc_w         get (r)
1058
  --               s_dstr_def           req @(r) (rmw if rmw op)
1059
  --               s_dstr_def_w         get @(r)
1060
  --               -> do_fork_opg
1061
  --
1062
  --     4  -(r)   s_dstr_dec           r-=s
1063
  --               s_dstr_dec1          req (r) (rmw if rmw op)
1064
  --               s_dstr_inc_w         get (r)
1065
  --               -> do_fork_opg
1066
  --
1067
  --     5  @-(r)  s_dstr_dec           r-=s
1068
  --               s_dstr_dec1          req (r)
1069
  --               s_dstr_inc_w         get (r)
1070
  --               s_dstr_def           req @(r) (rmw if rmw op)
1071
  --               s_dstr_def_w         get @(r)
1072
  --               -> do_fork_opg
1073
  --
1074
  --     6  n(r)   s_dstr_ind           req n
1075
  --               s_dstr_ind1_w        get n; ea=r+n
1076
  --               s_dstr_ind2          req n(r) (rmw if rmw op)
1077
  --               s_dstr_ind2_w        get n(r)
1078
  --               -> do_fork_opg
1079
  --
1080
  --     7  @n(r)  s_dstr_ind           req n
1081
  --               s_dstr_ind1_w        get n; ea=r+n
1082
  --               s_dstr_ind2          req n(r)
1083
  --               s_dstr_ind2_w        get n(r)
1084
  --               s_dstr_def           req @n(r) (rmw if rmw op)
1085
  --               s_dstr_def_w         get @n(r)
1086
  --               -> do_fork_opg
1087
 
1088
      when s_dstr_def =>
1089
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1090
        do_memread_d(nstate, nvmcntl, s_dstr_def_w,
1091
                     bytop=>R_IDSTAT.is_bytop, macc=>R_IDSTAT.is_rmwop);
1092
 
1093
      when s_dstr_def_w =>
1094
        nstate := s_dstr_def_w;
1095
        do_memcheck(nstate, nstatus, imemok);
1096
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1097
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1098
        if imemok then
1099
          ndpcntl.ddst_we := '1';                -- update DDST
1100
          do_fork_opg(nstate, R_IDSTAT);
1101
        end if;
1102
 
1103
      when s_dstr_inc =>
1104
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A=DDST
1105
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG);
1106
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
1107
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1108
        ndpcntl.gpr_adst := DSTREG;
1109
        ndpcntl.gpr_we := '1';
1110
        nmmumoni.regmod := '1';
1111
        nmmumoni.isdec := '0';
1112
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1113
        macc  := R_IDSTAT.is_rmwop and not DSTDEF;
1114
        bytop := R_IDSTAT.is_bytop and not DSTDEF;
1115
        do_memread_d(nstate, nvmcntl, s_dstr_inc_w,
1116
                     bytop=>bytop, macc=>macc, is_pci=>R_IDSTAT.is_dstpc);
1117
 
1118
      when s_dstr_inc_w =>
1119
        nstate := s_dstr_inc_w;
1120
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1121
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1122
        do_memcheck(nstate, nstatus, imemok);
1123
        if imemok then
1124
          ndpcntl.ddst_we := '1';                -- update DDST
1125
          if DSTDEF = '1' then
1126
            nstate := s_dstr_def;
1127
          else
1128
            do_fork_opg(nstate, R_IDSTAT);
1129
          end if;
1130
        end if;
1131
 
1132
      when s_dstr_dec =>
1133
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A=DDST
1134
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG);
1135
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
1136
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
1137
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1138
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1139
        ndpcntl.ddst_we := '1';                  -- update DDST
1140
        ndpcntl.gpr_adst := DSTREG;
1141
        ndpcntl.gpr_we := '1';
1142
        nmmumoni.regmod := '1';
1143
        nmmumoni.isdec := '1';
1144
        nstate := s_dstr_dec1;
1145
 
1146
      when s_dstr_dec1 =>
1147
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1148
        macc  := R_IDSTAT.is_rmwop and not DSTDEF;
1149
        bytop := R_IDSTAT.is_bytop and not DSTDEF;
1150
        do_memread_d(nstate, nvmcntl, s_dstr_inc_w,
1151
                     bytop=>bytop, macc=>macc);
1152
 
1153
      when s_dstr_ind =>
1154
        do_memread_i(nstate, ndpcntl, nvmcntl, s_dstr_ind1_w);
1155
 
1156
      when s_dstr_ind1_w =>
1157
        nstate := s_dstr_ind1_w;
1158
        if R_IDSTAT.is_dstpc = '0' then
1159
          ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST
1160
        else
1161
          ndpcntl.abox_asel := c_abox_asel_pc;   -- ABOX A = PC (for nn(pc))
1162
        end if;
1163
        ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT
1164
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1165
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1166
        do_memcheck(nstate, nstatus, imemok);
1167
        if imemok then
1168
          ndpcntl.ddst_we := '1';                -- update DDST
1169
          nstate := s_dstr_ind2;
1170
        end if;
1171
 
1172
      when s_dstr_ind2 =>
1173
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1174
        macc  := R_IDSTAT.is_rmwop and not DSTDEF;
1175
        bytop := R_IDSTAT.is_bytop and not DSTDEF;
1176
        do_memread_d(nstate, nvmcntl, s_dstr_ind2_w,
1177
                     bytop=>bytop, macc=>macc);
1178
 
1179
      when s_dstr_ind2_w =>
1180
        nstate := s_dstr_ind2_w;
1181
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1182
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1183
        do_memcheck(nstate, nstatus, imemok);
1184
        if imemok then
1185
          ndpcntl.ddst_we := '1';                -- update DDST
1186
          if DSTDEF = '1' then
1187
            nstate := s_dstr_def;
1188
          else
1189
            do_fork_opg(nstate, R_IDSTAT);
1190
          end if;
1191
        end if;
1192
 
1193
  -- destination write states -------------------------------------------------
1194
  --   flows:
1195
  --     1  (r)    s_dstw_def           wreq (r)            check kstack
1196
  --               s_dstw_def_w         ack  (r)
1197
  --               -> do_fork_next
1198
  --              
1199
  --     2  (r)+   s_dstw_inc           wreq (r)            check kstack
1200
  --               s_dstw_inc_w         ack  (r); r+=s
1201
  --               -> do_fork_next
1202
  --
1203
  --     3  @(r)+  s_dstw_inc           rreq (r); r+=s
1204
  --               s_dstw_incdef_w      get  (r)
1205
  --               s_dstw_def246        wreq @(r)
1206
  --               s_dstw_def_w         ack  @(r)
1207
  --               -> do_fork_next
1208
  --
1209
  --     4  -(r)   s_dstw_dec           r-=s
1210
  --               s_dstw_dec1          wreq (r)            check kstack
1211
  --               s_dstw_def_w         ack  (r)
1212
  --               -> do_fork_next
1213
  --
1214
  --     5  @-(r)  s_dstw_dec           r-=s
1215
  --               s_dstw_dec1          rreq (r)
1216
  --               s_dstw_incdef_w      get  (r)
1217
  --               s_dstw_def246        wreq @(r)
1218
  --               s_dstw_def_w         ack  @(r)
1219
  --               -> do_fork_next
1220
  --
1221
  --     6  n(r)   s_dstw_ind           rreq n
1222
  --               s_dstw_ind_w         get  n; ea=r+n
1223
  --               s_dstw_dec1          wreq n(r)           check kstack
1224
  --               s_dstw_def_w         ack  n(r)
1225
  --               -> do_fork_next
1226
  --
1227
  --     7  @n(r)  s_dstw_ind           rreq n
1228
  --               s_dstw_ind_w         get  n; ea=r+n
1229
  --               s_dstw_dec1          rreq n(r)
1230
  --               s_dstw_incdef_w      get  n(r)
1231
  --               s_dstw_def246        wreq @n(r)
1232
  --               s_dstw_def_w         ack  @n(r)
1233
  --               -> do_fork_next
1234
 
1235
      when s_dstw_def =>
1236
        ndpcntl.psr_ccwe := '1';
1237
        ndpcntl.dres_sel := R_IDSTAT.res_sel;      -- DRES = choice of idec
1238
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1239
        nvmcntl.kstack := is_dstkstack1246;
1240
        do_memwrite(nstate, nvmcntl, s_dstw_def_w);
1241
 
1242
      when s_dstw_def_w =>
1243
        nstate := s_dstw_def_w;
1244
        do_memcheck(nstate, nstatus, imemok);
1245
        if imemok then
1246
          do_fork_next(nstate, nstatus, nmmumoni);
1247
        end if;
1248
 
1249
      when s_dstw_inc =>
1250
        ndpcntl.psr_ccwe := '1';
1251
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;   -- VA = DDST
1252
        ndpcntl.abox_asel := c_abox_asel_ddst;       -- ABOX A=DDST  (for else)
1253
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG);  --(...)
1254
        ndpcntl.abox_bsel := c_abox_bsel_const;      -- ABOX B=const (for else)
1255
        if DSTDEF = '0' then
1256
          ndpcntl.dres_sel := R_IDSTAT.res_sel;      -- DRES = choice of idec
1257
          nvmcntl.kstack := is_dstkstack1246;
1258
          do_memwrite(nstate, nvmcntl, s_dstw_inc_w);
1259
          nstatus.do_gprwe := '1';
1260
        else
1261
          ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1262
          ndpcntl.gpr_adst := DSTREG;
1263
          ndpcntl.gpr_we := '1';
1264
          nmmumoni.regmod := '1';
1265
          nmmumoni.isdec := '0';
1266
          do_memread_d(nstate, nvmcntl, s_dstw_incdef_w,
1267
                       is_pci=>R_IDSTAT.is_dstpc);
1268
        end if;
1269
 
1270
      when s_dstw_inc_w =>
1271
        nstate := s_dstw_inc_w;
1272
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1273
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG);
1274
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const
1275
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1276
        ndpcntl.gpr_adst := DSTREG;
1277
        if R_STATUS.do_gprwe = '1' then
1278
          nmmumoni.regmod := '1';
1279
          nmmumoni.isdec := '0';
1280
          nmmumoni.trace_prev := '1';              -- ssr freeze of prev state
1281
          ndpcntl.gpr_we := '1';                   -- update DST reg
1282
        end if;
1283
        nstatus.do_gprwe := '0';
1284
        do_memcheck(nstate, nstatus, imemok);
1285
        if imemok then
1286
          do_fork_next(nstate, nstatus, nmmumoni);
1287
        end if;
1288
 
1289
      when s_dstw_incdef_w =>
1290
        nstate := s_dstw_incdef_w;
1291
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1292
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1293
        do_memcheck(nstate, nstatus, imemok);
1294
        if imemok then
1295
          ndpcntl.ddst_we := '1';                -- update DDST
1296
          nstate := s_dstw_def246;
1297
        end if;
1298
 
1299
      when s_dstw_dec =>
1300
        ndpcntl.psr_ccwe := '1';
1301
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A=DDST
1302
        do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG);
1303
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
1304
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
1305
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1306
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1307
        ndpcntl.ddst_we := '1';                  -- update DDST
1308
        ndpcntl.gpr_adst := DSTREG;
1309
        ndpcntl.gpr_we := '1';
1310
        nmmumoni.regmod := '1';
1311
        nmmumoni.isdec := '1';
1312
        nstate := s_dstw_dec1;
1313
 
1314
      when s_dstw_dec1 =>
1315
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1316
        ndpcntl.dres_sel := R_IDSTAT.res_sel;      -- DRES = from idec (for if)
1317
        if DSTDEF = '0' then
1318
          nvmcntl.kstack := is_dstkstack1246;
1319
          do_memwrite(nstate, nvmcntl, s_dstw_def_w);
1320
        else
1321
          do_memread_d(nstate, nvmcntl, s_dstw_incdef_w);
1322
        end if;
1323
 
1324
      when s_dstw_ind =>
1325
        ndpcntl.psr_ccwe := '1';
1326
        do_memread_i(nstate, ndpcntl, nvmcntl, s_dstw_ind_w);
1327
 
1328
      when s_dstw_ind_w =>
1329
        nstate := s_dstw_ind_w;
1330
        if R_IDSTAT.is_dstpc = '0' then
1331
          ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST
1332
        else
1333
          ndpcntl.abox_asel := c_abox_asel_pc;   -- ABOX A = PC (for nn(pc))
1334
        end if;
1335
        ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT
1336
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1337
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1338
        do_memcheck(nstate, nstatus, imemok);
1339
        if imemok then
1340
          ndpcntl.ddst_we := '1';                -- update DDST
1341
          nstate := s_dstw_dec1;
1342
        end if;
1343
 
1344
      when s_dstw_def246 =>
1345
        ndpcntl.dres_sel := R_IDSTAT.res_sel;      -- DRES = choice of idec
1346
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1347
        do_memwrite(nstate, nvmcntl, s_dstw_def_w);
1348
 
1349
  -- destination address states -----------------------------------------------
1350
  --   flows:
1351
  --     1  (r)    -> do_fork_opa
1352
  --              
1353
  --     2  (r)+   s_dsta_inc           r+=2
1354
  --               -> do_fork_opa
1355
  --
1356
  --     3  @(r)+  s_dsta_inc           req (r); r+=s
1357
  --               s_dsta_incdef_w      get (r)
1358
  --               -> do_fork_opa
1359
  --
1360
  --     4  -(r)   s_dsta_dec           r-=s
1361
  --               s_dsta_dec1          ?? FIXME ?? what is done here ??
1362
  --               -> do_fork_opa
1363
  --
1364
  --     5  @-(r)  s_dsta_dec           r-=s
1365
  --               s_dsta_dec1          req (r)
1366
  --               s_dsta_incdef_w      get (r)
1367
  --               -> do_fork_opa
1368
  --
1369
  --     6  n(r)   s_dsta_ind           req n
1370
  --               s_dsta_ind_w         get n; ea=r+n
1371
  --               s_dsta_dec1          ?? FIXME ?? what is done here ??
1372
  --               -> do_fork_opa
1373
  --
1374
  --     7  @n(r)  s_dsta_ind           req n
1375
  --               s_dsta_ind_w         get n; ea=r+n
1376
  --               s_dsta_dec1          req n(r)
1377
  --               s_dsta_incdef_w      get n(r)
1378
  --               -> do_fork_opa
1379
 
1380
      when s_dsta_inc =>
1381
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1382
        ndpcntl.abox_const := "000000010";
1383
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(2)
1384
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1385
        ndpcntl.gpr_adst := DSTREG;
1386
        ndpcntl.gpr_we := '1';
1387
        nmmumoni.regmod := '1';
1388
        nmmumoni.isdec := '0';
1389
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;      -- DSRC = DRES (for if)
1390
        if R_IDSTAT.updt_dstadsrc = '1' then       -- prevent stale DSRC copy 
1391
          ndpcntl.dsrc_we := '1';                    -- update DSRC
1392
        end if;
1393
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1394
        if DSTDEF = '0' then
1395
          do_fork_opa(nstate, R_IDSTAT);
1396
        else
1397
          do_memread_d(nstate, nvmcntl, s_dsta_incdef_w,
1398
                       is_pci=>R_IDSTAT.is_dstpc);
1399
        end if;
1400
 
1401
      when s_dsta_incdef_w =>
1402
        nstate := s_dsta_incdef_w;
1403
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1404
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1405
        do_memcheck(nstate, nstatus, imemok);
1406
        if imemok then
1407
          ndpcntl.ddst_we := '1';                -- update DDST
1408
          do_fork_opa(nstate, R_IDSTAT);
1409
        end if;
1410
 
1411
      when s_dsta_dec =>
1412
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A=DDST
1413
        ndpcntl.abox_const := "000000010";
1414
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const(2)
1415
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
1416
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1417
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1418
        ndpcntl.ddst_we := '1';                  -- update DDST
1419
        ndpcntl.gpr_adst := DSTREG;
1420
        ndpcntl.gpr_we := '1';
1421
        nmmumoni.regmod := '1';
1422
        nmmumoni.isdec := '1';
1423
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES (for if)
1424
        if R_IDSTAT.updt_dstadsrc = '1' then     -- prevent stale DSRC copy 
1425
          ndpcntl.dsrc_we := '1';                -- update DSRC
1426
        end if;
1427
        nstate := s_dsta_dec1;
1428
 
1429
      when s_dsta_dec1 =>
1430
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST
1431
        if DSTDEF = '0' then                       -- check here used also by
1432
          do_fork_opa(nstate, R_IDSTAT);           -- s_dsta_ind flow !!
1433
        else
1434
          do_memread_d(nstate, nvmcntl, s_dsta_incdef_w);
1435
        end if;
1436
 
1437
      when s_dsta_ind =>
1438
        do_memread_i(nstate, ndpcntl, nvmcntl, s_dsta_ind_w);
1439
 
1440
      when s_dsta_ind_w =>
1441
        nstate := s_dsta_ind_w;
1442
        if R_IDSTAT.is_dstpc = '0' then
1443
          ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST
1444
        else
1445
          ndpcntl.abox_asel := c_abox_asel_pc;   -- ABOX A = PC (for nn(pc))
1446
        end if;
1447
        ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT
1448
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1449
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1450
        do_memcheck(nstate, nstatus, imemok);
1451
        if imemok then
1452
          ndpcntl.ddst_we := '1';                -- update DDST
1453
          nstate := s_dsta_dec1;
1454
        end if;
1455
 
1456
  -- instruction operate states -----------------------------------------------
1457
 
1458
      when s_op_halt =>                 -- HALT
1459
        if is_kmode = '1' then          -- if in kernel mode execute
1460
          nmmumoni.idone := '1';
1461
          nstatus.cpugo := '0';
1462
          nstatus.cpuhalt := '1';
1463
          nstatus.cpurust := c_cpurust_halt;
1464
          nstate := s_idle;
1465
        else                            -- otherwise trap
1466
          ncpuerr.illhlt := '1';
1467
          nstate := s_trap_4;           -- trap 4 like 11/70
1468
        end if;
1469
 
1470
      when s_op_wait =>                 -- WAIT
1471
        nstate := s_op_wait;            -- spin here
1472
        if is_kmode = '0' then          -- but act as nop if not in kernel
1473
          nstate := s_idle;
1474
        elsif int_pending = '1' or      -- bail out if pending interrupt
1475
          R_STATUS.cpustep='1' then     --  or the instruction is only stepped
1476
          nstate := s_idle;
1477
        elsif R_STATUS.cmdbusy = '1' then -- suspend if a cp command is pending
1478
          nstatus.waitsusp := '1';
1479
          nstate := s_idle;
1480
        else
1481
          nstatus.cpuwait := '1';       -- if spinning here, signal with cpuwait
1482
        end if;
1483
 
1484
      when s_op_trap =>                 -- traps
1485
        lvector := "0000" & R_IDSTAT.trap_vec; -- vector
1486
        do_start_int(nstate, ndpcntl, lvector);
1487
 
1488
      when s_op_reset =>                -- RESET
1489
        if is_kmode = '1' then          -- if in kernel mode execute
1490
          nbreset := '1';
1491
        end if;
1492
        nstate := s_idle;
1493
 
1494
      when s_op_rts =>                  -- RTS
1495
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1496
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1497
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1498
        ndpcntl.gpr_adst := c_gpr_pc;
1499
        ndpcntl.gpr_we := '1';                     -- load PC with reg(dst)
1500
        nstate := s_op_rts_pop;
1501
 
1502
      when s_op_rts_pop =>
1503
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_op_rts_pop_w,
1504
                          nmmumoni, updt_sp=>'1');
1505
 
1506
      when s_op_rts_pop_w =>
1507
        nstate := s_op_rts_pop_w;
1508
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
1509
        ndpcntl.gpr_adst := DSTREG;
1510
        do_memcheck(nstate, nstatus, imemok);
1511
        if imemok then
1512
          ndpcntl.gpr_we := '1';                  -- load R with (SP)+
1513
          do_fork_next(nstate, nstatus, nmmumoni);
1514
        end if;
1515
 
1516
      when s_op_spl =>                  -- SPL
1517
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
1518
        ndpcntl.psr_func := c_psr_func_wspl;
1519
        if is_kmode = '1' then                   -- active only in kernel mode
1520
          ndpcntl.psr_we := '1';
1521
          nstate := s_ifetch;                    -- unconditionally fetch next
1522
                                                 -- instruction like a 11/70
1523
                                                 -- no interrupt recognition !
1524
        else
1525
          do_fork_next(nstate, nstatus, nmmumoni);  -- in non-kernel, noop
1526
        end if;
1527
 
1528
      when s_op_mcc =>                  -- CLx/SEx
1529
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
1530
        ndpcntl.psr_func := c_psr_func_wcc;
1531
        ndpcntl.psr_we := '1';
1532
        do_fork_next(nstate, nstatus, nmmumoni);
1533
 
1534
      when s_op_br =>                   -- BR
1535
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
1536
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
1537
        ndpcntl.abox_asel := c_abox_asel_pc;     -- ABOX A = PC
1538
        ndpcntl.abox_bsel := c_abox_bsel_ireg8;  -- ABOX B = IREG8
1539
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1540
        -- note: cc are NZVC
1541
        case brcode(3 downto 1) is
1542
          when "000" =>                 -- BR
1543
            brcond := '1';
1544
          when "001" =>                 -- BNE/BEQ: if Z = x
1545
            brcond := PSW.cc(2);
1546
          when "010" =>                 -- BGE/BLT: if N xor V = x
1547
            brcond := PSW.cc(3) xor PSW.cc(1);
1548
          when "011" =>                 -- BGT/BLE: if Z or (N xor V) = x
1549
            brcond := PSW.cc(2) or (PSW.cc(3) xor PSW.cc(1));
1550
          when "100" =>                 -- BPL/BMI: if N = x
1551
            brcond := PSW.cc(3);
1552
          when "101" =>                 -- BHI/BLOS:if C or Z = x
1553
            brcond := PSW.cc(2) or PSW.cc(0);
1554
          when "110" =>                 -- BVC/BVS: if V = x
1555
            brcond := PSW.cc(1);
1556
          when "111" =>                 -- BCC/BCS: if C = x
1557
            brcond := PSW.cc(0);
1558
          when others => null;
1559
        end case;
1560
 
1561
        ndpcntl.gpr_adst := c_gpr_pc;
1562
        if brcond = brcode(0) then      -- this coding creates redundant code
1563
          ndpcntl.gpr_we := '1';        --   but synthesis optimizes this way !
1564
          do_fork_next(nstate, nstatus, nmmumoni);
1565
        else
1566
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
1567
        end if;
1568
 
1569
      when s_op_mark =>                 -- MARK 
1570
        ndpcntl.abox_asel := c_abox_asel_pc;     -- ABOX A = PC
1571
        ndpcntl.abox_bsel := c_abox_bsel_ireg6;  -- ABOX B = IREG6
1572
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1573
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
1574
        ndpcntl.dsrc_we := '1';                  -- update DSRC (with PC+2*nn)
1575
        ndpcntl.gpr_adst := c_gpr_r5;            -- fetch r5
1576
        ndpcntl.ddst_sel := c_dpath_ddst_dst;
1577
        ndpcntl.ddst_we := '1';
1578
        nstate := s_op_mark1;
1579
 
1580
      when s_op_mark1 =>
1581
        ndpcntl.abox_asel := c_abox_asel_ddst;   -- ABOX A = DDST
1582
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B = const(0)
1583
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1584
        ndpcntl.gpr_adst := c_gpr_pc;
1585
        ndpcntl.gpr_we := '1';                   -- load PC with r5
1586
        nstate := s_op_mark_pop;
1587
 
1588
      when s_op_mark_pop =>
1589
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_op_mark_pop_w,
1590
                          nmmumoni, updt_sp=>'1');
1591
 
1592
      when s_op_mark_pop_w =>
1593
        nstate := s_op_mark_pop_w;
1594
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1595
        ndpcntl.gpr_adst := c_gpr_r5;
1596
        do_memcheck(nstate, nstatus, imemok);
1597
        if imemok then
1598
          ndpcntl.gpr_we := '1';                 -- load R5 with (sp)+
1599
          do_fork_next(nstate, nstatus, nmmumoni);
1600
        end if;
1601
 
1602
      when s_op_sob =>                  -- SOB (dec)
1603
        -- comment fork_next_pref out (blog 2006-10-02) due to synthesis impact
1604
        --nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
1605
        --ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
1606
        ndpcntl.dres_sel := R_IDSTAT.res_sel;
1607
        ndpcntl.gpr_adst := SRCREG;
1608
        ndpcntl.gpr_we := '1';
1609
 
1610
        if DP_STAT.ccout_z = '0' then   -- if z=0 branch, if z=1 fall thru
1611
          nstate := s_op_sob1;
1612
        else
1613
          --do_fork_next_pref(nstate, ndpcntl, nvmcntl, nmmumoni);
1614
          do_fork_next(nstate, nstatus, nmmumoni);
1615
        end if;
1616
 
1617
      when s_op_sob1 =>                 -- SOB (br) 
1618
        ndpcntl.abox_asel := c_abox_asel_pc;     -- ABOX A = PC
1619
        ndpcntl.abox_bsel := c_abox_bsel_ireg6;  -- ABOX B = IREG6
1620
        ndpcntl.abox_opsub := '1';               -- ABOX = A - B
1621
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1622
        ndpcntl.gpr_adst := c_gpr_pc;
1623
        ndpcntl.gpr_we := '1';
1624
        do_fork_next(nstate, nstatus, nmmumoni);
1625
 
1626
      when s_opg_gen =>
1627
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
1628
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
1629
        ndpcntl.gpr_bytop := R_IDSTAT.is_bytop;
1630
        ndpcntl.dres_sel := R_IDSTAT.res_sel;    -- DRES = choice of idec
1631
 
1632
        if R_IDSTAT.op_mov = '1' then            -- in case of MOV xx,R
1633
          ndpcntl.gpr_bytop := '0';              --  no bytop, do sign extend
1634
        end if;
1635
 
1636
        ndpcntl.psr_ccwe := '1';
1637
 
1638
        if R_IDSTAT.is_dstw_reg = '1' then
1639
          ndpcntl.gpr_we := '1';
1640
        end if;
1641
 
1642
        if R_IDSTAT.is_rmwop = '1' then
1643
          do_memwrite(nstate, nvmcntl, s_opg_gen_rmw_w, macc=>'1');
1644
        else
1645
          if R_STATUS.prefdone = '1' then
1646
            nstatus.prefdone :='0';
1647
            nstate := s_ifetch_w;
1648
            do_memcheck(nstate, nstatus, imemok);
1649
            if imemok then
1650
              ndpcntl.ireg_we := '1';
1651
              nstate := s_idecode;
1652
            end if;
1653
          else
1654
            if R_IDSTAT.is_dstw_pc = '1' then
1655
              nstate := s_idle;
1656
            else
1657
              do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
1658
            end if;
1659
          end if;
1660
        end if;
1661
 
1662
      when s_opg_gen_rmw_w =>
1663
        nstate := s_opg_gen_rmw_w;
1664
        do_memcheck(nstate, nstatus, imemok);
1665
        if imemok then
1666
          do_fork_next(nstate, nstatus, nmmumoni);
1667
        end if;
1668
 
1669
      when s_opg_mul =>                 -- MUL (oper)
1670
        ndpcntl.dres_sel := R_IDSTAT.res_sel;   -- DRES = choice of idec
1671
        ndpcntl.gpr_adst := SRCREG;             -- write high order result
1672
        ndpcntl.gpr_we := '1';
1673
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;   -- DSRC = DRES
1674
        ndpcntl.dsrc_we := '1';                 -- capture high order part
1675
        ndpcntl.dtmp_sel := c_dpath_dtmp_drese; -- DTMP = DRESE
1676
        ndpcntl.dtmp_we := '1';                 -- capture low order part
1677
        nstate := s_opg_mul1;
1678
 
1679
      when s_opg_mul1 =>                -- MUL (write odd reg)
1680
        ndpcntl.abox_asel := c_abox_asel_dtmp;   -- ABOX A = DTMP
1681
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B = const(0)
1682
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1683
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
1684
        ndpcntl.gpr_we := '1';
1685
        ndpcntl.psr_ccwe := '1';
1686
        do_fork_next(nstate, nstatus, nmmumoni);
1687
 
1688
      when s_opg_div =>                 -- DIV (load dd_low)
1689
        ndpcntl.mbox_s_div := '1';
1690
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
1691
        ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;
1692
        ndpcntl.dtmp_we := '1';
1693
        nstate := s_opg_div_cn;
1694
 
1695
      when s_opg_div_cn =>              -- DIV (1st...16th cycle)
1696
        ndpcntl.mbox_s_div_cn := '1';
1697
        ndpcntl.dres_sel := R_IDSTAT.res_sel;     -- DRES = choice of idec
1698
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;     -- DSRC = DRES
1699
        ndpcntl.dtmp_sel := c_dpath_dtmp_drese;   -- DTMP = DRESE
1700
        nstate := s_opg_div_cn;
1701
        if DP_STAT.div_zero='1' or DP_STAT.div_ovfl='1' then
1702
          nstate := s_opg_div_zero;
1703
        else
1704
          ndpcntl.dsrc_we := '1';                 -- update DSRC
1705
          ndpcntl.dtmp_we := '1';                 -- update DTMP
1706
        end if;
1707
        if DP_STAT.shc_tc = '1' then
1708
          nstate := s_opg_div_cr;
1709
        end if;
1710
 
1711
      when s_opg_div_cr =>              -- DIV (reminder correction)
1712
        ndpcntl.mbox_s_div_cr := '1';
1713
        ndpcntl.dres_sel := R_IDSTAT.res_sel;     -- DRES = choice of idec
1714
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;     -- DSRC = DRES
1715
        ndpcntl.dsrc_we := DP_STAT.div_cr;        -- update DSRC
1716
        nstate := s_opg_div_sq;
1717
 
1718
      when s_opg_div_sq =>              -- DIV (store quotient)
1719
        ndpcntl.abox_asel := c_abox_asel_dtmp;    -- ABOX A=DTMP
1720
        ndpcntl.abox_const := "00000000"&DP_STAT.div_cq;-- ABOX const = Q corr.
1721
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B=const (q cor)
1722
        ndpcntl.dres_sel := c_dpath_res_abox;     -- DRES = ABOX
1723
        ndpcntl.gpr_adst := SRCREG;               -- write result
1724
        ndpcntl.gpr_we := '1';
1725
        ndpcntl.dtmp_sel := c_dpath_dtmp_dres;    -- DTMP = DRES
1726
        ndpcntl.dtmp_we := '1';                   -- update DTMP (Q)
1727
        nstate := s_opg_div_sr;
1728
 
1729
      when s_opg_div_sr =>              -- DIV (store reminder)
1730
        ndpcntl.abox_asel := c_abox_asel_dsrc;    -- ABOX A=DSRC
1731
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B=const (0)
1732
        ndpcntl.dres_sel := c_dpath_res_abox;     -- DRES = ABOX
1733
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
1734
        ndpcntl.gpr_we := '1';
1735
        ndpcntl.psr_ccwe := '1';
1736
        do_fork_next(nstate, nstatus, nmmumoni);
1737
 
1738
      when s_opg_div_zero =>            -- DIV (/0 or 0/ abort)
1739
        ndpcntl.psr_ccwe := '1';
1740
        do_fork_next(nstate, nstatus, nmmumoni);
1741
 
1742
      when s_opg_ash =>                 -- ASH (load shc)
1743
        ndpcntl.mbox_s_ash := '1';
1744
        nstate := s_opg_ash_cn;
1745
 
1746
      when s_opg_ash_cn =>              -- ASH (shift cycles)
1747
        nvmcntl.dspace := '0';                    -- prepare do_fork_next_pref
1748
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;     -- DSRC = DRES
1749
        ndpcntl.abox_asel := c_abox_asel_dsrc;    -- ABOX A=DSRC
1750
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B=const(0)
1751
        ndpcntl.gpr_adst := SRCREG;               -- write result
1752
        ndpcntl.mbox_s_ash_cn := '1';
1753
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc;  -- VA = PC
1754
        nstate := s_opg_ash_cn;
1755
        if DP_STAT.shc_tc = '0' then
1756
          ndpcntl.dres_sel := R_IDSTAT.res_sel;   -- DRES = choice of idec
1757
          ndpcntl.dsrc_we := '1';                 -- update DSRC
1758
        else
1759
          ndpcntl.dres_sel := c_dpath_res_abox;   -- DRES = ABOX
1760
          ndpcntl.gpr_we := '1';
1761
          ndpcntl.psr_ccwe := '1';
1762
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
1763
        end if;
1764
 
1765
      when s_opg_ashc =>                -- ASHC (load low, load shc)
1766
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
1767
        ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;
1768
        ndpcntl.dtmp_we := '1';
1769
        ndpcntl.mbox_s_ashc := '1';
1770
        nstate := s_opg_ashc_cn;
1771
 
1772
      when s_opg_ashc_cn =>             -- ASHC (shift cycles)
1773
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;     -- DSRC = DRES
1774
        ndpcntl.dtmp_sel := c_dpath_dtmp_drese;   -- DTMP = DRESE
1775
        ndpcntl.abox_asel := c_abox_asel_dsrc;    -- ABOX A=DSRC
1776
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B=const(0)
1777
        ndpcntl.gpr_adst := SRCREG;               -- write result
1778
        ndpcntl.mbox_s_ashc_cn := '1';
1779
        nstate := s_opg_ashc_cn;
1780
        if DP_STAT.shc_tc = '0' then
1781
          ndpcntl.dres_sel := R_IDSTAT.res_sel;   -- DRES = choice of idec
1782
          ndpcntl.dsrc_we := '1';                 -- update DSRC
1783
          ndpcntl.dtmp_we := '1';                 -- update DTMP
1784
        else
1785
          ndpcntl.dres_sel := c_dpath_res_abox;   -- DRES = ABOX
1786
          ndpcntl.gpr_we := '1';
1787
          ndpcntl.psr_ccwe := '1';
1788
          nstate := s_opg_ashc_wl;
1789
        end if;
1790
 
1791
      when s_opg_ashc_wl =>             -- ASHC (write low)
1792
        ndpcntl.abox_asel := c_abox_asel_dtmp;   -- ABOX A = DTMP
1793
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B = const(0)
1794
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
1795
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
1796
        ndpcntl.gpr_we := '1';
1797
        do_fork_next(nstate, nstatus, nmmumoni);
1798
 
1799
  -- dsta mode operations -----------------------------------------------------
1800
 
1801
      when s_opa_jsr =>
1802
        ndpcntl.gpr_asrc := c_gpr_sp;              --                (for else)
1803
        ndpcntl.dsrc_sel := c_dpath_dsrc_src;      -- DSRC = regfile (for else)
1804
        if R_IDSTAT.is_dstmode0 = '1' then
1805
          nstate := s_trap_10;                     -- trap 10 like 11/70
1806
        else
1807
          ndpcntl.dsrc_we := '1';
1808
          nstate := s_opa_jsr1;
1809
        end if;
1810
 
1811
      when s_opa_jsr1 =>
1812
        ndpcntl.gpr_asrc := SRCREG;
1813
        ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;     -- DTMP = regfile
1814
        ndpcntl.dtmp_we := '1';
1815
 
1816
        ndpcntl.abox_asel := c_abox_asel_dsrc;     -- ABOX A=DSRC
1817
        ndpcntl.abox_const := "000000010";
1818
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(2)
1819
        ndpcntl.abox_opsub := '1';                 -- ABOX = A-B
1820
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1821
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;      -- DDST = DRES
1822
        ndpcntl.dsrc_we := '1';                    -- update DDST
1823
        ndpcntl.gpr_adst := c_gpr_sp;
1824
        ndpcntl.gpr_we := '1';                     -- update SP
1825
        nmmumoni.regmod := '1';
1826
        nmmumoni.isdec := '1';
1827
        nstate := s_opa_jsr_push;
1828
 
1829
      when s_opa_jsr_push =>
1830
        ndpcntl.abox_asel := c_abox_asel_dtmp;     -- ABOX A=DTMP
1831
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1832
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1833
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
1834
        nvmcntl.dspace := '1';
1835
        nvmcntl.kstack := is_kmode;
1836
        nvmcntl.wacc := '1';
1837
        nvmcntl.req := '1';
1838
        nstate := s_opa_jsr_push_w;
1839
 
1840
      when s_opa_jsr_push_w =>
1841
        nstate := s_opa_jsr_push_w;
1842
        ndpcntl.abox_asel := c_abox_asel_pc;       -- ABOX A=PC
1843
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1844
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1845
        ndpcntl.gpr_adst := SRCREG;
1846
        do_memcheck(nstate, nstatus, imemok);
1847
        if imemok then
1848
          ndpcntl.gpr_we := '1';                   -- load R with PC
1849
          nstate := s_opa_jsr2;
1850
        end if;
1851
 
1852
      when s_opa_jsr2 =>
1853
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1854
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1855
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1856
        ndpcntl.gpr_adst := c_gpr_pc;
1857
        ndpcntl.gpr_we := '1';                     -- load PC with dsta
1858
        do_fork_next(nstate, nstatus, nmmumoni);
1859
 
1860
      when s_opa_jmp =>
1861
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1862
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1863
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1864
        ndpcntl.gpr_adst := c_gpr_pc;
1865
        if R_IDSTAT.is_dstmode0 = '1' then
1866
          nstate := s_trap_10;                     -- trap 10 like 11/70
1867
        else
1868
          ndpcntl.gpr_we := '1';                   -- load PC with dsta
1869
          do_fork_next(nstate, nstatus, nmmumoni);
1870
        end if;
1871
 
1872
      when s_opa_mtp =>
1873
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_opa_mtp_pop_w,
1874
                          nmmumoni, updt_sp=>'1');
1875
 
1876
      when s_opa_mtp_pop_w =>
1877
        nstate := s_opa_mtp_pop_w;
1878
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
1879
        ndpcntl.dtmp_sel := c_dpath_dtmp_dres;    -- DTMP = DRES
1880
        do_memcheck(nstate, nstatus, imemok);
1881
        if imemok then
1882
          ndpcntl.dtmp_we := '1';                 -- load DTMP
1883
          if R_IDSTAT.is_dstmode0 = '1' then      -- handle register access
1884
            nstate := s_opa_mtp_reg;
1885
          else
1886
            case R_IDSTAT.fork_dsta is            -- 2nd dsta fork in s_idecode
1887
              when c_fork_dsta_def => nstate := s_opa_mtp_mem;
1888
              when c_fork_dsta_inc => nstate := s_dsta_inc;
1889
              when c_fork_dsta_dec => nstate := s_dsta_dec;
1890
              when c_fork_dsta_ind => nstate := s_dsta_ind;
1891
              when others => nstate := s_cpufail;
1892
            end case;
1893
          end if;
1894
        end if;
1895
        ndpcntl.ddst_sel := c_dpath_ddst_dst;     -- DDST = R(DST)
1896
        ndpcntl.ddst_we  := '1';                  -- update DDST (needed for sp)
1897
 
1898
      when s_opa_mtp_reg =>
1899
        ndpcntl.abox_asel := c_abox_asel_dtmp;    -- ABOX A = DTMP
1900
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B = const(0)
1901
        ndpcntl.dres_sel := c_dpath_res_abox;     -- DRES = ABOX
1902
        ndpcntl.psr_ccwe := '1';                  -- set cc (from abox too)
1903
        ndpcntl.gpr_mode := PSW.pmode;            -- load reg in pmode
1904
        ndpcntl.gpr_we := '1';
1905
        do_fork_next(nstate, nstatus, nmmumoni);
1906
 
1907
      when s_opa_mtp_mem =>
1908
        ndpcntl.abox_asel := c_abox_asel_dtmp;    -- ABOX A = DTMP
1909
        ndpcntl.abox_bsel := c_abox_bsel_const;   -- ABOX B = const(0)
1910
        ndpcntl.dres_sel := c_dpath_res_abox;     -- DRES = ABOX
1911
        ndpcntl.psr_ccwe := '1';                  -- set cc (from abox too)
1912
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;-- VA = DDST
1913
        nvmcntl.dspace := IREG(15);            -- msb indicates I/D: 0->I, 1->D
1914
        nvmcntl.mode := PSW.pmode;
1915
        nvmcntl.wacc := '1';
1916
        nvmcntl.req := '1';
1917
        nstate := s_opa_mtp_mem_w;
1918
 
1919
      when s_opa_mtp_mem_w =>
1920
        nstate := s_opa_mtp_mem_w;
1921
        do_memcheck(nstate, nstatus, imemok);
1922
        if imemok then
1923
          do_fork_next(nstate, nstatus, nmmumoni);
1924
        end if;
1925
 
1926
      when s_opa_mfp_reg =>
1927
        ndpcntl.gpr_mode := PSW.pmode;           -- fetch reg in pmode
1928
        ndpcntl.ddst_sel := c_dpath_ddst_dst;    -- DDST = reg(dst)
1929
        ndpcntl.ddst_we := '1';
1930
        nstate := s_opa_mfp_dec;
1931
 
1932
      when s_opa_mfp_mem =>
1933
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;   -- VA = DDST
1934
        if PSW.cmode=c_psw_umode and                 -- if cm=pm=user then
1935
           PSW.cmode=c_psw_umode then                -- MFPI works like it
1936
          nvmcntl.dspace := '1';                     -- were MFPD
1937
        else
1938
          nvmcntl.dspace := IREG(15);          -- msb indicates I/D: 0->I, 1->D
1939
        end if;
1940
        nvmcntl.mode := PSW.pmode;
1941
        nvmcntl.req := '1';
1942
        nstate := s_opa_mfp_mem_w;
1943
 
1944
      when s_opa_mfp_mem_w =>
1945
        nstate := s_opa_mfp_mem_w;
1946
        do_memcheck(nstate, nstatus, imemok);
1947
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
1948
        ndpcntl.ddst_sel := c_dpath_ddst_res;    -- DDST = DRES
1949
        if imemok then
1950
          ndpcntl.ddst_we := '1';
1951
          nstate := s_opa_mfp_dec;
1952
        end if;
1953
 
1954
      when s_opa_mfp_dec =>
1955
        ndpcntl.abox_asel := c_abox_asel_dsrc;     -- ABOX A=DSRC
1956
        ndpcntl.abox_const := "000000010";
1957
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(2)
1958
        ndpcntl.abox_opsub := '1';                 -- ABOX = A-B
1959
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1960
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;      -- DSRC = DRES
1961
        ndpcntl.dsrc_we := '1';                    -- update DSRC
1962
        ndpcntl.gpr_adst := c_gpr_sp;
1963
        ndpcntl.gpr_we := '1';                     -- update SP
1964
        nmmumoni.regmod := '1';
1965
        nmmumoni.isdec := '1';
1966
        nstate := s_opa_mfp_push;
1967
 
1968
      when s_opa_mfp_push =>
1969
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
1970
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const(0)
1971
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
1972
        ndpcntl.psr_ccwe := '1';                   -- set cc (from abox too)
1973
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
1974
        nvmcntl.dspace := '1';
1975
        nvmcntl.kstack := is_kmode;
1976
        nvmcntl.wacc := '1';
1977
        nvmcntl.req := '1';
1978
        nstate := s_opa_mfp_push_w;
1979
 
1980
      when s_opa_mfp_push_w =>
1981
        nstate := s_opa_mfp_push_w;
1982
        do_memcheck(nstate, nstatus, imemok);
1983
        if imemok then
1984
          do_fork_next(nstate, nstatus, nmmumoni);
1985
        end if;
1986
 
1987
  -- trap and interrupt handling states ---------------------------------------
1988
 
1989
      when s_trap_4 =>
1990
        lvector := "0000001";           -- vector (4)
1991
        do_start_int(nstate, ndpcntl, lvector);
1992
 
1993
      when s_trap_10 =>
1994
        lvector := "0000010";           -- vector (10)
1995
        do_start_int(nstate, ndpcntl, lvector);
1996
 
1997
      when s_trap_disp =>
1998
        if R_STATUS.trap_mmu = '1' then
1999
          nvmcntl.trap_done := '1';     -- mmu trap taken: set ssr0 trap bit
2000
          lvector := "0101010";         -- mmu trap: vector (250)
2001
        elsif R_STATUS.trap_ysv = '1' then
2002
          lvector := "0000001";         -- ysv trap: vector (4)          
2003
          ncpuerr.ysv := '1';
2004
        else
2005
          lvector := "0000011";         -- trace trap: vector (14)
2006
        end if;
2007
        nstatus.trap_mmu := '0';        -- clear pending trap flags
2008
        nstatus.trap_ysv := '0';        -- 
2009
        do_start_int(nstate, ndpcntl, lvector);
2010
 
2011
      when s_int_ext =>
2012
        lvector := R_STATUS.intvect;    -- external vector
2013
        do_start_int(nstate, ndpcntl, lvector);
2014
 
2015
      when s_int_getpc =>
2016
        nvmcntl.mode := c_psw_kmode;    -- fetch PC from kernel D space
2017
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getpc_w, nmmumoni);
2018
 
2019
      when s_int_getpc_w =>
2020
        nstate := s_int_getpc_w;
2021
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
2022
        ndpcntl.ddst_sel := c_dpath_ddst_res;     -- DDST = DRES
2023
        do_memcheck(nstate, nstatus, imemok);
2024
        if VM_STAT.err = '1' then                 -- in case of vm-err
2025
          nstatus.cpugo   := '0';                 -- non-recoverable error
2026
          nstatus.cpurust := c_cpurust_vecfet;    -- halt CPU
2027
          nstate := s_idle;
2028
        end if;
2029
        if imemok then
2030
          ndpcntl.ddst_we := '1';                 -- DDST = new PC
2031
          nstate := s_int_getps;
2032
        end if;
2033
 
2034
      when s_int_getps =>
2035
        nvmcntl.mode := c_psw_kmode;    -- fetch PS from kernel D space
2036
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getps_w, nmmumoni);
2037
 
2038
      when s_int_getps_w =>
2039
        nstate := s_int_getps_w;
2040
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
2041
        ndpcntl.psr_func := c_psr_func_wint;      -- interupt mode write
2042
        do_memcheck(nstate, nstatus, imemok);
2043
        if VM_STAT.err = '1' then                 -- in case of vm-err
2044
          nstatus.cpugo   := '0';                 -- non-recoverable error
2045
          nstatus.cpurust := c_cpurust_vecfet;    -- halt CPU
2046
          nstate := s_idle;
2047
        end if;
2048
        if imemok then
2049
          ndpcntl.psr_we := '1';                  -- store new PS
2050
          nstate := s_int_getsp;
2051
        end if;
2052
 
2053
      when s_int_getsp =>
2054
        ndpcntl.gpr_asrc := c_gpr_sp;
2055
        ndpcntl.dsrc_we := '1';                  -- DSRC = SP (in new mode)
2056
        nstate := s_int_decsp;
2057
 
2058
      when s_int_decsp =>
2059
        ndpcntl.abox_asel := c_abox_asel_dsrc;   -- ABOX A=DSRC
2060
        ndpcntl.abox_const := "000000010";       -- ABOX const=2
2061
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
2062
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
2063
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
2064
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
2065
        ndpcntl.dsrc_we := '1';                  -- update DSRC
2066
        ndpcntl.gpr_adst := c_gpr_sp;
2067
        ndpcntl.gpr_we := '1';                   -- update SP too
2068
        nstate := s_int_pushps;
2069
 
2070
      when s_int_pushps =>
2071
        ndpcntl.abox_asel := c_abox_asel_dtmp;     -- ABOX A=DTMP (old PS)
2072
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const (0)
2073
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
2074
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
2075
        nvmcntl.wacc := '1';                       -- write mem
2076
        nvmcntl.dspace := '1';
2077
        nvmcntl.kstack := is_kmode;
2078
        nvmcntl.req := '1';
2079
        nstate := s_int_pushps_w;
2080
 
2081
      when s_int_pushps_w =>
2082
        ndpcntl.abox_asel := c_abox_asel_dsrc;   -- ABOX A=DSRC
2083
        ndpcntl.abox_const := "000000010";       -- ABOX const=2
2084
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const
2085
        ndpcntl.abox_opsub := '1';               -- ABOX = A-B
2086
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
2087
        ndpcntl.dsrc_sel := c_dpath_dsrc_res;    -- DSRC = DRES
2088
        ndpcntl.gpr_adst := c_gpr_sp;
2089
 
2090
        nstate := s_int_pushps_w;
2091
        do_memcheck(nstate, nstatus, imemok);
2092
        if imemok then
2093
          ndpcntl.dsrc_we := '1';                -- update DSRC
2094
          ndpcntl.gpr_we := '1';                 -- update SP too
2095
          nstate := s_int_pushpc;
2096
        end if;
2097
 
2098
      when s_int_pushpc =>
2099
        ndpcntl.abox_asel := c_abox_asel_pc;       -- ABOX A=PC
2100
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const (0)
2101
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
2102
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC
2103
        nvmcntl.wacc := '1';                       -- write mem
2104
        nvmcntl.dspace := '1';
2105
        nvmcntl.kstack := is_kmode;
2106
        nvmcntl.req := '1';
2107
        nstate := s_int_pushpc_w;
2108
 
2109
      when s_int_pushpc_w =>
2110
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
2111
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const (0)
2112
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
2113
        ndpcntl.gpr_adst := c_gpr_pc;
2114
 
2115
        nstate := s_int_pushpc_w;
2116
        do_memcheck(nstate, nstatus, imemok);
2117
        if imemok then
2118
          nstatus.do_intrsv := '0';                -- signal end of rsv
2119
          ndpcntl.gpr_we := '1';                   -- load new PC
2120
          do_fork_next(nstate, nstatus, nmmumoni);         -- ???
2121
        end if;
2122
 
2123
  -- return from trap or interrupt handling states ----------------------------
2124
 
2125
      when s_rti_getpc =>
2126
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_rti_getpc_w,
2127
                          nmmumoni, updt_sp=>'1');
2128
 
2129
      when s_rti_getpc_w =>
2130
        nstate := s_rti_getpc_w;
2131
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
2132
        ndpcntl.ddst_sel := c_dpath_ddst_res;     -- DDST = DRES
2133
        do_memcheck(nstate, nstatus, imemok);
2134
        if imemok then
2135
          ndpcntl.ddst_we := '1';                 -- DDST = new PC
2136
          nstate := s_rti_getps;
2137
        end if;
2138
 
2139
      when s_rti_getps =>
2140
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_rti_getps_w,
2141
                          nmmumoni, updt_sp=>'1');
2142
 
2143
      when s_rti_getps_w =>
2144
        nstate := s_rti_getps_w;
2145
        do_memcheck(nstate, nstatus, imemok);
2146
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
2147
        if is_kmode = '1' then                    -- if in kernel mode
2148
          ndpcntl.psr_func := c_psr_func_wall;    --   write all fields
2149
        else
2150
          ndpcntl.psr_func := c_psr_func_wrti;    --   otherwise filter
2151
        end if;
2152
        if imemok then
2153
          ndpcntl.psr_we := '1';                  -- load new PS
2154
          nstate := s_rti_newpc;
2155
        end if;
2156
 
2157
      when s_rti_newpc =>
2158
        ndpcntl.abox_asel := c_abox_asel_ddst;     -- ABOX A=DDST
2159
        ndpcntl.abox_bsel := c_abox_bsel_const;    -- ABOX B=const (0)
2160
        ndpcntl.dres_sel := c_dpath_res_abox;      -- DRES = ABOX
2161
        ndpcntl.gpr_adst := c_gpr_pc;
2162
        ndpcntl.gpr_we := '1';                     -- load new PC
2163
        if R_IDSTAT.op_rtt = '1' then              -- if RTT instruction
2164
          nstate := s_ifetch;                      --   force fetch
2165
        else                                       -- otherwise RTI
2166
          do_fork_next(nstate, nstatus, nmmumoni);
2167
        end if;
2168
 
2169
  -- exception abort states ---------------------------------------------------
2170
 
2171
      when s_vmerr =>
2172
        nstate := s_cpufail;
2173
 
2174
                                            -- setup for R_VMSTAT.err_rsv='1'
2175
        ndpcntl.abox_azero := '1';               -- ABOX A = 0
2176
        ndpcntl.abox_const := "000000100";       -- emergency stack pointer
2177
        ndpcntl.abox_bsel := c_abox_bsel_const;  -- ABOX B=const(vector)
2178
        ndpcntl.dres_sel := c_dpath_res_abox;    -- DRES = ABOX
2179
        ndpcntl.gpr_mode := c_psw_kmode;         -- set kmode SP to 4
2180
        ndpcntl.gpr_adst := c_gpr_sp;
2181
 
2182
        nstatus.trap_mmu :='0';                  -- drop pending mmu trap
2183
 
2184
        if R_VMSTAT.fail = '1' then              -- vmbox failure
2185
          nstatus.cpugo   := '0';                  -- halt cpu
2186
          nstatus.cpurust := c_cpurust_vfail;
2187
          nstate := s_idle;
2188
 
2189
        elsif R_STATUS.do_intrsv = '1' then      -- double error
2190
          nstatus.cpugo := '0';                    -- give up, HALT cpu
2191
          nstatus.cpurust := c_cpurust_recrsv;
2192
          nstate := s_idle;
2193
 
2194
        elsif R_VMSTAT.err = '1' then            -- normal vm errors
2195
          if R_VMSTAT.err_rsv = '1' then
2196
            nstatus.do_intrsv := '1';              -- signal start of rsv
2197
            ndpcntl.gpr_we := '1';
2198
 
2199
            if R_VMSTAT.err_odd='1' or R_VMSTAT.err_mmu='1' then
2200
              ncpuerr.adderr := '1';
2201
            elsif R_VMSTAT.err_nxm = '1' then
2202
              ncpuerr.nxm := '1';
2203
            elsif R_VMSTAT.err_iobto = '1' then
2204
              ncpuerr.iobto := '1';
2205
            end if;
2206
            ncpuerr.rsv := '1';
2207
            nstate := s_trap_4;
2208
 
2209
          elsif R_VMSTAT.err_odd = '1' then
2210
            ncpuerr.adderr := '1';
2211
            nstate := s_trap_4;
2212
          elsif R_VMSTAT.err_nxm = '1' then
2213
            ncpuerr.nxm := '1';
2214
            nstate := s_trap_4;
2215
          elsif R_VMSTAT.err_iobto = '1' then
2216
            ncpuerr.iobto := '1';
2217
            nstate := s_trap_4;
2218
 
2219
          elsif R_VMSTAT.err_mmu = '1' then
2220
            lvector := "0101010";                    -- vector (250)
2221
            do_start_int(nstate, ndpcntl, lvector);
2222
          end if;
2223
        end if;
2224
 
2225
      when s_cpufail =>
2226
        nstatus.cpugo   := '0';
2227
        nstatus.cpurust := c_cpurust_sfail;
2228
        nstate := s_idle;
2229
 
2230
      when others =>
2231
        nstate := s_cpufail;             --!!! catch undefined states !!!
2232
 
2233
    end case;
2234
 
2235
    if nstatus.cmdack = '1' then        -- cmdack in next cycle ? Yes we test
2236
                                           -- nstatus here !!
2237
      nstatus.cmdbusy := '0';
2238
      ndpcntl.cpdout_we := '1';
2239
    end if;
2240
 
2241
    N_STATE  <= nstate;
2242
    N_STATUS <= nstatus;
2243
    N_CPUERR <= ncpuerr;
2244
    N_IDSTAT <= nidstat;
2245
 
2246
    CRESET <= ncreset;
2247
    BRESET <= nbreset;
2248
    INT_ACK <= nintack;
2249
 
2250
    DP_CNTL <= ndpcntl;
2251
    VM_CNTL <= nvmcntl;
2252
 
2253
    nmmumoni.regnum := ndpcntl.gpr_adst;
2254
    nmmumoni.delta := ndpcntl.abox_const(3 downto 0);
2255
    MMU_MONI <= nmmumoni;
2256
 
2257
  end process proc_next;
2258
 
2259
  proc_cpstat : process (R_STATUS)
2260
  begin
2261
    CP_STAT         <= cp_stat_init;
2262
    CP_STAT.cmdbusy <= R_STATUS.cmdbusy;
2263
    CP_STAT.cmdack  <= R_STATUS.cmdack;
2264
    CP_STAT.cmderr  <= R_STATUS.cmderr;
2265
    CP_STAT.cmdmerr <= R_STATUS.cmdmerr;
2266
    CP_STAT.cpugo   <= R_STATUS.cpugo;
2267
    CP_STAT.cpustep <= R_STATUS.cpustep;
2268
    CP_STAT.cpuhalt <= R_STATUS.cpuhalt;
2269
    CP_STAT.cpuwait <= R_STATUS.cpuwait;
2270
    CP_STAT.cpurust <= R_STATUS.cpurust;
2271
  end process proc_cpstat;
2272
 
2273
end syn;
2274
 

powered by: WebSVN 2.1.0

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