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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [leon3/] [iu3.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity:      iu3
20
-- File:        iu3.vhd
21
-- Author:      Jiri Gaisler, Edvin Catovic, Gaisler Research
22
-- Description: LEON3 7-stage integer pipline
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
use ieee.numeric_std.all;
28
library grlib;
29
use grlib.sparc.all;
30
use grlib.stdlib.all;
31
library techmap;
32
use techmap.gencomp.all;
33
library gaisler;
34
use gaisler.leon3.all;
35
use gaisler.libiu.all;
36
use gaisler.arith.all;
37
-- pragma translate_off
38
use grlib.sparc_disas.all;
39
-- pragma translate_on
40
 
41
entity iu3 is
42
  generic (
43
    nwin     : integer range 2 to 32 := 8;
44
    isets    : integer range 1 to 4 := 1;
45
    dsets    : integer range 1 to 4 := 1;
46
    fpu      : integer range 0 to 15 := 0;
47
    v8       : integer range 0 to 63 := 0;
48
    cp, mac  : integer range 0 to 1 := 0;
49
    dsu      : integer range 0 to 1 := 0;
50
    nwp      : integer range 0 to 4 := 0;
51
    pclow    : integer range 0 to 2 := 2;
52
    notag    : integer range 0 to 1 := 0;
53
    index    : integer range 0 to 15:= 0;
54
    lddel    : integer range 1 to 2 := 2;
55
    irfwt    : integer range 0 to 1 := 0;
56
    disas    : integer range 0 to 2 := 0;
57
    tbuf     : integer range 0 to 64 := 0;  -- trace buf size in kB (0 - no trace buffer)
58
    pwd      : integer range 0 to 2 := 0;   -- power-down
59
    svt      : integer range 0 to 1 := 0;   -- single-vector trapping
60
    rstaddr  : integer := 16#00000#;        -- reset vector MSB address
61
    smp      : integer range 0 to 15 := 0;  -- support SMP systems
62
    fabtech  : integer range 0 to NTECH := 0;
63
    clk2x    : integer := 0
64
  );
65
  port (
66
    clk   : in  std_ulogic;
67
    rstn  : in  std_ulogic;
68
    holdn : in  std_ulogic;
69
    ici   : out icache_in_type;
70
    ico   : in  icache_out_type;
71
    dci   : out dcache_in_type;
72
    dco   : in  dcache_out_type;
73
    rfi   : out iregfile_in_type;
74
    rfo   : in  iregfile_out_type;
75
    irqi  : in  l3_irq_in_type;
76
    irqo  : out l3_irq_out_type;
77
    dbgi  : in  l3_debug_in_type;
78
    dbgo  : out l3_debug_out_type;
79
    muli  : out mul32_in_type;
80
    mulo  : in  mul32_out_type;
81
    divi  : out div32_in_type;
82
    divo  : in  div32_out_type;
83
    fpo   : in  fpc_out_type;
84
    fpi   : out fpc_in_type;
85
    cpo   : in  fpc_out_type;
86
    cpi   : out fpc_in_type;
87
    tbo   : in  tracebuf_out_type;
88
    tbi   : out tracebuf_in_type;
89
    sclk   : in  std_ulogic
90
    );
91
end;
92
 
93
architecture rtl of iu3 is
94
 
95
  constant ISETMSB : integer := log2x(isets)-1;
96
  constant DSETMSB : integer := log2x(dsets)-1;
97
  constant RFBITS : integer range 6 to 10 := log2(NWIN+1) + 4;
98
  constant NWINLOG2   : integer range 1 to 5 := log2(NWIN);
99
  constant CWPOPT : boolean := (NWIN = (2**NWINLOG2));
100
  constant CWPMIN : std_logic_vector(NWINLOG2-1 downto 0) := (others => '0');
101
  constant CWPMAX : std_logic_vector(NWINLOG2-1 downto 0) :=
102
        conv_std_logic_vector(NWIN-1, NWINLOG2);
103
  constant FPEN   : boolean := (fpu /= 0);
104
  constant CPEN   : boolean := (cp = 1);
105
  constant MULEN  : boolean := (v8 /= 0);
106
  constant MULTYPE: integer := (v8 / 16);
107
  constant DIVEN  : boolean := (v8 /= 0);
108
  constant MACEN  : boolean := (mac = 1);
109
  constant MACPIPE: boolean := (mac = 1) and (v8/2 = 1);
110
  constant IMPL   : integer := 15;
111
  constant VER    : integer := 3;
112
  constant DBGUNIT : boolean := (dsu = 1);
113
  constant TRACEBUF   : boolean := (tbuf /= 0);
114
  constant TBUFBITS : integer := 10 + log2(tbuf) - 4;
115
  constant PWRD1  : boolean := false; --(pwd = 1) and not (index /= 0);
116
  constant PWRD2  : boolean := pwd /= 0; --(pwd = 2) or (index /= 0);
117
  constant RS1OPT : boolean := (is_fpga(FABTECH) /= 0);
118
  constant DYNRST : boolean := (rstaddr = 16#FFFFF#);
119
 
120
  subtype word is std_logic_vector(31 downto 0);
121
  subtype pctype is std_logic_vector(31 downto PCLOW);
122
  subtype rfatype is std_logic_vector(RFBITS-1 downto 0);
123
  subtype cwptype is std_logic_vector(NWINLOG2-1 downto 0);
124
  type icdtype is array (0 to isets-1) of word;
125
  type dcdtype is array (0 to dsets-1) of word;
126
 
127
  type dc_in_type is record
128
    signed, enaddr, read, write, lock , dsuen : std_ulogic;
129
    size : std_logic_vector(1 downto 0);
130
    asi  : std_logic_vector(7 downto 0);
131
  end record;
132
 
133
  type pipeline_ctrl_type is record
134
    pc    : pctype;
135
    inst  : word;
136
    cnt   : std_logic_vector(1 downto 0);
137
    rd    : rfatype;
138
    tt    : std_logic_vector(5 downto 0);
139
    trap  : std_ulogic;
140
    annul : std_ulogic;
141
    wreg  : std_ulogic;
142
    wicc  : std_ulogic;
143
    wy    : std_ulogic;
144
    ld    : std_ulogic;
145
    pv    : std_ulogic;
146
    rett  : std_ulogic;
147
  end record;
148
 
149
  type fetch_reg_type is record
150
    pc     : pctype;
151
    branch : std_ulogic;
152
  end record;
153
 
154
  type decode_reg_type is record
155
    pc    : pctype;
156
    inst  : icdtype;
157
    cwp   : cwptype;
158
    set   : std_logic_vector(ISETMSB downto 0);
159
    mexc  : std_ulogic;
160
    cnt   : std_logic_vector(1 downto 0);
161
    pv    : std_ulogic;
162
    annul : std_ulogic;
163
    inull : std_ulogic;
164
    step  : std_ulogic;
165
  end record;
166
 
167
  type regacc_reg_type is record
168
    ctrl  : pipeline_ctrl_type;
169
    rs1   : std_logic_vector(4 downto 0);
170
    rfa1, rfa2 : rfatype;
171
    rsel1, rsel2 : std_logic_vector(2 downto 0);
172
    rfe1, rfe2 : std_ulogic;
173
    cwp   : cwptype;
174
    imm   : word;
175
    ldcheck1 : std_ulogic;
176
    ldcheck2 : std_ulogic;
177
    ldchkra : std_ulogic;
178
    ldchkex : std_ulogic;
179
    su : std_ulogic;
180
    et : std_ulogic;
181
    wovf : std_ulogic;
182
    wunf : std_ulogic;
183
    ticc : std_ulogic;
184
    jmpl : std_ulogic;
185
    step  : std_ulogic;
186
    mulstart : std_ulogic;
187
    divstart : std_ulogic;
188
  end record;
189
 
190
  type execute_reg_type is record
191
    ctrl   : pipeline_ctrl_type;
192
    op1    : word;
193
    op2    : word;
194
    aluop  : std_logic_vector(2 downto 0);       -- Alu operation
195
    alusel : std_logic_vector(1 downto 0);       -- Alu result select
196
    aluadd : std_ulogic;
197
    alucin : std_ulogic;
198
    ldbp1, ldbp2 : std_ulogic;
199
    invop2 : std_ulogic;
200
    shcnt  : std_logic_vector(4 downto 0);       -- shift count
201
    sari   : std_ulogic;                                -- shift msb
202
    shleft : std_ulogic;                                -- shift left/right
203
    ymsb   : std_ulogic;                                -- shift left/right
204
    rd     : std_logic_vector(4 downto 0);
205
    jmpl   : std_ulogic;
206
    su     : std_ulogic;
207
    et     : std_ulogic;
208
    cwp    : cwptype;
209
    icc    : std_logic_vector(3 downto 0);
210
    mulstep: std_ulogic;
211
    mul    : std_ulogic;
212
    mac    : std_ulogic;
213
  end record;
214
 
215
  type memory_reg_type is record
216
    ctrl   : pipeline_ctrl_type;
217
    result : word;
218
    y      : word;
219
    icc    : std_logic_vector(3 downto 0);
220
    nalign : std_ulogic;
221
    dci    : dc_in_type;
222
    werr   : std_ulogic;
223
    wcwp   : std_ulogic;
224
    irqen  : std_ulogic;
225
    irqen2 : std_ulogic;
226
    mac    : std_ulogic;
227
    divz   : std_ulogic;
228
    su     : std_ulogic;
229
    mul    : std_ulogic;
230
  end record;
231
 
232
  type exception_state is (run, trap, dsu1, dsu2);
233
 
234
  type exception_reg_type is record
235
    ctrl   : pipeline_ctrl_type;
236
    result : word;
237
    y      : word;
238
    icc    : std_logic_vector( 3 downto 0);
239
    annul_all : std_ulogic;
240
    data   : dcdtype;
241
    set    : std_logic_vector(DSETMSB downto 0);
242
    mexc   : std_ulogic;
243
    dci    : dc_in_type;
244
    laddr  : std_logic_vector(1 downto 0);
245
    rstate : exception_state;
246
    npc    : std_logic_vector(2 downto 0);
247
    intack : std_ulogic;
248
    ipend  : std_ulogic;
249
    mac    : std_ulogic;
250
    debug  : std_ulogic;
251
    nerror : std_ulogic;
252
  end record;
253
 
254
  type dsu_registers is record
255
    tt      : std_logic_vector(7 downto 0);
256
    err     : std_ulogic;
257
    tbufcnt : std_logic_vector(TBUFBITS-1 downto 0);
258
    asi     : std_logic_vector(7 downto 0);
259
    crdy    : std_logic_vector(2 downto 1);  -- diag cache access ready
260
  end record;
261
 
262
  type irestart_register is record
263
    addr   : pctype;
264
    pwd    : std_ulogic;
265
  end record;
266
 
267
  type pwd_register_type is record
268
    pwd    : std_ulogic;
269
    error  : std_ulogic;
270
  end record;
271
 
272
  type special_register_type is record
273
    cwp    : cwptype;                             -- current window pointer
274
    icc    : std_logic_vector(3 downto 0);         -- integer condition codes
275
    tt     : std_logic_vector(7 downto 0);         -- trap type
276
    tba    : std_logic_vector(19 downto 0);        -- trap base address
277
    wim    : std_logic_vector(NWIN-1 downto 0);   -- window invalid mask
278
    pil    : std_logic_vector(3 downto 0);         -- processor interrupt level
279
    ec     : std_ulogic;                           -- enable CP 
280
    ef     : std_ulogic;                           -- enable FP 
281
    ps     : std_ulogic;                           -- previous supervisor flag
282
    s      : std_ulogic;                           -- supervisor flag
283
    et     : std_ulogic;                           -- enable traps
284
    y      : word;
285
    asr18  : word;
286
    svt    : std_ulogic;                           -- enable traps
287
    dwt    : std_ulogic;                           -- disable write error trap
288
  end record;
289
 
290
  type write_reg_type is record
291
    s      : special_register_type;
292
    result : word;
293
    wa     : rfatype;
294
    wreg   : std_ulogic;
295
    except : std_ulogic;
296
  end record;
297
 
298
  type registers is record
299
    f  : fetch_reg_type;
300
    d  : decode_reg_type;
301
    a  : regacc_reg_type;
302
    e  : execute_reg_type;
303
    m  : memory_reg_type;
304
    x  : exception_reg_type;
305
    w  : write_reg_type;
306
  end record;
307
 
308
  type exception_type is record
309
    pri   : std_ulogic;
310
    ill   : std_ulogic;
311
    fpdis : std_ulogic;
312
    cpdis : std_ulogic;
313
    wovf  : std_ulogic;
314
    wunf  : std_ulogic;
315
    ticc  : std_ulogic;
316
  end record;
317
 
318
  type watchpoint_register is record
319
    addr    : std_logic_vector(31 downto 2);  -- watchpoint address
320
    mask    : std_logic_vector(31 downto 2);  -- watchpoint mask
321
    exec    : std_ulogic;                           -- trap on instruction
322
    load    : std_ulogic;                           -- trap on load
323
    store   : std_ulogic;                           -- trap on store
324
  end record;
325
 
326
  type watchpoint_registers is array (0 to 3) of watchpoint_register;
327
 
328
  constant wpr_none : watchpoint_register := (
329
        zero32(31 downto 2), zero32(31 downto 2), '0', '0', '0');
330
 
331
  function dbgexc(r  : registers; dbgi : l3_debug_in_type; trap : std_ulogic; tt : std_logic_vector(7 downto 0)) return std_ulogic is
332
    variable dmode : std_ulogic;
333
  begin
334
    dmode := '0';
335
    if (not r.x.ctrl.annul and trap) = '1' then
336
      if (((tt = "00" & TT_WATCH) and (dbgi.bwatch = '1')) or
337
          ((dbgi.bsoft = '1') and (tt = "10000001")) or
338
          (dbgi.btrapa = '1') or
339
          ((dbgi.btrape = '1') and not ((tt(5 downto 0) = TT_PRIV) or
340
            (tt(5 downto 0) = TT_FPDIS) or (tt(5 downto 0) = TT_WINOF) or
341
            (tt(5 downto 0) = TT_WINUF) or (tt(5 downto 4) = "01") or (tt(7) = '1'))) or
342
          (((not r.w.s.et) and dbgi.berror) = '1')) then
343
        dmode := '1';
344
      end if;
345
    end if;
346
    return(dmode);
347
  end;
348
 
349
  function dbgerr(r : registers; dbgi : l3_debug_in_type;
350
                  tt : std_logic_vector(7 downto 0))
351
  return std_ulogic is
352
    variable err : std_ulogic;
353
  begin
354
    err := not r.w.s.et;
355
    if (((dbgi.dbreak = '1') and (tt = ("00" & TT_WATCH))) or
356
        ((dbgi.bsoft = '1') and (tt = ("10000001")))) then
357
      err := '0';
358
    end if;
359
    return(err);
360
  end;
361
 
362
  procedure diagwr(r    : in registers;
363
                   dsur : in dsu_registers;
364
                   ir   : in irestart_register;
365
                   dbg  : in l3_debug_in_type;
366
                   wpr  : in watchpoint_registers;
367
                   s    : out special_register_type;
368
                   vwpr : out watchpoint_registers;
369
                   asi : out std_logic_vector(7 downto 0);
370
                   pc, npc  : out pctype;
371
                   tbufcnt : out std_logic_vector(TBUFBITS-1 downto 0);
372
                   wr : out std_ulogic;
373
                   addr : out std_logic_vector(9 downto 0);
374
                   data : out word;
375
                   fpcwr : out std_ulogic) is
376
  variable i : integer range 0 to 3;
377
  begin
378
    s := r.w.s; pc := r.f.pc; npc := ir.addr; wr := '0';
379
    vwpr := wpr; asi := dsur.asi; addr := (others => '0');
380
    data := dbg.ddata;
381
    tbufcnt := dsur.tbufcnt; fpcwr := '0';
382
      if (dbg.dsuen and dbg.denable and dbg.dwrite) = '1' then
383
        case dbg.daddr(23 downto 20) is
384
          when "0001" =>
385
            if (dbg.daddr(16) = '1') and TRACEBUF then -- trace buffer control reg
386
              tbufcnt := dbg.ddata(TBUFBITS-1 downto 0);
387
            end if;
388
          when "0011" => -- IU reg file
389
            if dbg.daddr(12) = '0' then
390
              wr := '1';
391
              addr := (others => '0');
392
              addr(RFBITS-1 downto 0) := dbg.daddr(RFBITS+1 downto 2);
393
            else  -- FPC
394
              fpcwr := '1';
395
            end if;
396
          when "0100" => -- IU special registers
397
            case dbg.daddr(7 downto 6) is
398
              when "00" => -- IU regs Y - TBUF ctrl reg
399
                case dbg.daddr(5 downto 2) is
400
                  when "0000" => -- Y
401
                    s.y := dbg.ddata;
402
                  when "0001" => -- PSR
403
                    s.cwp := dbg.ddata(NWINLOG2-1 downto 0);
404
                    s.icc := dbg.ddata(23 downto 20);
405
                    s.ec  := dbg.ddata(13);
406
                    if FPEN then s.ef := dbg.ddata(12); end if;
407
                    s.pil := dbg.ddata(11 downto 8);
408
                    s.s   := dbg.ddata(7);
409
                    s.ps  := dbg.ddata(6);
410
                    s.et  := dbg.ddata(5);
411
                  when "0010" => -- WIM
412
                    s.wim := dbg.ddata(NWIN-1 downto 0);
413
                  when "0011" => -- TBR
414
                    s.tba := dbg.ddata(31 downto 12);
415
                    s.tt  := dbg.ddata(11 downto 4);
416
                  when "0100" => -- PC
417
                    pc := dbg.ddata(31 downto PCLOW);
418
                  when "0101" => -- NPC
419
                    npc := dbg.ddata(31 downto PCLOW);
420
                  when "0110" => --FSR
421
                    fpcwr := '1';
422
                  when "0111" => --CFSR
423
                  when "1001" => -- ASI reg
424
                    asi := dbg.ddata(7 downto 0);
425
                  --when "1001" => -- TBUF ctrl reg
426
                  --  tbufcnt := dbg.ddata(TBUFBITS-1 downto 0);
427
                  when others =>
428
                end case;
429
              when "01" => -- ASR16 - ASR31
430
                case dbg.daddr(5 downto 2) is
431
                when "0001" =>  -- %ASR17
432
                  s.dwt := dbg.ddata(14);
433
                  s.svt := dbg.ddata(13);
434
                when "0010" =>  -- %ASR18
435
                  if MACEN then s.asr18 := dbg.ddata; end if;
436
                when "1000" =>          -- %ASR24 - %ASR31
437
                  vwpr(0).addr := dbg.ddata(31 downto 2);
438
                  vwpr(0).exec := dbg.ddata(0);
439
                when "1001" =>
440
                  vwpr(0).mask := dbg.ddata(31 downto 2);
441
                  vwpr(0).load := dbg.ddata(1);
442
                  vwpr(0).store := dbg.ddata(0);
443
                when "1010" =>
444
                  vwpr(1).addr := dbg.ddata(31 downto 2);
445
                  vwpr(1).exec := dbg.ddata(0);
446
                when "1011" =>
447
                  vwpr(1).mask := dbg.ddata(31 downto 2);
448
                  vwpr(1).load := dbg.ddata(1);
449
                  vwpr(1).store := dbg.ddata(0);
450
                when "1100" =>
451
                  vwpr(2).addr := dbg.ddata(31 downto 2);
452
                  vwpr(2).exec := dbg.ddata(0);
453
                when "1101" =>
454
                  vwpr(2).mask := dbg.ddata(31 downto 2);
455
                  vwpr(2).load := dbg.ddata(1);
456
                  vwpr(2).store := dbg.ddata(0);
457
                when "1110" =>
458
                  vwpr(3).addr := dbg.ddata(31 downto 2);
459
                  vwpr(3).exec := dbg.ddata(0);
460
                when "1111" => -- 
461
                  vwpr(3).mask := dbg.ddata(31 downto 2);
462
                  vwpr(3).load := dbg.ddata(1);
463
                  vwpr(3).store := dbg.ddata(0);
464
                when others => -- 
465
                end case;
466
-- disabled due to bug in XST
467
--                  i := conv_integer(dbg.daddr(4 downto 3)); 
468
--                  if dbg.daddr(2) = '0' then
469
--                    vwpr(i).addr := dbg.ddata(31 downto 2);
470
--                    vwpr(i).exec := dbg.ddata(0); 
471
--                  else
472
--                    vwpr(i).mask := dbg.ddata(31 downto 2);
473
--                    vwpr(i).load := dbg.ddata(1);
474
--                    vwpr(i).store := dbg.ddata(0);              
475
--                  end if;                    
476
              when others =>
477
            end case;
478
          when others =>
479
        end case;
480
      end if;
481
  end;
482
 
483
  function asr17_gen ( r : in registers) return word is
484
  variable asr17 : word;
485
  variable fpu2 : integer range 0 to 3;
486
  begin
487
    asr17 := zero32;
488
    asr17(31 downto 28) := conv_std_logic_vector(index, 4);
489
    if (clk2x > 8) then
490
      asr17(16 downto 15) := conv_std_logic_vector(clk2x-8, 2);
491
      asr17(17) := '1';
492
    elsif (clk2x > 0) then
493
      asr17(16 downto 15) := conv_std_logic_vector(clk2x, 2);
494
    end if;
495
    asr17(14) := r.w.s.dwt;
496
    if svt = 1 then asr17(13) := r.w.s.svt; end if;
497
    if lddel = 2 then asr17(12) := '1'; end if;
498
    if (fpu > 0) and (fpu < 8) then fpu2 := 1;
499
    elsif (fpu >= 8) and (fpu < 15) then fpu2 := 3;
500
    elsif fpu = 15 then fpu2 := 2;
501
    else fpu2 := 0; end if;
502
    asr17(11 downto 10) := conv_std_logic_vector(fpu2, 2);
503
    if mac = 1 then asr17(9) := '1'; end if;
504
    if v8 /= 0 then asr17(8) := '1'; end if;
505
    asr17(7 downto 5) := conv_std_logic_vector(nwp, 3);
506
    asr17(4 downto 0) := conv_std_logic_vector(nwin-1, 5);
507
    return(asr17);
508
  end;
509
 
510
  procedure diagread(dbgi   : in l3_debug_in_type;
511
                     r      : in registers;
512
                     dsur   : in dsu_registers;
513
                     ir     : in irestart_register;
514
                     wpr    : in watchpoint_registers;
515
                     dco   : in  dcache_out_type;
516
                     tbufo  : in tracebuf_out_type;
517
                     data : out word) is
518
    variable cwp : std_logic_vector(4 downto 0);
519
    variable rd : std_logic_vector(4 downto 0);
520
    variable i : integer range 0 to 3;
521
  begin
522
    data := (others => '0'); cwp := (others => '0');
523
    cwp(NWINLOG2-1 downto 0) := r.w.s.cwp;
524
      case dbgi.daddr(22 downto 20) is
525
        when "001" => -- trace buffer
526
          if TRACEBUF then
527
            if dbgi.daddr(16) = '1' then -- trace buffer control reg
528
              if TRACEBUF then data(TBUFBITS-1 downto 0) := dsur.tbufcnt; end if;
529
            else
530
              case dbgi.daddr(3 downto 2) is
531
              when "00" => data := tbufo.data(127 downto 96);
532
              when "01" => data := tbufo.data(95 downto 64);
533
              when "10" => data := tbufo.data(63 downto 32);
534
              when others => data := tbufo.data(31 downto 0);
535
              end case;
536
            end if;
537
          end if;
538
        when "011" => -- IU reg file
539
          if dbgi.daddr(12) = '0' then
540
            data := rfo.data1(31 downto 0);
541
            if (dbgi.daddr(11) = '1') and (is_fpga(fabtech) = 0) then
542
              data := rfo.data2(31 downto 0);
543
            end if;
544
          else data := fpo.dbg.data; end if;
545
        when "100" => -- IU regs
546
          case dbgi.daddr(7 downto 6) is
547
            when "00" => -- IU regs Y - TBUF ctrl reg
548
              case dbgi.daddr(5 downto 2) is
549
                when "0000" =>
550
                  data := r.w.s.y;
551
                when "0001" =>
552
                  data := conv_std_logic_vector(IMPL, 4) & conv_std_logic_vector(VER, 4) &
553
                          r.w.s.icc & "000000" & r.w.s.ec & r.w.s.ef & r.w.s.pil &
554
                          r.w.s.s & r.w.s.ps & r.w.s.et & cwp;
555
                when "0010" =>
556
                  data(NWIN-1 downto 0) := r.w.s.wim;
557
                when "0011" =>
558
                  data := r.w.s.tba & r.w.s.tt & "0000";
559
                when "0100" =>
560
                  data(31 downto PCLOW) := r.f.pc;
561
                when "0101" =>
562
                  data(31 downto PCLOW) := ir.addr;
563
                when "0110" => -- FSR
564
                  data := fpo.dbg.data;
565
                when "0111" => -- CPSR
566
                when "1000" => -- TT reg
567
                  data(12 downto 4) := dsur.err & dsur.tt;
568
                when "1001" => -- ASI reg
569
                  data(7 downto 0) := dsur.asi;
570
                when others =>
571
              end case;
572
            when "01" =>
573
              if dbgi.daddr(5) = '0' then -- %ASR17
574
                if dbgi.daddr(4 downto 2) = "001" then -- %ASR17
575
                  data := asr17_gen(r);
576
                elsif MACEN and  dbgi.daddr(4 downto 2) = "010" then -- %ASR18
577
                  data := r.w.s.asr18;
578
                end if;
579
              else  -- %ASR24 - %ASR31
580
                i := conv_integer(dbgi.daddr(4 downto 3));                                           -- 
581
                if dbgi.daddr(2) = '0' then
582
                  data(31 downto 2) := wpr(i).addr;
583
                  data(0) := wpr(i).exec;
584
                else
585
                  data(31 downto 2) := wpr(i).mask;
586
                  data(1) := wpr(i).load;
587
                  data(0) := wpr(i).store;
588
                end if;
589
              end if;
590
            when others =>
591
          end case;
592
        when "111" =>
593
          data := r.x.data(conv_integer(r.x.set));
594
        when others =>
595
      end case;
596
  end;
597
 
598
 
599
  procedure itrace(r    : in registers;
600
                   dsur : in dsu_registers;
601
                   vdsu : in dsu_registers;
602
                   res  : in word;
603
                   exc  : in std_ulogic;
604
                   dbgi : in l3_debug_in_type;
605
                   error : in std_ulogic;
606
                   trap  : in std_ulogic;
607
                   tbufcnt : out std_logic_vector(TBUFBITS-1 downto 0);
608
                   di  : out tracebuf_in_type) is
609
  variable meminst : std_ulogic;
610
  begin
611
    di.addr := (others => '0'); di.data := (others => '0');
612
    di.enable := '0'; di.write := (others => '0');
613
    tbufcnt := vdsu.tbufcnt;
614
    meminst := r.x.ctrl.inst(31) and r.x.ctrl.inst(30);
615
    if TRACEBUF then
616
      di.addr(TBUFBITS-1 downto 0) := dsur.tbufcnt;
617
      di.data(127) := '0';
618
      di.data(126) := not r.x.ctrl.pv;
619
      di.data(125 downto 96) := dbgi.timer(29 downto 0);
620
      di.data(95 downto 64) := res;
621
      di.data(63 downto 34) := r.x.ctrl.pc(31 downto 2);
622
      di.data(33) := trap;
623
      di.data(32) := error;
624
      di.data(31 downto 0) := r.x.ctrl.inst;
625
      if (dbgi.tenable = '0') or (r.x.rstate = dsu2) then
626
        if ((dbgi.dsuen and dbgi.denable) = '1') and (dbgi.daddr(23 downto 20) & dbgi.daddr(16) = "00010") then
627
          di.enable := '1';
628
          di.addr(TBUFBITS-1 downto 0) := dbgi.daddr(TBUFBITS-1+4 downto 4);
629
          if dbgi.dwrite = '1' then
630
            case dbgi.daddr(3 downto 2) is
631
              when "00" => di.write(3) := '1';
632
              when "01" => di.write(2) := '1';
633
              when "10" => di.write(1) := '1';
634
              when others => di.write(0) := '1';
635
            end case;
636
            di.data := dbgi.ddata & dbgi.ddata & dbgi.ddata & dbgi.ddata;
637
          end if;
638
        end if;
639
      elsif (not r.x.ctrl.annul and (r.x.ctrl.pv or meminst) and not r.x.debug) = '1' then
640
        di.enable := '1'; di.write := (others => '1');
641
        tbufcnt := dsur.tbufcnt + 1;
642
      end if;
643
      di.diag := dco.testen & "000";
644
      if dco.scanen = '1' then di.enable := '0'; end if;
645
    end if;
646
  end;
647
 
648
  procedure dbg_cache(holdn    : in std_ulogic;
649
                      dbgi     :  in l3_debug_in_type;
650
                      r        : in registers;
651
                      dsur     : in dsu_registers;
652
                      mresult  : in word;
653
                      dci      : in dc_in_type;
654
                      mresult2 : out word;
655
                      dci2     : out dc_in_type
656
                      ) is
657
  begin
658
    mresult2 := mresult; dci2 := dci; dci2.dsuen := '0';
659
    if DBGUNIT then
660
      if r.x.rstate = dsu2 then
661
        dci2.asi := dsur.asi;
662
        if (dbgi.daddr(22 downto 20) = "111") and (dbgi.dsuen = '1') then
663
          dci2.dsuen := (dbgi.denable or r.m.dci.dsuen) and not dsur.crdy(2);
664
          dci2.enaddr := dbgi.denable;
665
          dci2.size := "10"; dci2.read := '1'; dci2.write := '0';
666
          if (dbgi.denable and not r.m.dci.enaddr) = '1' then
667
            mresult2 := (others => '0'); mresult2(19 downto 2) := dbgi.daddr(19 downto 2);
668
          else
669
            mresult2 := dbgi.ddata;
670
          end if;
671
          if dbgi.dwrite = '1' then
672
            dci2.read := '0'; dci2.write := '1';
673
          end if;
674
        end if;
675
      end if;
676
    end if;
677
  end;
678
 
679
  procedure fpexack(r : in registers; fpexc : out std_ulogic) is
680
  begin
681
    fpexc := '0';
682
    if FPEN then
683
      if r.x.ctrl.tt = TT_FPEXC then fpexc := '1'; end if;
684
    end if;
685
  end;
686
 
687
  procedure diagrdy(denable : in std_ulogic;
688
                    dsur : in dsu_registers;
689
                    dci   : in dc_in_type;
690
                    mds : in std_ulogic;
691
                    ico : in icache_out_type;
692
                    crdy : out std_logic_vector(2 downto 1)) is
693
  begin
694
    crdy := dsur.crdy(1) & '0';
695
    if dci.dsuen = '1' then
696
      case dsur.asi(4 downto 0) is
697
        when ASI_ITAG | ASI_IDATA | ASI_UINST | ASI_SINST =>
698
          crdy(2) := ico.diagrdy and not dsur.crdy(2);
699
        when ASI_DTAG | ASI_MMUSNOOP_DTAG | ASI_DDATA | ASI_UDATA | ASI_SDATA =>
700
          crdy(1) := not denable and dci.enaddr and not dsur.crdy(1);
701
        when others =>
702
          crdy(2) := dci.enaddr and denable;
703
      end case;
704
    end if;
705
  end;
706
 
707
 
708
  signal r, rin : registers;
709
  signal wpr, wprin : watchpoint_registers;
710
  signal dsur, dsuin : dsu_registers;
711
  signal ir, irin : irestart_register;
712
  signal rp, rpin : pwd_register_type;
713
 
714
-- execute stage operations
715
 
716
  constant EXE_AND   : std_logic_vector(2 downto 0) := "000";
717
  constant EXE_XOR   : std_logic_vector(2 downto 0) := "001"; -- must be equal to EXE_PASS2
718
  constant EXE_OR    : std_logic_vector(2 downto 0) := "010";
719
  constant EXE_XNOR  : std_logic_vector(2 downto 0) := "011";
720
  constant EXE_ANDN  : std_logic_vector(2 downto 0) := "100";
721
  constant EXE_ORN   : std_logic_vector(2 downto 0) := "101";
722
  constant EXE_DIV   : std_logic_vector(2 downto 0) := "110";
723
 
724
  constant EXE_PASS1 : std_logic_vector(2 downto 0) := "000";
725
  constant EXE_PASS2 : std_logic_vector(2 downto 0) := "001";
726
  constant EXE_STB   : std_logic_vector(2 downto 0) := "010";
727
  constant EXE_STH   : std_logic_vector(2 downto 0) := "011";
728
  constant EXE_ONES  : std_logic_vector(2 downto 0) := "100";
729
  constant EXE_RDY   : std_logic_vector(2 downto 0) := "101";
730
  constant EXE_SPR   : std_logic_vector(2 downto 0) := "110";
731
  constant EXE_LINK  : std_logic_vector(2 downto 0) := "111";
732
 
733
  constant EXE_SLL   : std_logic_vector(2 downto 0) := "001";
734
  constant EXE_SRL   : std_logic_vector(2 downto 0) := "010";
735
  constant EXE_SRA   : std_logic_vector(2 downto 0) := "100";
736
 
737
  constant EXE_NOP   : std_logic_vector(2 downto 0) := "000";
738
 
739
-- EXE result select
740
 
741
  constant EXE_RES_ADD   : std_logic_vector(1 downto 0) := "00";
742
  constant EXE_RES_SHIFT : std_logic_vector(1 downto 0) := "01";
743
  constant EXE_RES_LOGIC : std_logic_vector(1 downto 0) := "10";
744
  constant EXE_RES_MISC  : std_logic_vector(1 downto 0) := "11";
745
 
746
-- Load types
747
 
748
  constant SZBYTE    : std_logic_vector(1 downto 0) := "00";
749
  constant SZHALF    : std_logic_vector(1 downto 0) := "01";
750
  constant SZWORD    : std_logic_vector(1 downto 0) := "10";
751
  constant SZDBL     : std_logic_vector(1 downto 0) := "11";
752
 
753
-- calculate register file address
754
 
755
  procedure regaddr(cwp : std_logic_vector; reg : std_logic_vector(4 downto 0);
756
         rao : out rfatype) is
757
  variable ra : rfatype;
758
  constant globals : std_logic_vector(RFBITS-5  downto 0) :=
759
        conv_std_logic_vector(NWIN, RFBITS-4);
760
  begin
761
    ra := (others => '0'); ra(4 downto 0) := reg;
762
    if reg(4 downto 3) = "00" then ra(RFBITS -1 downto 4) := globals;
763
    else
764
      ra(NWINLOG2+3 downto 4) := cwp + ra(4);
765
      if ra(RFBITS-1 downto 4) = globals then
766
        ra(RFBITS-1 downto 4) := (others => '0');
767
      end if;
768
    end if;
769
    rao := ra;
770
  end;
771
 
772
-- branch adder
773
 
774
  function branch_address(inst : word; pc : pctype) return std_logic_vector is
775
  variable baddr, caddr, tmp : pctype;
776
  begin
777
    caddr := (others => '0'); caddr(31 downto 2) := inst(29 downto 0);
778
    caddr(31 downto 2) := caddr(31 downto 2) + pc(31 downto 2);
779
    baddr := (others => '0'); baddr(31 downto 24) := (others => inst(21));
780
    baddr(23 downto 2) := inst(21 downto 0);
781
    baddr(31 downto 2) := baddr(31 downto 2) + pc(31 downto 2);
782
    if inst(30) = '1' then tmp := caddr; else tmp := baddr; end if;
783
    return(tmp);
784
  end;
785
 
786
-- evaluate branch condition
787
 
788
  function branch_true(icc : std_logic_vector(3 downto 0); inst : word)
789
        return std_ulogic is
790
  variable n, z, v, c, branch : std_ulogic;
791
  begin
792
    n := icc(3); z := icc(2); v := icc(1); c := icc(0);
793
    case inst(27 downto 25) is
794
    when "000" =>  branch := inst(28) xor '0';                   -- bn, ba
795
    when "001" =>  branch := inst(28) xor z;                    -- be, bne
796
    when "010" =>  branch := inst(28) xor (z or (n xor v));     -- ble, bg
797
    when "011" =>  branch := inst(28) xor (n xor v);            -- bl, bge
798
    when "100" =>  branch := inst(28) xor (c or z);             -- bleu, bgu
799
    when "101" =>  branch := inst(28) xor c;                    -- bcs, bcc 
800
    when "110" =>  branch := inst(28) xor n;                    -- bneg, bpos
801
    when others => branch := inst(28) xor v;                    -- bvs, bvc   
802
    end case;
803
    return(branch);
804
  end;
805
 
806
-- detect RETT instruction in the pipeline and set the local psr.su and psr.et
807
 
808
  procedure su_et_select(r : in registers; xc_ps, xc_s, xc_et : in std_ulogic;
809
                       su, et : out std_ulogic) is
810
  begin
811
   if ((r.a.ctrl.rett or r.e.ctrl.rett or r.m.ctrl.rett or r.x.ctrl.rett) = '1')
812
     and (r.x.annul_all = '0')
813
   then su := xc_ps; et := '1';
814
   else su := xc_s; et := xc_et; end if;
815
  end;
816
 
817
-- detect watchpoint trap
818
 
819
  function wphit(r : registers; wpr : watchpoint_registers; debug : l3_debug_in_type)
820
    return std_ulogic is
821
  variable exc : std_ulogic;
822
  begin
823
    exc := '0';
824
    for i in 1 to NWP loop
825
      if ((wpr(i-1).exec and r.a.ctrl.pv and not r.a.ctrl.annul) = '1') then
826
         if (((wpr(i-1).addr xor r.a.ctrl.pc(31 downto 2)) and wpr(i-1).mask) = Zero32(31 downto 2)) then
827
           exc := '1';
828
         end if;
829
      end if;
830
    end loop;
831
 
832
   if DBGUNIT then
833
     if (debug.dsuen and not r.a.ctrl.annul) = '1' then
834
       exc := exc or (r.a.ctrl.pv and ((debug.dbreak and debug.bwatch) or r.a.step));
835
     end if;
836
   end if;
837
    return(exc);
838
  end;
839
 
840
-- 32-bit shifter
841
 
842
  function shift3(r : registers; aluin1, aluin2 : word) return word is
843
  variable shiftin : unsigned(63 downto 0);
844
  variable shiftout : unsigned(63 downto 0);
845
  variable cnt : natural range 0 to 31;
846
  begin
847
 
848
    cnt := conv_integer(r.e.shcnt);
849
    if r.e.shleft = '1' then
850
      shiftin(30 downto 0) := (others => '0');
851
      shiftin(63 downto 31) := '0' & unsigned(aluin1);
852
    else
853
      shiftin(63 downto 32) := (others => r.e.sari);
854
      shiftin(31 downto 0) := unsigned(aluin1);
855
    end if;
856
    shiftout := SHIFT_RIGHT(shiftin, cnt);
857
    return(std_logic_vector(shiftout(31 downto 0)));
858
 
859
  end;
860
 
861
  function shift2(r : registers; aluin1, aluin2 : word) return word is
862
  variable ushiftin : unsigned(31 downto 0);
863
  variable sshiftin : signed(32 downto 0);
864
  variable cnt : natural range 0 to 31;
865
  begin
866
 
867
    cnt := conv_integer(r.e.shcnt);
868
    ushiftin := unsigned(aluin1);
869
    sshiftin := signed('0' & aluin1);
870
    if r.e.shleft = '1' then
871
      return(std_logic_vector(SHIFT_LEFT(ushiftin, cnt)));
872
    else
873
      if r.e.sari = '1' then sshiftin(32) := aluin1(31); end if;
874
      sshiftin := SHIFT_RIGHT(sshiftin, cnt);
875
      return(std_logic_vector(sshiftin(31 downto 0)));
876
--      else 
877
--      ushiftin := SHIFT_RIGHT(ushiftin, cnt);
878
--        return(std_logic_vector(ushiftin));
879
--      end if;
880
    end if;
881
 
882
  end;
883
 
884
  function shift(r : registers; aluin1, aluin2 : word;
885
                 shiftcnt : std_logic_vector(4 downto 0); sari : std_ulogic ) return word is
886
  variable shiftin : std_logic_vector(63 downto 0);
887
  begin
888
    shiftin := zero32 & aluin1;
889
    if r.e.shleft = '1' then
890
      shiftin(31 downto 0) := zero32; shiftin(63 downto 31) := '0' & aluin1;
891
    else shiftin(63 downto 32) := (others => sari); end if;
892
    if shiftcnt (4) = '1' then shiftin(47 downto 0) := shiftin(63 downto 16); end if;
893
    if shiftcnt (3) = '1' then shiftin(39 downto 0) := shiftin(47 downto 8); end if;
894
    if shiftcnt (2) = '1' then shiftin(35 downto 0) := shiftin(39 downto 4); end if;
895
    if shiftcnt (1) = '1' then shiftin(33 downto 0) := shiftin(35 downto 2); end if;
896
    if shiftcnt (0) = '1' then shiftin(31 downto 0) := shiftin(32 downto 1); end if;
897
    return(shiftin(31 downto 0));
898
  end;
899
 
900
-- Check for illegal and privileged instructions
901
 
902
procedure exception_detect(r : registers; wpr : watchpoint_registers; dbgi : l3_debug_in_type;
903
        trapin : in std_ulogic; ttin : in std_logic_vector(5 downto 0);
904
        trap : out std_ulogic; tt : out std_logic_vector(5 downto 0)) is
905
variable illegal_inst, privileged_inst : std_ulogic;
906
variable cp_disabled, fp_disabled, fpop : std_ulogic;
907
variable op : std_logic_vector(1 downto 0);
908
variable op2 : std_logic_vector(2 downto 0);
909
variable op3 : std_logic_vector(5 downto 0);
910
variable rd  : std_logic_vector(4 downto 0);
911
variable inst : word;
912
variable wph : std_ulogic;
913
begin
914
  inst := r.a.ctrl.inst; trap := trapin; tt := ttin;
915
  if r.a.ctrl.annul = '0' then
916
    op  := inst(31 downto 30); op2 := inst(24 downto 22);
917
    op3 := inst(24 downto 19); rd  := inst(29 downto 25);
918
    illegal_inst := '0'; privileged_inst := '0'; cp_disabled := '0';
919
    fp_disabled := '0'; fpop := '0';
920
    case op is
921
    when CALL => null;
922
    when FMT2 =>
923
      case op2 is
924
      when SETHI | BICC => null;
925
      when FBFCC =>
926
        if FPEN then fp_disabled := not r.w.s.ef; else fp_disabled := '1'; end if;
927
      when CBCCC =>
928
        if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if;
929
      when others => illegal_inst := '1';
930
      end case;
931
    when FMT3 =>
932
      case op3 is
933
      when IAND | ANDCC | ANDN | ANDNCC | IOR | ORCC | ORN | ORNCC | IXOR |
934
        XORCC | IXNOR | XNORCC | ISLL | ISRL | ISRA | MULSCC | IADD | ADDX |
935
        ADDCC | ADDXCC | ISUB | SUBX | SUBCC | SUBXCC | FLUSH | JMPL | TICC |
936
        SAVE | RESTORE | RDY => null;
937
      when TADDCC | TADDCCTV | TSUBCC | TSUBCCTV =>
938
        if notag = 1 then illegal_inst := '1'; end if;
939
      when UMAC | SMAC =>
940
        if not MACEN then illegal_inst := '1'; end if;
941
      when UMUL | SMUL | UMULCC | SMULCC =>
942
        if not MULEN then illegal_inst := '1'; end if;
943
      when UDIV | SDIV | UDIVCC | SDIVCC =>
944
        if not DIVEN then illegal_inst := '1'; end if;
945
      when RETT => illegal_inst := r.a.et; privileged_inst := not r.a.su;
946
      when RDPSR | RDTBR | RDWIM => privileged_inst := not r.a.su;
947
      when WRY  => null;
948
      when WRPSR =>
949
        privileged_inst := not r.a.su;
950
      when WRWIM | WRTBR  => privileged_inst := not r.a.su;
951
      when FPOP1 | FPOP2 =>
952
        if FPEN then fp_disabled := not r.w.s.ef; fpop := '1';
953
        else fp_disabled := '1'; fpop := '0'; end if;
954
      when CPOP1 | CPOP2 =>
955
        if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if;
956
      when others => illegal_inst := '1';
957
      end case;
958
    when others =>      -- LDST
959
      case op3 is
960
      when LDD | ISTD => illegal_inst := rd(0);  -- trap if odd destination register
961
      when LD | LDUB | LDSTUB | LDUH | LDSB | LDSH | ST | STB | STH | SWAP =>
962
        null;
963
      when LDDA | STDA =>
964
        illegal_inst := inst(13) or rd(0); privileged_inst := not r.a.su;
965
      when LDA | LDUBA| LDSTUBA | LDUHA | LDSBA | LDSHA | STA | STBA | STHA |
966
           SWAPA =>
967
        illegal_inst := inst(13); privileged_inst := not r.a.su;
968
      when LDDF | STDF | LDF | LDFSR | STF | STFSR =>
969
        if FPEN then fp_disabled := not r.w.s.ef;
970
        else fp_disabled := '1'; end if;
971
      when STDFQ =>
972
        privileged_inst := not r.a.su;
973
        if (not FPEN) or (r.w.s.ef = '0') then fp_disabled := '1'; end if;
974
      when STDCQ =>
975
        privileged_inst := not r.a.su;
976
        if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if;
977
      when LDC | LDCSR | LDDC | STC | STCSR | STDC =>
978
        if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if;
979
      when others => illegal_inst := '1';
980
      end case;
981
    end case;
982
 
983
    wph := wphit(r, wpr, dbgi);
984
 
985
    trap := '1';
986
    if r.a.ctrl.trap = '1' then tt := TT_IAEX;
987
    elsif privileged_inst = '1' then tt := TT_PRIV;
988
    elsif illegal_inst = '1' then tt := TT_IINST;
989
    elsif fp_disabled = '1' then tt := TT_FPDIS;
990
    elsif cp_disabled = '1' then tt := TT_CPDIS;
991
    elsif wph = '1' then tt := TT_WATCH;
992
    elsif r.a.wovf= '1' then tt := TT_WINOF;
993
    elsif r.a.wunf= '1' then tt := TT_WINUF;
994
    elsif r.a.ticc= '1' then tt := TT_TICC;
995
    else trap := '0'; tt:= (others => '0'); end if;
996
  end if;
997
end;
998
 
999
-- instructions that write the condition codes (psr.icc)
1000
 
1001
procedure wicc_y_gen(inst : word; wicc, wy : out std_ulogic) is
1002
begin
1003
  wicc := '0'; wy := '0';
1004
  if inst(31 downto 30) = FMT3 then
1005
    case inst(24 downto 19) is
1006
    when SUBCC | TSUBCC | TSUBCCTV | ADDCC | ANDCC | ORCC | XORCC | ANDNCC |
1007
         ORNCC | XNORCC | TADDCC | TADDCCTV | ADDXCC | SUBXCC | WRPSR =>
1008
      wicc := '1';
1009
    when WRY =>
1010
      if r.d.inst(conv_integer(r.d.set))(29 downto 25) = "00000" then wy := '1'; end if;
1011
    when MULSCC =>
1012
      wicc := '1'; wy := '1';
1013
    when  UMAC | SMAC  =>
1014
      if MACEN then wy := '1'; end if;
1015
    when UMULCC | SMULCC =>
1016
      if MULEN and (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then
1017
        wicc := '1'; wy := '1';
1018
      end if;
1019
    when UMUL | SMUL =>
1020
      if MULEN and (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then
1021
        wy := '1';
1022
      end if;
1023
    when UDIVCC | SDIVCC =>
1024
      if DIVEN and (divo.nready = '1') and (r.d.cnt /= "00") then
1025
        wicc := '1';
1026
      end if;
1027
    when others =>
1028
    end case;
1029
  end if;
1030
end;
1031
 
1032
-- select cwp 
1033
 
1034
procedure cwp_gen(r, v : registers; annul, wcwp : std_ulogic; ncwp : cwptype;
1035
                  cwp : out cwptype) is
1036
begin
1037
  if (r.x.rstate = trap) or (r.x.rstate = dsu2) or (rstn = '0') then cwp := v.w.s.cwp;
1038
  elsif (wcwp = '1') and (annul = '0') then cwp := ncwp;
1039
  elsif r.m.wcwp = '1' then cwp := r.m.result(NWINLOG2-1 downto 0);
1040
  else cwp := r.d.cwp; end if;
1041
end;
1042
 
1043
-- generate wcwp in ex stage
1044
 
1045
procedure cwp_ex(r : in  registers; wcwp : out std_ulogic) is
1046
begin
1047
  if (r.e.ctrl.inst(31 downto 30) = FMT3) and
1048
     (r.e.ctrl.inst(24 downto 19) = WRPSR)
1049
  then wcwp := not r.e.ctrl.annul; else wcwp := '0'; end if;
1050
end;
1051
 
1052
-- generate next cwp & window under- and overflow traps
1053
 
1054
procedure cwp_ctrl(r : in registers; xc_wim : in std_logic_vector(NWIN-1 downto 0);
1055
        inst : word; de_cwp : out cwptype; wovf_exc, wunf_exc, wcwp : out std_ulogic) is
1056
variable op : std_logic_vector(1 downto 0);
1057
variable op3 : std_logic_vector(5 downto 0);
1058
variable wim : word;
1059
variable ncwp : cwptype;
1060
begin
1061
  op := inst(31 downto 30); op3 := inst(24 downto 19);
1062
  wovf_exc := '0'; wunf_exc := '0'; wim := (others => '0');
1063
  wim(NWIN-1 downto 0) := xc_wim; ncwp := r.d.cwp; wcwp := '0';
1064
 
1065
  if (op = FMT3) and ((op3 = RETT) or (op3 = RESTORE) or (op3 = SAVE)) then
1066
    wcwp := '1';
1067
    if (op3 = SAVE) then
1068
      if (not CWPOPT) and (r.d.cwp = CWPMIN) then ncwp := CWPMAX;
1069
      else ncwp := r.d.cwp - 1 ; end if;
1070
    else
1071
      if (not CWPOPT) and (r.d.cwp = CWPMAX) then ncwp := CWPMIN;
1072
      else ncwp := r.d.cwp + 1; end if;
1073
    end if;
1074
    if wim(conv_integer(ncwp)) = '1' then
1075
      if op3 = SAVE then wovf_exc := '1'; else wunf_exc := '1'; end if;
1076
    end if;
1077
  end if;
1078
  de_cwp := ncwp;
1079
end;
1080
 
1081
-- generate register read address 1
1082
 
1083
procedure rs1_gen(r : registers; inst : word;  rs1 : out std_logic_vector(4 downto 0);
1084
        rs1mod : out std_ulogic) is
1085
variable op : std_logic_vector(1 downto 0);
1086
variable op3 : std_logic_vector(5 downto 0);
1087
begin
1088
  op := inst(31 downto 30); op3 := inst(24 downto 19);
1089
  rs1 := inst(18 downto 14); rs1mod := '0';
1090
  if (op = LDST) then
1091
    if ((r.d.cnt = "01") and ((op3(2) and not op3(3)) = '1')) or
1092
        (r.d.cnt = "10")
1093
    then rs1mod := '1'; rs1 := inst(29 downto 25); end if;
1094
    if ((r.d.cnt = "10") and (op3(3 downto 0) = "0111")) then
1095
      rs1(0) := '1';
1096
    end if;
1097
  end if;
1098
end;
1099
 
1100
-- load/icc interlock detection
1101
 
1102
  procedure lock_gen(r : registers; rs2, rd : std_logic_vector(4 downto 0);
1103
        rfa1, rfa2, rfrd : rfatype; inst : word; fpc_lock, mulinsn, divinsn : std_ulogic;
1104
        lldcheck1, lldcheck2, lldlock, lldchkra, lldchkex : out std_ulogic) is
1105
  variable op : std_logic_vector(1 downto 0);
1106
  variable op2 : std_logic_vector(2 downto 0);
1107
  variable op3 : std_logic_vector(5 downto 0);
1108
  variable cond : std_logic_vector(3 downto 0);
1109
  variable rs1  : std_logic_vector(4 downto 0);
1110
  variable i, ldcheck1, ldcheck2, ldchkra, ldchkex, ldcheck3 : std_ulogic;
1111
  variable ldlock, icc_check, bicc_hold, chkmul, y_check : std_ulogic;
1112
  variable lddlock : boolean;
1113
  begin
1114
    op := inst(31 downto 30); op3 := inst(24 downto 19);
1115
    op2 := inst(24 downto 22); cond := inst(28 downto 25);
1116
    rs1 := inst(18 downto 14); lddlock := false; i := inst(13);
1117
    ldcheck1 := '0'; ldcheck2 := '0'; ldcheck3 := '0'; ldlock := '0';
1118
    ldchkra := '1'; ldchkex := '1'; icc_check := '0'; bicc_hold := '0';
1119
    y_check := '0';
1120
 
1121
    if (r.d.annul = '0') then
1122
      case op is
1123
      when FMT2 =>
1124
        if (op2 = BICC) and (cond(2 downto 0) /= "000") then
1125
          icc_check := '1';
1126
        end if;
1127
      when FMT3 =>
1128
        ldcheck1 := '1'; ldcheck2 := not i;
1129
        case op3 is
1130
        when TICC =>
1131
          if (cond(2 downto 0) /= "000") then icc_check := '1'; end if;
1132
        when RDY =>
1133
          ldcheck1 := '0'; ldcheck2 := '0';
1134
          if MACPIPE then y_check := '1'; end if;
1135
        when RDWIM | RDTBR =>
1136
          ldcheck1 := '0'; ldcheck2 := '0';
1137
        when RDPSR =>
1138
          ldcheck1 := '0'; ldcheck2 := '0'; icc_check := '1';
1139
          if MULEN then icc_check := '1'; end if;
1140
--      when ADDX | ADDXCC | SUBX | SUBXCC =>
1141
--        if MULEN then icc_check := '1'; end if;
1142
        when SDIV | SDIVCC | UDIV | UDIVCC =>
1143
          if DIVEN then y_check := '1'; end if;
1144
        when FPOP1 | FPOP2 => ldcheck1:= '0'; ldcheck2 := '0';
1145
        when others =>
1146
        end case;
1147
      when LDST =>
1148
        ldcheck1 := '1'; ldchkra := '0';
1149
        case r.d.cnt is
1150
        when "00" =>
1151
          if (lddel = 2) and (op3(2) = '1') then ldcheck3 := '1'; end if;
1152
          ldcheck2 := not i; ldchkra := '1';
1153
        when "01" => ldcheck2 := not i;
1154
        when others => ldchkex := '0';
1155
        end case;
1156
        if  (op3(2 downto 0) = "011") then lddlock := true; end if;
1157
      when others => null;
1158
      end case;
1159
    end if;
1160
 
1161
    if MULEN or DIVEN then
1162
      chkmul := mulinsn;
1163
      bicc_hold := bicc_hold or (icc_check and r.m.ctrl.wicc and (r.m.ctrl.cnt(0) or r.m.mul));
1164
    else chkmul := '0'; end if;
1165
    if DIVEN then
1166
      bicc_hold := bicc_hold or (y_check and (r.a.ctrl.wy or r.e.ctrl.wy));
1167
      chkmul := chkmul or divinsn;
1168
    end if;
1169
 
1170
    bicc_hold := bicc_hold or (icc_check and (r.a.ctrl.wicc or r.e.ctrl.wicc));
1171
 
1172
    if (((r.a.ctrl.ld or chkmul) and r.a.ctrl.wreg and ldchkra) = '1') and
1173
       (((ldcheck1 = '1') and (r.a.ctrl.rd = rfa1)) or
1174
        ((ldcheck2 = '1') and (r.a.ctrl.rd = rfa2)) or
1175
        ((ldcheck3 = '1') and (r.a.ctrl.rd = rfrd)))
1176
    then ldlock := '1'; end if;
1177
 
1178
    if (((r.e.ctrl.ld or r.e.mac) and r.e.ctrl.wreg and ldchkex) = '1') and
1179
        ((lddel = 2) or (MACPIPE and (r.e.mac = '1')) or ((MULTYPE = 3) and (r.e.mul = '1'))) and
1180
       (((ldcheck1 = '1') and (r.e.ctrl.rd = rfa1)) or
1181
        ((ldcheck2 = '1') and (r.e.ctrl.rd = rfa2)))
1182
    then ldlock := '1'; end if;
1183
 
1184
    ldlock := ldlock or bicc_hold or fpc_lock;
1185
 
1186
    lldcheck1 := ldcheck1; lldcheck2:= ldcheck2; lldlock := ldlock;
1187
    lldchkra := ldchkra; lldchkex := ldchkex;
1188
  end;
1189
 
1190
  procedure fpbranch(inst : in word; fcc  : in std_logic_vector(1 downto 0);
1191
                      branch : out std_ulogic) is
1192
  variable cond : std_logic_vector(3 downto 0);
1193
  variable fbres : std_ulogic;
1194
  begin
1195
    cond := inst(28 downto 25);
1196
    case cond(2 downto 0) is
1197
      when "000" => fbres := '0';                        -- fba, fbn
1198
      when "001" => fbres := fcc(1) or fcc(0);
1199
      when "010" => fbres := fcc(1) xor fcc(0);
1200
      when "011" => fbres := fcc(0);
1201
      when "100" => fbres := (not fcc(1)) and fcc(0);
1202
      when "101" => fbres := fcc(1);
1203
      when "110" => fbres := fcc(1) and not fcc(0);
1204
      when others => fbres := fcc(1) and fcc(0);
1205
    end case;
1206
    branch := cond(3) xor fbres;
1207
  end;
1208
 
1209
-- PC generation
1210
 
1211
  procedure ic_ctrl(r : registers; inst : word; annul_all, ldlock, branch_true,
1212
        fbranch_true, cbranch_true, fccv, cccv : in std_ulogic;
1213
        cnt : out std_logic_vector(1 downto 0);
1214
        de_pc : out pctype; de_branch, ctrl_annul, de_annul, jmpl_inst, inull,
1215
        de_pv, ctrl_pv, de_hold_pc, ticc_exception, rett_inst, mulstart,
1216
        divstart : out std_ulogic) is
1217
  variable op : std_logic_vector(1 downto 0);
1218
  variable op2 : std_logic_vector(2 downto 0);
1219
  variable op3 : std_logic_vector(5 downto 0);
1220
  variable cond : std_logic_vector(3 downto 0);
1221
  variable hold_pc, annul_current, annul_next, branch, annul, pv : std_ulogic;
1222
  variable de_jmpl : std_ulogic;
1223
  begin
1224
    branch := '0'; annul_next := '0'; annul_current := '0'; pv := '1';
1225
    hold_pc := '0'; ticc_exception := '0'; rett_inst := '0';
1226
    op := inst(31 downto 30); op3 := inst(24 downto 19);
1227
    op2 := inst(24 downto 22); cond := inst(28 downto 25);
1228
    annul := inst(29); de_jmpl := '0'; cnt := "00";
1229
    mulstart := '0'; divstart := '0';
1230
    if r.d.annul = '0' then
1231
      case inst(31 downto 30) is
1232
      when CALL =>
1233
        branch := '1';
1234
        if r.d.inull = '1' then
1235
          hold_pc := '1'; annul_current := '1';
1236
        end if;
1237
      when FMT2 =>
1238
        if (op2 = BICC) or (FPEN and (op2 = FBFCC)) or (CPEN and (op2 = CBCCC)) then
1239
          if (FPEN and (op2 = FBFCC)) then
1240
            branch := fbranch_true;
1241
            if fccv /= '1' then hold_pc := '1'; annul_current := '1'; end if;
1242
          elsif (CPEN and (op2 = CBCCC)) then
1243
            branch := cbranch_true;
1244
            if cccv /= '1' then hold_pc := '1'; annul_current := '1'; end if;
1245
          else branch := branch_true; end if;
1246
          if hold_pc = '0' then
1247
            if (branch = '1') then
1248
              if (cond = BA) and (annul = '1') then annul_next := '1'; end if;
1249
            else annul_next := annul; end if;
1250
            if r.d.inull = '1' then -- contention with JMPL
1251
              hold_pc := '1'; annul_current := '1'; annul_next := '0';
1252
            end if;
1253
          end if;
1254
        end if;
1255
      when FMT3 =>
1256
        case op3 is
1257
        when UMUL | SMUL | UMULCC | SMULCC =>
1258
          if MULEN and (MULTYPE /= 0) then mulstart := '1'; end if;
1259
          if MULEN and (MULTYPE = 0) then
1260
            case r.d.cnt is
1261
            when "00" =>
1262
              cnt := "01"; hold_pc := '1'; pv := '0'; mulstart := '1';
1263
            when "01" =>
1264
              if mulo.nready = '1' then cnt := "00";
1265
              else cnt := "01"; pv := '0'; hold_pc := '1'; end if;
1266
            when others => null;
1267
            end case;
1268
          end if;
1269
        when UDIV | SDIV | UDIVCC | SDIVCC =>
1270
          if DIVEN then
1271
            case r.d.cnt is
1272
            when "00" =>
1273
              cnt := "01"; hold_pc := '1'; pv := '0';
1274
              divstart := '1';
1275
            when "01" =>
1276
              if divo.nready = '1' then cnt := "00";
1277
              else cnt := "01"; pv := '0'; hold_pc := '1'; end if;
1278
            when others => null;
1279
            end case;
1280
          end if;
1281
        when TICC =>
1282
          if branch_true = '1' then ticc_exception := '1'; end if;
1283
        when RETT =>
1284
          rett_inst := '1'; --su := sregs.ps; 
1285
        when JMPL =>
1286
          de_jmpl := '1';
1287
        when WRY =>
1288
          if PWRD1 then
1289
            if inst(29 downto 25) = "10011" then -- %ASR19
1290
              case r.d.cnt is
1291
              when "00" =>
1292
                pv := '0'; cnt := "00"; hold_pc := '1';
1293
                if r.x.ipend = '1' then cnt := "01"; end if;
1294
              when "01" =>
1295
                cnt := "00";
1296
              when others =>
1297
              end case;
1298
            end if;
1299
          end if;
1300
        when others => null;
1301
        end case;
1302
      when others =>  -- LDST 
1303
        case r.d.cnt is
1304
        when "00" =>
1305
          if (op3(2) = '1') or (op3(1 downto 0) = "11") then -- ST/LDST/SWAP/LDD
1306
            cnt := "01"; hold_pc := '1'; pv := '0';
1307
          end if;
1308
        when "01" =>
1309
          if (op3(2 downto 0) = "111") or (op3(3 downto 0) = "1101") or
1310
             ((CPEN or FPEN) and ((op3(5) & op3(2 downto 0)) = "1110"))
1311
          then  -- LDD/STD/LDSTUB/SWAP
1312
            cnt := "10"; pv := '0'; hold_pc := '1';
1313
          else
1314
            cnt := "00";
1315
          end if;
1316
        when "10" =>
1317
          cnt := "00";
1318
        when others => null;
1319
        end case;
1320
      end case;
1321
    end if;
1322
 
1323
    if ldlock = '1' then
1324
      cnt := r.d.cnt; annul_next := '0'; pv := '1';
1325
    end if;
1326
    hold_pc := (hold_pc or ldlock) and not annul_all;
1327
 
1328
    if hold_pc = '1' then de_pc := r.d.pc; else de_pc := r.f.pc; end if;
1329
 
1330
    annul_current := (annul_current or ldlock or annul_all);
1331
    ctrl_annul := r.d.annul or annul_all or annul_current;
1332
    pv := pv and not ((r.d.inull and not hold_pc) or annul_all);
1333
    jmpl_inst := de_jmpl and not annul_current;
1334
    annul_next := (r.d.inull and not hold_pc) or annul_next or annul_all;
1335
    if (annul_next = '1') or (rstn = '0') then
1336
      cnt := (others => '0');
1337
    end if;
1338
 
1339
    de_hold_pc := hold_pc; de_branch := branch; de_annul := annul_next;
1340
    de_pv := pv; ctrl_pv := r.d.pv and
1341
        not ((r.d.annul and not r.d.pv) or annul_all or annul_current);
1342
    inull := (not rstn) or r.d.inull or hold_pc or annul_all;
1343
 
1344
  end;
1345
 
1346
-- register write address generation
1347
 
1348
  procedure rd_gen(r : registers; inst : word; wreg, ld : out std_ulogic;
1349
        rdo : out std_logic_vector(4 downto 0)) is
1350
  variable write_reg : std_ulogic;
1351
  variable op : std_logic_vector(1 downto 0);
1352
  variable op2 : std_logic_vector(2 downto 0);
1353
  variable op3 : std_logic_vector(5 downto 0);
1354
  variable rd  : std_logic_vector(4 downto 0);
1355
  begin
1356
 
1357
    op    := inst(31 downto 30);
1358
    op2   := inst(24 downto 22);
1359
    op3   := inst(24 downto 19);
1360
 
1361
    write_reg := '0'; rd := inst(29 downto 25); ld := '0';
1362
 
1363
    case op is
1364
    when CALL =>
1365
        write_reg := '1'; rd := "01111";    -- CALL saves PC in r[15] (%o7)
1366
    when FMT2 =>
1367
        if (op2 = SETHI) then write_reg := '1'; end if;
1368
    when FMT3 =>
1369
        case op3 is
1370
        when UMUL | SMUL | UMULCC | SMULCC =>
1371
          if MULEN then
1372
            if (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then
1373
              write_reg := '1';
1374
            end if;
1375
          else write_reg := '1'; end if;
1376
        when UDIV | SDIV | UDIVCC | SDIVCC =>
1377
          if DIVEN then
1378
            if (divo.nready = '1') and (r.d.cnt /= "00") then
1379
              write_reg := '1';
1380
            end if;
1381
          else write_reg := '1'; end if;
1382
        when RETT | WRPSR | WRY | WRWIM | WRTBR | TICC | FLUSH => null;
1383
        when FPOP1 | FPOP2 => null;
1384
        when CPOP1 | CPOP2 => null;
1385
        when others => write_reg := '1';
1386
        end case;
1387
      when others =>   -- LDST
1388
        ld := not op3(2);
1389
        if (op3(2) = '0') and not ((CPEN or FPEN) and (op3(5) = '1'))
1390
        then write_reg := '1'; end if;
1391
        case op3 is
1392
        when SWAP | SWAPA | LDSTUB | LDSTUBA =>
1393
          if r.d.cnt = "00" then write_reg := '1'; ld := '1'; end if;
1394
        when others => null;
1395
        end case;
1396
        if r.d.cnt = "01" then
1397
          case op3 is
1398
          when LDD | LDDA | LDDC | LDDF => rd(0) := '1';
1399
          when others =>
1400
          end case;
1401
        end if;
1402
    end case;
1403
 
1404
    if (rd = "00000") then write_reg := '0'; end if;
1405
    wreg := write_reg; rdo := rd;
1406
  end;
1407
 
1408
-- immediate data generation
1409
 
1410
  function imm_data (r : registers; insn : word)
1411
        return word is
1412
  variable immediate_data, inst : word;
1413
  begin
1414
    immediate_data := (others => '0'); inst := insn;
1415
    case inst(31 downto 30) is
1416
    when FMT2 =>
1417
      immediate_data := inst(21 downto 0) & "0000000000";
1418
    when others =>      -- LDST
1419
      immediate_data(31 downto 13) := (others => inst(12));
1420
      immediate_data(12 downto 0) := inst(12 downto 0);
1421
    end case;
1422
    return(immediate_data);
1423
  end;
1424
 
1425
-- read special registers
1426
  function get_spr (r : registers) return word is
1427
  variable spr : word;
1428
  begin
1429
    spr := (others => '0');
1430
      case r.e.ctrl.inst(24 downto 19) is
1431
      when RDPSR => spr(31 downto 5) := conv_std_logic_vector(IMPL,4) &
1432
        conv_std_logic_vector(VER,4) & r.m.icc & "000000" & r.w.s.ec & r.w.s.ef &
1433
        r.w.s.pil & r.e.su & r.w.s.ps & r.e.et;
1434
        spr(NWINLOG2-1 downto 0) := r.e.cwp;
1435
      when RDTBR => spr(31 downto 4) := r.w.s.tba & r.w.s.tt;
1436
      when RDWIM => spr(NWIN-1 downto 0) := r.w.s.wim;
1437
      when others =>
1438
      end case;
1439
    return(spr);
1440
  end;
1441
 
1442
-- immediate data select
1443
 
1444
  function imm_select(inst : word) return boolean is
1445
  variable imm : boolean;
1446
  begin
1447
    imm := false;
1448
    case inst(31 downto 30) is
1449
    when FMT2 =>
1450
      case inst(24 downto 22) is
1451
      when SETHI => imm := true;
1452
      when others =>
1453
      end case;
1454
    when FMT3 =>
1455
      case inst(24 downto 19) is
1456
      when RDWIM | RDPSR | RDTBR => imm := true;
1457
      when others => if (inst(13) = '1') then imm := true; end if;
1458
      end case;
1459
    when LDST =>
1460
      if (inst(13) = '1') then imm := true; end if;
1461
    when others =>
1462
    end case;
1463
    return(imm);
1464
  end;
1465
 
1466
-- EXE operation
1467
 
1468
  procedure alu_op(r : in registers; iop1, iop2 : in word; me_icc : std_logic_vector(3 downto 0);
1469
        my, ldbp : std_ulogic; aop1, aop2 : out word; aluop  : out std_logic_vector(2 downto 0);
1470
        alusel : out std_logic_vector(1 downto 0); aluadd : out std_ulogic;
1471
        shcnt : out std_logic_vector(4 downto 0); sari, shleft, ymsb,
1472
        mulins, divins, mulstep, macins, ldbp2, invop2 : out std_ulogic) is
1473
  variable op : std_logic_vector(1 downto 0);
1474
  variable op2 : std_logic_vector(2 downto 0);
1475
  variable op3 : std_logic_vector(5 downto 0);
1476
  variable rd  : std_logic_vector(4 downto 0);
1477
  variable icc : std_logic_vector(3 downto 0);
1478
  variable y0  : std_ulogic;
1479
  begin
1480
 
1481
    op   := r.a.ctrl.inst(31 downto 30);
1482
    op2  := r.a.ctrl.inst(24 downto 22);
1483
    op3  := r.a.ctrl.inst(24 downto 19);
1484
    aop1 := iop1; aop2 := iop2; ldbp2 := ldbp;
1485
    aluop := EXE_NOP; alusel := EXE_RES_MISC; aluadd := '1';
1486
    shcnt := iop2(4 downto 0); sari := '0'; shleft := '0'; invop2 := '0';
1487
    ymsb := iop1(0); mulins := '0'; divins := '0'; mulstep := '0';
1488
    macins := '0';
1489
 
1490
    if r.e.ctrl.wy = '1' then y0 := my;
1491
    elsif r.m.ctrl.wy = '1' then y0 := r.m.y(0);
1492
    elsif r.x.ctrl.wy = '1' then y0 := r.x.y(0);
1493
    else y0 := r.w.s.y(0); end if;
1494
 
1495
    if r.e.ctrl.wicc = '1' then icc := me_icc;
1496
    elsif r.m.ctrl.wicc = '1' then icc := r.m.icc;
1497
    elsif r.x.ctrl.wicc = '1' then icc := r.x.icc;
1498
    else icc := r.w.s.icc; end if;
1499
 
1500
    case op is
1501
    when CALL =>
1502
      aluop := EXE_LINK;
1503
    when FMT2 =>
1504
      case op2 is
1505
      when SETHI => aluop := EXE_PASS2;
1506
      when others =>
1507
      end case;
1508
    when FMT3 =>
1509
      case op3 is
1510
      when IADD | ADDX | ADDCC | ADDXCC | TADDCC | TADDCCTV | SAVE | RESTORE |
1511
           TICC | JMPL | RETT  => alusel := EXE_RES_ADD;
1512
      when ISUB | SUBX | SUBCC | SUBXCC | TSUBCC | TSUBCCTV  =>
1513
        alusel := EXE_RES_ADD; aluadd := '0'; aop2 := not iop2; invop2 := '1';
1514
      when MULSCC => alusel := EXE_RES_ADD;
1515
        aop1 := (icc(3) xor icc(1)) & iop1(31 downto 1);
1516
        if y0 = '0' then aop2 := (others => '0'); ldbp2 := '0'; end if;
1517
        mulstep := '1';
1518
      when UMUL | UMULCC | SMUL | SMULCC =>
1519
        if MULEN then mulins := '1'; end if;
1520
      when UMAC | SMAC =>
1521
        if MACEN then mulins := '1'; macins := '1'; end if;
1522
      when UDIV | UDIVCC | SDIV | SDIVCC =>
1523
        if DIVEN then
1524
          aluop := EXE_DIV; alusel := EXE_RES_LOGIC; divins := '1';
1525
        end if;
1526
      when IAND | ANDCC => aluop := EXE_AND; alusel := EXE_RES_LOGIC;
1527
      when ANDN | ANDNCC => aluop := EXE_ANDN; alusel := EXE_RES_LOGIC;
1528
      when IOR | ORCC  => aluop := EXE_OR; alusel := EXE_RES_LOGIC;
1529
      when ORN | ORNCC  => aluop := EXE_ORN; alusel := EXE_RES_LOGIC;
1530
      when IXNOR | XNORCC  => aluop := EXE_XNOR; alusel := EXE_RES_LOGIC;
1531
      when XORCC | IXOR | WRPSR | WRWIM | WRTBR | WRY  =>
1532
        aluop := EXE_XOR; alusel := EXE_RES_LOGIC;
1533
      when RDPSR | RDTBR | RDWIM => aluop := EXE_SPR;
1534
      when RDY => aluop := EXE_RDY;
1535
      when ISLL => aluop := EXE_SLL; alusel := EXE_RES_SHIFT; shleft := '1';
1536
                   shcnt := not iop2(4 downto 0); invop2 := '1';
1537
      when ISRL => aluop := EXE_SRL; alusel := EXE_RES_SHIFT;
1538
      when ISRA => aluop := EXE_SRA; alusel := EXE_RES_SHIFT; sari := iop1(31);
1539
      when FPOP1 | FPOP2 =>
1540
      when others =>
1541
      end case;
1542
    when others =>      -- LDST
1543
      case r.a.ctrl.cnt is
1544
      when "00" =>
1545
        alusel := EXE_RES_ADD;
1546
      when "01" =>
1547
        case op3 is
1548
        when LDD | LDDA | LDDC => alusel := EXE_RES_ADD;
1549
        when LDDF => alusel := EXE_RES_ADD;
1550
        when SWAP | SWAPA | LDSTUB | LDSTUBA => alusel := EXE_RES_ADD;
1551
        when STF | STDF =>
1552
        when others =>
1553
          aluop := EXE_PASS1;
1554
          if op3(2) = '1' then
1555
            if op3(1 downto 0) = "01" then aluop := EXE_STB;
1556
            elsif op3(1 downto 0) = "10" then aluop := EXE_STH; end if;
1557
          end if;
1558
        end case;
1559
      when "10" =>
1560
        aluop := EXE_PASS1;
1561
        if op3(2) = '1' then  -- ST
1562
          if (op3(3) and not op3(1))= '1' then aluop := EXE_ONES; end if; -- LDSTUB/A
1563
        end if;
1564
      when others =>
1565
      end case;
1566
    end case;
1567
  end;
1568
 
1569
  function ra_inull_gen(r, v : registers) return std_ulogic is
1570
  variable de_inull : std_ulogic;
1571
  begin
1572
    de_inull := '0';
1573
    if ((v.e.jmpl or v.e.ctrl.rett) and not v.e.ctrl.annul and not (r.e.jmpl and not r.e.ctrl.annul)) = '1' then de_inull := '1'; end if;
1574
    if ((v.a.jmpl or v.a.ctrl.rett) and not v.a.ctrl.annul and not (r.a.jmpl and not r.a.ctrl.annul)) = '1' then de_inull := '1'; end if;
1575
    return(de_inull);
1576
  end;
1577
 
1578
-- operand generation
1579
 
1580
  procedure op_mux(r : in registers; rfd, ed, md, xd, im : in word;
1581
        rsel : in std_logic_vector(2 downto 0);
1582
        ldbp : out std_ulogic; d : out word) is
1583
  begin
1584
    ldbp := '0';
1585
    case rsel is
1586
    when "000" => d := rfd;
1587
    when "001" => d := ed;
1588
    when "010" => d := md; if lddel = 1 then ldbp := r.m.ctrl.ld; end if;
1589
    when "011" => d := xd;
1590
    when "100" => d := im;
1591
    when "101" => d := (others => '0');
1592
    when "110" => d := r.w.result;
1593
    when others => d := (others => '-');
1594
    end case;
1595
  end;
1596
 
1597
  procedure op_find(r : in registers; ldchkra : std_ulogic; ldchkex : std_ulogic;
1598
         rs1 : std_logic_vector(4 downto 0); ra : rfatype; im : boolean; rfe : out std_ulogic;
1599
        osel : out std_logic_vector(2 downto 0); ldcheck : std_ulogic) is
1600
  begin
1601
    rfe := '0';
1602
    if im then osel := "100";
1603
    elsif rs1 = "00000" then osel := "101";     -- %g0
1604
    elsif ((r.a.ctrl.wreg and ldchkra) = '1') and (ra = r.a.ctrl.rd) then osel := "001";
1605
    elsif ((r.e.ctrl.wreg and ldchkex) = '1') and (ra = r.e.ctrl.rd) then osel := "010";
1606
    elsif r.m.ctrl.wreg = '1' and (ra = r.m.ctrl.rd) then osel := "011";
1607
    elsif (irfwt = 0) and r.x.ctrl.wreg = '1' and (ra = r.x.ctrl.rd) then osel := "110";
1608
    else  osel := "000"; rfe := ldcheck; end if;
1609
  end;
1610
 
1611
-- generate carry-in for alu
1612
 
1613
  procedure cin_gen(r : registers; me_cin : in std_ulogic; cin : out std_ulogic) is
1614
  variable op : std_logic_vector(1 downto 0);
1615
  variable op3 : std_logic_vector(5 downto 0);
1616
  variable ncin : std_ulogic;
1617
  begin
1618
 
1619
    op := r.a.ctrl.inst(31 downto 30); op3 := r.a.ctrl.inst(24 downto 19);
1620
    if r.e.ctrl.wicc = '1' then ncin := me_cin;
1621
    else ncin := r.m.icc(0); end if;
1622
    cin := '0';
1623
    case op is
1624
    when FMT3 =>
1625
      case op3 is
1626
      when ISUB | SUBCC | TSUBCC | TSUBCCTV => cin := '1';
1627
      when ADDX | ADDXCC => cin := ncin;
1628
      when SUBX | SUBXCC => cin := not ncin;
1629
      when others => null;
1630
      end case;
1631
    when others => null;
1632
    end case;
1633
  end;
1634
 
1635
  procedure logic_op(r : registers; aluin1, aluin2, mey : word;
1636
        ymsb : std_ulogic; logicres, y : out word) is
1637
  variable logicout : word;
1638
  begin
1639
    case r.e.aluop is
1640
    when EXE_AND   => logicout := aluin1 and aluin2;
1641
    when EXE_ANDN  => logicout := aluin1 and not aluin2;
1642
    when EXE_OR    => logicout := aluin1 or aluin2;
1643
    when EXE_ORN   => logicout := aluin1 or not aluin2;
1644
    when EXE_XOR   => logicout := aluin1 xor aluin2;
1645
    when EXE_XNOR  => logicout := aluin1 xor not aluin2;
1646
    when EXE_DIV   =>
1647
      if DIVEN then logicout := aluin2;
1648
      else logicout := (others => '-'); end if;
1649
    when others => logicout := (others => '-');
1650
    end case;
1651
    if (r.e.ctrl.wy and r.e.mulstep) = '1' then
1652
      y := ymsb & r.m.y(31 downto 1);
1653
    elsif r.e.ctrl.wy = '1' then y := logicout;
1654
    elsif r.m.ctrl.wy = '1' then y := mey;
1655
    elsif MACPIPE and (r.x.mac = '1') then y := mulo.result(63 downto 32);
1656
    elsif r.x.ctrl.wy = '1' then y := r.x.y;
1657
    else y := r.w.s.y; end if;
1658
    logicres := logicout;
1659
  end;
1660
 
1661
  procedure misc_op(r : registers; wpr : watchpoint_registers;
1662
        aluin1, aluin2, ldata, mey : word;
1663
        mout, edata : out word) is
1664
  variable miscout, bpdata, stdata : word;
1665
  variable wpi : integer;
1666
  begin
1667
    wpi := 0; miscout := r.e.ctrl.pc(31 downto 2) & "00";
1668
    edata := aluin1; bpdata := aluin1;
1669
    if ((r.x.ctrl.wreg and r.x.ctrl.ld and not r.x.ctrl.annul) = '1') and
1670
       (r.x.ctrl.rd = r.e.ctrl.rd) and (r.e.ctrl.inst(31 downto 30) = LDST) and
1671
        (r.e.ctrl.cnt /= "10")
1672
    then bpdata := ldata; end if;
1673
 
1674
    case r.e.aluop is
1675
    when EXE_STB   => miscout := bpdata(7 downto 0) & bpdata(7 downto 0) &
1676
                             bpdata(7 downto 0) & bpdata(7 downto 0);
1677
                      edata := miscout;
1678
    when EXE_STH   => miscout := bpdata(15 downto 0) & bpdata(15 downto 0);
1679
                      edata := miscout;
1680
    when EXE_PASS1 => miscout := bpdata; edata := miscout;
1681
    when EXE_PASS2 => miscout := aluin2;
1682
    when EXE_ONES  => miscout := (others => '1');
1683
                      edata := miscout;
1684
    when EXE_RDY  =>
1685
      if MULEN and (r.m.ctrl.wy = '1') then miscout := mey;
1686
      else miscout := r.m.y; end if;
1687
      if (NWP > 0) and (r.e.ctrl.inst(18 downto 17) = "11") then
1688
        wpi := conv_integer(r.e.ctrl.inst(16 downto 15));
1689
        if r.e.ctrl.inst(14) = '0' then miscout := wpr(wpi).addr & '0' & wpr(wpi).exec;
1690
        else miscout := wpr(wpi).mask & wpr(wpi).load & wpr(wpi).store; end if;
1691
      end if;
1692
      if (r.e.ctrl.inst(18 downto 17) = "10") and (r.e.ctrl.inst(14) = '1') then --%ASR17
1693
        miscout := asr17_gen(r);
1694
      end if;
1695
      if MACEN then
1696
        if (r.e.ctrl.inst(18 downto 14) = "10010") then --%ASR18
1697
          if ((r.m.mac = '1') and not MACPIPE) or ((r.x.mac = '1') and MACPIPE) then
1698
            miscout := mulo.result(31 downto 0); -- data forward of asr18
1699
          else miscout := r.w.s.asr18; end if;
1700
        else
1701
          if ((r.m.mac = '1') and not MACPIPE) or ((r.x.mac = '1') and MACPIPE) then
1702
            miscout := mulo.result(63 downto 32);   -- data forward Y
1703
          end if;
1704
        end if;
1705
      end if;
1706
    when EXE_SPR  =>
1707
      miscout := get_spr(r);
1708
    when others => null;
1709
    end case;
1710
    mout := miscout;
1711
  end;
1712
 
1713
  procedure alu_select(r : registers; addout : std_logic_vector(32 downto 0);
1714
        op1, op2 : word; shiftout, logicout, miscout : word; res : out word;
1715
        me_icc : std_logic_vector(3 downto 0);
1716
        icco : out std_logic_vector(3 downto 0); divz : out std_ulogic) is
1717
  variable op : std_logic_vector(1 downto 0);
1718
  variable op3 : std_logic_vector(5 downto 0);
1719
  variable icc : std_logic_vector(3 downto 0);
1720
  variable aluresult : word;
1721
  begin
1722
    op   := r.e.ctrl.inst(31 downto 30); op3  := r.e.ctrl.inst(24 downto 19);
1723
    icc := (others => '0');
1724
    case r.e.alusel is
1725
    when EXE_RES_ADD =>
1726
      aluresult := addout(32 downto 1);
1727
      if r.e.aluadd = '0' then
1728
        icc(0) := ((not op1(31)) and not op2(31)) or     -- Carry
1729
                 (addout(32) and ((not op1(31)) or not op2(31)));
1730
        icc(1) := (op1(31) and (op2(31)) and not addout(32)) or         -- Overflow
1731
                 (addout(32) and (not op1(31)) and not op2(31));
1732
      else
1733
        icc(0) := (op1(31) and op2(31)) or       -- Carry
1734
                 ((not addout(32)) and (op1(31) or op2(31)));
1735
        icc(1) := (op1(31) and op2(31) and not addout(32)) or   -- Overflow
1736
                 (addout(32) and (not op1(31)) and (not op2(31)));
1737
      end if;
1738
      if notag = 0 then
1739
        case op is
1740
        when FMT3 =>
1741
          case op3 is
1742
          when TADDCC | TADDCCTV =>
1743
            icc(1) := op1(0) or op1(1) or op2(0) or op2(1) or icc(1);
1744
          when TSUBCC | TSUBCCTV =>
1745
            icc(1) := op1(0) or op1(1) or (not op2(0)) or (not op2(1)) or icc(1);
1746
          when others => null;
1747
          end case;
1748
        when others => null;
1749
        end case;
1750
      end if;
1751
 
1752
      if aluresult = zero32 then icc(2) := '1'; end if;
1753
    when EXE_RES_SHIFT => aluresult := shiftout;
1754
    when EXE_RES_LOGIC => aluresult := logicout;
1755
      if aluresult = zero32 then icc(2) := '1'; end if;
1756
    when others => aluresult := miscout;
1757
    end case;
1758
    if r.e.jmpl = '1' then aluresult := r.e.ctrl.pc(31 downto 2) & "00"; end if;
1759
    icc(3) := aluresult(31); divz := icc(2);
1760
    if r.e.ctrl.wicc = '1' then
1761
      if (op = FMT3) and (op3 = WRPSR) then icco := logicout(23 downto 20);
1762
      else icco := icc; end if;
1763
    elsif r.m.ctrl.wicc = '1' then icco := me_icc;
1764
    elsif r.x.ctrl.wicc = '1' then icco := r.x.icc;
1765
    else icco := r.w.s.icc; end if;
1766
    res := aluresult;
1767
  end;
1768
 
1769
  procedure dcache_gen(r, v : registers; dci : out dc_in_type;
1770
        link_pc, jump, force_a2, load : out std_ulogic) is
1771
  variable op : std_logic_vector(1 downto 0);
1772
  variable op3 : std_logic_vector(5 downto 0);
1773
  variable su : std_ulogic;
1774
  begin
1775
    op := r.e.ctrl.inst(31 downto 30); op3 := r.e.ctrl.inst(24 downto 19);
1776
    dci.signed := '0'; dci.lock := '0'; dci.dsuen := '0'; dci.size := SZWORD;
1777
    if op = LDST then
1778
    case op3 is
1779
      when LDUB | LDUBA => dci.size := SZBYTE;
1780
      when LDSTUB | LDSTUBA => dci.size := SZBYTE; dci.lock := '1';
1781
      when LDUH | LDUHA => dci.size := SZHALF;
1782
      when LDSB | LDSBA => dci.size := SZBYTE; dci.signed := '1';
1783
      when LDSH | LDSHA => dci.size := SZHALF; dci.signed := '1';
1784
      when LD | LDA | LDF | LDC => dci.size := SZWORD;
1785
      when SWAP | SWAPA => dci.size := SZWORD; dci.lock := '1';
1786
      when LDD | LDDA | LDDF | LDDC => dci.size := SZDBL;
1787
      when STB | STBA => dci.size := SZBYTE;
1788
      when STH | STHA => dci.size := SZHALF;
1789
      when ST | STA | STF => dci.size := SZWORD;
1790
      when ISTD | STDA => dci.size := SZDBL;
1791
      when STDF | STDFQ => if FPEN then dci.size := SZDBL; end if;
1792
      when STDC | STDCQ => if CPEN then dci.size := SZDBL; end if;
1793
      when others => dci.size := SZWORD; dci.lock := '0'; dci.signed := '0';
1794
    end case;
1795
    end if;
1796
 
1797
    link_pc := '0'; jump:= '0'; force_a2 := '0'; load := '0';
1798
    dci.write := '0'; dci.enaddr := '0'; dci.read := not op3(2);
1799
 
1800
-- load/store control decoding
1801
 
1802
    if (r.e.ctrl.annul = '0') then
1803
      case op is
1804
      when CALL => link_pc := '1';
1805
      when FMT3 =>
1806
        case op3 is
1807
        when JMPL => jump := '1'; link_pc := '1';
1808
        when RETT => jump := '1';
1809
        when others => null;
1810
        end case;
1811
      when LDST =>
1812
          case r.e.ctrl.cnt is
1813
          when "00" =>
1814
            dci.read := op3(3) or not op3(2);   -- LD/LDST/SWAP
1815
            load := op3(3) or not op3(2);
1816
            dci.enaddr := '1';
1817
          when "01" =>
1818
            force_a2 := not op3(2);     -- LDD
1819
            load := not op3(2); dci.enaddr := not op3(2);
1820
            if op3(3 downto 2) = "01" then              -- ST/STD
1821
              dci.write := '1';
1822
            end if;
1823
            if op3(3 downto 2) = "11" then              -- LDST/SWAP
1824
              dci.enaddr := '1';
1825
            end if;
1826
          when "10" =>                                  -- STD/LDST/SWAP
1827
            dci.write := '1';
1828
          when others => null;
1829
          end case;
1830
        if (r.e.ctrl.trap or (v.x.ctrl.trap and not v.x.ctrl.annul)) = '1' then
1831
          dci.enaddr := '0';
1832
        end if;
1833
      when others => null;
1834
      end case;
1835
    end if;
1836
 
1837
    if ((r.x.ctrl.rett and not r.x.ctrl.annul) = '1') then su := r.w.s.ps;
1838
    else su := r.w.s.s; end if;
1839
    if su = '1' then dci.asi := "00001011"; else dci.asi := "00001010"; end if;
1840
    if (op3(4) = '1') and ((op3(5) = '0') or not CPEN) then
1841
      dci.asi := r.e.ctrl.inst(12 downto 5);
1842
    end if;
1843
 
1844
  end;
1845
 
1846
  procedure fpstdata(r : in registers; edata, eres : in word; fpstdata : in std_logic_vector(31 downto 0);
1847
                       edata2, eres2 : out word) is
1848
    variable op : std_logic_vector(1 downto 0);
1849
    variable op3 : std_logic_vector(5 downto 0);
1850
  begin
1851
    edata2 := edata; eres2 := eres;
1852
    op := r.e.ctrl.inst(31 downto 30); op3 := r.e.ctrl.inst(24 downto 19);
1853
    if FPEN then
1854
      if FPEN and (op = LDST) and  ((op3(5 downto 4) & op3(2)) = "101") and (r.e.ctrl.cnt /= "00") then
1855
        edata2 := fpstdata; eres2 := fpstdata;
1856
      end if;
1857
    end if;
1858
  end;
1859
 
1860
  function ld_align(data : dcdtype; set : std_logic_vector(DSETMSB downto 0);
1861
        size, laddr : std_logic_vector(1 downto 0); signed : std_ulogic) return word is
1862
  variable align_data, rdata : word;
1863
  begin
1864
    align_data := data(conv_integer(set)); rdata := (others => '0');
1865
    case size is
1866
    when "00" =>                        -- byte read
1867
      case laddr is
1868
      when "00" =>
1869
        rdata(7 downto 0) := align_data(31 downto 24);
1870
        if signed = '1' then rdata(31 downto 8) := (others => align_data(31)); end if;
1871
      when "01" =>
1872
        rdata(7 downto 0) := align_data(23 downto 16);
1873
        if signed = '1' then rdata(31 downto 8) := (others => align_data(23)); end if;
1874
      when "10" =>
1875
        rdata(7 downto 0) := align_data(15 downto 8);
1876
        if signed = '1' then rdata(31 downto 8) := (others => align_data(15)); end if;
1877
      when others =>
1878
        rdata(7 downto 0) := align_data(7 downto 0);
1879
        if signed = '1' then rdata(31 downto 8) := (others => align_data(7)); end if;
1880
      end case;
1881
    when "01" =>                        -- half-word read
1882
      if  laddr(1) = '1' then
1883
        rdata(15 downto 0) := align_data(15 downto 0);
1884
        if signed = '1' then rdata(31 downto 15) := (others => align_data(15)); end if;
1885
      else
1886
        rdata(15 downto 0) := align_data(31 downto 16);
1887
        if signed = '1' then rdata(31 downto 15) := (others => align_data(31)); end if;
1888
      end if;
1889
    when others =>                      -- single and double word read
1890
      rdata := align_data;
1891
    end case;
1892
    return(rdata);
1893
  end;
1894
 
1895
  procedure mem_trap(r : registers; wpr : watchpoint_registers;
1896
                     annul, holdn : in std_ulogic;
1897
                     trapout, iflush, nullify, werrout : out std_ulogic;
1898
                     tt : out std_logic_vector(5 downto 0)) is
1899
  variable cwp   : std_logic_vector(NWINLOG2-1 downto 0);
1900
  variable cwpx  : std_logic_vector(5 downto NWINLOG2);
1901
  variable op : std_logic_vector(1 downto 0);
1902
  variable op2 : std_logic_vector(2 downto 0);
1903
  variable op3 : std_logic_vector(5 downto 0);
1904
  variable nalign_d : std_ulogic;
1905
  variable trap, werr : std_ulogic;
1906
  begin
1907
    op := r.m.ctrl.inst(31 downto 30); op2  := r.m.ctrl.inst(24 downto 22);
1908
    op3 := r.m.ctrl.inst(24 downto 19);
1909
    cwpx := r.m.result(5 downto NWINLOG2); cwpx(5) := '0';
1910
    iflush := '0'; trap := r.m.ctrl.trap; nullify := annul;
1911
    tt := r.m.ctrl.tt; werr := (dco.werr or r.m.werr) and not r.w.s.dwt;
1912
    nalign_d := r.m.nalign or r.m.result(2);
1913
    if ((annul or trap) /= '1') and (r.m.ctrl.pv = '1') then
1914
      if (werr and holdn) = '1' then
1915
        trap := '1'; tt := TT_DSEX; werr := '0';
1916
        if op = LDST then nullify := '1'; end if;
1917
      end if;
1918
    end if;
1919
    if ((annul or trap) /= '1') then
1920
      case op is
1921
      when FMT2 =>
1922
        case op2 is
1923
        when FBFCC =>
1924
          if FPEN and (fpo.exc = '1') then trap := '1'; tt := TT_FPEXC; end if;
1925
        when CBCCC =>
1926
          if CPEN and (cpo.exc = '1') then trap := '1'; tt := TT_CPEXC; end if;
1927
        when others => null;
1928
        end case;
1929
      when FMT3 =>
1930
        case op3 is
1931
        when WRPSR =>
1932
          if (orv(cwpx) = '1') then trap := '1'; tt := TT_IINST; end if;
1933
        when UDIV | SDIV | UDIVCC | SDIVCC =>
1934
          if DIVEN then
1935
            if r.m.divz = '1' then trap := '1'; tt := TT_DIV; end if;
1936
          end if;
1937
        when JMPL | RETT =>
1938
          if r.m.nalign = '1' then trap := '1'; tt := TT_UNALA; end if;
1939
        when TADDCCTV | TSUBCCTV =>
1940
          if (notag = 0) and (r.m.icc(1) = '1') then
1941
            trap := '1'; tt := TT_TAG;
1942
          end if;
1943
        when FLUSH => iflush := '1';
1944
        when FPOP1 | FPOP2 =>
1945
          if FPEN and (fpo.exc = '1') then trap := '1'; tt := TT_FPEXC; end if;
1946
        when CPOP1 | CPOP2 =>
1947
          if CPEN and (cpo.exc = '1') then trap := '1'; tt := TT_CPEXC; end if;
1948
        when others => null;
1949
        end case;
1950
      when LDST =>
1951
        if r.m.ctrl.cnt = "00" then
1952
          case op3 is
1953
            when LDDF | STDF | STDFQ =>
1954
            if FPEN then
1955
              if nalign_d = '1' then
1956
                trap := '1'; tt := TT_UNALA; nullify := '1';
1957
              elsif (fpo.exc and r.m.ctrl.pv) = '1'
1958
              then trap := '1'; tt := TT_FPEXC; nullify := '1'; end if;
1959
            end if;
1960
          when LDDC | STDC | STDCQ =>
1961
            if CPEN then
1962
              if nalign_d = '1' then
1963
                trap := '1'; tt := TT_UNALA; nullify := '1';
1964
              elsif ((cpo.exc and r.m.ctrl.pv) = '1')
1965
              then trap := '1'; tt := TT_CPEXC; nullify := '1'; end if;
1966
            end if;
1967
          when LDD | ISTD | LDDA | STDA =>
1968
            if r.m.result(2 downto 0) /= "000" then
1969
              trap := '1'; tt := TT_UNALA; nullify := '1';
1970
            end if;
1971
          when LDF | LDFSR | STFSR | STF =>
1972
            if FPEN and (r.m.nalign = '1') then
1973
              trap := '1'; tt := TT_UNALA; nullify := '1';
1974
            elsif FPEN and ((fpo.exc and r.m.ctrl.pv) = '1')
1975
            then trap := '1'; tt := TT_FPEXC; nullify := '1'; end if;
1976
          when LDC | LDCSR | STCSR | STC =>
1977
            if CPEN and (r.m.nalign = '1') then
1978
              trap := '1'; tt := TT_UNALA; nullify := '1';
1979
            elsif CPEN and ((cpo.exc and r.m.ctrl.pv) = '1')
1980
            then trap := '1'; tt := TT_CPEXC; nullify := '1'; end if;
1981
          when LD | LDA | ST | STA | SWAP | SWAPA =>
1982
            if r.m.result(1 downto 0) /= "00" then
1983
              trap := '1'; tt := TT_UNALA; nullify := '1';
1984
            end if;
1985
          when LDUH | LDUHA | LDSH | LDSHA | STH | STHA =>
1986
            if r.m.result(0) /= '0' then
1987
              trap := '1'; tt := TT_UNALA; nullify := '1';
1988
            end if;
1989
          when others => null;
1990
          end case;
1991
          for i in 1 to NWP loop
1992
            if ((((wpr(i-1).load and not op3(2)) or (wpr(i-1).store and op3(2))) = '1') and
1993
                (((wpr(i-1).addr xor r.m.result(31 downto 2)) and wpr(i-1).mask) = zero32(31 downto 2)))
1994
            then trap := '1'; tt := TT_WATCH; nullify := '1'; end if;
1995
          end loop;
1996
        end if;
1997
      when others => null;
1998
      end case;
1999
    end if;
2000
    if (rstn = '0') or (r.x.rstate = dsu2) then werr := '0'; end if;
2001
    trapout := trap; werrout := werr;
2002
  end;
2003
 
2004
  procedure irq_trap(r       : in registers;
2005
                     ir      : in irestart_register;
2006
                     irl     : in std_logic_vector(3 downto 0);
2007
                     annul   : in std_ulogic;
2008
                     pv      : in std_ulogic;
2009
                     trap    : in std_ulogic;
2010
                     tt      : in std_logic_vector(5 downto 0);
2011
                     nullify : in std_ulogic;
2012
                     irqen   : out std_ulogic;
2013
                     irqen2  : out std_ulogic;
2014
                     nullify2 : out std_ulogic;
2015
                     trap2, ipend  : out std_ulogic;
2016
                     tt2      : out std_logic_vector(5 downto 0)) is
2017
    variable op : std_logic_vector(1 downto 0);
2018
    variable op3 : std_logic_vector(5 downto 0);
2019
    variable pend : std_ulogic;
2020
  begin
2021
    nullify2 := nullify; trap2 := trap; tt2 := tt;
2022
    op := r.m.ctrl.inst(31 downto 30); op3 := r.m.ctrl.inst(24 downto 19);
2023
    irqen := '1'; irqen2 := r.m.irqen;
2024
 
2025
    if (annul or trap) = '0' then
2026
      if ((op = FMT3) and (op3 = WRPSR)) then irqen := '0'; end if;
2027
    end if;
2028
 
2029
    if (irl = "1111") or (irl > r.w.s.pil) then
2030
      pend := r.m.irqen and r.m.irqen2 and r.w.s.et and not ir.pwd;
2031
    else pend := '0'; end if;
2032
    ipend := pend;
2033
 
2034
    if ((not annul) and pv and (not trap) and pend) = '1' then
2035
      trap2 := '1'; tt2 := "01" & irl;
2036
      if op = LDST then nullify2 := '1'; end if;
2037
    end if;
2038
  end;
2039
 
2040
  procedure irq_intack(r : in registers; holdn : in std_ulogic; intack: out std_ulogic) is
2041
  begin
2042
    intack := '0';
2043
    if r.x.rstate = trap then
2044
      if r.w.s.tt(7 downto 4) = "0001" then intack := '1'; end if;
2045
    end if;
2046
  end;
2047
 
2048
-- write special registers
2049
 
2050
  procedure sp_write (r : registers; wpr : watchpoint_registers;
2051
        s : out special_register_type; vwpr : out watchpoint_registers) is
2052
  variable op : std_logic_vector(1 downto 0);
2053
  variable op2 : std_logic_vector(2 downto 0);
2054
  variable op3 : std_logic_vector(5 downto 0);
2055
  variable rd  : std_logic_vector(4 downto 0);
2056
  variable i   : integer range 0 to 3;
2057
  begin
2058
 
2059
    op  := r.x.ctrl.inst(31 downto 30);
2060
    op2 := r.x.ctrl.inst(24 downto 22);
2061
    op3 := r.x.ctrl.inst(24 downto 19);
2062
    s   := r.w.s;
2063
    rd  := r.x.ctrl.inst(29 downto 25);
2064
    vwpr := wpr;
2065
 
2066
      case op is
2067
      when FMT3 =>
2068
        case op3 is
2069
        when WRY =>
2070
          if rd = "00000" then
2071
            s.y := r.x.result;
2072
          elsif MACEN and (rd = "10010") then
2073
            s.asr18 := r.x.result;
2074
          elsif (rd = "10001") then
2075
            s.dwt := r.x.result(14);
2076
            if (svt = 1) then s.svt := r.x.result(13); end if;
2077
          elsif rd(4 downto 3) = "11" then -- %ASR24 - %ASR31
2078
            case rd(2 downto 0) is
2079
            when "000" =>
2080
              vwpr(0).addr := r.x.result(31 downto 2);
2081
              vwpr(0).exec := r.x.result(0);
2082
            when "001" =>
2083
              vwpr(0).mask := r.x.result(31 downto 2);
2084
              vwpr(0).load := r.x.result(1);
2085
              vwpr(0).store := r.x.result(0);
2086
            when "010" =>
2087
              vwpr(1).addr := r.x.result(31 downto 2);
2088
              vwpr(1).exec := r.x.result(0);
2089
            when "011" =>
2090
              vwpr(1).mask := r.x.result(31 downto 2);
2091
              vwpr(1).load := r.x.result(1);
2092
              vwpr(1).store := r.x.result(0);
2093
            when "100" =>
2094
              vwpr(2).addr := r.x.result(31 downto 2);
2095
              vwpr(2).exec := r.x.result(0);
2096
            when "101" =>
2097
              vwpr(2).mask := r.x.result(31 downto 2);
2098
              vwpr(2).load := r.x.result(1);
2099
              vwpr(2).store := r.x.result(0);
2100
            when "110" =>
2101
              vwpr(3).addr := r.x.result(31 downto 2);
2102
              vwpr(3).exec := r.x.result(0);
2103
            when others =>   -- "111"
2104
              vwpr(3).mask := r.x.result(31 downto 2);
2105
              vwpr(3).load := r.x.result(1);
2106
              vwpr(3).store := r.x.result(0);
2107
            end case;
2108
          end if;
2109
        when WRPSR =>
2110
          s.cwp := r.x.result(NWINLOG2-1 downto 0);
2111
          s.icc := r.x.result(23 downto 20);
2112
          s.ec  := r.x.result(13);
2113
          if FPEN then s.ef  := r.x.result(12); end if;
2114
          s.pil := r.x.result(11 downto 8);
2115
          s.s   := r.x.result(7);
2116
          s.ps  := r.x.result(6);
2117
          s.et  := r.x.result(5);
2118
        when WRWIM =>
2119
          s.wim := r.x.result(NWIN-1 downto 0);
2120
        when WRTBR =>
2121
          s.tba := r.x.result(31 downto 12);
2122
        when SAVE =>
2123
          if (not CWPOPT) and (r.w.s.cwp = CWPMIN) then s.cwp := CWPMAX;
2124
          else s.cwp := r.w.s.cwp - 1 ; end if;
2125
        when RESTORE =>
2126
          if (not CWPOPT) and (r.w.s.cwp = CWPMAX) then s.cwp := CWPMIN;
2127
          else s.cwp := r.w.s.cwp + 1; end if;
2128
        when RETT =>
2129
          if (not CWPOPT) and (r.w.s.cwp = CWPMAX) then s.cwp := CWPMIN;
2130
          else s.cwp := r.w.s.cwp + 1; end if;
2131
          s.s := r.w.s.ps;
2132
          s.et := '1';
2133
        when others => null;
2134
        end case;
2135
      when others => null;
2136
      end case;
2137
      if r.x.ctrl.wicc = '1' then s.icc := r.x.icc; end if;
2138
      if r.x.ctrl.wy = '1' then s.y := r.x.y; end if;
2139
      if MACPIPE and (r.x.mac = '1') then
2140
        s.asr18 := mulo.result(31 downto 0);
2141
        s.y := mulo.result(63 downto 32);
2142
      end if;
2143
  end;
2144
 
2145
  function npc_find (r : registers) return std_logic_vector is
2146
  variable npc : std_logic_vector(2 downto 0);
2147
  begin
2148
    npc := "011";
2149
    if r.m.ctrl.pv = '1' then npc := "000";
2150
    elsif r.e.ctrl.pv = '1' then npc := "001";
2151
    elsif r.a.ctrl.pv = '1' then npc := "010";
2152
    elsif r.d.pv = '1' then npc := "011";
2153
    elsif v8 /= 0 then npc := "100"; end if;
2154
    return(npc);
2155
  end;
2156
 
2157
  function npc_gen (r : registers) return word is
2158
  variable npc : std_logic_vector(31 downto 0);
2159
  begin
2160
    npc :=  r.a.ctrl.pc(31 downto 2) & "00";
2161
    case r.x.npc is
2162
    when "000" => npc(31 downto 2) := r.x.ctrl.pc(31 downto 2);
2163
    when "001" => npc(31 downto 2) := r.m.ctrl.pc(31 downto 2);
2164
    when "010" => npc(31 downto 2) := r.e.ctrl.pc(31 downto 2);
2165
    when "011" => npc(31 downto 2) := r.a.ctrl.pc(31 downto 2);
2166
    when others =>
2167
        if v8 /= 0 then npc(31 downto 2) := r.d.pc(31 downto 2); end if;
2168
    end case;
2169
    return(npc);
2170
  end;
2171
 
2172
  procedure mul_res(r : registers; asr18in : word; result, y, asr18 : out word;
2173
          icc : out std_logic_vector(3 downto 0)) is
2174
  variable op  : std_logic_vector(1 downto 0);
2175
  variable op3 : std_logic_vector(5 downto 0);
2176
  begin
2177
    op    := r.m.ctrl.inst(31 downto 30); op3   := r.m.ctrl.inst(24 downto 19);
2178
    result := r.m.result; y := r.m.y; icc := r.m.icc; asr18 := asr18in;
2179
    case op is
2180
    when FMT3 =>
2181
      case op3 is
2182
      when UMUL | SMUL =>
2183
        if MULEN then
2184
          result := mulo.result(31 downto 0);
2185
          y := mulo.result(63 downto 32);
2186
        end if;
2187
      when UMULCC | SMULCC =>
2188
        if MULEN then
2189
          result := mulo.result(31 downto 0); icc := mulo.icc;
2190
          y := mulo.result(63 downto 32);
2191
        end if;
2192
      when UMAC | SMAC =>
2193
        if MACEN and not MACPIPE then
2194
          result := mulo.result(31 downto 0);
2195
          asr18  := mulo.result(31 downto 0);
2196
          y := mulo.result(63 downto 32);
2197
        end if;
2198
      when UDIV | SDIV =>
2199
        if DIVEN then
2200
          result := divo.result(31 downto 0);
2201
        end if;
2202
      when UDIVCC | SDIVCC =>
2203
        if DIVEN then
2204
          result := divo.result(31 downto 0); icc := divo.icc;
2205
        end if;
2206
      when others => null;
2207
      end case;
2208
    when others => null;
2209
    end case;
2210
  end;
2211
 
2212
  function powerdwn(r : registers; trap : std_ulogic; rp : pwd_register_type) return std_ulogic is
2213
    variable op : std_logic_vector(1 downto 0);
2214
    variable op3 : std_logic_vector(5 downto 0);
2215
    variable rd  : std_logic_vector(4 downto 0);
2216
    variable pd  : std_ulogic;
2217
  begin
2218
    op := r.x.ctrl.inst(31 downto 30);
2219
    op3 := r.x.ctrl.inst(24 downto 19);
2220
    rd  := r.x.ctrl.inst(29 downto 25);
2221
    pd := '0';
2222
    if (not (r.x.ctrl.annul or trap) and r.x.ctrl.pv) = '1' then
2223
      if ((op = FMT3) and (op3 = WRY) and (rd = "10011")) then pd := '1'; end if;
2224
      pd := pd or rp.pwd;
2225
    end if;
2226
    return(pd);
2227
  end;
2228
 
2229
  signal dummy : std_ulogic;
2230
  signal cpu_index : std_logic_vector(3 downto 0);
2231
  signal disasen : std_ulogic;
2232
 
2233
begin
2234
 
2235
  comb : process(ico, dco, rfo, r, wpr, ir, dsur, rstn, holdn, irqi, dbgi, fpo, cpo, tbo,
2236
                 mulo, divo, dummy, rp)
2237
 
2238
  variable v    : registers;
2239
  variable vp   : pwd_register_type;
2240
  variable vwpr : watchpoint_registers;
2241
  variable vdsu : dsu_registers;
2242
  variable npc  : std_logic_vector(31 downto PCLOW);
2243
  variable de_raddr1, de_raddr2 : std_logic_vector(9 downto 0);
2244
  variable de_rs2, de_rd : std_logic_vector(4 downto 0);
2245
  variable de_hold_pc, de_branch, de_fpop, de_ldlock : std_ulogic;
2246
  variable de_cwp, de_cwp2 : cwptype;
2247
  variable de_inull : std_ulogic;
2248
  variable de_ren1, de_ren2 : std_ulogic;
2249
  variable de_wcwp : std_ulogic;
2250
  variable de_inst : word;
2251
  variable de_branch_address : pctype;
2252
  variable de_icc : std_logic_vector(3 downto 0);
2253
  variable de_fbranch, de_cbranch : std_ulogic;
2254
  variable de_rs1mod : std_ulogic;
2255
 
2256
  variable ra_op1, ra_op2 : word;
2257
  variable ra_div : std_ulogic;
2258
 
2259
  variable ex_jump, ex_link_pc : std_ulogic;
2260
  variable ex_jump_address : pctype;
2261
  variable ex_add_res : std_logic_vector(32 downto 0);
2262
  variable ex_shift_res, ex_logic_res, ex_misc_res : word;
2263
  variable ex_edata, ex_edata2 : word;
2264
  variable ex_dci : dc_in_type;
2265
  variable ex_force_a2, ex_load, ex_ymsb : std_ulogic;
2266
  variable ex_op1, ex_op2, ex_result, ex_result2, mul_op2 : word;
2267
  variable ex_shcnt : std_logic_vector(4 downto 0);
2268
  variable ex_dsuen : std_ulogic;
2269
  variable ex_ldbp2 : std_ulogic;
2270
  variable ex_sari : std_ulogic;
2271
 
2272
  variable me_inull, me_nullify, me_nullify2 : std_ulogic;
2273
  variable me_iflush : std_ulogic;
2274
  variable me_newtt : std_logic_vector(5 downto 0);
2275
  variable me_asr18 : word;
2276
  variable me_signed : std_ulogic;
2277
  variable me_size, me_laddr : std_logic_vector(1 downto 0);
2278
  variable me_icc : std_logic_vector(3 downto 0);
2279
 
2280
 
2281
  variable xc_result : word;
2282
  variable xc_df_result : word;
2283
  variable xc_waddr : std_logic_vector(9 downto 0);
2284
  variable xc_exception, xc_wreg : std_ulogic;
2285
  variable xc_trap_address : pctype;
2286
  variable xc_vectt : std_logic_vector(7 downto 0);
2287
  variable xc_trap : std_ulogic;
2288
  variable xc_fpexack : std_ulogic;
2289
  variable xc_rstn, xc_halt : std_ulogic;
2290
 
2291
--  variable wr_rf1_data, wr_rf2_data : word;
2292
  variable diagdata : word;
2293
  variable tbufi : tracebuf_in_type;
2294
  variable dbgm : std_ulogic;
2295
  variable fpcdbgwr : std_ulogic;
2296
  variable vfpi : fpc_in_type;
2297
  variable dsign : std_ulogic;
2298
  variable pwrd, sidle : std_ulogic;
2299
  variable vir : irestart_register;
2300
  variable icnt : std_ulogic;
2301
  variable tbufcntx : std_logic_vector(TBUFBITS-1 downto 0);
2302
 
2303
  begin
2304
 
2305
    v := r; vwpr := wpr; vdsu := dsur; vp := rp;
2306
    xc_fpexack := '0'; sidle := '0';
2307
    fpcdbgwr := '0'; vir := ir; xc_rstn := rstn;
2308
 
2309
-----------------------------------------------------------------------
2310
-- WRITE STAGE
2311
-----------------------------------------------------------------------
2312
 
2313
--    wr_rf1_data := rfo.data1; wr_rf2_data := rfo.data2;
2314
--    if irfwt = 0 then
2315
--      if r.w.wreg = '1' then
2316
--      if r.a.rfa1 = r.w.wa then wr_rf1_data := r.w.result; end if;
2317
--      if r.a.rfa2 = r.w.wa then wr_rf2_data := r.w.result; end if;
2318
--      end if;
2319
--    end if;
2320
 
2321
-----------------------------------------------------------------------
2322
-- EXCEPTION STAGE
2323
-----------------------------------------------------------------------
2324
 
2325
    xc_exception := '0'; xc_halt := '0'; icnt := '0';
2326
    xc_waddr := (others => '0');
2327
    xc_waddr(RFBITS-1 downto 0) := r.x.ctrl.rd(RFBITS-1 downto 0);
2328
    xc_trap := r.x.mexc or r.x.ctrl.trap;
2329
    v.x.nerror := rp.error;
2330
 
2331
    if r.x.mexc = '1' then xc_vectt := "00" & TT_DAEX;
2332
    elsif r.x.ctrl.tt = TT_TICC then
2333
      xc_vectt := '1' & r.x.result(6 downto 0);
2334
    else xc_vectt := "00" & r.x.ctrl.tt; end if;
2335
    if r.w.s.svt = '0' then
2336
      xc_trap_address(31 downto 4) := r.w.s.tba & xc_vectt;
2337
    else
2338
      xc_trap_address(31 downto 4) := r.w.s.tba & "00000000";
2339
    end if;
2340
    xc_trap_address(3 downto PCLOW) := (others => '0');
2341
    xc_wreg := '0'; v.x.annul_all := '0';
2342
    if (r.x.ctrl.ld = '1') then
2343
      if (lddel = 2) then
2344
        xc_result := ld_align(r.x.data, r.x.set, r.x.dci.size, r.x.laddr, r.x.dci.signed);
2345
      else xc_result := r.x.data(0); end if;
2346
    elsif MACEN and MACPIPE and (r.x.mac = '1') then
2347
      xc_result := mulo.result(31 downto 0);
2348
    else xc_result := r.x.result; end if;
2349
    xc_df_result := xc_result;
2350
    if DBGUNIT then
2351
      dbgm := dbgexc(r, dbgi, xc_trap, xc_vectt);
2352
      if (dbgi.dsuen and dbgi.dbreak) = '0'then v.x.debug := '0'; end if;
2353
    else dbgm := '0'; v.x.debug := '0'; end if;
2354
    if PWRD2 then pwrd := powerdwn(r, xc_trap, rp); else pwrd := '0'; end if;
2355
 
2356
    case r.x.rstate is
2357
    when run =>
2358
      if (not r.x.ctrl.annul and r.x.ctrl.pv and not r.x.debug) = '1' then
2359
        icnt := holdn;
2360
      end if;
2361
      if dbgm = '1' then
2362
        v.x.annul_all := '1'; vir.addr := r.x.ctrl.pc;
2363
        v.x.rstate := dsu1; v.x.debug := '1';
2364
        v.x.npc := npc_find(r);
2365
        vdsu.tt := xc_vectt; vdsu.err := dbgerr(r, dbgi, xc_vectt);
2366
      elsif (pwrd = '1') and (ir.pwd = '0') then
2367
        v.x.annul_all := '1'; vir.addr := r.x.ctrl.pc;
2368
        v.x.rstate := dsu1; v.x.npc := npc_find(r); vp.pwd := '1';
2369
      elsif (r.x.ctrl.annul or xc_trap) = '0' then
2370
        xc_wreg := r.x.ctrl.wreg;
2371
        sp_write (r, wpr, v.w.s, vwpr);
2372
        vir.pwd := '0';
2373
      elsif ((not r.x.ctrl.annul) and xc_trap) = '1' then
2374
        xc_exception := '1'; xc_result := r.x.ctrl.pc(31 downto 2) & "00";
2375
        xc_wreg := '1'; v.w.s.tt := xc_vectt; v.w.s.ps := r.w.s.s;
2376
        v.w.s.s := '1'; v.x.annul_all := '1'; v.x.rstate := trap;
2377
        xc_waddr := (others => '0');
2378
        xc_waddr(NWINLOG2 + 3  downto 0) :=  r.w.s.cwp & "0001";
2379
        v.x.npc := npc_find(r);
2380
        fpexack(r, xc_fpexack);
2381
        if r.w.s.et = '0' then
2382
--        v.x.rstate := dsu1; xc_wreg := '0'; vp.error := '1';
2383
           xc_wreg := '0';
2384
        end if;
2385
      end if;
2386
    when trap =>
2387
      xc_result := npc_gen(r); xc_wreg := '1';
2388
      xc_waddr := (others => '0');
2389
      xc_waddr(NWINLOG2 + 3  downto 0) :=  r.w.s.cwp & "0010";
2390
      if (r.w.s.et = '1') then
2391
        v.w.s.et := '0'; v.x.rstate := run;
2392
        if (not CWPOPT) and (r.w.s.cwp = CWPMIN) then v.w.s.cwp := CWPMAX;
2393
        else v.w.s.cwp := r.w.s.cwp - 1 ; end if;
2394
      else
2395
        v.x.rstate := dsu1; xc_wreg := '0'; vp.error := '1';
2396
      end if;
2397
    when dsu1 =>
2398
      xc_exception := '1'; v.x.annul_all := '1';
2399
      xc_trap_address(31 downto PCLOW) := r.f.pc;
2400
      if DBGUNIT or PWRD2 or (smp /= 0) then
2401
        xc_trap_address(31 downto PCLOW) := ir.addr;
2402
        vir.addr := npc_gen(r)(31 downto PCLOW);
2403
        v.x.rstate := dsu2;
2404
      end if;
2405
      if DBGUNIT then v.x.debug := r.x.debug; end if;
2406
    when dsu2 =>
2407
      xc_exception := '1'; v.x.annul_all := '1';
2408
      xc_trap_address(31 downto PCLOW) := r.f.pc;
2409
      if DBGUNIT or PWRD2 or (smp /= 0) then
2410
        sidle := (rp.pwd or rp.error) and ico.idle and dco.idle and not r.x.debug;
2411
        if DBGUNIT then
2412
          if dbgi.reset = '1' then
2413
            if smp /=0 then vp.pwd := not irqi.run; else vp.pwd := '0'; end if;
2414
            vp.error := '0';
2415
          end if;
2416
          if (dbgi.dsuen and dbgi.dbreak) = '1'then v.x.debug := '1'; end if;
2417
          diagwr(r, dsur, ir, dbgi, wpr, v.w.s, vwpr, vdsu.asi, xc_trap_address,
2418
            vir.addr, vdsu.tbufcnt, xc_wreg, xc_waddr, xc_result, fpcdbgwr);
2419
          xc_halt := dbgi.halt;
2420
        end if;
2421
        if r.x.ipend = '1' then vp.pwd := '0'; end if;
2422
        if (rp.error or rp.pwd or r.x.debug or xc_halt) = '0' then
2423
          v.x.rstate := run; v.x.annul_all := '0'; vp.error := '0';
2424
          xc_trap_address(31 downto PCLOW) := ir.addr; v.x.debug := '0';
2425
          vir.pwd := '1';
2426
        end if;
2427
        if (smp /= 0) and (irqi.rst = '1') then
2428
          vp.pwd := '0'; vp.error := '0';
2429
        end if;
2430
      end if;
2431
    when others =>
2432
    end case;
2433
 
2434
    irq_intack(r, holdn, v.x.intack);
2435
    itrace(r, dsur, vdsu, xc_result, xc_exception, dbgi, rp.error, xc_trap, tbufcntx, tbufi);
2436
    vdsu.tbufcnt := tbufcntx;
2437
 
2438
    v.w.except := xc_exception; v.w.result := xc_result;
2439
    if (r.x.rstate = dsu2) then v.w.except := '0'; end if;
2440
    v.w.wa := xc_waddr(RFBITS-1 downto 0); v.w.wreg := xc_wreg and holdn;
2441
 
2442
    rfi.wdata <= xc_result; rfi.waddr <= xc_waddr;
2443
    rfi.wren <= (xc_wreg and holdn) and not dco.scanen;
2444
    irqo.intack <= r.x.intack and holdn;
2445
    irqo.irl <= r.w.s.tt(3 downto 0);
2446
    irqo.pwd <= rp.pwd;
2447
    dbgo.halt <= xc_halt;
2448
    dbgo.pwd <= rp.pwd;
2449
    dbgo.idle <= sidle;
2450
    dbgo.icnt <= icnt;
2451
    dci.intack <= r.x.intack and holdn;
2452
 
2453
    if (xc_rstn = '0') then
2454
      v.w.except := '0'; v.w.s.et := '0'; v.w.s.svt := '0'; v.w.s.dwt := '0';
2455
      v.x.annul_all := '1'; v.x.rstate := run; vir.pwd := '0';
2456
      vp.pwd := '0'; v.x.debug := '0'; --vp.error := '0';
2457
      v.x.nerror := '0';
2458
      if svt = 1 then  v.w.s.tt := (others => '0'); end if;
2459
      if DBGUNIT then
2460
        if (dbgi.dsuen and dbgi.dbreak) = '1' then
2461
          v.x.rstate := dsu1; v.x.debug := '1';
2462
        end if;
2463
      end if;
2464
      if (smp /= 0) and (irqi.run = '0') and (rstn = '0') then
2465
        v.x.rstate := dsu1; vp.pwd := '1';
2466
      end if;
2467
    end if;
2468
 
2469
    if not FPEN then v.w.s.ef := '0'; end if;
2470
 
2471
-----------------------------------------------------------------------
2472
-- MEMORY STAGE
2473
-----------------------------------------------------------------------
2474
 
2475
    v.x.ctrl := r.m.ctrl; v.x.dci := r.m.dci;
2476
    v.x.ctrl.rett := r.m.ctrl.rett and not r.m.ctrl.annul;
2477
    v.x.mac := r.m.mac; v.x.laddr := r.m.result(1 downto 0);
2478
    v.x.ctrl.annul := r.m.ctrl.annul or v.x.annul_all;
2479
 
2480
    mul_res(r, v.w.s.asr18, v.x.result, v.x.y, me_asr18, me_icc);
2481
    mem_trap(r, wpr, v.x.ctrl.annul, holdn, v.x.ctrl.trap, me_iflush,
2482
             me_nullify, v.m.werr, v.x.ctrl.tt);
2483
    me_newtt := v.x.ctrl.tt;
2484
 
2485
    irq_trap(r, ir, irqi.irl, v.x.ctrl.annul, v.x.ctrl.pv, v.x.ctrl.trap, me_newtt, me_nullify,
2486
             v.m.irqen, v.m.irqen2, me_nullify2, v.x.ctrl.trap,
2487
             v.x.ipend, v.x.ctrl.tt);
2488
 
2489
    if (r.m.ctrl.ld or not dco.mds) = '1' then
2490
      for i in 0 to dsets-1 loop v.x.data(i) := dco.data(i); end loop;
2491
      v.x.set := dco.set(DSETMSB downto 0);
2492
      if dco.mds = '0' then
2493
        me_size := r.x.dci.size; me_laddr := r.x.laddr; me_signed := r.x.dci.signed;
2494
      else
2495
        me_size := v.x.dci.size; me_laddr := v.x.laddr; me_signed := v.x.dci.signed;
2496
      end if;
2497
      if lddel /= 2 then
2498
        v.x.data(0) := ld_align(v.x.data, v.x.set, me_size, me_laddr, me_signed);
2499
      end if;
2500
    end if;
2501
    v.x.mexc := dco.mexc;
2502
 
2503
    v.x.icc := me_icc;
2504
    v.x.ctrl.wicc := r.m.ctrl.wicc and not v.x.annul_all;
2505
 
2506
    if MACEN and ((v.x.ctrl.annul or v.x.ctrl.trap) = '0') then
2507
      v.w.s.asr18 := me_asr18;
2508
    end if;
2509
 
2510
    if (r.x.rstate = dsu2) then
2511
      me_nullify2 := '0'; v.x.set := dco.set(DSETMSB downto 0);
2512
    end if;
2513
 
2514
    dci.maddress <= r.m.result;
2515
    dci.enaddr   <= r.m.dci.enaddr;
2516
    dci.asi      <= r.m.dci.asi;
2517
    dci.size     <= r.m.dci.size;
2518
    dci.nullify  <= me_nullify2;
2519
    dci.lock     <= r.m.dci.lock and not r.m.ctrl.annul;
2520
    dci.read     <= r.m.dci.read;
2521
    dci.write    <= r.m.dci.write;
2522
    dci.flush    <= me_iflush;
2523
    dci.dsuen    <= r.m.dci.dsuen;
2524
    dci.msu    <= r.m.su;
2525
    dci.esu    <= r.e.su;
2526
    dbgo.ipend <= v.x.ipend;
2527
 
2528
-----------------------------------------------------------------------
2529
-- EXECUTE STAGE
2530
-----------------------------------------------------------------------
2531
 
2532
    v.m.ctrl := r.e.ctrl; ex_op1 := r.e.op1; ex_op2 := r.e.op2;
2533
    v.m.ctrl.rett := r.e.ctrl.rett and not r.e.ctrl.annul;
2534
    v.m.ctrl.wreg := r.e.ctrl.wreg and not v.x.annul_all;
2535
    ex_ymsb := r.e.ymsb; mul_op2 := ex_op2; ex_shcnt := r.e.shcnt;
2536
    v.e.cwp := r.a.cwp; ex_sari := r.e.sari;
2537
    v.m.su := r.e.su;
2538
    if MULTYPE = 3 then v.m.mul := r.e.mul; else v.m.mul := '0'; end if;
2539
 
2540
    if lddel = 1 then
2541
      if r.e.ldbp1 = '1' then
2542
        ex_op1 := r.x.data(0);
2543
        ex_sari := r.x.data(0)(31) and r.e.ctrl.inst(19) and r.e.ctrl.inst(20);
2544
      end if;
2545
      if r.e.ldbp2 = '1' then
2546
        ex_op2 := r.x.data(0); ex_ymsb := r.x.data(0)(0);
2547
        mul_op2 := ex_op2; ex_shcnt := r.x.data(0)(4 downto 0);
2548
        if r.e.invop2 = '1' then
2549
          ex_op2 := not ex_op2; ex_shcnt := not ex_shcnt;
2550
        end if;
2551
      end if;
2552
    end if;
2553
 
2554
    ex_add_res := (ex_op1 & '1') + (ex_op2 & r.e.alucin);
2555
 
2556
    if ex_add_res(2 downto 1) = "00" then v.m.nalign := '0';
2557
    else v.m.nalign := '1'; end if;
2558
 
2559
    dcache_gen(r, v, ex_dci, ex_link_pc, ex_jump, ex_force_a2, ex_load );
2560
    ex_jump_address := ex_add_res(32 downto PCLOW+1);
2561
    logic_op(r, ex_op1, ex_op2, v.x.y, ex_ymsb, ex_logic_res, v.m.y);
2562
    ex_shift_res := shift(r, ex_op1, ex_op2, ex_shcnt, ex_sari);
2563
    misc_op(r, wpr, ex_op1, ex_op2, xc_df_result, v.x.y, ex_misc_res, ex_edata);
2564
    ex_add_res(3):= ex_add_res(3) or ex_force_a2;
2565
    alu_select(r, ex_add_res, ex_op1, ex_op2, ex_shift_res, ex_logic_res,
2566
        ex_misc_res, ex_result, me_icc, v.m.icc, v.m.divz);
2567
    dbg_cache(holdn, dbgi, r, dsur, ex_result, ex_dci, ex_result2, v.m.dci);
2568
    fpstdata(r, ex_edata, ex_result2, fpo.data, ex_edata2, v.m.result);
2569
    cwp_ex(r, v.m.wcwp);
2570
 
2571
    v.m.ctrl.annul := v.m.ctrl.annul or v.x.annul_all;
2572
    v.m.ctrl.wicc := r.e.ctrl.wicc and not v.x.annul_all;
2573
    v.m.mac := r.e.mac;
2574
    if (DBGUNIT and (r.x.rstate = dsu2)) then v.m.ctrl.ld := '1'; end if;
2575
    dci.eenaddr  <= v.m.dci.enaddr;
2576
    dci.eaddress <= ex_add_res(32 downto 1);
2577
    dci.edata <= ex_edata2;
2578
 
2579
-----------------------------------------------------------------------
2580
-- REGFILE STAGE
2581
-----------------------------------------------------------------------
2582
 
2583
    v.e.ctrl := r.a.ctrl; v.e.jmpl := r.a.jmpl;
2584
    v.e.ctrl.annul := r.a.ctrl.annul or v.x.annul_all;
2585
    v.e.ctrl.rett := r.a.ctrl.rett and not r.a.ctrl.annul;
2586
    v.e.ctrl.wreg := r.a.ctrl.wreg and not v.x.annul_all;
2587
    v.e.su := r.a.su; v.e.et := r.a.et;
2588
    v.e.ctrl.wicc := r.a.ctrl.wicc and not v.x.annul_all;
2589
 
2590
    exception_detect(r, wpr, dbgi, r.a.ctrl.trap, r.a.ctrl.tt,
2591
                     v.e.ctrl.trap, v.e.ctrl.tt);
2592
    op_mux(r, rfo.data1, v.m.result, v.x.result, xc_df_result, zero32,
2593
        r.a.rsel1, v.e.ldbp1, ra_op1);
2594
    op_mux(r, rfo.data2,  v.m.result, v.x.result, xc_df_result, r.a.imm,
2595
        r.a.rsel2, ex_ldbp2, ra_op2);
2596
    alu_op(r, ra_op1, ra_op2, v.m.icc, v.m.y(0), ex_ldbp2, v.e.op1, v.e.op2,
2597
           v.e.aluop, v.e.alusel, v.e.aluadd, v.e.shcnt, v.e.sari, v.e.shleft,
2598
           v.e.ymsb, v.e.mul, ra_div, v.e.mulstep, v.e.mac, v.e.ldbp2, v.e.invop2);
2599
    cin_gen(r, v.m.icc(0), v.e.alucin);
2600
 
2601
-----------------------------------------------------------------------
2602
-- DECODE STAGE
2603
-----------------------------------------------------------------------
2604
 
2605
    if ISETS > 1 then de_inst := r.d.inst(conv_integer(r.d.set));
2606
    else de_inst := r.d.inst(0); end if;
2607
 
2608
    de_icc := r.m.icc; v.a.cwp := r.d.cwp;
2609
    su_et_select(r, v.w.s.ps, v.w.s.s, v.w.s.et, v.a.su, v.a.et);
2610
    wicc_y_gen(de_inst, v.a.ctrl.wicc, v.a.ctrl.wy);
2611
    cwp_ctrl(r, v.w.s.wim, de_inst, de_cwp, v.a.wovf, v.a.wunf, de_wcwp);
2612
    rs1_gen(r, de_inst, v.a.rs1, de_rs1mod);
2613
    de_rs2 := de_inst(4 downto 0);
2614
    de_raddr1 := (others => '0'); de_raddr2 := (others => '0');
2615
 
2616
    if RS1OPT then
2617
      if de_rs1mod = '1' then
2618
        regaddr(r.d.cwp, de_inst(29 downto 26) & v.a.rs1(0), de_raddr1(RFBITS-1 downto 0));
2619
      else
2620
        regaddr(r.d.cwp, de_inst(18 downto 15) & v.a.rs1(0), de_raddr1(RFBITS-1 downto 0));
2621
      end if;
2622
    else
2623
      regaddr(r.d.cwp, v.a.rs1, de_raddr1(RFBITS-1 downto 0));
2624
    end if;
2625
    regaddr(r.d.cwp, de_rs2, de_raddr2(RFBITS-1 downto 0));
2626
    v.a.rfa1 := de_raddr1(RFBITS-1 downto 0);
2627
    v.a.rfa2 := de_raddr2(RFBITS-1 downto 0);
2628
 
2629
    rd_gen(r, de_inst, v.a.ctrl.wreg, v.a.ctrl.ld, de_rd);
2630
    regaddr(de_cwp, de_rd, v.a.ctrl.rd);
2631
 
2632
    fpbranch(de_inst, fpo.cc, de_fbranch);
2633
    fpbranch(de_inst, cpo.cc, de_cbranch);
2634
    v.a.imm := imm_data(r, de_inst);
2635
    lock_gen(r, de_rs2, de_rd, v.a.rfa1, v.a.rfa2, v.a.ctrl.rd, de_inst,
2636
        fpo.ldlock, v.e.mul, ra_div, v.a.ldcheck1, v.a.ldcheck2, de_ldlock,
2637
        v.a.ldchkra, v.a.ldchkex);
2638
    ic_ctrl(r, de_inst, v.x.annul_all, de_ldlock, branch_true(de_icc, de_inst),
2639
        de_fbranch, de_cbranch, fpo.ccv, cpo.ccv, v.d.cnt, v.d.pc, de_branch,
2640
        v.a.ctrl.annul, v.d.annul, v.a.jmpl, de_inull, v.d.pv, v.a.ctrl.pv,
2641
        de_hold_pc, v.a.ticc, v.a.ctrl.rett, v.a.mulstart, v.a.divstart);
2642
 
2643
    cwp_gen(r, v, v.a.ctrl.annul, de_wcwp, de_cwp, v.d.cwp);
2644
 
2645
    v.d.inull := ra_inull_gen(r, v);
2646
 
2647
    op_find(r, v.a.ldchkra, v.a.ldchkex, v.a.rs1, v.a.rfa1,
2648
            false, v.a.rfe1, v.a.rsel1, v.a.ldcheck1);
2649
    op_find(r, v.a.ldchkra, v.a.ldchkex, de_rs2, v.a.rfa2,
2650
            imm_select(de_inst), v.a.rfe2, v.a.rsel2, v.a.ldcheck2);
2651
 
2652
    de_branch_address := branch_address(de_inst, r.d.pc);
2653
 
2654
    v.a.ctrl.annul := v.a.ctrl.annul or v.x.annul_all;
2655
    v.a.ctrl.wicc := v.a.ctrl.wicc and not v.a.ctrl.annul;
2656
    v.a.ctrl.wreg := v.a.ctrl.wreg and not v.a.ctrl.annul;
2657
    v.a.ctrl.rett := v.a.ctrl.rett and not v.a.ctrl.annul;
2658
    v.a.ctrl.wy := v.a.ctrl.wy and not v.a.ctrl.annul;
2659
 
2660
    v.a.ctrl.trap := r.d.mexc;
2661
    v.a.ctrl.tt := "000000";
2662
    v.a.ctrl.inst := de_inst;
2663
    v.a.ctrl.pc := r.d.pc;
2664
    v.a.ctrl.cnt := r.d.cnt;
2665
    v.a.step := r.d.step;
2666
 
2667
    if holdn = '0' then
2668
      de_raddr1(RFBITS-1 downto 0) := r.a.rfa1;
2669
      de_raddr2(RFBITS-1 downto 0) := r.a.rfa2;
2670
      de_ren1 := r.a.rfe1; de_ren2 := r.a.rfe2;
2671
    else
2672
      de_ren1 := v.a.rfe1; de_ren2 := v.a.rfe2;
2673
    end if;
2674
 
2675
    if DBGUNIT then
2676
      if ((dbgi.denable and not dbgi.dwrite) = '1') and (r.x.rstate = dsu2) then
2677
        de_raddr1(RFBITS-1 downto 0) := dbgi.daddr(RFBITS+1 downto 2); de_ren1 := '1';
2678
      end if;
2679
      v.d.step := dbgi.step and not r.d.annul;
2680
    end if;
2681
 
2682
    rfi.raddr1 <= de_raddr1; rfi.raddr2 <= de_raddr2;
2683
    rfi.ren1 <= de_ren1 and not dco.scanen;
2684
    rfi.ren2 <= de_ren2 and not dco.scanen;
2685
    rfi.diag <= dco.testen & "000";
2686
    ici.inull <= de_inull;
2687
    ici.flush <= me_iflush;
2688
    if (xc_rstn = '0') then v.d.cnt := (others => '0'); end if;
2689
 
2690
-----------------------------------------------------------------------
2691
-- FETCH STAGE
2692
-----------------------------------------------------------------------
2693
 
2694
    npc := r.f.pc;
2695
    if (xc_rstn = '0') then
2696
      v.f.pc := (others => '0'); v.f.branch := '0';
2697
      if DYNRST then v.f.pc(31 downto 12) := irqi.rstvec;
2698
      else
2699
        v.f.pc(31 downto 12) := conv_std_logic_vector(rstaddr, 20);
2700
      end if;
2701
    elsif xc_exception = '1' then       -- exception
2702
      v.f.branch := '1'; v.f.pc := xc_trap_address;
2703
      npc := v.f.pc;
2704
--    elsif (not ra_inull and de_hold_pc) = '1' then
2705
    elsif de_hold_pc = '1' then
2706
      v.f.pc := r.f.pc; v.f.branch := r.f.branch;
2707
      if ex_jump = '1' then
2708
        v.f.pc := ex_jump_address; v.f.branch := '1';
2709
        npc := v.f.pc;
2710
      end if;
2711
    elsif ex_jump = '1' then
2712
      v.f.pc := ex_jump_address; v.f.branch := '1';
2713
      npc := v.f.pc;
2714
    elsif de_branch = '1' then
2715
      v.f.pc := branch_address(de_inst, r.d.pc); v.f.branch := '1';
2716
      npc := v.f.pc;
2717
    else
2718
      v.f.branch := '0';
2719
      v.f.pc(31 downto 2) := r.f.pc(31 downto 2) + 1;    -- Address incrementer
2720
      npc := v.f.pc;
2721
    end if;
2722
 
2723
    ici.dpc <= r.d.pc(31 downto 2) & "00";
2724
    ici.fpc <= r.f.pc(31 downto 2) & "00";
2725
    ici.rpc <= npc(31 downto 2) & "00";
2726
    ici.fbranch <= r.f.branch;
2727
    ici.rbranch <= v.f.branch;
2728
    ici.su <= v.a.su;
2729
    ici.fline <= (others => '0');
2730
    ici.flushl <= '0';
2731
 
2732
    if (ico.mds and de_hold_pc) = '0' then
2733
      for i in 0 to isets-1 loop
2734
        v.d.inst(i) := ico.data(i);                     -- latch instruction
2735
      end loop;
2736
      v.d.set := ico.set(ISETMSB downto 0);             -- latch instruction
2737
      v.d.mexc := ico.mexc;                             -- latch instruction
2738
    end if;
2739
 
2740
-----------------------------------------------------------------------
2741
-----------------------------------------------------------------------
2742
 
2743
    if DBGUNIT then -- DSU diagnostic read    
2744
      diagread(dbgi, r, dsur, ir, wpr, dco, tbo, diagdata);
2745
      diagrdy(dbgi.denable, dsur, r.m.dci, dco.mds, ico, vdsu.crdy);
2746
    end if;
2747
 
2748
-----------------------------------------------------------------------
2749
-- OUTPUTS
2750
-----------------------------------------------------------------------
2751
 
2752
    rin <= v; wprin <= vwpr; dsuin <= vdsu; irin <= vir;
2753
    muli.start <= r.a.mulstart and not r.a.ctrl.annul;
2754
    muli.signed <= r.e.ctrl.inst(19);
2755
    muli.op1 <= (ex_op1(31) and r.e.ctrl.inst(19)) & ex_op1;
2756
    muli.op2 <= (mul_op2(31) and r.e.ctrl.inst(19)) & mul_op2;
2757
    muli.mac <= r.e.ctrl.inst(24);
2758
    if MACPIPE then muli.acc(39 downto 32) <= r.w.s.y(7 downto 0);
2759
    else muli.acc(39 downto 32) <= r.x.y(7 downto 0); end if;
2760
    muli.acc(31 downto 0) <= r.w.s.asr18;
2761
    muli.flush <= r.x.annul_all;
2762
    divi.start <= r.a.divstart and not r.a.ctrl.annul;
2763
    divi.signed <= r.e.ctrl.inst(19);
2764
    divi.flush <= r.x.annul_all;
2765
    divi.op1 <= (ex_op1(31) and r.e.ctrl.inst(19)) & ex_op1;
2766
    divi.op2 <= (ex_op2(31) and r.e.ctrl.inst(19)) & ex_op2;
2767
    if (r.a.divstart and not r.a.ctrl.annul) = '1' then
2768
      dsign :=  r.a.ctrl.inst(19);
2769
    else dsign := r.e.ctrl.inst(19); end if;
2770
    divi.y <= (r.m.y(31) and dsign) & r.m.y;
2771
    rpin <= vp;
2772
 
2773
    if DBGUNIT then
2774
      dbgo.dsu <= '1'; dbgo.dsumode <= r.x.debug; dbgo.crdy <= dsur.crdy(2);
2775
      dbgo.data <= diagdata;
2776
      if TRACEBUF then tbi <= tbufi; else
2777
        tbi.addr <= (others => '0'); tbi.data <= (others => '0');
2778
        tbi.enable <= '0'; tbi.write <= (others => '0'); tbi.diag <= "0000";
2779
      end if;
2780
    else
2781
      dbgo.dsu <= '0'; dbgo.data <= (others => '0'); dbgo.crdy  <= '0';
2782
      dbgo.dsumode <= '0';
2783
      tbi.addr <= (others => '0'); tbi.data <= (others => '0');
2784
      tbi.enable <= '0'; tbi.write <= (others => '0'); tbi.diag <= "0000";
2785
    end if;
2786
    dbgo.error <= dummy and not r.x.nerror;
2787
 
2788
-- pragma translate_off
2789
    if FPEN then
2790
-- pragma translate_on
2791
      vfpi.flush := v.x.annul_all; vfpi.exack := xc_fpexack; vfpi.a_rs1 := r.a.rs1; vfpi.d.inst := de_inst;
2792
      vfpi.d.cnt := r.d.cnt; vfpi.d.annul := v.x.annul_all or r.d.annul; vfpi.d.trap := r.d.mexc;
2793
      vfpi.d.pc(1 downto 0) := (others => '0'); vfpi.d.pc(31 downto PCLOW) := r.d.pc(31 downto PCLOW);
2794
      vfpi.d.pv := r.d.pv;
2795
      vfpi.a.pc(1 downto 0) := (others => '0'); vfpi.a.pc(31 downto PCLOW) := r.a.ctrl.pc(31 downto PCLOW);
2796
      vfpi.a.inst := r.a.ctrl.inst; vfpi.a.cnt := r.a.ctrl.cnt; vfpi.a.trap := r.a.ctrl.trap;
2797
      vfpi.a.annul := r.a.ctrl.annul; vfpi.a.pv := r.a.ctrl.pv;
2798
      vfpi.e.pc(1 downto 0) := (others => '0'); vfpi.e.pc(31 downto PCLOW) := r.e.ctrl.pc(31 downto PCLOW);
2799
      vfpi.e.inst := r.e.ctrl.inst; vfpi.e.cnt := r.e.ctrl.cnt; vfpi.e.trap := r.e.ctrl.trap; vfpi.e.annul := r.e.ctrl.annul;
2800
      vfpi.e.pv := r.e.ctrl.pv;
2801
      vfpi.m.pc(1 downto 0) := (others => '0'); vfpi.m.pc(31 downto PCLOW) := r.m.ctrl.pc(31 downto PCLOW);
2802
      vfpi.m.inst := r.m.ctrl.inst; vfpi.m.cnt := r.m.ctrl.cnt; vfpi.m.trap := r.m.ctrl.trap; vfpi.m.annul := r.m.ctrl.annul;
2803
      vfpi.m.pv := r.m.ctrl.pv;
2804
      vfpi.x.pc(1 downto 0) := (others => '0'); vfpi.x.pc(31 downto PCLOW) := r.x.ctrl.pc(31 downto PCLOW);
2805
      vfpi.x.inst := r.x.ctrl.inst; vfpi.x.cnt := r.x.ctrl.cnt; vfpi.x.trap := xc_trap;
2806
      vfpi.x.annul := r.x.ctrl.annul; vfpi.x.pv := r.x.ctrl.pv; vfpi.lddata := xc_df_result;--xc_result;
2807
      if r.x.rstate = dsu2 then vfpi.dbg.enable := dbgi.denable;
2808
      else vfpi.dbg.enable := '0'; end if;
2809
      vfpi.dbg.write := fpcdbgwr;
2810
      vfpi.dbg.fsr := dbgi.daddr(22); -- IU reg access
2811
      vfpi.dbg.addr := dbgi.daddr(6 downto 2);
2812
      vfpi.dbg.data := dbgi.ddata;
2813
      fpi <= vfpi;
2814
      cpi <= vfpi;  -- dummy, just to kill some warnings ...
2815
-- pragma translate_off
2816
    end if;
2817
-- pragma translate_on
2818
 
2819
  end process;
2820
 
2821
  preg : process (sclk)
2822
  begin
2823
    if rising_edge(sclk) then
2824
      rp <= rpin;
2825
      if rstn = '0' then rp.error <= '0'; end if;
2826
    end if;
2827
  end process;
2828
 
2829
  reg : process (clk)
2830
  begin
2831
    if rising_edge(clk) then
2832
      if (holdn = '1') then
2833
        r <= rin;
2834
      else
2835
        r.x.ipend <= rin.x.ipend;
2836
        r.m.werr <= rin.m.werr;
2837
        if (holdn or ico.mds) = '0' then
2838
          r.d.inst <= rin.d.inst; r.d.mexc <= rin.d.mexc;
2839
          r.d.set <= rin.d.set;
2840
        end if;
2841
        if (holdn or dco.mds) = '0' then
2842
          r.x.data <= rin.x.data; r.x.mexc <= rin.x.mexc;
2843
          r.x.set <= rin.x.set;
2844
        end if;
2845
      end if;
2846
      if rstn = '0' then
2847
        r.w.s.s <= '1';
2848
        if fabtech = axcel then
2849
          r.d.inst <= (others => (others => '0'));
2850
        end if;
2851
      end if;
2852
    end if;
2853
  end process;
2854
 
2855
 
2856
  dsugen : if DBGUNIT generate
2857
    dsureg : process(clk) begin
2858
      if rising_edge(clk) then
2859
        if holdn = '1' then
2860
          dsur <= dsuin;
2861
        else
2862
          dsur.crdy <= dsuin.crdy;
2863
        end if;
2864
      end if;
2865
    end process;
2866
  end generate;
2867
 
2868
  nodsugen : if not DBGUNIT generate
2869
    dsur.err <= '0'; dsur.tbufcnt <= (others => '0'); dsur.tt <= (others => '0');
2870
    dsur.asi <= (others => '0'); dsur.crdy <= (others => '0');
2871
  end generate;
2872
 
2873
  irreg : if (DBGUNIT or PWRD2) generate
2874
    dsureg : process(clk) begin
2875
      if rising_edge(clk) then
2876
        if holdn = '1' then ir <= irin; end if;
2877
      end if;
2878
    end process;
2879
  end generate;
2880
 
2881
  nirreg : if not (DBGUNIT or PWRD2) generate
2882
    ir.pwd <= '0'; ir.addr <= (others => '0');
2883
  end generate;
2884
 
2885
  wpgen : for i in 0 to 3 generate
2886
    wpg0 : if nwp > i generate
2887
      wpreg : process(clk) begin
2888
        if rising_edge(clk) then
2889
          if holdn = '1' then wpr(i) <= wprin(i); end if;
2890
          if rstn = '0' then
2891
            wpr(i).exec <= '0'; wpr(i).load <= '0'; wpr(i).store <= '0';
2892
          end if;
2893
        end if;
2894
      end process;
2895
    end generate;
2896
    wpg1 : if nwp <= i generate
2897
      wpr(i) <= wpr_none;
2898
    end generate;
2899
  end generate;
2900
 
2901
-- pragma translate_off
2902
  dis1 : if disas = 1 generate
2903
    trc : process(clk)
2904
      variable valid : boolean;
2905
      variable op : std_logic_vector(1 downto 0);
2906
      variable op3 : std_logic_vector(5 downto 0);
2907
      variable fpins, fpld : boolean;
2908
    begin
2909
    if (disas = 1) and rising_edge(clk) and (rstn = '1') then
2910
      if (fpu /= 0) then
2911
        op := r.x.ctrl.inst(31 downto 30); op3 := r.x.ctrl.inst(24 downto 19);
2912
        fpins := (op = FMT3) and ((op3 = FPOP1) or (op3 = FPOP2));
2913
        fpld := (op = LDST) and ((op3 = LDF) or (op3 = LDDF) or (op3 = LDFSR));
2914
      else
2915
        fpins := false; fpld := false;
2916
      end if;
2917
      valid := (((not r.x.ctrl.annul) and r.x.ctrl.pv) = '1') and
2918
        (not ((fpins or fpld) and (r.x.ctrl.trap = '0')));
2919
      valid := valid and (holdn = '1');
2920
      if rising_edge(clk) and (rstn = '1') then
2921
        print_insn (index, r.x.ctrl.pc(31 downto 2) & "00", r.x.ctrl.inst,
2922
                  rin.w.result, valid, r.x.ctrl.trap = '1', rin.w.wreg = '1', false);
2923
      end if;
2924
    end if;
2925
    end process;
2926
  end generate;
2927
-- pragma translate_on
2928
 
2929
  dis0 : if disas < 2 generate dummy <= '1'; end generate;
2930
 
2931
  dis2 : if disas > 1 generate
2932
      disasen <= '1' when disas /= 0 else '0';
2933
      cpu_index <= conv_std_logic_vector(index, 4);
2934
      x0 : cpu_disasx
2935
      port map (clk, rstn, dummy, r.x.ctrl.inst, r.x.ctrl.pc(31 downto 2),
2936
        rin.w.result, cpu_index, rin.w.wreg, r.x.ctrl.annul, holdn,
2937
        r.x.ctrl.pv, r.x.ctrl.trap, disasen);
2938
  end generate;
2939
end;

powered by: WebSVN 2.1.0

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