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 13

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

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

powered by: WebSVN 2.1.0

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