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

Subversion Repositories w11

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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