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

Subversion Repositories w11

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

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

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

powered by: WebSVN 2.1.0

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