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

Subversion Repositories w11

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

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

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

powered by: WebSVN 2.1.0

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